h8300-protos.h: Add a prototype for h8300_shift_needs_scratch_p.
authorKazu Hirata <kazu@cs.umass.edu>
Sat, 1 Jun 2002 10:38:58 +0000 (10:38 +0000)
committerKazu Hirata <kazu@gcc.gnu.org>
Sat, 1 Jun 2002 10:38:58 +0000 (10:38 +0000)
* 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.

From-SVN: r54143

gcc/ChangeLog
gcc/config/h8300/h8300-protos.h
gcc/config/h8300/h8300.c
gcc/config/h8300/h8300.h
gcc/config/h8300/h8300.md

index a4d913e..fed41ea 100644 (file)
@@ -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.
index aa337d1..9637aeb 100644 (file)
@@ -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));
index 59e3161..89918ab 100644 (file)
@@ -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 *
index 8109aee..2bee304 100644 (file)
@@ -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)
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
index b789a3b..9aa47ce 100644 (file)
   [(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);"
   [(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);"
   [(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);"