"TARGET_FUSED_MADD"
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
+
+;; Official C99 versions of the fmaf family of operations.
+(define_insn "fmasf4"
+ [(set (match_operand:SF 0 "fr_register_operand" "=f")
+ (fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
+ ""
+ "fma.s %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+(define_insn "*fmssf4"
+ [(set (match_operand:SF 0 "fr_register_operand" "=f")
+ (fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
+ (neg:SF
+ (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+ ""
+ "fms.s %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+;; This insn is officially "-(a * b) + c" which is "(-a * b) + c".
+(define_insn "*nfmasf4"
+ [(set (match_operand:SF 0 "fr_register_operand" "=f")
+ (fma:SF (neg:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG"))
+ (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
+ ""
+ "fnma.s %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
\f
;; ::::::::::::::::::::
;; ::
"TARGET_FUSED_MADD"
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
+
+;; Official C99 versions of the fma family of operations.
+(define_insn "fmadf4"
+ [(set (match_operand:DF 0 "fr_register_operand" "=f")
+ (fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
+ ""
+ "fma.d %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+(define_insn "*fmsdf4"
+ [(set (match_operand:DF 0 "fr_register_operand" "=f")
+ (fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
+ (neg:DF
+ (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+ ""
+ "fms.d %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+;; See comment for nfmasf4.
+(define_insn "*nfmadf4"
+ [(set (match_operand:DF 0 "fr_register_operand" "=f")
+ (fma:DF (neg:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG"))
+ (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
+ ""
+ "fnma.d %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
\f
;; ::::::::::::::::::::
;; ::
"TARGET_FUSED_MADD"
"fnma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
+
+;; Official C99 versions of the fmal family of operations.
+(define_insn "fmaxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
+ ""
+ "fma %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+(define_insn "*fmsxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
+ (neg:XF
+ (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+ ""
+ "fms %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+;; See comment for nfmasf4.
+(define_insn "*nfmaxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (fma:XF (neg:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG"))
+ (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
+ (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
+ ""
+ "fnma %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
\f
;; ::::::::::::::::::::
;; ::
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* Don't confuse the fma insn with the fma in the filename. */
+/* { dg-final { scan-assembler-times "fma\\." 4 } } */
+/* { dg-final { scan-assembler-times "fms" 2 } } */
+/* { dg-final { scan-assembler-times "fnma" 4 } } */
+
+#ifndef __FP_FAST_FMAF
+# error "__FP_FAST_FMAF should be defined"
+#endif
+#ifndef __FP_FAST_FMA
+# error "__FP_FAST_FMA should be defined"
+#endif
+
+float f0(float x, float y, float z) { return __builtin_fmaf(x,y,z); }
+float f1(float x, float y, float z) { return __builtin_fmaf(x,y,-z); }
+float f2(float x, float y, float z) { return __builtin_fmaf(-x,y,z); }
+float f3(float x, float y, float z) { return __builtin_fmaf(x,-y,z); }
+float f4(float x, float y, float z) { return __builtin_fmaf(-x,-y,z); }
+
+double d0(double x, double y, double z) { return __builtin_fma(x,y,z); }
+double d1(double x, double y, double z) { return __builtin_fma(x,y,-z); }
+double d2(double x, double y, double z) { return __builtin_fma(-x,y,z); }
+double d3(double x, double y, double z) { return __builtin_fma(x,-y,z); }
+double d4(double x, double y, double z) { return __builtin_fma(-x,-y,z); }
--- /dev/null
+/* { dg-do compile } */
+/* { dg-skip-if "128-bit long double" { *-*-hpux* } { "*" } { "" } } */
+/* { dg-options "-O" } */
+/* Don't confuse the fma insn with the fma in the filename. */
+/* { dg-final { scan-assembler-times "fma\[ \]" 2 } } */
+/* { dg-final { scan-assembler-times "fms" 1 } } */
+/* { dg-final { scan-assembler-times "fnma" 2 } } */
+
+#ifndef __FP_FAST_FMAL
+# error "__FP_FAST_FMAL should be defined"
+#endif
+
+typedef long double LD;
+
+LD L0(LD x, LD y, LD z) { return __builtin_fmal(x,y,z); }
+LD L1(LD x, LD y, LD z) { return __builtin_fmal(x,y,-z); }
+LD L2(LD x, LD y, LD z) { return __builtin_fmal(-x,y,z); }
+LD L3(LD x, LD y, LD z) { return __builtin_fmal(x,-y,z); }
+LD L4(LD x, LD y, LD z) { return __builtin_fmal(-x,-y,z); }