Tweaking mul_acc_si/mul_sub_si was necessary to fix the implicit
assumption that CPUs with madd/msub support also support MUL3
multiplication. This disables the non-existent alternative if the CPU
does not have proper MUL3 support. This issue exists also for other CPUs
(ie. using -march=mips1 with -mimadd fails).
gcc/ChangeLog:
* config/mips/mips.h (ISA_HAS_MADD_MSUB): Include allegrex.
* config/mips/mips.md: Tweak mul_acc_si/mul_sub_si to make it
work when MUL3 is not available.
gcc/testsuite/ChangeLog:
* gcc.target/mips/madd-10.c: New test.
* gcc.target/mips/maddu-5.c: New test.
* gcc.target/mips/msub-9.c: New test.
* gcc.target/mips/msubu-5.c: New test.
Signed-off-by: David Guillen Fandos <[email protected]>
---
gcc/config/mips/mips.h | 5 +++--
gcc/config/mips/mips.md | 18 ++++++++++++------
gcc/testsuite/gcc.target/mips/madd-10.c | 15 +++++++++++++++
gcc/testsuite/gcc.target/mips/maddu-5.c | 20 ++++++++++++++++++++
gcc/testsuite/gcc.target/mips/msub-9.c | 15 +++++++++++++++
gcc/testsuite/gcc.target/mips/msubu-5.c | 14 ++++++++++++++
6 files changed, 79 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/mips/madd-10.c
create mode 100644 gcc/testsuite/gcc.target/mips/maddu-5.c
create mode 100644 gcc/testsuite/gcc.target/mips/msub-9.c
create mode 100644 gcc/testsuite/gcc.target/mips/msubu-5.c
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 1620345ea56..07b2f6efb66 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1149,8 +1149,9 @@ struct mips_cpu_info {
&& !TARGET_MIPS16)
/* ISA has integer multiply-accumulate instructions, madd and msub. */
-#define ISA_HAS_MADD_MSUB (mips_isa_rev >= 1 \
- && mips_isa_rev <= 5)
+#define ISA_HAS_MADD_MSUB ((mips_isa_rev >= 1 \
+ && mips_isa_rev <= 5) \
+ || TARGET_ALLEGREX)
/* Integer multiply-accumulate instructions should be generated. */
#define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 7b256c62ad3..fcd73c3fe23 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1795,9 +1795,12 @@
(set_attr "mode" "SI")
(set_attr "insn_count" "1,1,2")
(set (attr "enabled")
- (cond [(eq_attr "alternative" "1,2")
- (const_string "yes")]
- (const_string "no")))])
+ (cond [(eq_attr "alternative" "1")
+ (const_string "yes")
+ (and (eq_attr "alternative" "2")
+ (match_test "ISA_HAS_MUL3"))
+ (const_string "yes")]
+ (const_string "no")))])
;; The same idea applies here. The middle alternative needs one less
;; clobber than the final alternative, so we add "*?" as a counterweight.
@@ -2041,9 +2044,12 @@
(set_attr "mode" "SI")
(set_attr "insn_count" "1,1,2")
(set (attr "enabled")
- (cond [(eq_attr "alternative" "1,2")
- (const_string "yes")]
- (const_string "no")))])
+ (cond [(eq_attr "alternative" "1")
+ (const_string "yes")
+ (and (eq_attr "alternative" "2")
+ (match_test "ISA_HAS_MUL3"))
+ (const_string "yes")]
+ (const_string "no")))])
;; Split *mul_sub_si if both the source and destination accumulator
;; values are GPRs.
diff --git a/gcc/testsuite/gcc.target/mips/madd-10.c
b/gcc/testsuite/gcc.target/mips/madd-10.c
new file mode 100644
index 00000000000..514b8d97f2f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/madd-10.c
@@ -0,0 +1,15 @@
+/* { dg-options "-march=allegrex -fexpensive-optimizations" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { 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/maddu-5.c
b/gcc/testsuite/gcc.target/mips/maddu-5.c
new file mode 100644
index 00000000000..c316b2f0860
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/maddu-5.c
@@ -0,0 +1,20 @@
+/* { dg-options "-march=allegrex -fexpensive-optimizations" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-not "\tmul\t" } } */
+/* { dg-final { scan-assembler "\tmaddu\t" } } */
+
+typedef unsigned int ui;
+typedef unsigned long long ull;
+
+NOMIPS16 ull
+f1 (ui x, ui y, ull z)
+{
+ return (ull) x * y + z;
+}
+
+NOMIPS16 ull
+f2 (ui x, ui y, ull z)
+{
+ return z + (ull) y * x;
+}
+
diff --git a/gcc/testsuite/gcc.target/mips/msub-9.c
b/gcc/testsuite/gcc.target/mips/msub-9.c
new file mode 100644
index 00000000000..c6b94cb512d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msub-9.c
@@ -0,0 +1,15 @@
+/* { dg-options "-march=allegrex -fexpensive-optimizations" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { 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/msubu-5.c
b/gcc/testsuite/gcc.target/mips/msubu-5.c
new file mode 100644
index 00000000000..ba3a8e77a75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msubu-5.c
@@ -0,0 +1,14 @@
+/* { dg-options "-march=allegrex -fexpensive-optimizations" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-not "\tmul\t" } } */
+/* { dg-final { scan-assembler "\tmsubu\t" } } */
+
+typedef unsigned int ui;
+typedef unsigned long long ull;
+
+NOMIPS16 ull
+f2 (ui x, ui y, ull z)
+{
+ return z - (ull) y * x;
+}
+
--
2.50.1