OSDN Git Service

* config/mips/mips.h (PREDICATE_CODES): Add macc_msac_operand.
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 17 Apr 2004 07:02:32 +0000 (07:02 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 17 Apr 2004 07:02:32 +0000 (07:02 +0000)
* config/mips/mips.c (macc_msac_operand): New function.
* config/mips/mips.md (*msac): Move after *macc.
(*msac2): New.  Generalize macc-related peepholes so that they apply
to msac too.

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

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vr-mult-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vr-mult-2.c [new file with mode: 0644]

index 0a29202..e8f9213 100644 (file)
@@ -1,3 +1,11 @@
+2004-04-17  Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/mips/mips.h (PREDICATE_CODES): Add macc_msac_operand.
+       * config/mips/mips.c (macc_msac_operand): New function.
+       * config/mips/mips.md (*msac): Move after *macc.
+       (*msac2): New.  Generalize macc-related peepholes so that they apply
+       to msac too.
+
 2004-04-17  Paolo Bonzini  <bonzini@gnu.org>
 
        * opts.c (decode_options): Do not enable flag_rename_registers
index b8d27a3..16a1ab2 100644 (file)
@@ -1449,6 +1449,22 @@ extend_operator (rtx op, enum machine_mode mode)
          && (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND));
 }
 
+/* Return true if X is the right hand side of a "macc" or "msac" instruction.
+   This predicate is intended for use in peephole optimizations.  */
+
+int
+macc_msac_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  if (ISA_HAS_MACC && GET_CODE (x) == PLUS && REG_P (XEXP (x, 1)))
+    x = XEXP (x, 0);
+  else if (ISA_HAS_MSAC && GET_CODE (x) == MINUS && REG_P (XEXP (x, 0)))
+    x = XEXP (x, 1);
+  else
+    return false;
+
+  return GET_CODE (x) == MULT && REG_P (XEXP (x, 0)) && REG_P (XEXP (x, 1));
+}
+
 /* Return nonzero if the code of this rtx pattern is EQ or NE.  */
 
 int
index c4b7769..8bd9fb7 100644 (file)
@@ -2742,6 +2742,7 @@ typedef struct mips_args {
                                  CONST_DOUBLE, CONST }},               \
   {"fcc_register_operand",     { REG, SUBREG }},                       \
   {"hilo_operand",             { REG }},                               \
+  {"macc_msac_operand",                { PLUS, MINUS }},                       \
   {"extend_operator",          { ZERO_EXTEND, SIGN_EXTEND }},
 
 /* A list of predicates that do special things with modes, and so
index fdf3f96..0ac9444 100644 (file)
   [(set_attr "type" "imadd")
    (set_attr "mode" "SI")])
 
-;; Pattern generated by define_peephole2 below
+(define_insn "*msac"
+  [(set (match_operand:SI 0 "register_operand" "=l,d")
+        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
+                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
+                           (match_operand:SI 3 "register_operand" "d,d"))))
+   (clobber (match_scratch:SI 4 "=h,h"))
+   (clobber (match_scratch:SI 5 "=X,1"))]
+  "ISA_HAS_MSAC"
+{
+  if (which_alternative == 1)
+    return "msac\t%0,%2,%3";
+  else if (TARGET_MIPS5500)
+    return "msub\t%2,%3";
+  else
+    return "msac\t$0,%2,%3";
+}
+  [(set_attr "type"     "imadd")
+   (set_attr "mode"     "SI")])
+
+;; Patterns generated by the define_peephole2 below.
+
 (define_insn "*macc2"
   [(set (match_operand:SI 0 "register_operand" "=l")
        (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
   [(set_attr "type"    "imadd")
    (set_attr "mode"    "SI")])
 
+(define_insn "*msac2"
+  [(set (match_operand:SI 0 "register_operand" "=l")
+       (minus:SI (match_dup 0)
+                 (mult:SI (match_operand:SI 1 "register_operand" "d")
+                          (match_operand:SI 2 "register_operand" "d"))))
+   (set (match_operand:SI 3 "register_operand" "=d")
+       (minus:SI (match_dup 0)
+                 (mult:SI (match_dup 1)
+                          (match_dup 2))))
+   (clobber (match_scratch:SI 4 "=h"))]
+  "ISA_HAS_MSAC && reload_completed"
+  "msac\t%3,%1,%2"
+  [(set_attr "type"    "imadd")
+   (set_attr "mode"    "SI")])
+
 ;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2>
+;; Similarly msac.
 ;;
 ;; Operand 0: LO
-;; Operand 1: GPR (1st multiplication operand)
-;; Operand 2: GPR (2nd multiplication operand)
-;; Operand 3: HI
-;; Operand 4: GPR (destination)
+;; Operand 1: macc/msac
+;; Operand 2: HI
+;; Operand 3: GPR (destination)
 (define_peephole2
   [(parallel
        [(set (match_operand:SI 0 "register_operand" "")
-            (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "")
-                              (match_operand:SI 2 "register_operand" ""))
-                     (match_dup 0)))
-       (clobber (match_operand:SI 3 "register_operand" ""))
+            (match_operand:SI 1 "macc_msac_operand" ""))
+       (clobber (match_operand:SI 2 "register_operand" ""))
        (clobber (scratch:SI))])
-   (set (match_operand:SI 4 "register_operand" "")
+   (set (match_operand:SI 3 "register_operand" "")
        (match_dup 0))]
-  "ISA_HAS_MACC
-   && true_regnum (operands[0]) == LO_REGNUM
-   && GP_REG_P (true_regnum (operands[4]))"
+  "true_regnum (operands[0]) == LO_REGNUM
+   && GP_REG_P (true_regnum (operands[3]))"
   [(parallel [(set (match_dup 0)
-                  (plus:SI (mult:SI (match_dup 1)
-                                    (match_dup 2))
-                           (match_dup 0)))
-             (set (match_dup 4)
-                  (plus:SI (mult:SI (match_dup 1)
-                                    (match_dup 2))
-                           (match_dup 0)))
-             (clobber (match_dup 3))])]
+                  (match_dup 1))
+             (set (match_dup 3)
+                  (match_dup 1))
+             (clobber (match_dup 2))])]
   "")
 
 ;; When we have a three-address multiplication instruction, it should
 ;; Operand 1: LO
 ;; Operand 2: GPR (addend)
 ;; Operand 3: GPR (destination)
-;; Operand 4: GPR (1st multiplication operand)
-;; Operand 5: GPR (2nd multiplication operand)
-;; Operand 6: HI
+;; Operand 4: macc/msac
+;; Operand 5: HI
+;; Operand 6: new multiplication
+;; Operand 7: new addition/subtraction
 (define_peephole2
   [(match_scratch:SI 0 "d")
    (set (match_operand:SI 1 "register_operand" "")
    (match_dup 0)
    (parallel
        [(set (match_operand:SI 3 "register_operand" "")
-            (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "")
-                              (match_operand:SI 5 "register_operand" ""))
-                     (match_dup 1)))
-       (clobber (match_operand:SI 6 "register_operand" ""))
+            (match_operand:SI 4 "macc_msac_operand" ""))
+       (clobber (match_operand:SI 5 "register_operand" ""))
        (clobber (match_dup 1))])]
-  "ISA_HAS_MACC && GENERATE_MULT3_SI
+  "GENERATE_MULT3_SI
    && true_regnum (operands[1]) == LO_REGNUM
    && peep2_reg_dead_p (2, operands[1])
    && GP_REG_P (true_regnum (operands[3]))"
   [(parallel [(set (match_dup 0)
-                  (mult:SI (match_dup 4)
-                           (match_dup 5)))
-             (clobber (match_dup 6))
+                  (match_dup 6))
+             (clobber (match_dup 5))
              (clobber (match_dup 1))])
    (set (match_dup 3)
-       (plus:SI (match_dup 0)
-                (match_dup 2)))]
-  "")
+       (match_dup 7))]
+{
+  operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
+  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
+                               operands[2], operands[0]);
+})
 
 ;; Same as above, except LO is the initial target of the macc.
 ;;
 ;; Operand 0: GPR (scratch)
 ;; Operand 1: LO
 ;; Operand 2: GPR (addend)
-;; Operand 3: GPR (1st multiplication operand)
-;; Operand 4: GPR (2nd multiplication operand)
-;; Operand 5: HI
-;; Operand 6: GPR (destination)
+;; Operand 3: macc/msac
+;; Operand 4: HI
+;; Operand 5: GPR (destination)
+;; Operand 6: new multiplication
+;; Operand 7: new addition/subtraction
 (define_peephole2
   [(match_scratch:SI 0 "d")
    (set (match_operand:SI 1 "register_operand" "")
    (match_dup 0)
    (parallel
        [(set (match_dup 1)
-            (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "")
-                              (match_operand:SI 4 "register_operand" ""))
-                     (match_dup 1)))
-       (clobber (match_operand:SI 5 "register_operand" ""))
+            (match_operand:SI 3 "macc_msac_operand" ""))
+       (clobber (match_operand:SI 4 "register_operand" ""))
        (clobber (scratch:SI))])
    (match_dup 0)
-   (set (match_operand:SI 6 "register_operand" "")
+   (set (match_operand:SI 5 "register_operand" "")
        (match_dup 1))]
-  "ISA_HAS_MACC && GENERATE_MULT3_SI
+  "GENERATE_MULT3_SI
    && true_regnum (operands[1]) == LO_REGNUM
    && peep2_reg_dead_p (3, operands[1])
-   && GP_REG_P (true_regnum (operands[6]))"
+   && GP_REG_P (true_regnum (operands[5]))"
   [(parallel [(set (match_dup 0)
-                  (mult:SI (match_dup 3)
-                           (match_dup 4)))
-             (clobber (match_dup 5))
+                  (match_dup 6))
+             (clobber (match_dup 4))
              (clobber (match_dup 1))])
-   (set (match_dup 6)
-       (plus:SI (match_dup 0)
-                (match_dup 2)))]
-  "")
+   (set (match_dup 5)
+       (match_dup 7))]
+{
+  operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1);
+  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode,
+                               operands[2], operands[0]);
+})
 
 (define_insn "*mul_sub_si"
   [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
   [(set_attr "type"     "imul")
    (set_attr "mode"     "SI")])
 
-(define_insn "*msac"
-  [(set (match_operand:SI 0 "register_operand" "=l,d")
-        (minus:SI (match_operand:SI 1 "register_operand" "0,l")
-                  (mult:SI (match_operand:SI 2 "register_operand" "d,d")
-                           (match_operand:SI 3 "register_operand" "d,d"))))
-   (clobber (match_scratch:SI 4 "=h,h"))
-   (clobber (match_scratch:SI 5 "=X,1"))]
-  "ISA_HAS_MSAC"
-{
-  if (which_alternative == 1)
-    return "msac\t%0,%2,%3";
-  else if (TARGET_MIPS5500)
-    return "msub\t%2,%3";
-  else
-    return "msac\t$0,%2,%3";
-}
-  [(set_attr "type"     "imadd")
-   (set_attr "mode"     "SI")])
-
 (define_expand "muldi3"
   [(set (match_operand:DI 0 "register_operand" "")
        (mult:DI (match_operand:DI 1 "register_operand" "")
index e3fd06a..a8a7364 100644 (file)
@@ -1,3 +1,7 @@
+2004-04-17  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gcc.dg/vr-mult-[12].c: New tests.
+
 2004-04-16  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        * gcc.dg/funcorder.c: xfail hppa*64*-*-*.
diff --git a/gcc/testsuite/gcc.dg/vr-mult-1.c b/gcc/testsuite/gcc.dg/vr-mult-1.c
new file mode 100644 (file)
index 0000000..a208067
--- /dev/null
@@ -0,0 +1,10 @@
+/* Make sure that mul/addu is preferred over mtlo/macc on targets that
+   support both.  */
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-options "-O2" } */
+#if defined (_MIPS_ARCH_VR5400) || defined (_MIPS_ARCH_VR5500)
+int f (int a, int b, int c) { return a + b * c; }
+#else
+void f () { asm volatile ("mul/addu"); }
+#endif
+/* { dg-final { scan-assembler "mul.*addu" } } */
diff --git a/gcc/testsuite/gcc.dg/vr-mult-2.c b/gcc/testsuite/gcc.dg/vr-mult-2.c
new file mode 100644 (file)
index 0000000..4a3ad98
--- /dev/null
@@ -0,0 +1,10 @@
+/* Make sure that mul/subu is preferred over mtlo/msac on targets that
+   support both.  */
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-options "-O2" } */
+#if defined (_MIPS_ARCH_VR5400) || defined (_MIPS_ARCH_VR5500)
+int f (int a, int b, int c) { return a - b * c; }
+#else
+void f () { asm volatile ("mul/subu"); }
+#endif
+/* { dg-final { scan-assembler "mul.*subu" } } */