aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2008-11-17 22:49:05 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2008-11-17 22:49:05 +0000
commit4d58b18004958593229d258b2e4b87fd743a1b47 (patch)
tree36cb3165b921ef395682a3eab8b8469d2af9cc09
parent0f0f2f885709405eb008b6c17d962f646d7a51c9 (diff)
gcc/
* config/mips/mips.md (*mul_acc_si): Remove middle alternative and its associated define_split. Expose the all-d alternative to the register allocator, but mark it with "?". Mark the first alternative with "*?*?". (*mul_sub_si): Likewise. (*mul_acc_si_r3900): New pattern. gcc/testsuite/ * gcc.target/mips/madd-5.c: New test. * gcc.target/mips/madd-6.c: Likewise. * gcc.target/mips/madd-7.c: Likewise. * gcc.target/mips/madd-8.c: Likewise. * gcc.target/mips/msub-5.c: Likewise. * gcc.target/mips/msub-6.c: Likewise. * gcc.target/mips/msub-7.c: Likewise. * gcc.target/mips/msub-8.c: Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@141954 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/mips/mips.md113
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-5.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-6.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-7.c14
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-8.c15
-rw-r--r--gcc/testsuite/gcc.target/mips/msub-5.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/msub-6.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/msub-7.c14
-rw-r--r--gcc/testsuite/gcc.target/mips/msub-8.c15
11 files changed, 153 insertions, 66 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff382751044..37bedc06aea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.md (*mul_acc_si): Remove middle alternative
+ and its associated define_split. Expose the all-d alternative
+ to the register allocator, but mark it with "?". Mark the first
+ alternative with "*?*?".
+ (*mul_sub_si): Likewise.
+ (*mul_acc_si_r3900): New pattern.
+
2008-11-17 Jakub Jelinek <jakub@redhat.com>
PR middle-end/38140
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 222e41d7369..92e637c5a58 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1474,34 +1474,50 @@
;; Multiply-accumulate patterns
-;; For processors that can copy the output to a general register:
-;;
-;; The all-d alternative is needed because the combiner will find this
-;; pattern and then register alloc/reload will move registers around to
-;; make them fit, and we don't want to trigger unnecessary loads to LO.
-;;
-;; The last alternative should be made slightly less desirable, but adding
-;; "?" to the constraint is too strong, and causes values to be loaded into
-;; LO even when that's more costly. For now, using "*d" mostly does the
-;; trick.
+;; This pattern is first matched by combine, which tries to use the
+;; pattern wherever it can. We don't know until later whether it
+;; is actually profitable to use MADD over a "MUL; ADDIU" sequence,
+;; so we need to keep both options open.
+;;
+;; The second alternative has a "?" marker because it is generally
+;; one instruction more costly than the first alternative. This "?"
+;; marker is enough to convey the relative costs to the register
+;; allocator.
+;;
+;; However, reload counts reloads of operands 4 and 5 in the same way as
+;; reloads of the other operands, even though operands 4 and 5 need no
+;; copy instructions. Reload therefore thinks that the second alternative
+;; is two reloads more costly than the first. We add "*?*?" to the first
+;; alternative as a counterweight.
(define_insn "*mul_acc_si"
- [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
+ [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
+ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "register_operand" "d,d"))
+ (match_operand:SI 3 "register_operand" "0,d")))
+ (clobber (match_scratch:SI 4 "=X,l"))
+ (clobber (match_scratch:SI 5 "=X,&d"))]
+ "GENERATE_MADD_MSUB && !TARGET_MIPS16"
+ "@
+ madd\t%1,%2
+ #"
+ [(set_attr "type" "imadd")
+ (set_attr "mode" "SI")
+ (set_attr "length" "4,8")])
+
+;; The same idea applies here. The middle alternative needs one less
+;; clobber than the final alternative, so we add "*?" as a counterweight.
+(define_insn "*mul_acc_si_r3900"
+ [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
(match_operand:SI 2 "register_operand" "d,d,d"))
- (match_operand:SI 3 "register_operand" "0,l,*d")))
+ (match_operand:SI 3 "register_operand" "0,l,d")))
(clobber (match_scratch:SI 4 "=X,3,l"))
(clobber (match_scratch:SI 5 "=X,X,&d"))]
- "(TARGET_MIPS3900
- || GENERATE_MADD_MSUB)
- && !TARGET_MIPS16"
-{
- static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" };
- if (which_alternative == 2)
- return "#";
- if (GENERATE_MADD_MSUB && which_alternative != 0)
- return "#";
- return madd[which_alternative];
-}
+ "TARGET_MIPS3900 && !TARGET_MIPS16"
+ "@
+ madd\t%1,%2
+ madd\t%0,%1,%2
+ #"
[(set_attr "type" "imadd")
(set_attr "mode" "SI")
(set_attr "length" "4,4,8")])
@@ -1522,23 +1538,6 @@
(set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))]
"")
-;; Split *mul_acc_si if the destination accumulator value is in a GPR
-;; and the source accumulator value is in LO.
-(define_split
- [(set (match_operand:SI 0 "d_operand")
- (plus:SI (mult:SI (match_operand:SI 1 "d_operand")
- (match_operand:SI 2 "d_operand"))
- (match_operand:SI 3 "lo_operand")))
- (clobber (match_dup 3))
- (clobber (scratch:SI))]
- "reload_completed"
- [(parallel [(set (match_dup 3)
- (plus:SI (mult:SI (match_dup 1) (match_dup 2))
- (match_dup 3)))
- (clobber (scratch:SI))
- (clobber (scratch:SI))])
- (set (match_dup 0) (match_dup 3))])
-
(define_insn "*macc"
[(set (match_operand:SI 0 "register_operand" "=l,d")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1718,21 +1717,21 @@
operands[2], operands[0]);
})
+;; See the comment above *mul_add_si for details.
(define_insn "*mul_sub_si"
- [(set (match_operand:SI 0 "register_operand" "=l,*d,*d")
- (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d")
- (mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
- (match_operand:SI 3 "register_operand" "d,d,d"))))
- (clobber (match_scratch:SI 4 "=X,1,l"))
- (clobber (match_scratch:SI 5 "=X,X,&d"))]
+ [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,d")
+ (mult:SI (match_operand:SI 2 "register_operand" "d,d")
+ (match_operand:SI 3 "register_operand" "d,d"))))
+ (clobber (match_scratch:SI 4 "=X,l"))
+ (clobber (match_scratch:SI 5 "=X,&d"))]
"GENERATE_MADD_MSUB"
"@
msub\t%2,%3
- #
#"
[(set_attr "type" "imadd")
(set_attr "mode" "SI")
- (set_attr "length" "4,8,8")])
+ (set_attr "length" "4,8")])
;; Split *mul_sub_si if both the source and destination accumulator
;; values are GPRs.
@@ -1750,24 +1749,6 @@
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))]
"")
-;; Split *mul_acc_si if the destination accumulator value is in a GPR
-;; and the source accumulator value is in LO.
-(define_split
- [(set (match_operand:SI 0 "d_operand")
- (minus:SI (match_operand:SI 1 "lo_operand")
- (mult:SI (match_operand:SI 2 "d_operand")
- (match_operand:SI 3 "d_operand"))))
- (clobber (match_dup 1))
- (clobber (scratch:SI))]
- "reload_completed"
- [(parallel [(set (match_dup 1)
- (minus:SI (match_dup 1)
- (mult:SI (match_dup 2) (match_dup 3))))
- (clobber (scratch:SI))
- (clobber (scratch:SI))])
- (set (match_dup 0) (match_dup 1))]
- "")
-
(define_insn "*muls"
[(set (match_operand:SI 0 "register_operand" "=l,d")
(neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2b90e3dc361..1d97976cf7b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,16 @@
2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
+ * gcc.target/mips/madd-5.c: New test.
+ * gcc.target/mips/madd-6.c: Likewise.
+ * gcc.target/mips/madd-7.c: Likewise.
+ * gcc.target/mips/madd-8.c: Likewise.
+ * gcc.target/mips/msub-5.c: Likewise.
+ * gcc.target/mips/msub-6.c: Likewise.
+ * gcc.target/mips/msub-7.c: Likewise.
+ * gcc.target/mips/msub-8.c: Likewise.
+
+2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
+
* gcc.target/mips/no-smartmips-ror-1.c: Use -march=mips32 instead
of -march=mips32r2.
diff --git a/gcc/testsuite/gcc.target/mips/madd-5.c b/gcc/testsuite/gcc.target/mips/madd-5.c
new file mode 100644
index 00000000000..780194dc7e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-5.c
@@ -0,0 +1,8 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler-times "\tmadd\t" 4 } } */
+/* { dg-final { scan-assembler-not "\tmtlo\t" } } */
+/* { dg-final { scan-assembler-times "\tmflo\t" 3 } } */
+
+NOMIPS16 void f1 (int *a) { a[0] = a[0] * a[1] + a[2] * a[3]; }
+NOMIPS16 void f2 (int *a) { a[0] = a[0] * a[1] + a[2] * a[3] + a[4]; }
+NOMIPS16 void f3 (int *a) { a[0] = a[0] * a[1] + a[2] * a[3] + a[4] * a[5]; }
diff --git a/gcc/testsuite/gcc.target/mips/madd-6.c b/gcc/testsuite/gcc.target/mips/madd-6.c
new file mode 100644
index 00000000000..bbb6783d4a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-6.c
@@ -0,0 +1,6 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler-not "\tmadd\t" } } */
+/* { dg-final { scan-assembler "\tmul\t" } } */
+/* { dg-final { scan-assembler "\taddu\t" } } */
+
+NOMIPS16 void f1 (int *a) { a[0] = a[0] * a[1] + a[2]; }
diff --git a/gcc/testsuite/gcc.target/mips/madd-7.c b/gcc/testsuite/gcc.target/mips/madd-7.c
new file mode 100644
index 00000000000..25fd07db128
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-7.c
@@ -0,0 +1,14 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler-not "\tmul\t" } } */
+/* { dg-final { scan-assembler "\tmadd\t" } } */
+
+NOMIPS16 int
+f1 (int *a, int *b, int n)
+{
+ int x, i;
+
+ x = 0;
+ for (i = 0; i < n; i++)
+ x += a[i] * b[i];
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/mips/madd-8.c b/gcc/testsuite/gcc.target/mips/madd-8.c
new file mode 100644
index 00000000000..0fc680e5979
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-8.c
@@ -0,0 +1,15 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler "\tmul\t" } } */
+/* { dg-final { scan-assembler-not "\tmadd\t" } } */
+/* { dg-final { scan-assembler-not "\tmtlo\t" } } */
+/* { dg-final { scan-assembler-not "\tmflo\t" } } */
+
+NOMIPS16 int
+f2 (int x, int y, int z)
+{
+ asm volatile ("" ::: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17",
+ "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25",
+ "$31");
+ return x * y + z;
+}
diff --git a/gcc/testsuite/gcc.target/mips/msub-5.c b/gcc/testsuite/gcc.target/mips/msub-5.c
new file mode 100644
index 00000000000..675da64a5e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msub-5.c
@@ -0,0 +1,8 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler-times "\tmsub\t" 4 } } */
+/* { dg-final { scan-assembler-not "\tmtlo\t" } } */
+/* { dg-final { scan-assembler-times "\tmflo\t" 3 } } */
+
+NOMIPS16 void f1 (int *a) { a[0] = a[0] * a[1] - a[2] * a[3]; }
+NOMIPS16 void f2 (int *a) { a[0] = a[0] * a[1] - a[2] * a[3] - a[4]; }
+NOMIPS16 void f3 (int *a) { a[0] = a[0] * a[1] - a[2] * a[3] - a[4] * a[5]; }
diff --git a/gcc/testsuite/gcc.target/mips/msub-6.c b/gcc/testsuite/gcc.target/mips/msub-6.c
new file mode 100644
index 00000000000..afe01cb5162
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msub-6.c
@@ -0,0 +1,6 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler-not "\tmsub\t" } } */
+/* { dg-final { scan-assembler "\tmul\t" } } */
+/* { dg-final { scan-assembler "\tsubu\t" } } */
+
+NOMIPS16 void f1 (int *a) { a[0] = a[0] - a[1] * a[2]; }
diff --git a/gcc/testsuite/gcc.target/mips/msub-7.c b/gcc/testsuite/gcc.target/mips/msub-7.c
new file mode 100644
index 00000000000..9fff31d5132
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msub-7.c
@@ -0,0 +1,14 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler-not "\tmul\t" } } */
+/* { dg-final { scan-assembler "\tmsub\t" } } */
+
+NOMIPS16 int
+f1 (int *a, int *b, int n)
+{
+ int x, i;
+
+ x = 100;
+ for (i = 0; i < n; i++)
+ x -= a[i] * b[i];
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/mips/msub-8.c b/gcc/testsuite/gcc.target/mips/msub-8.c
new file mode 100644
index 00000000000..7517540cdc4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msub-8.c
@@ -0,0 +1,15 @@
+/* { dg-mips-options "-O2 -march=5kc" } */
+/* { dg-final { scan-assembler "\tmul\t" } } */
+/* { dg-final { scan-assembler-not "\tmsub\t" } } */
+/* { dg-final { scan-assembler-not "\tmtlo\t" } } */
+/* { dg-final { scan-assembler-not "\tmflo\t" } } */
+
+NOMIPS16 int
+f2 (int x, int y, int z)
+{
+ asm volatile ("" ::: "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17",
+ "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25",
+ "$31");
+ return x - y * z;
+}