diff options
author | kazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-01 10:38:58 +0000 |
---|---|---|
committer | kazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-06-01 10:38:58 +0000 |
commit | 6b30b2e679399b0af0fe436761b7e1207188abfa (patch) | |
tree | 47987182d6c74d206e1e47074caa0553e2ab6ef0 /gcc/config | |
parent | 7fb1218827e698e99f883407e8745d401b6dd84c (diff) | |
download | gcc-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.h | 1 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 52 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.h | 20 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.md | 6 |
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);" |