From 6b30b2e679399b0af0fe436761b7e1207188abfa Mon Sep 17 00:00:00 2001 From: kazu Date: Sat, 1 Jun 2002 10:38:58 +0000 Subject: [PATCH] * 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 --- gcc/ChangeLog | 12 ++++++++++ gcc/config/h8300/h8300-protos.h | 1 + gcc/config/h8300/h8300.c | 52 +++++++++++++++++++++++++++++++++++++++++ gcc/config/h8300/h8300.h | 20 +++++++++++++++- gcc/config/h8300/h8300.md | 6 ++--- 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4d913ec2c1..fed41ea17df 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-06-01 Kazu Hirata + + * 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. + Sat Jun 1 11:23:22 CEST 2002 Zdenek Dvorak * basic-block.h (struct basic_block_def): New field loop_father. 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);" -- 2.11.4.GIT