aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-04-17 07:02:32 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-04-17 07:02:32 +0000
commit3bd06df78aded83cc747f067fb57b5c666046efa (patch)
treeddbb0765cad6fa08e7d2e3e69d8d639d767011fe
parent38d396e511338696ce8953e36b0fa838e9f3ce7a (diff)
downloadgcc-3bd06df78aded83cc747f067fb57b5c666046efa.zip
gcc-3bd06df78aded83cc747f067fb57b5c666046efa.tar.gz
gcc-3bd06df78aded83cc747f067fb57b5c666046efa.tar.bz2
mips.h (PREDICATE_CODES): Add macc_msac_operand.
* 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. From-SVN: r80790
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/mips/mips.c16
-rw-r--r--gcc/config/mips/mips.h1
-rw-r--r--gcc/config/mips/mips.md155
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/vr-mult-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/vr-mult-2.c10
7 files changed, 132 insertions, 72 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a29202..e8f9213 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b8d27a3..16a1ab2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index c4b7769..8bd9fb71 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index fdf3f96..0ac9444 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1678,7 +1678,27 @@
[(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")
@@ -1694,35 +1714,43 @@
[(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
@@ -1736,9 +1764,10 @@
;; 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" "")
@@ -1746,34 +1775,35 @@
(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" "")
@@ -1781,27 +1811,27 @@
(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")
@@ -1873,25 +1903,6 @@
[(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" "")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e3fd06a..a8a7364 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..a208067
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vr-mult-1.c
@@ -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
index 0000000..4a3ad98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vr-mult-2.c
@@ -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" } } */