summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-01 10:38:58 +0000
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-01 10:38:58 +0000
commit6b30b2e679399b0af0fe436761b7e1207188abfa (patch)
tree47987182d6c74d206e1e47074caa0553e2ab6ef0 /gcc/config
parent7fb1218827e698e99f883407e8745d401b6dd84c (diff)
downloadgcc-6b30b2e679399b0af0fe436761b7e1207188abfa.tar.gz
* config/h8300/h8300-protos.h: Add a prototype for
h8300_shift_needs_scratch_p. * config/h8300/h8300.c (h8300_shift_needs_scratch_p): New. * config/h8300/h8300.h (OK_FOR_R): New. (OK_FOR_S): Likewise. (OK_FOR_T): Likewise. (EXTRA_CONSTRAINT): Call OK_FOR_R, OK_FOR_S, and OK_FOR_T. * config/h8300/h8300.md (anonymous shift patterns): Use constraints R, S, and T. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54143 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/h8300/h8300-protos.h1
-rw-r--r--gcc/config/h8300/h8300.c52
-rw-r--r--gcc/config/h8300/h8300.h20
-rw-r--r--gcc/config/h8300/h8300.md6
4 files changed, 75 insertions, 4 deletions
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index aa337d15e50..9637aeb5de1 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -41,6 +41,7 @@ extern unsigned int compute_logical_op_length PARAMS ((enum machine_mode,
rtx *));
extern int compute_logical_op_cc PARAMS ((enum machine_mode, rtx *));
extern int expand_a_shift PARAMS ((enum machine_mode, int, rtx[]));
+extern int h8300_shift_needs_scratch_p PARAMS ((int, enum machine_mode));
extern int expand_a_rotate PARAMS ((enum rtx_code, rtx[]));
extern int fix_bit_operand PARAMS ((rtx *, int, enum rtx_code));
extern int h8300_adjust_insn_length PARAMS ((rtx, int));
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 59e316192a7..89918ab7c97 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -2694,6 +2694,58 @@ get_shift_alg (shift_type, shift_mode, count, info)
info->shift2 = NULL;
}
+/* Given COUNT and MODE of a shift, return 1 if a scratch reg may be
+ needed for some shift with COUNT and MODE. Return 0 otherwise. */
+
+int
+h8300_shift_needs_scratch_p (count, mode)
+ int count;
+ enum machine_mode mode;
+{
+ int cpu;
+ int a, lr, ar;
+
+ if (GET_MODE_BITSIZE (mode) <= count)
+ return 1;
+
+ /* Find out the target CPU. */
+ if (TARGET_H8300)
+ cpu = 0;
+ else if (TARGET_H8300H)
+ cpu = 1;
+ else
+ cpu = 2;
+
+ /* Find the shift algorithm. */
+ switch (mode)
+ {
+ case QImode:
+ a = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
+ lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
+ ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
+ break;
+
+ case HImode:
+ a = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
+ lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
+ ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
+ break;
+
+ case SImode:
+ a = shift_alg_si[cpu][SHIFT_ASHIFT][count];
+ lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
+ ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* On H8/300H and H8/S, count == 8 uses the scratch register. */
+ return (a == SHIFT_LOOP || lr == SHIFT_LOOP || ar == SHIFT_LOOP
+ || (!TARGET_H8300 && mode == SImode && count == 8));
+}
+
/* Emit the assembler code for doing shifts. */
const char *
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 8109aee683c..2bee304bbe8 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -803,6 +803,21 @@ struct cum_arg
/* Extra constraints. */
+#define OK_FOR_R(OP) \
+ (GET_CODE (OP) == CONST_INT \
+ ? !h8300_shift_needs_scratch_p (INTVAL (OP), QImode) \
+ : 0)
+
+#define OK_FOR_S(OP) \
+ (GET_CODE (OP) == CONST_INT \
+ ? !h8300_shift_needs_scratch_p (INTVAL (OP), HImode) \
+ : 0)
+
+#define OK_FOR_T(OP) \
+ (GET_CODE (OP) == CONST_INT \
+ ? !h8300_shift_needs_scratch_p (INTVAL (OP), SImode) \
+ : 0)
+
/* Nonzero if X is a constant address suitable as an 8-bit absolute on
the H8/300H, which is a special case of the 'R' operand. */
@@ -840,7 +855,10 @@ struct cum_arg
&& GET_CODE (XEXP (OP, 0)) == CONST_INT))
#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'U' ? OK_FOR_U (OP) : \
+ ((C) == 'R' ? OK_FOR_R (OP) : \
+ (C) == 'S' ? OK_FOR_S (OP) : \
+ (C) == 'T' ? OK_FOR_T (OP) : \
+ (C) == 'U' ? OK_FOR_U (OP) : \
0)
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index b789a3b446a..9aa47ce8f45 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -1754,7 +1754,7 @@
[(set (match_operand:QI 0 "register_operand" "=r,r")
(match_operator:QI 3 "nshift_operator"
[ (match_operand:QI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "KM,rn")]))
+ (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
"* return output_a_shift (operands);"
@@ -1789,7 +1789,7 @@
[(set (match_operand:HI 0 "register_operand" "=r,r")
(match_operator:HI 3 "nshift_operator"
[ (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "KM,rn")]))
+ (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
"* return output_a_shift (operands);"
@@ -1824,7 +1824,7 @@
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operator:SI 3 "nshift_operator"
[ (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:QI 2 "nonmemory_operand" "K,rn")]))
+ (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
(clobber (match_scratch:QI 4 "=X,&r"))]
""
"* return output_a_shift (operands);"