aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>2010-10-15 17:42:05 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2010-10-15 17:42:05 +0000
commit1b1562a55947daed482e2d8ef47a4f577397beb9 (patch)
tree5a6ace72e7cb1c4c33366822e3836c93b74e3f78 /gcc/config
parente74bf53a08b08e94ef88b0e1b0401e393efb1dac (diff)
downloadgcc-1b1562a55947daed482e2d8ef47a4f577397beb9.zip
gcc-1b1562a55947daed482e2d8ef47a4f577397beb9.tar.gz
gcc-1b1562a55947daed482e2d8ef47a4f577397beb9.tar.bz2
Add fma support
From-SVN: r165515
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/altivec.md82
-rw-r--r--gcc/config/rs6000/rs6000.c16
-rw-r--r--gcc/config/rs6000/rs6000.md130
-rw-r--r--gcc/config/rs6000/vsx.md143
4 files changed, 230 insertions, 141 deletions
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 7bf3c66..9f1b3fe 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -143,7 +143,6 @@
(UNSPEC_VUPKLS_V4SF 325)
(UNSPEC_VUPKHU_V4SF 326)
(UNSPEC_VUPKLU_V4SF 327)
- (UNSPEC_VNMSUBFP 328)
])
(define_constants
@@ -513,12 +512,39 @@
"vsel %0,%3,%2,%1"
[(set_attr "type" "vecperm")])
-;; Fused multiply add
-(define_insn "altivec_vmaddfp"
+;; Fused multiply add. By default expand the FMA into (plus (mult)) to help
+;; loop unrolling. Don't do negate multiply ops, because of complications with
+;; honoring signed zero and fused-madd.
+
+(define_expand "altivec_vmaddfp"
+ [(set (match_operand:V4SF 0 "register_operand" "")
+ (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "")
+ (match_operand:V4SF 2 "register_operand" ""))
+ (match_operand:V4SF 3 "register_operand" "")))]
+ "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
+{
+ if (!TARGET_FUSED_MADD)
+ {
+ emit_insn (gen_altivec_vmaddfp_2 (operands[0], operands[1], operands[2],
+ operands[3]));
+ DONE;
+ }
+})
+
+(define_insn "*altivec_vmaddfp_1"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
(match_operand:V4SF 2 "register_operand" "v"))
(match_operand:V4SF 3 "register_operand" "v")))]
+ "VECTOR_UNIT_ALTIVEC_P (V4SFmode) && TARGET_FUSED_MADD"
+ "vmaddfp %0,%1,%2,%3"
+ [(set_attr "type" "vecfloat")])
+
+(define_insn "altivec_vmaddfp_2"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
+ (match_operand:V4SF 2 "register_operand" "v")
+ (match_operand:V4SF 3 "register_operand" "v")))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"vmaddfp %0,%1,%2,%3"
[(set_attr "type" "vecfloat")])
@@ -529,7 +555,7 @@
[(use (match_operand:V4SF 0 "register_operand" ""))
(use (match_operand:V4SF 1 "register_operand" ""))
(use (match_operand:V4SF 2 "register_operand" ""))]
- "VECTOR_UNIT_ALTIVEC_P (V4SFmode) && TARGET_FUSED_MADD"
+ "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
"
{
rtx neg0;
@@ -627,34 +653,18 @@
}")
;; Fused multiply subtract
-(define_expand "altivec_vnmsubfp"
- [(match_operand:V4SF 0 "register_operand" "")
- (match_operand:V4SF 1 "register_operand" "")
- (match_operand:V4SF 2 "register_operand" "")
- (match_operand:V4SF 3 "register_operand" "")]
+(define_insn "altivec_vnmsubfp"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (neg:V4SF
+ (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
+ (match_operand:V4SF 2 "register_operand" "v")
+ (neg:V4SF
+ (match_operand:V4SF 3 "register_operand" "v")))))]
"VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
-{
- if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (SFmode))
- {
- emit_insn (gen_altivec_vnmsubfp_1 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
- else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
- {
- emit_insn (gen_altivec_vnmsubfp_2 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
- else
- {
- emit_insn (gen_altivec_vnmsubfp_3 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
-})
+ "vnmsubfp %0,%1,%2,%3"
+ [(set_attr "type" "vecfloat")])
-(define_insn "altivec_vnmsubfp_1"
+(define_insn "*altivec_vnmsubfp_1"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(neg:V4SF
(minus:V4SF
@@ -667,7 +677,7 @@
"vnmsubfp %0,%1,%2,%3"
[(set_attr "type" "vecfloat")])
-(define_insn "altivec_vnmsubfp_2"
+(define_insn "*altivec_vnmsubfp_2"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(minus:V4SF
(match_operand:V4SF 3 "register_operand" "v")
@@ -679,16 +689,6 @@
"vnmsubfp %0,%1,%2,%3"
[(set_attr "type" "vecfloat")])
-(define_insn "altivec_vnmsubfp_3"
- [(set (match_operand:V4SF 0 "register_operand" "=v")
- (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
- (match_operand:V4SF 2 "register_operand" "v")
- (match_operand:V4SF 3 "register_operand" "v")]
- UNSPEC_VNMSUBFP))]
- "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
- "vnmsubfp %0,%1,%2,%3"
- [(set_attr "type" "vecfloat")])
-
(define_insn "altivec_vmsumu<VI_char>m"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 3afedd2..f977301 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3938,6 +3938,22 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
break;
+ case BUILT_IN_FMA:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
+ break;
+ case BUILT_IN_FMAF:
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
+ else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
+ break;
case BUILT_IN_TRUNC:
if (VECTOR_UNIT_VSX_P (V2DFmode)
&& out_mode == DFmode && out_n == 2
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 9fa2ff1..f1e63cc 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5844,6 +5844,78 @@
"fres %0,%1"
[(set_attr "type" "fp")])
+; builtin fmaf support
+; If the user explicitly uses the fma builtin, don't convert this to
+; (plus (mult op1 op2) op3)
+(define_expand "fmasf4"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "")
+ (fma:SF (match_operand:SF 1 "gpc_reg_operand" "")
+ (match_operand:SF 2 "gpc_reg_operand" "")
+ (match_operand:SF 3 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
+ "")
+
+(define_insn "fmasf4_fpr"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
+ (match_operand:SF 2 "gpc_reg_operand" "f")
+ (match_operand:SF 3 "gpc_reg_operand" "f")))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
+ "*
+{
+ return ((TARGET_POWERPC)
+ ? \"fmadds %0,%1,%2,%3\"
+ : \"{fma|fmadd} %0,%1,%2,%3\");
+}"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+(define_insn "*fmssf4_fpr"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
+ (match_operand:SF 2 "gpc_reg_operand" "f")
+ (neg:SF (match_operand:SF 3 "gpc_reg_operand" "f"))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
+ "*
+{
+ return ((TARGET_POWERPC)
+ ? \"fmsubs %0,%1,%2,%3\"
+ : \"{fms|fmsub} %0,%1,%2,%3\");
+}"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+(define_insn "*fnmasf4_fpr"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
+ (match_operand:SF 2 "gpc_reg_operand" "f")
+ (match_operand:SF 3 "gpc_reg_operand" "f"))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
+ "*
+{
+ return ((TARGET_POWERPC)
+ ? \"fnmadds %0,%1,%2,%3\"
+ : \"{fnma|fnmadd} %0,%1,%2,%3\");
+}"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+(define_insn "*fnmssf4_fpr"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
+ (neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
+ (match_operand:SF 2 "gpc_reg_operand" "f")
+ (neg:SF (match_operand:SF 3 "gpc_reg_operand" "f")))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
+ "*
+{
+ return ((TARGET_POWERPC)
+ ? \"fnmsubs %0,%1,%2,%3\"
+ : \"{fnms|fnmsub} %0,%1,%2,%3\");
+}"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+; Fused multiply/add ops created by the combiner
(define_insn "*fmaddsf4_powerpc"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
@@ -5854,7 +5926,7 @@
"fmadds %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
-
+
(define_insn "*fmaddsf4_power"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
@@ -6312,6 +6384,62 @@
"frsqrte %0,%1"
[(set_attr "type" "fp")])
+; builtin fma support
+; If the user explicitly uses the fma builtin, don't convert this to
+; (plus (mult op1 op2) op3)
+(define_expand "fmadf4"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "")
+ (fma:DF (match_operand:DF 1 "gpc_reg_operand" "")
+ (match_operand:DF 2 "gpc_reg_operand" "")
+ (match_operand:DF 3 "gpc_reg_operand" "")))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
+ "")
+
+(define_insn "fmadf4_fpr"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
+ (match_operand:DF 2 "gpc_reg_operand" "f")
+ (match_operand:DF 3 "gpc_reg_operand" "f")))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+ && VECTOR_UNIT_NONE_P (DFmode)"
+ "{fma|fmadd} %0,%1,%2,%3"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+(define_insn "*fmsdf4_fpr"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
+ (match_operand:DF 2 "gpc_reg_operand" "f")
+ (neg:DF (match_operand:DF 3 "gpc_reg_operand" "f"))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+ && VECTOR_UNIT_NONE_P (DFmode)"
+ "{fms|fmsub} %0,%1,%2,%3"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+(define_insn "*fnmadf4_fpr"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
+ (match_operand:DF 2 "gpc_reg_operand" "f")
+ (match_operand:DF 3 "gpc_reg_operand" "f"))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+ && VECTOR_UNIT_NONE_P (DFmode)"
+ "{fnma|fnmadd} %0,%1,%2,%3"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+(define_insn "*fnmsdf4_fpr"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
+ (match_operand:DF 2 "gpc_reg_operand" "f")
+ (neg:DF (match_operand:DF 3 "gpc_reg_operand" "f")))))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
+ && VECTOR_UNIT_NONE_P (DFmode)"
+ "{fnms|fnmsub} %0,%1,%2,%3"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_maddsub_s")])
+
+; Fused multiply/add ops created by the combiner
(define_insn "*fmadddf4_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 4b395e3..a861cc0 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -194,11 +194,7 @@
(UNSPEC_VSX_CVUXDSP 507)
(UNSPEC_VSX_CVSPSXDS 508)
(UNSPEC_VSX_CVSPUXDS 509)
- (UNSPEC_VSX_MADD 510)
- (UNSPEC_VSX_MSUB 511)
- (UNSPEC_VSX_NMADD 512)
- (UNSPEC_VSX_NMSUB 513)
- ;; 514 deleted
+ ;; 510-514 deleted
(UNSPEC_VSX_TDIV 515)
(UNSPEC_VSX_TSQRT 516)
(UNSPEC_VSX_XXPERMDI 517)
@@ -499,19 +495,22 @@
;; does not check -mfused-madd to allow users to use these ops when they know
;; they want the fused multiply/add.
+;; Fused multiply add. By default expand the FMA into (plus (mult)) to help
+;; loop unrolling. Don't do negate multiply ops, because of complications with
+;; honoring signed zero and fused-madd.
+
(define_expand "vsx_fmadd<mode>4"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "")
(plus:VSX_B
- (mult:VSX_B
- (match_operand:VSX_B 1 "vsx_register_operand" "")
- (match_operand:VSX_B 2 "vsx_register_operand" ""))
+ (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "")
+ (match_operand:VSX_B 2 "vsx_register_operand" ""))
(match_operand:VSX_B 3 "vsx_register_operand" "")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
{
if (!TARGET_FUSED_MADD)
{
- emit_insn (gen_vsx_fmadd<mode>4_2 (operands[0], operands[1], operands[2],
- operands[3]));
+ emit_insn (gen_vsx_fmadd<mode>4_2 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
}
})
@@ -534,10 +533,9 @@
(define_insn "vsx_fmadd<mode>4_2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
- (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
- (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
- (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
- UNSPEC_VSX_MADD))]
+ (fma:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
+ (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"@
x<VSv>madda<VSs> %x0,%x1,%x2
@@ -550,16 +548,15 @@
(define_expand "vsx_fmsub<mode>4"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "")
(minus:VSX_B
- (mult:VSX_B
- (match_operand:VSX_B 1 "vsx_register_operand" "")
- (match_operand:VSX_B 2 "vsx_register_operand" ""))
+ (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "")
+ (match_operand:VSX_B 2 "vsx_register_operand" ""))
(match_operand:VSX_B 3 "vsx_register_operand" "")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
{
if (!TARGET_FUSED_MADD)
{
- emit_insn (gen_vsx_fmsub<mode>4_2 (operands[0], operands[1], operands[2],
- operands[3]));
+ emit_insn (gen_vsx_fmsub<mode>4_2 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
}
})
@@ -582,10 +579,10 @@
(define_insn "vsx_fmsub<mode>4_2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
- (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
- (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
- (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
- UNSPEC_VSX_MSUB))]
+ (fma:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
+ (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ (neg:VSX_B
+ (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"@
x<VSv>msuba<VSs> %x0,%x1,%x2
@@ -595,32 +592,21 @@
[(set_attr "type" "<VStype_mul>")
(set_attr "fp_type" "<VSfptype_mul>")])
-(define_expand "vsx_fnmadd<mode>4"
- [(match_operand:VSX_B 0 "vsx_register_operand" "")
- (match_operand:VSX_B 1 "vsx_register_operand" "")
- (match_operand:VSX_B 2 "vsx_register_operand" "")
- (match_operand:VSX_B 3 "vsx_register_operand" "")]
+(define_insn "vsx_fnmadd<mode>4"
+ [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
+ (neg:VSX_B
+ (fma:VSX_B
+ (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa")
+ (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
-{
- if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
- {
- emit_insn (gen_vsx_fnmadd<mode>4_1 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
- else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
- {
- emit_insn (gen_vsx_fnmadd<mode>4_2 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
- else
- {
- emit_insn (gen_vsx_fnmadd<mode>4_3 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
-})
+ "@
+ x<VSv>nmadda<VSs> %x0,%x1,%x2
+ x<VSv>nmaddm<VSs> %x0,%x1,%x3
+ x<VSv>nmadda<VSs> %x0,%x1,%x2
+ x<VSv>nmaddm<VSs> %x0,%x1,%x3"
+ [(set_attr "type" "<VStype_mul>")
+ (set_attr "fp_type" "<VSfptype_mul>")])
(define_insn "vsx_fnmadd<mode>4_1"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
@@ -658,48 +644,22 @@
[(set_attr "type" "<VStype_mul>")
(set_attr "fp_type" "<VSfptype_mul>")])
-(define_insn "vsx_fnmadd<mode>4_3"
+(define_insn "vsx_fnmsub<mode>4"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
- (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa")
- (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
- (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
- UNSPEC_VSX_NMADD))]
+ (neg:VSX_B
+ (fma:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
+ (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
+ (neg:VSX_B
+ (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"@
- x<VSv>nmadda<VSs> %x0,%x1,%x2
- x<VSv>nmaddm<VSs> %x0,%x1,%x3
- x<VSv>nmadda<VSs> %x0,%x1,%x2
- x<VSv>nmaddm<VSs> %x0,%x1,%x3"
+ x<VSv>nmsuba<VSs> %x0,%x1,%x2
+ x<VSv>nmsubm<VSs> %x0,%x1,%x3
+ x<VSv>nmsuba<VSs> %x0,%x1,%x2
+ x<VSv>nmsubm<VSs> %x0,%x1,%x3"
[(set_attr "type" "<VStype_mul>")
(set_attr "fp_type" "<VSfptype_mul>")])
-(define_expand "vsx_fnmsub<mode>4"
- [(match_operand:VSX_B 0 "vsx_register_operand" "")
- (match_operand:VSX_B 1 "vsx_register_operand" "")
- (match_operand:VSX_B 2 "vsx_register_operand" "")
- (match_operand:VSX_B 3 "vsx_register_operand" "")]
- "VECTOR_UNIT_VSX_P (<MODE>mode)"
-{
- if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode))
- {
- emit_insn (gen_vsx_fnmsub<mode>4_1 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
- else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
- {
- emit_insn (gen_vsx_fnmsub<mode>4_2 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
- else
- {
- emit_insn (gen_vsx_fnmsub<mode>4_3 (operands[0], operands[1],
- operands[2], operands[3]));
- DONE;
- }
-})
-
(define_insn "vsx_fnmsub<mode>4_1"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
(neg:VSX_B
@@ -735,21 +695,6 @@
[(set_attr "type" "<VStype_mul>")
(set_attr "fp_type" "<VSfptype_mul>")])
-(define_insn "vsx_fnmsub<mode>4_3"
- [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
- (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa")
- (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")
- (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")]
- UNSPEC_VSX_NMSUB))]
- "VECTOR_UNIT_VSX_P (<MODE>mode)"
- "@
- x<VSv>nmsuba<VSs> %x0,%x1,%x2
- x<VSv>nmsubm<VSs> %x0,%x1,%x3
- x<VSv>nmsuba<VSs> %x0,%x1,%x2
- x<VSv>nmsubm<VSs> %x0,%x1,%x3"
- [(set_attr "type" "<VStype_mul>")
- (set_attr "fp_type" "<VSfptype_mul>")])
-
;; Vector conditional expressions (no scalar version for these instructions)
(define_insn "vsx_eq<mode>"
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")