diff options
author | sje <sje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-06 17:29:33 +0000 |
---|---|---|
committer | sje <sje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-07-06 17:29:33 +0000 |
commit | 668de2f7109d29355d24e77e6528545c23e182cb (patch) | |
tree | eeb68eda2252eab992fcaa371458ca9022d1d8a4 | |
parent | 44121e9f4bf1c8bc5cfabb675c60c450d9f71d35 (diff) | |
download | gcc-668de2f7109d29355d24e77e6528545c23e182cb.tar.gz |
2015-07-06 Steve Ellcey <sellcey@imgtec.com>
* config.gcc <mips*-*-*>: Add fused-madd.opt.
* config/mips/mips.opt (mfused-madd): Remove.
* config/mips/mips.c (mips_rtx_costs): Update cost calculations.
* config/mips/mips.h (TARGET_MIPS8000): New.
(ISA_HAS_FP_MADD4_MSUB4): Remove.
(ISA_HAS_FP_MADDF_MSUBF): Remove.
(ISA_HAS_FP_MADD3_MSUB3): Remove.
(ISA_HAS_NMADD4_NMSUB4): Remove.
(ISA_HAS_NMADD3_NMSUB3): Remove.
(ISA_HAS_FUSED_MADD4): New.
(ISA_HAS_UNFUSED_MADD4): New.
(ISA_HAS_FUSED_MADDF): New.
(ISA_HAS_FUSED_MADD3): New.
* config/mips/mips.md: (fma<mode>4) Change from insn to expand.
(*fma<mode>4_madd3) New.
(*fma<mode>4_madd4) New.
(*fma<mode>4_maddf) New.
(fms<mode>4) New.
(*fms<mode>4_msub3) New.
(*fms<mode>4_msub4) New.
(fnma<mode>4) New.
(*fnma<mode>4_nmadd3) New.
(*fnma<mode>4_nmadd4) New.
(fnms<mode>4) New.
(*fnms<mode>4_nmsub3) New.
(*fnms<mode>4_nmsub4) New.
(*madd4<mode>) Modify to be unfused only.
(*msub4<mode>) Modify to be unfused only.
(*nmadd4<mode>) Modify to be unfused only.
(*nmsub4<mode>) Modify to be unfused only.
(*madd3<mode>) Remove.
(*msub3<mode>) Remove.
(*nmadd3<mode>) Remove.
(*nmsub3<mode>) Remove.
(*nmadd3<mode>_fastmath) Remove.
(*nmsub3<mode>_fastmath) Remove.
(*nmadd4<mode>_fastmath) Update condition.
(*nmsub4<mode>_fastmath) Update condition.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@225468 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 41 | ||||
-rw-r--r-- | gcc/config.gcc | 2 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 26 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 26 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 265 | ||||
-rw-r--r-- | gcc/config/mips/mips.opt | 4 |
6 files changed, 234 insertions, 130 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe64509b9af..7c73d50d052 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,44 @@ +2015-07-06 Steve Ellcey <sellcey@imgtec.com> + + * config.gcc <mips*-*-*>: Add fused-madd.opt. + * config/mips/mips.opt (mfused-madd): Remove. + * config/mips/mips.c (mips_rtx_costs): Update cost calculations. + * config/mips/mips.h (TARGET_MIPS8000): New. + (ISA_HAS_FP_MADD4_MSUB4): Remove. + (ISA_HAS_FP_MADDF_MSUBF): Remove. + (ISA_HAS_FP_MADD3_MSUB3): Remove. + (ISA_HAS_NMADD4_NMSUB4): Remove. + (ISA_HAS_NMADD3_NMSUB3): Remove. + (ISA_HAS_FUSED_MADD4): New. + (ISA_HAS_UNFUSED_MADD4): New. + (ISA_HAS_FUSED_MADDF): New. + (ISA_HAS_FUSED_MADD3): New. + * config/mips/mips.md: (fma<mode>4) Change from insn to expand. + (*fma<mode>4_madd3) New. + (*fma<mode>4_madd4) New. + (*fma<mode>4_maddf) New. + (fms<mode>4) New. + (*fms<mode>4_msub3) New. + (*fms<mode>4_msub4) New. + (fnma<mode>4) New. + (*fnma<mode>4_nmadd3) New. + (*fnma<mode>4_nmadd4) New. + (fnms<mode>4) New. + (*fnms<mode>4_nmsub3) New. + (*fnms<mode>4_nmsub4) New. + (*madd4<mode>) Modify to be unfused only. + (*msub4<mode>) Modify to be unfused only. + (*nmadd4<mode>) Modify to be unfused only. + (*nmsub4<mode>) Modify to be unfused only. + (*madd3<mode>) Remove. + (*msub3<mode>) Remove. + (*nmadd3<mode>) Remove. + (*nmsub3<mode>) Remove. + (*nmadd3<mode>_fastmath) Remove. + (*nmsub3<mode>_fastmath) Remove. + (*nmadd4<mode>_fastmath) Update condition. + (*nmsub4<mode>_fastmath) Update condition. + 2015-07-06 Alan Lawrence <alan.lawrence@arm.com> PR target/65956 diff --git a/gcc/config.gcc b/gcc/config.gcc index f0405fe2bcd..900aa18c95d 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -418,7 +418,7 @@ microblaze*-*-*) mips*-*-*) cpu_type=mips extra_headers="loongson.h" - extra_options="${extra_options} g.opt mips/mips-tables.opt" + extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt" ;; nds32*) cpu_type=nds32 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 95a0ae3f44c..ce21a0fd215 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4054,13 +4054,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return true; case MINUS: - if (float_mode_p - && (ISA_HAS_NMADD4_NMSUB4 || ISA_HAS_NMADD3_NMSUB3) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode)) + if (float_mode_p && ISA_HAS_UNFUSED_MADD4 && !HONOR_SIGNED_ZEROS (mode)) { - /* See if we can use NMADD or NMSUB. See mips.md for the - associated patterns. */ + /* See if we can use NMADD or NMSUB via the *nmadd4<mode>_fastmath + or *nmsub4<mode>_fastmath patterns. These patterns check for + HONOR_SIGNED_ZEROS so we check here too. */ rtx op0 = XEXP (x, 0); rtx op1 = XEXP (x, 1); if (GET_CODE (op0) == MULT && GET_CODE (XEXP (op0, 0)) == NEG) @@ -4087,9 +4085,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, { /* If this is part of a MADD or MSUB, treat the PLUS as being free. */ - if ((ISA_HAS_FP_MADD4_MSUB4 || ISA_HAS_FP_MADD3_MSUB3) - && TARGET_FUSED_MADD - && GET_CODE (XEXP (x, 0)) == MULT) + if (ISA_HAS_UNFUSED_MADD4 && GET_CODE (XEXP (x, 0)) == MULT) *total = 0; else *total = mips_cost->fp_add; @@ -4121,13 +4117,10 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return true; case NEG: - if (float_mode_p - && (ISA_HAS_NMADD4_NMSUB4 || ISA_HAS_NMADD3_NMSUB3) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode)) + if (float_mode_p && ISA_HAS_UNFUSED_MADD4) { - /* See if we can use NMADD or NMSUB. See mips.md for the - associated patterns. */ + /* See if we can use NMADD or NMSUB via the *nmadd4<mode> or + *nmsub4<mode> patterns. */ rtx op = XEXP (x, 0); if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) && GET_CODE (XEXP (op, 0)) == MULT) @@ -4147,8 +4140,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return false; case FMA: - if (ISA_HAS_FP_MADDF_MSUBF) - *total = mips_fp_mult_cost (mode); + *total = mips_fp_mult_cost (mode); return false; case MULT: diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index bceef31b4a3..7a6f9171ac7 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -236,6 +236,7 @@ struct mips_cpu_info { #define TARGET_MIPS5500 (mips_arch == PROCESSOR_R5500) #define TARGET_MIPS5900 (mips_arch == PROCESSOR_R5900) #define TARGET_MIPS7000 (mips_arch == PROCESSOR_R7000) +#define TARGET_MIPS8000 (mips_arch == PROCESSOR_R8000) #define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000) #define TARGET_OCTEON (mips_arch == PROCESSOR_OCTEON \ || mips_arch == PROCESSOR_OCTEON2 \ @@ -998,22 +999,21 @@ struct mips_cpu_info { /* Integer multiply-accumulate instructions should be generated. */ #define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16) -/* ISA has floating-point madd and msub instructions 'd = a * b [+-] c'. */ -#define ISA_HAS_FP_MADD4_MSUB4 ISA_HAS_FP4 +/* ISA has 4 operand fused madd instructions of the form + 'd = [+-] (a * b [+-] c)'. */ +#define ISA_HAS_FUSED_MADD4 TARGET_MIPS8000 -/* ISA has floating-point MADDF and MSUBF instructions 'd = d [+-] a * b'. */ -#define ISA_HAS_FP_MADDF_MSUBF (mips_isa_rev >= 6) +/* ISA has 4 operand unfused madd instructions of the form + 'd = [+-] (a * b [+-] c)'. */ +#define ISA_HAS_UNFUSED_MADD4 (ISA_HAS_FP4 && !TARGET_MIPS8000) -/* ISA has floating-point madd and msub instructions 'c = a * b [+-] c'. */ -#define ISA_HAS_FP_MADD3_MSUB3 TARGET_LOONGSON_2EF +/* ISA has 3 operand r6 fused madd instructions of the form + 'c = c [+-] (a * b)'. */ +#define ISA_HAS_FUSED_MADDF (mips_isa_rev >= 6) -/* ISA has floating-point nmadd and nmsub instructions - 'd = -((a * b) [+-] c)'. */ -#define ISA_HAS_NMADD4_NMSUB4 ISA_HAS_FP4 - -/* ISA has floating-point nmadd and nmsub instructions - 'c = -((a * b) [+-] c)'. */ -#define ISA_HAS_NMADD3_NMSUB3 TARGET_LOONGSON_2EF +/* ISA has 3 operand loongson fused madd instructions of the form + 'c = [+-] (a * b [+-] c)'. */ +#define ISA_HAS_FUSED_MADD3 TARGET_LOONGSON_2EF /* ISA has floating-point RECIP.fmt and RSQRT.fmt instructions. The MIPS64 rev. 1 ISA says that RECIP.D and RSQRT.D are unpredictable when diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index f6912e11c2d..4f5692ce662 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2475,164 +2475,239 @@ ;; Floating point multiply accumulate instructions. -;; The various multiply accumulate instructions can be used even when -;; HONOR_NANS is true because while IEEE 754-2008 requires the negate -;; operation to negate the sign of a NAN and the MIPS neg instruction does -;; not do this, the multiply and add (or minus) parts of these instructions -;; have no requirement on how the sign of a NAN is handled and so the final -;; sign bit of the entire operation is undefined. +(define_expand "fma<mode>4" + [(set (match_operand:ANYF 0 "register_operand") + (fma:ANYF (match_operand:ANYF 1 "register_operand") + (match_operand:ANYF 2 "register_operand") + (match_operand:ANYF 3 "register_operand")))] + "ISA_HAS_FUSED_MADDF || ISA_HAS_FUSED_MADD3 || ISA_HAS_FUSED_MADD4") -(define_insn "*madd4<mode>" +(define_insn "*fma<mode>4_madd3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] - "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" + (fma: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_MADD3" + "madd.<fmt>\t%0,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "<UNITMODE>")]) + +(define_insn "*fma<mode>4_madd4" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "f")))] + "ISA_HAS_FUSED_MADD4" "madd.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "fma<mode>4" +(define_insn "*fma<mode>4_maddf" [(set (match_operand:ANYF 0 "register_operand" "=f") (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") (match_operand:ANYF 2 "register_operand" "f") (match_operand:ANYF 3 "register_operand" "0")))] - "ISA_HAS_FP_MADDF_MSUBF" + "ISA_HAS_FUSED_MADDF" "maddf.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*madd3<mode>" +;; The fms, fnma, and fnms instructions can be used even when HONOR_NANS +;; is true because while IEEE 754-2008 requires the negate operation to +;; negate the sign of a NAN and the MIPS neg instruction does not do this, +;; the fma part of the instruction has no requirement on how the sign of +;; a NAN is handled and so the final sign bit of the entire operation is +;; undefined. + +(define_expand "fms<mode>4" + [(set (match_operand:ANYF 0 "register_operand") + (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)") + +(define_insn "*fms<mode>4_msub3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "0")))] - "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" - "madd.<fmt>\t%0,%1,%2" + (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_MADD3" + "msub.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*msub4<mode>" +(define_insn "*fms<mode>4_msub4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] - "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_FUSED_MADD4" "msub.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*msub3<mode>" +;; 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) +;; This transformation means we may return the wrong signed zero +;; so we check HONOR_SIGNED_ZEROS. + +(define_expand "fnma<mode>4" + [(set (match_operand:ANYF 0 "register_operand") + (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)") + +(define_insn "*fnma<mode>4_nmsub3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "0")))] - "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" - "msub.<fmt>\t%0,%1,%2" + (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_MADD3 && !HONOR_SIGNED_ZEROS (<MODE>mode)" + "nmsub.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd4<mode>" +(define_insn "*fnma<mode>4_nmsub4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (plus:ANYF - (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f"))))] - "ISA_HAS_NMADD4_NMSUB4 - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode)" - "nmadd.<fmt>\t%0,%3,%1,%2" + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "f")))] + "ISA_HAS_FUSED_MADD4 && !HONOR_SIGNED_ZEROS (<MODE>mode)" + "nmsub.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd3<mode>" +;; 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) +;; This transformation means we may return the wrong signed zero +;; so we check HONOR_SIGNED_ZEROS. + +(define_expand "fnms<mode>4" + [(set (match_operand:ANYF 0 "register_operand") + (fma:ANYF + (neg: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) + && !HONOR_SIGNED_ZEROS (<MODE>mode)") + +(define_insn "*fnms<mode>4_nmadd3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (plus:ANYF - (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "0"))))] - "ISA_HAS_NMADD3_NMSUB3 - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode)" + (fma:ANYF + (neg: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_MADD3 && !HONOR_SIGNED_ZEROS (<MODE>mode)" "nmadd.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd4<mode>_fastmath" +(define_insn "*fnms<mode>4_nmadd4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF - (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] - "ISA_HAS_NMADD4_NMSUB4 - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (<MODE>mode)" + (fma:ANYF + (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_FUSED_MADD4 && !HONOR_SIGNED_ZEROS (<MODE>mode)" "nmadd.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd3<mode>_fastmath" +;; Non-fused Floating point multiply accumulate instructions. + +;; These instructions are not fused and round in between the multiply +;; and the add (or subtract) so they are equivalent to the separate +;; multiply and add/sub instructions. + +(define_insn "*madd4<mode>" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF - (mult: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_NMADD3_NMSUB3 - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (<MODE>mode)" - "nmadd.<fmt>\t%0,%1,%2" + (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f")) + (match_operand:ANYF 3 "register_operand" "f")))] + "ISA_HAS_UNFUSED_MADD4" + "madd.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub4<mode>" +(define_insn "*msub4<mode>" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (minus:ANYF - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f")) - (match_operand:ANYF 1 "register_operand" "f"))))] - "ISA_HAS_NMADD4_NMSUB4 - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode)" - "nmsub.<fmt>\t%0,%1,%2,%3" + (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f")) + (match_operand:ANYF 3 "register_operand" "f")))] + "ISA_HAS_UNFUSED_MADD4" + "msub.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub3<mode>" +;; Like with the fused fms, fnma, and fnms instructions, these unfused +;; instructions can be used even if HONOR_NANS is set because while +;; IEEE 754-2008 requires the negate operation to negate the sign of a +;; NAN and the MIPS neg instruction does not do this, the multiply and +;; add (or subtract) part of the instruction has no requirement on how +;; the sign of a NAN is handled and so the final sign bit of the entire +;; operation is undefined. + +(define_insn "*nmadd4<mode>" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (neg:ANYF (plus:ANYF + (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f")) + (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_UNFUSED_MADD4" + "nmadd.<fmt>\t%0,%3,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "<UNITMODE>")]) + +(define_insn "*nmsub4<mode>" [(set (match_operand:ANYF 0 "register_operand" "=f") (neg:ANYF (minus:ANYF - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f")) - (match_operand:ANYF 1 "register_operand" "0"))))] - "ISA_HAS_NMADD3_NMSUB3 - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode)" - "nmsub.<fmt>\t%0,%1,%2" + (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f")) + (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_UNFUSED_MADD4" + "nmsub.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub4<mode>_fastmath" +;; Fast-math Non-fused Floating point multiply accumulate instructions. + +;; These instructions are not fused but the expressions they match are +;; not exactly what the instruction implements in the sense that they +;; may not generate the properly signed zeros. + +;; This instruction recognizes ((-op1) * op2) - op3 and generates an +;; nmadd which is really -((op1 * op2) + op3). They are equivalent +;; except for the sign bit when the result is zero or NaN. + +(define_insn "*nmadd4<mode>_fastmath" [(set (match_operand:ANYF 0 "register_operand" "=f") (minus:ANYF - (match_operand:ANYF 1 "register_operand" "f") - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f"))))] - "ISA_HAS_NMADD4_NMSUB4 - && TARGET_FUSED_MADD + (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f")) + (match_operand:ANYF 3 "register_operand" "f")))] + "ISA_HAS_UNFUSED_MADD4 && !HONOR_SIGNED_ZEROS (<MODE>mode)" - "nmsub.<fmt>\t%0,%1,%2,%3" + "nmadd.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub3<mode>_fastmath" +;; This instruction recognizes (op1 - (op2 * op3) and generates an +;; nmsub which is really -((op2 * op3) - op1). They are equivalent +;; except for the sign bit when the result is zero or NaN. + +(define_insn "*nmsub4<mode>_fastmath" [(set (match_operand:ANYF 0 "register_operand" "=f") (minus:ANYF - (match_operand:ANYF 1 "register_operand" "f") - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "0"))))] - "ISA_HAS_NMADD3_NMSUB3 - && TARGET_FUSED_MADD + (match_operand:ANYF 1 "register_operand" "f") + (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_UNFUSED_MADD4 && !HONOR_SIGNED_ZEROS (<MODE>mode)" - "nmsub.<fmt>\t%0,%1,%2" + "nmsub.<fmt>\t%0,%1,%2,%3" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index a9baebe6a44..348c6e03f1e 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -209,10 +209,6 @@ mflush-func= Target RejectNegative Joined Var(mips_cache_flush_func) Init(CACHE_FLUSH_FUNC) -mflush-func=FUNC Use FUNC to flush the cache before calling stack trampolines -mfused-madd -Target Report Var(TARGET_FUSED_MADD) Init(1) -Generate floating-point multiply-add instructions - mabs= Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_abs) Init(MIPS_IEEE_754_DEFAULT) -mabs=MODE Select the IEEE 754 ABS/NEG instruction execution mode |