diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 130 |
1 files changed, 129 insertions, 1 deletions
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") |