From 9cd1665b997d3cdf4d6984b6268d3d9da19dcba8 Mon Sep 17 00:00:00 2001 From: Paul Koning Date: Thu, 28 Jun 2018 14:50:12 -0400 Subject: [PATCH] Fix insn length for pdp11 shift patterns. * config/pdp11/pdp11-protos.h (pdp11_shift_length): New function. * config/pdp11/pdp11.c (pdp11_shift_length): New function. * config/pdp11/pdp11.h (ADJUST_INSN_LENGTH): Remove. * config/pdp11/pdp11.md: Correct "length" attribute calculation for shift insn patterns. From-SVN: r262227 --- gcc/ChangeLog | 8 ++++++++ gcc/config/pdp11/pdp11-protos.h | 1 + gcc/config/pdp11/pdp11.c | 29 +++++++++++++++++++++++++++++ gcc/config/pdp11/pdp11.h | 16 ---------------- gcc/config/pdp11/pdp11.md | 13 ++++++------- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92e31fc..1edab9e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-06-28 Paul Koning + + * config/pdp11/pdp11-protos.h (pdp11_shift_length): New function. + * config/pdp11/pdp11.c (pdp11_shift_length): New function. + * config/pdp11/pdp11.h (ADJUST_INSN_LENGTH): Remove. + * config/pdp11/pdp11.md: Correct "length" attribute calculation + for shift insn patterns. + 2018-06-28 David Malcolm * cgraph.c (cgraph_node::get_body): Replace assignments to diff --git a/gcc/config/pdp11/pdp11-protos.h b/gcc/config/pdp11/pdp11-protos.h index 4536323..754a29d 100644 --- a/gcc/config/pdp11/pdp11-protos.h +++ b/gcc/config/pdp11/pdp11-protos.h @@ -41,6 +41,7 @@ extern machine_mode pdp11_cc_mode (enum rtx_code, rtx, rtx); extern bool pdp11_expand_shift (rtx *, rtx (*) (rtx, rtx, rtx), rtx (*) (rtx, rtx, rtx)); extern const char * pdp11_assemble_shift (rtx *, machine_mode, int); +extern int pdp11_shift_length (rtx *, machine_mode, int, bool); extern bool pdp11_small_shift (int); #endif /* RTX_CODE */ diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c index ab73693..142a565 100644 --- a/gcc/config/pdp11/pdp11.c +++ b/gcc/config/pdp11/pdp11.c @@ -2020,6 +2020,35 @@ pdp11_assemble_shift (rtx *operands, machine_mode m, int code) return ""; } +/* Figure out the length of the instructions that will be produced for + the given operands by pdp11_assemble_shift above. */ +int +pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand_p) +{ + int shift_size; + + /* Shift by 1 is 2 bytes if simple operand, 4 bytes if 2-word addressing mode. */ + shift_size = simple_operand_p ? 2 : 4; + + /* In SImode, two shifts are needed per data item. */ + if (m == E_SImode) + shift_size *= 2; + + /* If shifting by a small constant, the loop is unrolled by the + shift count. Otherwise, account for the size of the decrement + and branch. */ + if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]))) + shift_size *= INTVAL (operands[2]); + else + shift_size += 4; + + /* Logical right shift takes one more instruction (CLC). */ + if (code == LSHIFTRT) + shift_size += 2; + + return shift_size; +} + /* Worker function for TARGET_TRAMPOLINE_INIT. trampoline - how should i do it in separate i+d ? diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h index f995bc8..67386ca 100644 --- a/gcc/config/pdp11/pdp11.h +++ b/gcc/config/pdp11/pdp11.h @@ -123,22 +123,6 @@ extern const struct real_format pdp11_d_format; /* Define this if move instructions will actually fail to work when given unaligned data. */ #define STRICT_ALIGNMENT 1 - -/* Adjust the length of shifts by small constant amounts. The base - value (in "length" on input) is the length of a shift by one, not - including the CLC in logical shifts. */ -#define ADJUST_INSN_LENGTH(insn, length) \ - if ((GET_CODE (insn) == ASHIFT || \ - GET_CODE (insn) == ASHIFTRT || \ - GET_CODE (insn) == LSHIFTRT) && \ - GET_CODE (XEXP (insn, 2)) == CONST_INT && \ - pdp11_small_shift (XINT (insn, 2))) \ - { \ - if (GET_CODE (insn) == LSHIFTRT) \ - length = (length * XINT (insn, 2)) + 2; \ - else \ - length *= XINT (insn, 2); \ - } /* Standard register usage. */ diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md index 1dd069f..6592a2c 100644 --- a/gcc/config/pdp11/pdp11.md +++ b/gcc/config/pdp11/pdp11.md @@ -1297,18 +1297,15 @@ ;; used to reduce the amount of very similar code. ;; ;; First the insns used for small constant shifts. -; -;; The "length" attribute values are modified by the ADJUST_INSN_LENGTH -;; macro for the small constant shift case (first two alternatives). -;; For those, the value coded in the length attribute is the cost of just -;; the shift for a single shift. (define_insn "_sc" [(set (match_operand:QHSint 0 "nonimmediate_operand" "=rD,Q") (SHF:QHSint (match_operand:QHSint 1 "general_operand" "0,0") (match_operand:HI 2 "expand_shift_operand" "O,O")))] "" "* return pdp11_assemble_shift (operands, , );" - [(set_attr "length" "2,4")]) + [(set (attr "length") + (symbol_ref "pdp11_shift_length (operands, , + , which_alternative == 0)"))]) ;; Next, shifts that are done as a loop on base (11/10 class) machines. ;; This applies to shift counts too large to unroll, or variable shift @@ -1320,7 +1317,9 @@ (clobber (match_dup 2))] "" "* return pdp11_assemble_shift (operands, , );" - [(set_attr "length" "2,4")]) + [(set (attr "length") + (symbol_ref "pdp11_shift_length (operands, , + , which_alternative == 0)"))]) ;; Next the insns that use the extended instructions ash and ashc. ;; Note that these are just left shifts, and HI/SI only. (Right shifts -- 2.7.4