OSDN Git Service

* config/m32c/shift.md: Rewrite: Allow arbitrary operands for
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jan 2006 03:34:40 +0000 (03:34 +0000)
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jan 2006 03:34:40 +0000 (03:34 +0000)
shift counts, separate SI shifts for m32c vs m16c, pass shift type
so that constant shifts can be split.
* config/m32c/m32c.c (m32c_const_ok_for_constraint_p): Add In6.
(m32c_valid_pointer_mode): Make static.
(shift_gen_func_for): New.
(m32c_prepare_shift): Use it.  Split large const shifts into
multiple shifts.
* config/m32c/predicates.md (shiftcount_operand): Allow more
general operands.
(longshiftcount_operand): New.
* doc/md.texi (Machine Constraints): Document In6.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109661 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/m32c/m32c.c
gcc/config/m32c/predicates.md
gcc/config/m32c/shift.md
gcc/doc/md.texi

index a87c296..4da37fd 100644 (file)
@@ -1,3 +1,18 @@
+2006-01-12  DJ Delorie  <dj@redhat.com>
+
+       * config/m32c/shift.md: Rewrite: Allow arbitrary operands for
+       shift counts, separate SI shifts for m32c vs m16c, pass shift type
+       so that constant shifts can be split.
+       * config/m32c/m32c.c (m32c_const_ok_for_constraint_p): Add In6.
+       (m32c_valid_pointer_mode): Make static.
+       (shift_gen_func_for): New.
+       (m32c_prepare_shift): Use it.  Split large const shifts into
+       multiple shifts.
+       * config/m32c/predicates.md (shiftcount_operand): Allow more
+       general operands.
+       (longshiftcount_operand): New.
+       * doc/md.texi (Machine Constraints): Document In6.
+
 2006-01-13  Ben Elliston  <bje@au.ibm.com>
 
        * doc/tm.texi (Data Output): Add REAL_VALUE_TO_TARGET_DECIMAL32,
index 8712131..24b7fff 100644 (file)
@@ -901,6 +901,10 @@ m32c_const_ok_for_constraint_p (HOST_WIDE_INT value,
     {
       return (-16 <= value && value && value <= 16);
     }
+  if (memcmp (str, "In6", 3) == 0)
+    {
+      return (-32 <= value && value && value <= 32);
+    }
   if (memcmp (str, "IM2", 3) == 0)
     {
       return (-65536 <= value && value && value <= -1);
@@ -1505,7 +1509,7 @@ m32c_function_arg_regno_p (int r)
    for some opcodes in R8C/M16C and for reset vectors and such.  */
 #undef TARGET_VALID_POINTER_MODE
 #define TARGET_VALID_POINTER_MODE m32c_valid_pointer_mode
-bool
+static bool
 m32c_valid_pointer_mode (enum machine_mode mode)
 {
   if (mode == HImode
@@ -2834,27 +2838,63 @@ m32c_split_move (rtx * operands, enum machine_mode mode, int split_all)
   return rv;
 }
 
+typedef rtx (*shift_gen_func)(rtx, rtx, rtx);
+
+static shift_gen_func
+shift_gen_func_for (int mode, int code)
+{
+#define GFF(m,c,f) if (mode == m && code == c) return f
+  GFF(QImode,  ASHIFT,   gen_ashlqi3_i);
+  GFF(QImode,  ASHIFTRT, gen_ashrqi3_i);
+  GFF(QImode,  LSHIFTRT, gen_lshrqi3_i);
+  GFF(HImode,  ASHIFT,   gen_ashlhi3_i);
+  GFF(HImode,  ASHIFTRT, gen_ashrhi3_i);
+  GFF(HImode,  LSHIFTRT, gen_lshrhi3_i);
+  GFF(PSImode, ASHIFT,   gen_ashlpsi3_i);
+  GFF(PSImode, ASHIFTRT, gen_ashrpsi3_i);
+  GFF(PSImode, LSHIFTRT, gen_lshrpsi3_i);
+  GFF(SImode,  ASHIFT,   TARGET_A16 ? gen_ashlsi3_16 : gen_ashlsi3_24);
+  GFF(SImode,  ASHIFTRT, TARGET_A16 ? gen_ashrsi3_16 : gen_ashrsi3_24);
+  GFF(SImode,  LSHIFTRT, TARGET_A16 ? gen_lshrsi3_16 : gen_lshrsi3_24);
+#undef GFF
+}
+
 /* The m32c only has one shift, but it takes a signed count.  GCC
    doesn't want this, so we fake it by negating any shift count when
    we're pretending to shift the other way.  */
 int
-m32c_prepare_shift (rtx * operands, int scale, int bits)
+m32c_prepare_shift (rtx * operands, int scale, int shift_code)
 {
+  enum machine_mode mode = GET_MODE (operands[0]);
+  shift_gen_func func = shift_gen_func_for (mode, shift_code);
   rtx temp;
-  if (GET_CODE (operands[2]) == CONST_INT
-      && INTVAL (operands[2]) <= (1 << (bits - 1))
-      && INTVAL (operands[2]) >= -(1 << (bits - 1)))
+
+  if (GET_CODE (operands[2]) == CONST_INT)
     {
-      operands[2] = GEN_INT (scale * INTVAL (operands[2]));
-      return 0;
+      int maxc = TARGET_A24 && (mode == PSImode || mode == SImode) ? 32 : 8;
+      int count = INTVAL (operands[2]) * scale;
+
+      while (count > maxc)
+       {
+         temp = gen_reg_rtx (mode);
+         emit_insn (func (temp, operands[1], GEN_INT (maxc)));
+         operands[1] = temp;
+         count -= maxc;
+       }
+      while (count < -maxc)
+       {
+         temp = gen_reg_rtx (mode);
+         emit_insn (func (temp, operands[1], GEN_INT (-maxc)));
+         operands[1] = temp;
+         count += maxc;
+       }
+      emit_insn (func (operands[0], operands[1], GEN_INT (count)));
+      return 1;
     }
   if (scale < 0)
     {
       temp = gen_reg_rtx (QImode);
-      if (GET_CODE (operands[2]) == CONST_INT)
-       temp = GEN_INT (-INTVAL (operands[2]));
-      else
-       emit_move_insn (temp, gen_rtx_NEG (QImode, operands[2]));
+      emit_move_insn (temp, gen_rtx_NEG (QImode, operands[2]));
     }
   else
     temp = operands[2];
index 0c80e1a..c3b44b8 100644 (file)
 ; TRUE if we can shift by this amount.  Constant shift counts have a
 ; limited range.
 (define_predicate "shiftcount_operand"
-  (ior (match_operand 0 "m32c_pseudo" "")
+  (ior (match_operand 0 "mra_operand" "")
        (and (match_operand 2 "const_int_operand" "")
            (match_test "-8 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 8"))))
+(define_predicate "longshiftcount_operand"
+  (ior (match_operand 0 "mra_operand" "")
+       (and (match_operand 2 "const_int_operand" "")
+           (match_test "-32 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 32"))))
 
 ; TRUE for r0..r3, a0..a1, or sp.
 (define_predicate "mra_or_sp_operand"
index 95b298c..3e07b25 100644 (file)
 (define_insn "ashlqi3_i"
   [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
        (ashift:QI (match_operand:QI 1 "mra_operand" "0,0")
-                  (match_operand:QI 2 "mrai_operand" "In4,R1w")))
+                  (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   ""
   "@
    sha.b\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.b\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
   )
 
 (define_insn "ashrqi3_i"
   [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
        (ashiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
-                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   ""
   "@
    sha.b\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.b\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.b\tr1h,%0"
   )
 
-(define_insn "lshlqi3_i"
+(define_insn "lshrqi3_i"
   [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm")
        (lshiftrt:QI (match_operand:QI 1 "mra_operand" "0,0")
-                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   ""
   "@
    shl.b\t%2,%0
-   mov.b\tr1l,r1h\n\tshl.b\tr1h,%0"
+   mov.b\t%2,r1h\n\tshl.b\tr1h,%0"
   )
 
 
@@ -70,7 +70,7 @@
                   (match_operand:QI 2 "general_operand" "")))
    (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, 1, 4))
+  "if (m32c_prepare_shift (operands, 1, ASHIFT))
      DONE;"
   )
 
@@ -80,7 +80,7 @@
                     (neg:QI (match_operand:QI 2 "general_operand" ""))))
    (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
      DONE;"
   )
 
@@ -90,7 +90,7 @@
                                (neg:QI (match_operand:QI 2 "general_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
      DONE;"
   )
 
 (define_insn "ashlhi3_i"
   [(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
        (ashift:HI (match_operand:HI 1 "mra_operand" "0,0")
-                  (match_operand:QI 2 "mrai_operand" "In4,R1w")))
+                  (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   ""
   "@
    sha.w\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.w\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
   )
 
 (define_insn "ashrhi3_i"
   [(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm")
        (ashiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
-                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   ""
   "@
    sha.w\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.w\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.w\tr1h,%0"
   )
 
-(define_insn "lshlhi3_i"
+(define_insn "lshrhi3_i"
   [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,RhiSd*Rmm")
        (lshiftrt:HI (match_operand:HI 1 "mra_operand" "0,0")
-                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   ""
   "@
    shl.w\t%2,%0
-   mov.b\tr1l,r1h\n\tshl.w\tr1h,%0"
+   mov.b\t%2,r1h\n\tshl.w\tr1h,%0"
   )
 
 
                              (match_operand:QI 2 "general_operand" "")))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, 1, 4))
+  "if (m32c_prepare_shift (operands, 1, ASHIFT))
      DONE;"
   )
 
                                (neg:QI (match_operand:QI 2 "general_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
      DONE;"
   )
 
                                (neg:QI (match_operand:QI 2 "general_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
      DONE;"
   )
 
 (define_insn "ashlpsi3_i"
   [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
        (ashift:PSI (match_operand:PSI 1 "mra_operand" "0,0")
-                   (match_operand:QI 2 "mrai_operand" "In4,R1w")))
+                   (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   "TARGET_A24"
   "@
    sha.l\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
   )
 
 (define_insn "ashrpsi3_i"
   [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm")
        (ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
-                     (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                     (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   "TARGET_A24"
   "@
    sha.l\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
   )
 
-(define_insn "lshlpsi3_i"
+(define_insn "lshrpsi3_i"
   [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd,??Rmm")
        (lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0")
-                     (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,R1w"))))
+                     (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
   "TARGET_A24"
   "@
    shl.l\t%2,%0
-   mov.b\tr1l,r1h\n\tshl.l\tr1h,%0"
+   mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
   )
 
 
                               (match_operand:QI 2 "mrai_operand" "")))
              (clobber (match_scratch:HI 3 ""))])]
   "TARGET_A24"
-  "if (m32c_prepare_shift (operands, 1, 4))
+  "if (m32c_prepare_shift (operands, 1, ASHIFT))
      DONE;"
   )
 
                                 (neg:QI (match_operand:QI 2 "mrai_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   "TARGET_A24"
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
      DONE;"
   )
 
                                 (neg:QI (match_operand:QI 2 "mrai_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   "TARGET_A24"
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
      DONE;"
   )
 
 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
+; The m16c has a maximum shift count of -16..16, even when in a
+; register.  It's optimal to use multiple shifts of -8..8 rather than
+; loading larger constants into R1H multiple time.  The m32c can shift
+; -32..32 either via immediates or in registers.  Hence, separate
+; patterns.
 
 
-(define_insn "ashlsi3_i"
+(define_insn "ashlsi3_16"
   [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
        (ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
-                  (match_operand:QI 2 "mrai_operand" "In4,R1w")))
+                  (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
-  ""
+  "TARGET_A16"
   "@
    sha.l\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
+  [(set_attr "flags" "sz,sz")]
   )
 
-(define_insn "ashrsi3_i"
+(define_insn "ashrsi3_16"
   [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
        (ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
-                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                    (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
-  ""
+  "TARGET_A16"
   "@
    sha.l\t%2,%0
-   mov.b\tr1l,r1h\n\tsha.l\tr1h,%0"
+   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
   )
 
-(define_insn "lshlsi3_i"
+(define_insn "lshrsi3_16"
   [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
        (lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
-                    (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w"))))
+                    (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))))
    (clobber (match_scratch:HI 3 "=X,R1w"))]
-  ""
+  "TARGET_A16"
   "@
    shl.l\t%2,%0
-   mov.b\tr1l,r1h\n\tshl.l\tr1h,%0"
+   mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
+  )
+
+
+
+(define_insn "ashlsi3_24"
+  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
+       (ashift:SI (match_operand:SI 1 "r0123_operand" "0,0")
+                  (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd")))
+   (clobber (match_scratch:HI 3 "=X,R1w"))]
+  "TARGET_A24"
+  "@
+   sha.l\t%2,%0
+   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
   )
 
+(define_insn "ashrsi3_24"
+  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
+       (ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
+                    (neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))))
+   (clobber (match_scratch:HI 3 "=X,R1w"))]
+  "TARGET_A24"
+  "@
+   sha.l\t%2,%0
+   mov.b\t%2,r1h\n\tsha.l\tr1h,%0"
+  )
+
+(define_insn "lshrsi3_24"
+  [(set (match_operand:SI 0 "r0123_operand" "=R03,R03")
+       (lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0")
+                    (neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))))
+   (clobber (match_scratch:HI 3 "=X,R1w"))]
+  "TARGET_A24"
+  "@
+   shl.l\t%2,%0
+   mov.b\t%2,r1h\n\tshl.l\tr1h,%0"
+  )
+
+
+
 
 (define_expand "ashlsi3"
   [(parallel [(set (match_operand:SI 0 "r0123_operand" "")
-       (ashift:SI (match_operand:SI 1 "r0123_operand" "")
-                  (match_operand:QI 2 "mrai_operand" "")))
+                  (ashift:SI (match_operand:SI 1 "r0123_operand" "")
+                             (match_operand:QI 2 "mrai_operand" "")))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, 1, 4))
+  "if (m32c_prepare_shift (operands, 1, ASHIFT))
      DONE;"
   )
 
                                (neg:QI (match_operand:QI 2 "mrai_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, -1, 4))
+  "if (m32c_prepare_shift (operands, -1, ASHIFTRT))
      DONE;"
   )
 
                                (neg:QI (match_operand:QI 2 "mrai_operand" ""))))
              (clobber (match_scratch:HI 3 ""))])]
   ""
-  "if (m32c_prepare_shift (operands, -1, 5))
+  "if (m32c_prepare_shift (operands, -1, LSHIFTRT))
      DONE;"
   )
index cce838d..90efcc3 100644 (file)
@@ -2323,8 +2323,8 @@ Used to match function return values.
 @item In5
 -16 @dots{} -1 or 1 @dots{} 16
 
-@item In4
--8 @dots{} -1 or 1 @dots{} 8
+@item In6
+-32 @dots{} -1 or 1 @dots{} 32
 
 @item IM2
 -65536 @dots{} -1