aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pdp11
diff options
context:
space:
mode:
authorPaul Koning <ni1d@arrl.net>2018-06-28 14:50:12 -0400
committerPaul Koning <pkoning@gcc.gnu.org>2018-06-28 14:50:12 -0400
commit9cd1665b997d3cdf4d6984b6268d3d9da19dcba8 (patch)
treeb72a5172e0ecaaf1d6250379e74bd185fcb3a7b6 /gcc/config/pdp11
parenta0e8e6308fa856a7783f4c60938f0c57521cb473 (diff)
downloadgcc-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.h1
-rw-r--r--gcc/config/pdp11/pdp11.c29
-rw-r--r--gcc/config/pdp11/pdp11.h16
-rw-r--r--gcc/config/pdp11/pdp11.md13
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