[gcc r16-4110] MIPS: Add MSUBF.fmt instruction for MIPSr6
YunQiang Su
syq@gcc.gnu.org
Sat Sep 27 06:08:38 GMT 2025
https://gcc.gnu.org/g:51a3669ab65586c3cffe302a1bf7c368ad08e61a
commit r16-4110-g51a3669ab65586c3cffe302a1bf7c368ad08e61a
Author: Jie Mei <jie.mei@oss.cipunited.com>
Date: Sat Sep 14 15:04:09 2024 +0800
MIPS: Add MSUBF.fmt instruction for MIPSr6
GCC currently uses two instructions (NEG.fmt and MADDF.fmt) for
operations like `x - (y * z)' for MIPSr6. We can further tune this by
using only MSUBF.fmt instead of those two.
This patch adds MSUBF.fmt instrutions with corresponding tests.
gcc/ChangeLog:
* config/mips/mips.md (fms<mode>4): Generates MSUBF.fmt
instructions.
(*fms<mode>4_msubf): Same as above.
(fnma<mode>4): Same as above.
(*fnma<mode>4_msubf): Same as above.
gcc/testsuite/ChangeLog:
* gcc.target/mips/mips-msubf.c: New tests for MIPSr6.
Diff:
---
gcc/config/mips/mips.md | 28 ++++++++++++++++++++++++---
gcc/testsuite/gcc.target/mips/mips-msubf.c | 31 ++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index aadf4dd676e2..99654cc8fde0 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -2617,7 +2617,8 @@
(fma:ANYF (match_operand:ANYF 1 "register_operand")
(match_operand:ANYF 2 "register_operand")
(neg:ANYF (match_operand:ANYF 3 "register_operand"))))]
- "(ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4)")
+ "(ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4)
+ || ISA_HAS_FUSED_MADDF")
(define_insn "*fms<mode>4_msub3"
[(set (match_operand:ANYF 0 "register_operand" "=f")
@@ -2639,6 +2640,16 @@
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
+(define_insn "*fms<mode>4_msubf"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (fma:ANYF (match_operand:ANYF 1 "register_operand" "f")
+ (match_operand:ANYF 2 "register_operand" "f")
+ (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))]
+ "ISA_HAS_FUSED_MADDF"
+ "msubf.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
;; fnma is defined in GCC as (fma (neg op1) op2 op3)
;; (-op1 * op2) + op3 ==> -(op1 * op2) + op3 ==> -((op1 * op2) - op3)
;; The mips nmsub instructions implement -((op1 * op2) - op3)
@@ -2650,8 +2661,9 @@
(fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand"))
(match_operand:ANYF 2 "register_operand")
(match_operand:ANYF 3 "register_operand")))]
- "(ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4)
- && !HONOR_SIGNED_ZEROS (<MODE>mode)")
+ "((ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4)
+ && !HONOR_SIGNED_ZEROS (<MODE>mode))
+ || ISA_HAS_FUSED_MADDF")
(define_insn "*fnma<mode>4_nmsub3"
[(set (match_operand:ANYF 0 "register_operand" "=f")
@@ -2673,6 +2685,16 @@
[(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")])
+(define_insn "*fnma<mode>4_msubf"
+ [(set (match_operand:ANYF 0 "register_operand" "=f")
+ (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
+ (match_operand:ANYF 2 "register_operand" "f")
+ (match_operand:ANYF 3 "register_operand" "0")))]
+ "ISA_HAS_FUSED_MADDF"
+ "msubf.<fmt>\t%0,%1,%2"
+ [(set_attr "type" "fmadd")
+ (set_attr "mode" "<UNITMODE>")])
+
;; fnms is defined as: (fma (neg op1) op2 (neg op3))
;; ((-op1) * op2) - op3 ==> -(op1 * op2) - op3 ==> -((op1 * op2) + op3)
;; The mips nmadd instructions implement -((op1 * op2) + op3)
diff --git a/gcc/testsuite/gcc.target/mips/mips-msubf.c b/gcc/testsuite/gcc.target/mips/mips-msubf.c
new file mode 100644
index 000000000000..424ca21e7f8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips-msubf.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-mhard-float -ffast-math -march=mips32r6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" } { "" } } */
+/* { dg-final { scan-assembler-times "\tmsubf\\.s\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tmsubf\\.d\t" 2 } } */
+
+NOMIPS16 float
+test01 (float x, float y, float z)
+{
+ return x - (y * z);
+}
+
+NOMIPS16 double
+test02 (double x, double y, double z)
+{
+ return x - (y * z);
+}
+
+NOMIPS16 float
+test03 (float x, float y, float z)
+{
+ return (y * z) - x;
+}
+
+NOMIPS16 double
+test04 (double x, double y, double z)
+{
+ return (y * z) - x;
+}
+
+
More information about the Gcc-cvs
mailing list