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

Reply via email to