&& !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)
(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.
(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.
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
+
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
+