diff options
author | Paul Koning <ni1d@arrl.net> | 2018-06-28 14:50:12 -0400 |
---|---|---|
committer | Paul Koning <pkoning@gcc.gnu.org> | 2018-06-28 14:50:12 -0400 |
commit | 9cd1665b997d3cdf4d6984b6268d3d9da19dcba8 (patch) | |
tree | b72a5172e0ecaaf1d6250379e74bd185fcb3a7b6 /gcc/config/pdp11 | |
parent | a0e8e6308fa856a7783f4c60938f0c57521cb473 (diff) | |
download | gcc-9cd1665b997d3cdf4d6984b6268d3d9da19dcba8.zip gcc-9cd1665b997d3cdf4d6984b6268d3d9da19dcba8.tar.gz gcc-9cd1665b997d3cdf4d6984b6268d3d9da19dcba8.tar.bz2 |
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
Diffstat (limited to 'gcc/config/pdp11')
-rw-r--r-- | gcc/config/pdp11/pdp11-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/pdp11/pdp11.c | 29 | ||||
-rw-r--r-- | gcc/config/pdp11/pdp11.h | 16 | ||||
-rw-r--r-- | gcc/config/pdp11/pdp11.md | 13 |
4 files changed, 36 insertions, 23 deletions
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..142a5655 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 "<code><mode>_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, <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 |