diff options
| -rw-r--r-- | gcc/ChangeLog | 12 | ||||
| -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 | 
5 files changed, 87 insertions, 4 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4d913e..fed41ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-06-01  Kazu Hirata  <kazu@cs.umass.edu> + +	* 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  <rakdver@atrey.karlin.mff.cuni.cz>  	* 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 aa337d1..9637aeb 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 59e3161..89918ab 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 8109aee6..2bee304 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 b789a3b..9aa47ce 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);" | 
