@@ -2609,7 +2609,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")
@@ -2631,6 +2632,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)
@@ -2642,8 +2653,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")
@@ -2665,6 +2677,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)
new file mode 100644
@@ -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;
+}
+
+