Commit e5aac417 by Steve Ellcey Committed by Steve Ellcey

config.gcc: Add fused-madd.opt.

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.

From-SVN: r225468
parent 25a57fac
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> 2015-07-06 Alan Lawrence <alan.lawrence@arm.com>
PR target/65956 PR target/65956
......
...@@ -418,7 +418,7 @@ microblaze*-*-*) ...@@ -418,7 +418,7 @@ microblaze*-*-*)
mips*-*-*) mips*-*-*)
cpu_type=mips cpu_type=mips
extra_headers="loongson.h" 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*) nds32*)
cpu_type=nds32 cpu_type=nds32
......
...@@ -4054,13 +4054,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, ...@@ -4054,13 +4054,11 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
return true; return true;
case MINUS: case MINUS:
if (float_mode_p if (float_mode_p && ISA_HAS_UNFUSED_MADD4 && !HONOR_SIGNED_ZEROS (mode))
&& (ISA_HAS_NMADD4_NMSUB4 || ISA_HAS_NMADD3_NMSUB3)
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (mode))
{ {
/* See if we can use NMADD or NMSUB. See mips.md for the /* See if we can use NMADD or NMSUB via the *nmadd4<mode>_fastmath
associated patterns. */ or *nmsub4<mode>_fastmath patterns. These patterns check for
HONOR_SIGNED_ZEROS so we check here too. */
rtx op0 = XEXP (x, 0); rtx op0 = XEXP (x, 0);
rtx op1 = XEXP (x, 1); rtx op1 = XEXP (x, 1);
if (GET_CODE (op0) == MULT && GET_CODE (XEXP (op0, 0)) == NEG) 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, ...@@ -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 /* If this is part of a MADD or MSUB, treat the PLUS as
being free. */ being free. */
if ((ISA_HAS_FP_MADD4_MSUB4 || ISA_HAS_FP_MADD3_MSUB3) if (ISA_HAS_UNFUSED_MADD4 && GET_CODE (XEXP (x, 0)) == MULT)
&& TARGET_FUSED_MADD
&& GET_CODE (XEXP (x, 0)) == MULT)
*total = 0; *total = 0;
else else
*total = mips_cost->fp_add; *total = mips_cost->fp_add;
...@@ -4121,13 +4117,10 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, ...@@ -4121,13 +4117,10 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
return true; return true;
case NEG: case NEG:
if (float_mode_p if (float_mode_p && ISA_HAS_UNFUSED_MADD4)
&& (ISA_HAS_NMADD4_NMSUB4 || ISA_HAS_NMADD3_NMSUB3)
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (mode))
{ {
/* See if we can use NMADD or NMSUB. See mips.md for the /* See if we can use NMADD or NMSUB via the *nmadd4<mode> or
associated patterns. */ *nmsub4<mode> patterns. */
rtx op = XEXP (x, 0); rtx op = XEXP (x, 0);
if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
&& GET_CODE (XEXP (op, 0)) == MULT) && GET_CODE (XEXP (op, 0)) == MULT)
...@@ -4147,7 +4140,6 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, ...@@ -4147,7 +4140,6 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
return false; return false;
case FMA: case FMA:
if (ISA_HAS_FP_MADDF_MSUBF)
*total = mips_fp_mult_cost (mode); *total = mips_fp_mult_cost (mode);
return false; return false;
......
...@@ -236,6 +236,7 @@ struct mips_cpu_info { ...@@ -236,6 +236,7 @@ struct mips_cpu_info {
#define TARGET_MIPS5500 (mips_arch == PROCESSOR_R5500) #define TARGET_MIPS5500 (mips_arch == PROCESSOR_R5500)
#define TARGET_MIPS5900 (mips_arch == PROCESSOR_R5900) #define TARGET_MIPS5900 (mips_arch == PROCESSOR_R5900)
#define TARGET_MIPS7000 (mips_arch == PROCESSOR_R7000) #define TARGET_MIPS7000 (mips_arch == PROCESSOR_R7000)
#define TARGET_MIPS8000 (mips_arch == PROCESSOR_R8000)
#define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000) #define TARGET_MIPS9000 (mips_arch == PROCESSOR_R9000)
#define TARGET_OCTEON (mips_arch == PROCESSOR_OCTEON \ #define TARGET_OCTEON (mips_arch == PROCESSOR_OCTEON \
|| mips_arch == PROCESSOR_OCTEON2 \ || mips_arch == PROCESSOR_OCTEON2 \
...@@ -998,22 +999,21 @@ struct mips_cpu_info { ...@@ -998,22 +999,21 @@ struct mips_cpu_info {
/* Integer multiply-accumulate instructions should be generated. */ /* Integer multiply-accumulate instructions should be generated. */
#define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16) #define GENERATE_MADD_MSUB (TARGET_IMADD && !TARGET_MIPS16)
/* ISA has floating-point madd and msub instructions 'd = a * b [+-] c'. */ /* ISA has 4 operand fused madd instructions of the form
#define ISA_HAS_FP_MADD4_MSUB4 ISA_HAS_FP4 'd = [+-] (a * b [+-] c)'. */
#define ISA_HAS_FUSED_MADD4 TARGET_MIPS8000
/* ISA has floating-point MADDF and MSUBF instructions 'd = d [+-] a * b'. */ /* ISA has 4 operand unfused madd instructions of the form
#define ISA_HAS_FP_MADDF_MSUBF (mips_isa_rev >= 6) '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'. */ /* ISA has 3 operand r6 fused madd instructions of the form
#define ISA_HAS_FP_MADD3_MSUB3 TARGET_LOONGSON_2EF 'c = c [+-] (a * b)'. */
#define ISA_HAS_FUSED_MADDF (mips_isa_rev >= 6)
/* ISA has floating-point nmadd and nmsub instructions /* ISA has 3 operand loongson fused madd instructions of the form
'd = -((a * b) [+-] c)'. */ 'c = [+-] (a * b [+-] c)'. */
#define ISA_HAS_NMADD4_NMSUB4 ISA_HAS_FP4 #define ISA_HAS_FUSED_MADD3 TARGET_LOONGSON_2EF
/* ISA has floating-point nmadd and nmsub instructions
'c = -((a * b) [+-] c)'. */
#define ISA_HAS_NMADD3_NMSUB3 TARGET_LOONGSON_2EF
/* ISA has floating-point RECIP.fmt and RSQRT.fmt instructions. The /* 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 MIPS64 rev. 1 ISA says that RECIP.D and RSQRT.D are unpredictable when
......
...@@ -2475,164 +2475,239 @@ ...@@ -2475,164 +2475,239 @@
;; Floating point multiply accumulate instructions. ;; Floating point multiply accumulate instructions.
;; The various multiply accumulate instructions can be used even when (define_expand "fma<mode>4"
;; HONOR_NANS is true because while IEEE 754-2008 requires the negate [(set (match_operand:ANYF 0 "register_operand")
;; operation to negate the sign of a NAN and the MIPS neg instruction does (fma:ANYF (match_operand:ANYF 1 "register_operand")
;; not do this, the multiply and add (or minus) parts of these instructions (match_operand:ANYF 2 "register_operand")
;; have no requirement on how the sign of a NAN is handled and so the final (match_operand:ANYF 3 "register_operand")))]
;; sign bit of the entire operation is undefined. "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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") (fma:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "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")))] (match_operand:ANYF 3 "register_operand" "f")))]
"ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" "ISA_HAS_FUSED_MADD4"
"madd.<fmt>\t%0,%3,%1,%2" "madd.<fmt>\t%0,%3,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "fma<mode>4" (define_insn "*fma<mode>4_maddf"
[(set (match_operand:ANYF 0 "register_operand" "=f") [(set (match_operand:ANYF 0 "register_operand" "=f")
(fma:ANYF (match_operand:ANYF 1 "register_operand" "f") (fma:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f") (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "0")))] (match_operand:ANYF 3 "register_operand" "0")))]
"ISA_HAS_FP_MADDF_MSUBF" "ISA_HAS_FUSED_MADDF"
"maddf.<fmt>\t%0,%1,%2" "maddf.<fmt>\t%0,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") (fma:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "0")))] (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))]
"ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" "ISA_HAS_FUSED_MADD3"
"madd.<fmt>\t%0,%1,%2" "msub.<fmt>\t%0,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "*msub4<mode>" (define_insn "*fms<mode>4_msub4"
[(set (match_operand:ANYF 0 "register_operand" "=f") [(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") (fma:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f")))] (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))]
"ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" "ISA_HAS_FUSED_MADD4"
"msub.<fmt>\t%0,%3,%1,%2" "msub.<fmt>\t%0,%3,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "0")))] (match_operand:ANYF 3 "register_operand" "0")))]
"ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" "ISA_HAS_FUSED_MADD3 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
"msub.<fmt>\t%0,%1,%2" "nmsub.<fmt>\t%0,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "*nmadd4<mode>" (define_insn "*fnma<mode>4_nmsub4"
[(set (match_operand:ANYF 0 "register_operand" "=f") [(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (plus:ANYF (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(mult:ANYF (match_operand:ANYF 1 "register_operand" "f") (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 3 "register_operand" "f")))]
(match_operand:ANYF 3 "register_operand" "f"))))] "ISA_HAS_FUSED_MADD4 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
"ISA_HAS_NMADD4_NMSUB4 "nmsub.<fmt>\t%0,%3,%1,%2"
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmadd.<fmt>\t%0,%3,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (plus:ANYF (fma:ANYF
(mult:ANYF (match_operand:ANYF 1 "register_operand" "f") (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "0"))))] (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))]
"ISA_HAS_NMADD3_NMSUB3 "ISA_HAS_FUSED_MADD3 && !HONOR_SIGNED_ZEROS (<MODE>mode)"
&& TARGET_FUSED_MADD
&& HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmadd.<fmt>\t%0,%1,%2" "nmadd.<fmt>\t%0,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "*nmadd4<mode>_fastmath" (define_insn "*fnms<mode>4_nmadd4"
[(set (match_operand:ANYF 0 "register_operand" "=f") [(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (fma:ANYF
(mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) (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>")])
;; 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")
(plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "f")))] (match_operand:ANYF 3 "register_operand" "f")))]
"ISA_HAS_NMADD4_NMSUB4 "ISA_HAS_UNFUSED_MADD4"
&& TARGET_FUSED_MADD "madd.<fmt>\t%0,%3,%1,%2"
&& !HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmadd.<fmt>\t%0,%3,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "*nmadd3<mode>_fastmath" (define_insn "*msub4<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f") [(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(match_operand:ANYF 2 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "0")))] (match_operand:ANYF 3 "register_operand" "f")))]
"ISA_HAS_NMADD3_NMSUB3 "ISA_HAS_UNFUSED_MADD4"
&& TARGET_FUSED_MADD "msub.<fmt>\t%0,%3,%1,%2"
&& !HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmadd.<fmt>\t%0,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "*nmsub4<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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (minus:ANYF (neg:ANYF (plus:ANYF
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f") (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 1 "register_operand" "f"))))] (match_operand:ANYF 3 "register_operand" "f"))))]
"ISA_HAS_NMADD4_NMSUB4 "ISA_HAS_UNFUSED_MADD4"
&& TARGET_FUSED_MADD "nmadd.<fmt>\t%0,%3,%1,%2"
&& HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmsub.<fmt>\t%0,%1,%2,%3"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
(define_insn "*nmsub3<mode>" (define_insn "*nmsub4<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f") [(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (minus:ANYF (neg:ANYF (minus:ANYF
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f") (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "f")) (match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 1 "register_operand" "0"))))] (match_operand:ANYF 3 "register_operand" "f"))))]
"ISA_HAS_NMADD3_NMSUB3 "ISA_HAS_UNFUSED_MADD4"
&& TARGET_FUSED_MADD "nmsub.<fmt>\t%0,%3,%1,%2"
&& HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmsub.<fmt>\t%0,%1,%2"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (minus:ANYF
(match_operand:ANYF 1 "register_operand" "f") (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f") (match_operand:ANYF 2 "register_operand" "f"))
(match_operand:ANYF 3 "register_operand" "f"))))] (match_operand:ANYF 3 "register_operand" "f")))]
"ISA_HAS_NMADD4_NMSUB4 "ISA_HAS_UNFUSED_MADD4
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)" && !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 "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (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") [(set (match_operand:ANYF 0 "register_operand" "=f")
(minus:ANYF (minus:ANYF
(match_operand:ANYF 1 "register_operand" "f") (match_operand:ANYF 1 "register_operand" "f")
(mult:ANYF (match_operand:ANYF 2 "register_operand" "f") (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
(match_operand:ANYF 3 "register_operand" "0"))))] (match_operand:ANYF 3 "register_operand" "f"))))]
"ISA_HAS_NMADD3_NMSUB3 "ISA_HAS_UNFUSED_MADD4
&& TARGET_FUSED_MADD
&& !HONOR_SIGNED_ZEROS (<MODE>mode)" && !HONOR_SIGNED_ZEROS (<MODE>mode)"
"nmsub.<fmt>\t%0,%1,%2" "nmsub.<fmt>\t%0,%1,%2,%3"
[(set_attr "type" "fmadd") [(set_attr "type" "fmadd")
(set_attr "mode" "<UNITMODE>")]) (set_attr "mode" "<UNITMODE>")])
......
...@@ -209,10 +209,6 @@ mflush-func= ...@@ -209,10 +209,6 @@ mflush-func=
Target RejectNegative Joined Var(mips_cache_flush_func) Init(CACHE_FLUSH_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 -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= mabs=
Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_abs) Init(MIPS_IEEE_754_DEFAULT) 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 -mabs=MODE Select the IEEE 754 ABS/NEG instruction execution mode
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment