This patch corrects the setting of the "length" attributes in the pdp11 target for certain shift cases.
Committed. paul ChangeLog: 2018-06-28 Paul Koning <n...@arrl.net> * 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. Index: config/pdp11/pdp11-protos.h =================================================================== --- config/pdp11/pdp11-protos.h (revision 262198) +++ config/pdp11/pdp11-protos.h (working copy) @@ -41,6 +41,7 @@ extern machine_mode pdp11_cc_mode (enum rtx_code, 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 */ Index: config/pdp11/pdp11.c =================================================================== --- config/pdp11/pdp11.c (revision 262198) +++ config/pdp11/pdp11.c (working copy) @@ -2020,6 +2020,35 @@ pdp11_assemble_shift (rtx *operands, machine_mode 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 ? Index: config/pdp11/pdp11.h =================================================================== --- config/pdp11/pdp11.h (revision 262198) +++ config/pdp11/pdp11.h (working copy) @@ -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. */ Index: config/pdp11/pdp11.md =================================================================== --- config/pdp11/pdp11.md (revision 262198) +++ config/pdp11/pdp11.md (working copy) @@ -1297,11 +1297,6 @@ ;; 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 "<code><mode>_sc" [(set (match_operand:QHSint 0 "nonimmediate_operand" "=rD,Q") (SHF:QHSint (match_operand:QHSint 1 "general_operand" "0,0") @@ -1308,7 +1303,9 @@ (match_operand:HI 2 "expand_shift_operand" "O,O")))] "" "* return pdp11_assemble_shift (operands, <QHSint:mname>, <CODE>);" - [(set_attr "length" "2,4")]) + [(set (attr "length") + (symbol_ref "pdp11_shift_length (operands, <QHSint:mname>, + <CODE>, 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, <QHSint:mname>, <CODE>);" - [(set_attr "length" "2,4")]) + [(set (attr "length") + (symbol_ref "pdp11_shift_length (operands, <QHSint:mname>, + <CODE>, 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