https://gcc.gnu.org/g:93754d984b500c5914c3d1a437b6561e031aa604
commit r16-5819-g93754d984b500c5914c3d1a437b6561e031aa604 Author: David Guillen Fandos <[email protected]> Date: Fri Sep 19 18:48:11 2025 +0200 MIPS: Add Allegrex support for madd/msub instructions. 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]> Diff: --- 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(-) diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 7d1fc6552d6f..4d65bbf44709 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 939e51719297..5117dfd5d442 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 000000000000..514b8d97f2f6 --- /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 000000000000..c316b2f0860f --- /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 000000000000..c6b94cb512dc --- /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 000000000000..ba3a8e77a758 --- /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; +} +
