Commit 0609bdf2 by Michael Meissner Committed by Michael Meissner

rs6000-builtin.def (XSRDPIM): Use floatdf2, ceildf2, btruncdf2, instead of vsx_* name.

[gcc]
2013-10-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/rs6000/rs6000-builtin.def (XSRDPIM): Use floatdf2,
	ceildf2, btruncdf2, instead of vsx_* name.

	* config/rs6000/vsx.md (vsx_add<mode>3): Change arithmetic
	iterators to only do V2DF and V4SF here.  Move the DF code to
	rs6000.md where it is combined with SF mode.  Replace <VSv> with
	just 'v' since only vector operations are handled with these insns
	after moving the DF support to rs6000.md.
	(vsx_sub<mode>3): Likewise.
	(vsx_mul<mode>3): Likewise.
	(vsx_div<mode>3): Likewise.
	(vsx_fre<mode>2): Likewise.
	(vsx_neg<mode>2): Likewise.
	(vsx_abs<mode>2): Likewise.
	(vsx_nabs<mode>2): Likewise.
	(vsx_smax<mode>3): Likewise.
	(vsx_smin<mode>3): Likewise.
	(vsx_sqrt<mode>2): Likewise.
	(vsx_rsqrte<mode>2): Likewise.
	(vsx_fms<mode>4): Likewise.
	(vsx_nfma<mode>4): Likewise.
	(vsx_copysign<mode>3): Likewise.
	(vsx_btrunc<mode>2): Likewise.
	(vsx_floor<mode>2): Likewise.
	(vsx_ceil<mode>2): Likewise.
	(vsx_smaxsf3): Delete scalar ops that were moved to rs6000.md.
	(vsx_sminsf3): Likewise.
	(vsx_fmadf4): Likewise.
	(vsx_fmsdf4): Likewise.
	(vsx_nfmadf4): Likewise.
	(vsx_nfmsdf4): Likewise.
	(vsx_cmpdf_internal1): Likewise.

	* config/rs6000/rs6000.h (TARGET_SF_SPE): Define macros to make it
	simpler to select whether a target has SPE or traditional floating
	point support in iterators.
	(TARGET_DF_SPE): Likewise.
	(TARGET_SF_FPR): Likewise.
	(TARGET_DF_FPR): Likewise.
	(TARGET_SF_INSN): Macros to say whether floating point support
	exists for a given operation for expanders.
	(TARGET_DF_INSN): Likewise.

	* config/rs6000/rs6000.c (Ftrad): New mode attributes to allow
	combining of SF/DF mode operations, using both traditional and VSX
	registers.
	(Fvsx): Likewise.
	(Ff): Likewise.
	(Fv): Likewise.
	(Fs): Likewise.
	(Ffre): Likewise.
	(FFRE): Likewise.
	(abs<mode>2): Combine SF/DF modes using traditional floating point
	instructions.  Add support for using the upper DF registers with
	VSX support, and SF registers with power8-vector support.  Update
	expanders for operations supported by both the SPE and traditional
	floating point units.
	(abs<mode>2_fpr): Likewise.
	(nabs<mode>2): Likewise.
	(nabs<mode>2_fpr): Likewise.
	(neg<mode>2): Likewise.
	(neg<mode>2_fpr): Likewise.
	(add<mode>3): Likewise.
	(add<mode>3_fpr): Likewise.
	(sub<mode>3): Likewise.
	(sub<mode>3_fpr): Likewise.
	(mul<mode>3): Likewise.
	(mul<mode>3_fpr): Likewise.
	(div<mode>3): Likewise.
	(div<mode>3_fpr): Likewise.
	(sqrt<mode>3): Likewise.
	(sqrt<mode>3_fpr): Likewise.
	(fre<Fs>): Likewise.
	(rsqrt<mode>2): Likewise.
	(cmp<mode>_fpr): Likewise.
	(smax<mode>3): Likewise.
	(smin<mode>3): Likewise.
	(smax<mode>3_vsx): Likewise.
	(smin<mode>3_vsx): Likewise.
	(negsf2): Delete SF operations that are merged with DF.
	(abssf2): Likewise.
	(addsf3): Likewise.
	(subsf3): Likewise.
	(mulsf3): Likewise.
	(divsf3): Likewise.
	(fres): Likewise.
	(fmasf4_fpr): Likewise.
	(fmssf4_fpr): Likewise.
	(nfmasf4_fpr): Likewise.
	(nfmssf4_fpr): Likewise.
	(sqrtsf2): Likewise.
	(rsqrtsf_internal1): Likewise.
	(smaxsf3): Likewise.
	(sminsf3): Likewise.
	(cmpsf_internal1): Likewise.
	(copysign<mode>3_fcpsgn): Add VSX/power8-vector support.
	(negdf2): Delete DF operations that are merged with SF.
	(absdf2): Likewise.
	(nabsdf2): Likewise.
	(adddf3): Likewise.
	(subdf3): Likewise.
	(muldf3): Likewise.
	(divdf3): Likewise.
	(fred): Likewise.
	(rsqrtdf_internal1): Likewise.
	(fmadf4_fpr): Likewise.
	(fmsdf4_fpr): Likewise.
	(nfmadf4_fpr): Likewise.
	(nfmsdf4_fpr): Likewise.
	(sqrtdf2): Likewise.
	(smaxdf3): Likewise.
	(smindf3): Likewise.
	(cmpdf_internal1): Likewise.
	(lrint<mode>di2): Use TARGET_<MODE>_FPR macro.
	(btrunc<mode>2): Delete separate expander, and combine with the
	insn and add VSX instruction support.  Use TARGET_<MODE>_FPR.
	(btrunc<mode>2_fpr): Likewise.
	(ceil<mode>2): Likewise.
	(ceil<mode>2_fpr): Likewise.
	(floor<mode>2): Likewise.
	(floor<mode>2_fpr): Likewise.
	(fma<mode>4_fpr): Combine SF and DF fused multiply/add support.
	Add support for using the upper registers with VSX and
	power8-vector.  Move insns to be closer to the define_expands. On
	VSX systems, prefer the traditional form of FMA over the VSX
	version, since the traditional form allows the target not to
	overlap with the inputs.
	(fms<mode>4_fpr): Likewise.
	(nfma<mode>4_fpr): Likewise.
	(nfms<mode>4_fpr): Likewise.

[gcc/testsuite]
2013-10-03  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/p8vector-fp.c: New test for floating point
	scalar operations when using -mupper-regs-sf and -mupper-regs-df.
	* gcc.target/powerpc/ppc-target-1.c: Update tests to allow either
	VSX scalar operations or the traditional floating point form of
	the instruction.
	* gcc.target/powerpc/ppc-target-2.c: Likewise.
	* gcc.target/powerpc/recip-3.c: Likewise.
	* gcc.target/powerpc/recip-5.c: Likewise.
	* gcc.target/powerpc/pr72747.c: Likewise.
	* gcc.target/powerpc/vsx-builtin-3.c: Likewise.

From-SVN: r203162
parent 5bea0c6c
2013-10-03 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000-builtin.def (XSRDPIM): Use floatdf2,
ceildf2, btruncdf2, instead of vsx_* name.
* config/rs6000/vsx.md (vsx_add<mode>3): Change arithmetic
iterators to only do V2DF and V4SF here. Move the DF code to
rs6000.md where it is combined with SF mode. Replace <VSv> with
just 'v' since only vector operations are handled with these insns
after moving the DF support to rs6000.md.
(vsx_sub<mode>3): Likewise.
(vsx_mul<mode>3): Likewise.
(vsx_div<mode>3): Likewise.
(vsx_fre<mode>2): Likewise.
(vsx_neg<mode>2): Likewise.
(vsx_abs<mode>2): Likewise.
(vsx_nabs<mode>2): Likewise.
(vsx_smax<mode>3): Likewise.
(vsx_smin<mode>3): Likewise.
(vsx_sqrt<mode>2): Likewise.
(vsx_rsqrte<mode>2): Likewise.
(vsx_fms<mode>4): Likewise.
(vsx_nfma<mode>4): Likewise.
(vsx_copysign<mode>3): Likewise.
(vsx_btrunc<mode>2): Likewise.
(vsx_floor<mode>2): Likewise.
(vsx_ceil<mode>2): Likewise.
(vsx_smaxsf3): Delete scalar ops that were moved to rs6000.md.
(vsx_sminsf3): Likewise.
(vsx_fmadf4): Likewise.
(vsx_fmsdf4): Likewise.
(vsx_nfmadf4): Likewise.
(vsx_nfmsdf4): Likewise.
(vsx_cmpdf_internal1): Likewise.
* config/rs6000/rs6000.h (TARGET_SF_SPE): Define macros to make it
simpler to select whether a target has SPE or traditional floating
point support in iterators.
(TARGET_DF_SPE): Likewise.
(TARGET_SF_FPR): Likewise.
(TARGET_DF_FPR): Likewise.
(TARGET_SF_INSN): Macros to say whether floating point support
exists for a given operation for expanders.
(TARGET_DF_INSN): Likewise.
* config/rs6000/rs6000.c (Ftrad): New mode attributes to allow
combining of SF/DF mode operations, using both traditional and VSX
registers.
(Fvsx): Likewise.
(Ff): Likewise.
(Fv): Likewise.
(Fs): Likewise.
(Ffre): Likewise.
(FFRE): Likewise.
(abs<mode>2): Combine SF/DF modes using traditional floating point
instructions. Add support for using the upper DF registers with
VSX support, and SF registers with power8-vector support. Update
expanders for operations supported by both the SPE and traditional
floating point units.
(abs<mode>2_fpr): Likewise.
(nabs<mode>2): Likewise.
(nabs<mode>2_fpr): Likewise.
(neg<mode>2): Likewise.
(neg<mode>2_fpr): Likewise.
(add<mode>3): Likewise.
(add<mode>3_fpr): Likewise.
(sub<mode>3): Likewise.
(sub<mode>3_fpr): Likewise.
(mul<mode>3): Likewise.
(mul<mode>3_fpr): Likewise.
(div<mode>3): Likewise.
(div<mode>3_fpr): Likewise.
(sqrt<mode>3): Likewise.
(sqrt<mode>3_fpr): Likewise.
(fre<Fs>): Likewise.
(rsqrt<mode>2): Likewise.
(cmp<mode>_fpr): Likewise.
(smax<mode>3): Likewise.
(smin<mode>3): Likewise.
(smax<mode>3_vsx): Likewise.
(smin<mode>3_vsx): Likewise.
(negsf2): Delete SF operations that are merged with DF.
(abssf2): Likewise.
(addsf3): Likewise.
(subsf3): Likewise.
(mulsf3): Likewise.
(divsf3): Likewise.
(fres): Likewise.
(fmasf4_fpr): Likewise.
(fmssf4_fpr): Likewise.
(nfmasf4_fpr): Likewise.
(nfmssf4_fpr): Likewise.
(sqrtsf2): Likewise.
(rsqrtsf_internal1): Likewise.
(smaxsf3): Likewise.
(sminsf3): Likewise.
(cmpsf_internal1): Likewise.
(copysign<mode>3_fcpsgn): Add VSX/power8-vector support.
(negdf2): Delete DF operations that are merged with SF.
(absdf2): Likewise.
(nabsdf2): Likewise.
(adddf3): Likewise.
(subdf3): Likewise.
(muldf3): Likewise.
(divdf3): Likewise.
(fred): Likewise.
(rsqrtdf_internal1): Likewise.
(fmadf4_fpr): Likewise.
(fmsdf4_fpr): Likewise.
(nfmadf4_fpr): Likewise.
(nfmsdf4_fpr): Likewise.
(sqrtdf2): Likewise.
(smaxdf3): Likewise.
(smindf3): Likewise.
(cmpdf_internal1): Likewise.
(lrint<mode>di2): Use TARGET_<MODE>_FPR macro.
(btrunc<mode>2): Delete separate expander, and combine with the
insn and add VSX instruction support. Use TARGET_<MODE>_FPR.
(btrunc<mode>2_fpr): Likewise.
(ceil<mode>2): Likewise.
(ceil<mode>2_fpr): Likewise.
(floor<mode>2): Likewise.
(floor<mode>2_fpr): Likewise.
(fma<mode>4_fpr): Combine SF and DF fused multiply/add support.
Add support for using the upper registers with VSX and
power8-vector. Move insns to be closer to the define_expands. On
VSX systems, prefer the traditional form of FMA over the VSX
version, since the traditional form allows the target not to
overlap with the inputs.
(fms<mode>4_fpr): Likewise.
(nfma<mode>4_fpr): Likewise.
(nfms<mode>4_fpr): Likewise.
2013-10-03 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Richard Earnshaw <richard.earnshaw@arm.com>
......
......@@ -1209,9 +1209,9 @@ BU_VSX_1 (XVRSPIZ, "xvrspiz", CONST, vsx_btruncv4sf2)
BU_VSX_1 (XSRDPI, "xsrdpi", CONST, vsx_xsrdpi)
BU_VSX_1 (XSRDPIC, "xsrdpic", CONST, vsx_xsrdpic)
BU_VSX_1 (XSRDPIM, "xsrdpim", CONST, vsx_floordf2)
BU_VSX_1 (XSRDPIP, "xsrdpip", CONST, vsx_ceildf2)
BU_VSX_1 (XSRDPIZ, "xsrdpiz", CONST, vsx_btruncdf2)
BU_VSX_1 (XSRDPIM, "xsrdpim", CONST, floordf2)
BU_VSX_1 (XSRDPIP, "xsrdpip", CONST, ceildf2)
BU_VSX_1 (XSRDPIZ, "xsrdpiz", CONST, btruncdf2)
/* VSX predicate functions. */
BU_VSX_P (XVCMPEQSP_P, "xvcmpeqsp_p", CONST, vector_eq_v4sf_p)
......
......@@ -617,6 +617,25 @@ extern int rs6000_vector_align[];
|| rs6000_cpu == PROCESSOR_PPC8548)
/* Whether SF/DF operations are supported on the E500. */
#define TARGET_SF_SPE (TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT \
&& !TARGET_FPRS)
#define TARGET_DF_SPE (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT \
&& !TARGET_FPRS && TARGET_E500_DOUBLE)
/* Whether SF/DF operations are supported by by the normal floating point unit
(or the vector/scalar unit). */
#define TARGET_SF_FPR (TARGET_HARD_FLOAT && TARGET_FPRS \
&& TARGET_SINGLE_FLOAT)
#define TARGET_DF_FPR (TARGET_HARD_FLOAT && TARGET_FPRS \
&& TARGET_DOUBLE_FLOAT)
/* Whether SF/DF operations are supported by any hardware. */
#define TARGET_SF_INSN (TARGET_SF_FPR || TARGET_SF_SPE)
#define TARGET_DF_INSN (TARGET_DF_FPR || TARGET_DF_SPE)
/* Which machine supports the various reciprocal estimate instructions. */
#define TARGET_FRES (TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT \
&& TARGET_FPRS && TARGET_SINGLE_FLOAT)
......
......@@ -337,6 +337,25 @@
; Iterator for just SF/DF
(define_mode_iterator SFDF [SF DF])
; SF/DF suffix for traditional floating instructions
(define_mode_attr Ftrad [(SF "s") (DF "")])
; SF/DF suffix for VSX instructions
(define_mode_attr Fvsx [(SF "sp") (DF "dp")])
; SF/DF constraint for arithmetic on traditional floating point registers
(define_mode_attr Ff [(SF "f") (DF "d")])
; SF/DF constraint for arithmetic on VSX registers
(define_mode_attr Fv [(SF "wy") (DF "ws")])
; s/d suffix for things like fp_addsub_s/fp_addsub_d
(define_mode_attr Fs [(SF "s") (DF "d")])
; FRE/FRES support
(define_mode_attr Ffre [(SF "fres") (DF "fre")])
(define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
; Conditional returns.
(define_code_iterator any_return [return simple_return])
(define_code_attr return_pred [(return "direct_return ()")
......@@ -5045,22 +5064,172 @@
(const_int 0)))]
"")
;; Floating-point insns, excluding normal data motion.
;;
;; PowerPC has a full set of single-precision floating point instructions.
;;
;; For the POWER architecture, we pretend that we have both SFmode and
;; DFmode insns, while, in fact, all fp insns are actually done in double.
;; The only conversions we will do will be when storing to memory. In that
;; case, we will use the "frsp" instruction before storing.
;;
;; Note that when we store into a single-precision memory location, we need to
;; use the frsp insn first. If the register being stored isn't dead, we
;; need a scratch register for the frsp. But this is difficult when the store
;; is done by reload. It is not incorrect to do the frsp on the register in
;; this case, we just lose precision that we would have otherwise gotten but
;; is not guaranteed. Perhaps this should be tightened up at some point.
;; Floating-point insns, excluding normal data motion. We combine the SF/DF
;; modes here, and also add in conditional vsx/power8-vector support to access
;; values in the traditional Altivec registers if the appropriate
;; -mupper-regs-{df,sf} option is enabled.
(define_expand "abs<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
"TARGET_<MODE>_INSN"
"")
(define_insn "*abs<mode>2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fabs %0,%1
xsabsdp %x0,%x1"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_insn "*nabs<mode>2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(neg:SFDF
(abs:SFDF
(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
"TARGET_<MODE>_FPR"
"@
fnabs %0,%1
xsnabsdp %x0,%x1"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_expand "neg<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
"TARGET_<MODE>_INSN"
"")
(define_insn "*neg<mode>2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fneg %0,%1
xsnegdp %x0,%x1"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_expand "add<mode>3"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" "")))]
"TARGET_<MODE>_INSN"
"")
(define_insn "*add<mode>3_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fadd<Ftrad> %0,%1,%2
xsadd<Fvsx> %x0,%x1,%x2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_expand "sub<mode>3"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" "")))]
"TARGET_<MODE>_INSN"
"")
(define_insn "*sub<mode>3_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fsub<Ftrad> %0,%1,%2
xssub<Fvsx> %x0,%x1,%x2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_expand "mul<mode>3"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" "")))]
"TARGET_<MODE>_INSN"
"")
(define_insn "*mul<mode>3_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fmul<Ftrad> %0,%1,%2
xsmul<Fvsx> %x0,%x1,%x2"
[(set_attr "type" "dmul")
(set_attr "fp_type" "fp_mul_<Fs>")])
(define_expand "div<mode>3"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" "")))]
"TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
"")
(define_insn "*div<mode>3_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
"@
fdiv<Ftrad> %0,%1,%2
xsdiv<Fvsx> %x0,%x1,%x2"
[(set_attr "type" "<Fs>div")
(set_attr "fp_type" "fp_div_<Fs>")])
(define_insn "sqrt<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
&& (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
"@
fsqrt<Ftrad> %0,%1
xssqrt<Fvsx> %x0,%x1"
[(set_attr "type" "<Fs>sqrt")
(set_attr "fp_type" "fp_sqrt_<Fs>")])
;; Floating point reciprocal approximation
(define_insn "fre<Fs>"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_FRES))]
"TARGET_<FFRE>"
"@
fre<Ftrad> %0,%1
xsre<Fvsx> %x0,%x1"
[(set_attr "type" "fp")])
(define_insn "*rsqrt<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_RSQRT))]
"RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
"@
frsqrte<Ftrad> %0,%1
xsrsqrte<Fvsx> %x0,%x1"
[(set_attr "type" "fp")])
;; Floating point comparisons
(define_insn "*cmp<mode>_fpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
(compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fcmpu %0,%1,%2
xscmpudp %x0,%x1,%x2"
[(set_attr "type" "fpcompare")])
;; Floating point conversions
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
......@@ -5117,175 +5286,6 @@
"frsp %0,%1"
[(set_attr "type" "fp")])
(define_expand "negsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn "*negsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fneg %0,%1"
[(set_attr "type" "fp")])
(define_expand "abssf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn "*abssf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fabs %0,%1"
[(set_attr "type" "fp")])
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fnabs %0,%1"
[(set_attr "type" "fp")])
(define_expand "addsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fadds %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_s")])
(define_expand "subsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fsubs %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_s")])
(define_expand "mulsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fmuls %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_mul_s")])
(define_expand "divsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
"fdivs %0,%1,%2"
[(set_attr "type" "sdiv")])
(define_insn "fres"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
"TARGET_FRES"
"fres %0,%1"
[(set_attr "type" "fp")])
; builtin fmaf support
(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"
"fmadds %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"
"fmsubs %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_insn "*nfmasf4_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"
"fnmadds %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_insn "*nfmssf4_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"
"fnmsubs %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_s")])
(define_expand "sqrtsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
"(TARGET_PPC_GPOPT || TARGET_XILINX_FPU)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
&& !TARGET_SIMPLE_FPU"
"")
(define_insn ""
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
"(TARGET_PPC_GPOPT || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT
&& TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
"fsqrts %0,%1"
[(set_attr "type" "ssqrt")])
(define_insn "*rsqrtsf_internal1"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")]
UNSPEC_RSQRT))]
"TARGET_FRSQRTES"
"frsqrtes %0,%1"
[(set_attr "type" "fp")])
;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
;; builtins.c and optabs.c that are not correct for IBM long double
;; when little-endian.
......@@ -5353,37 +5353,82 @@
;; Use an unspec rather providing an if-then-else in RTL, to prevent the
;; compiler from optimizing -0.0
(define_insn "copysign<mode>3_fcpsgn"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")
(match_operand:SFDF 2 "gpc_reg_operand" "<rreg2>")]
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_COPYSIGN))]
"TARGET_CMPB && !VECTOR_UNIT_VSX_P (<MODE>mode)"
"fcpsgn %0,%2,%1"
"TARGET_<MODE>_FPR && TARGET_CMPB"
"@
fcpsgn %0,%2,%1
xscpsgn<VSs> %x0,%x2,%x1"
[(set_attr "type" "fp")])
;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
;; fsel instruction and some auxiliary computations. Then we just have a
;; single DEFINE_INSN for fsel and the define_splits to make them if made by
;; combine.
(define_expand "smaxsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" ""))
(match_dup 1)
(match_dup 2)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
;; computations. Then we just have a single DEFINE_INSN for fsel and the
;; define_splits to make them if made by combine. On VSX machines we have the
;; min/max instructions.
;;
;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
;; to allow either DF/SF to use only traditional registers.
(define_expand "sminsf3"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "")
(match_operand:SF 2 "gpc_reg_operand" ""))
(match_dup 2)
(match_dup 1)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
&& TARGET_SINGLE_FLOAT && !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
(define_expand "smax<mode>3"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" ""))
(match_dup 1)
(match_dup 2)))]
"TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
{
rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
DONE;
})
(define_insn "*smax<mode>3_vsx"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(smax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR && TARGET_VSX"
"xsmaxdp %x0,%x1,%x2"
[(set_attr "type" "fp")])
(define_expand "smin<mode>3"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(if_then_else:SFDF (ge (match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" ""))
(match_dup 2)
(match_dup 1)))]
"TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math"
{
rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
DONE;
})
(define_insn "*smin<mode>3_vsx"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(smin:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")))]
"TARGET_<MODE>_FPR && TARGET_VSX"
"xsmindp %x0,%x1,%x2"
[(set_attr "type" "fp")])
(define_split
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(match_operator:SFDF 3 "min_max_operator"
[(match_operand:SFDF 1 "gpc_reg_operand" "")
(match_operand:SFDF 2 "gpc_reg_operand" "")]))]
"TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT && !flag_trapping_math
&& !TARGET_VSX"
[(const_int 0)]
{
rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), operands[1],
operands[2]);
DONE;
})
(define_split
[(set (match_operand:SF 0 "gpc_reg_operand" "")
......@@ -5515,208 +5560,9 @@
"fsel %0,%1,%2,%3"
[(set_attr "type" "fp")])
(define_expand "negdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*negdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fneg %0,%1"
[(set_attr "type" "fp")])
(define_expand "absdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*absdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fabs %0,%1"
[(set_attr "type" "fp")])
(define_insn "*nabsdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fnabs %0,%1"
[(set_attr "type" "fp")])
(define_expand "adddf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*adddf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fadd %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")])
(define_expand "subdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*subdf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(minus:DF (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fsub %0,%1,%2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")])
(define_expand "muldf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
"")
(define_insn "*muldf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fmul %0,%1,%2"
[(set_attr "type" "dmul")
(set_attr "fp_type" "fp_mul_d")])
(define_expand "divdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT
&& ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)
&& !TARGET_SIMPLE_FPU"
"")
(define_insn "*divdf3_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(div:DF (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fdiv %0,%1,%2"
[(set_attr "type" "ddiv")])
(define_insn "*fred_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
"TARGET_FRE && !VECTOR_UNIT_VSX_P (DFmode)"
"fre %0,%1"
[(set_attr "type" "fp")])
(define_insn "*rsqrtdf_internal1"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
UNSPEC_RSQRT))]
"TARGET_FRSQRTE && !VECTOR_UNIT_VSX_P (DFmode)"
"frsqrte %0,%1"
[(set_attr "type" "fp")])
; builtin fma support
(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)"
"fmadd %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(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)"
"fmsub %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*nfmadf4_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)"
"fnmadd %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*nfmsdf4_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)"
"fnmsub %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
"TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
"")
(define_insn "*sqrtdf2_fpr"
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
"TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fsqrt %0,%1"
[(set_attr "type" "dsqrt")])
;; The conditional move instructions allow us to perform max and min
;; operations even when
(define_expand "smaxdf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" ""))
(match_dup 1)
(match_dup 2)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
(define_expand "smindf3"
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "")
(match_operand:DF 2 "gpc_reg_operand" ""))
(match_dup 2)
(match_dup 1)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !flag_trapping_math"
"{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
(define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(match_operator:DF 3 "min_max_operator"
......@@ -6400,66 +6246,52 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
UNSPEC_FCTID))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
"TARGET_<MODE>_FPR && TARGET_FPRND"
"fctid %0,%1"
[(set_attr "type" "fp")])
(define_expand "btrunc<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIZ))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
"")
(define_insn "*btrunc<mode>2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
(define_insn "btrunc<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_FRIZ))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
&& !VECTOR_UNIT_VSX_P (<MODE>mode)"
"friz %0,%1"
[(set_attr "type" "fp")])
"TARGET_<MODE>_FPR && TARGET_FPRND"
"@
friz %0,%1
xsrdpiz %x0,%x1"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_expand "ceil<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
(define_insn "ceil<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_FRIP))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
"")
(define_insn "*ceil<mode>2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
UNSPEC_FRIP))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
&& !VECTOR_UNIT_VSX_P (<MODE>mode)"
"frip %0,%1"
[(set_attr "type" "fp")])
(define_expand "floor<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
UNSPEC_FRIM))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
"")
"TARGET_<MODE>_FPR && TARGET_FPRND"
"@
frip %0,%1
xsrdpip %x0,%x1"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
(define_insn "*floor<mode>2_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
(define_insn "floor<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
UNSPEC_FRIM))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
&& !VECTOR_UNIT_VSX_P (<MODE>mode)"
"frim %0,%1"
[(set_attr "type" "fp")])
"TARGET_<MODE>_FPR && TARGET_FPRND"
"@
frim %0,%1
xsrdpim %x0,%x1"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
;; No VSX equivalent to frin
(define_insn "round<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
UNSPEC_FRIN))]
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
"TARGET_<MODE>_FPR && TARGET_FPRND"
"frin %0,%1"
[(set_attr "type" "fp")])
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_<Fs>")])
; An UNSPEC is used so we don't have to support SImode in FP registers.
(define_insn "stfiwx"
......@@ -13331,23 +13163,6 @@
[(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
(define_insn "*cmpsf_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
(match_operand:SF 2 "gpc_reg_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
"fcmpu %0,%1,%2"
[(set_attr "type" "fpcompare")])
(define_insn "*cmpdf_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d")
(match_operand:DF 2 "gpc_reg_operand" "d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& !VECTOR_UNIT_VSX_P (DFmode)"
"fcmpu %0,%1,%2"
[(set_attr "type" "fpcompare")])
;; Only need to compare second words if first words equal
(define_insn "*cmptf_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
......@@ -15642,6 +15457,20 @@
""
"")
(define_insn "*fma<mode>4_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
(fma:SFDF
(match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
(match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))]
"TARGET_<MODE>_FPR"
"@
fmadd<Ftrad> %0,%1,%2,%3
xsmadda<Fvsx> %x0,%x1,%x2
xsmaddm<Fvsx> %x0,%x1,%x3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_<Fs>")])
; Altivec only has fma and nfms.
(define_expand "fms<mode>4"
[(set (match_operand:FMA_F 0 "register_operand" "")
......@@ -15652,6 +15481,20 @@
"!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"")
(define_insn "*fms<mode>4_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
(fma:SFDF
(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
(neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
"TARGET_<MODE>_FPR"
"@
fmsub<Ftrad> %0,%1,%2,%3
xsmsuba<Fvsx> %x0,%x1,%x2
xsmsubm<Fvsx> %x0,%x1,%x3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_<Fs>")])
;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
(define_expand "fnma<mode>4"
[(set (match_operand:FMA_F 0 "register_operand" "")
......@@ -15685,6 +15528,21 @@
"!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
"")
(define_insn "*nfma<mode>4_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
(neg:SFDF
(fma:SFDF
(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
(match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>"))))]
"TARGET_<MODE>_FPR"
"@
fnmadd<Ftrad> %0,%1,%2,%3
xsnmadda<Fvsx> %x0,%x1,%x2
xsnmaddm<Fvsx> %x0,%x1,%x3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_<Fs>")])
; Not an official optab name, but used from builtins.
(define_expand "nfms<mode>4"
[(set (match_operand:FMA_F 0 "register_operand" "")
......@@ -15696,6 +15554,23 @@
""
"")
(define_insn "*nfmssf4_fpr"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>,<Fv>")
(neg:SFDF
(fma:SFDF
(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>,<Fv>")
(match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>,0")
(neg:SFDF
(match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv>")))))]
"TARGET_<MODE>_FPR"
"@
fnmsub<Ftrad> %0,%1,%2,%3
xsnmsuba<Fvsx> %x0,%x1,%x2
xsnmsubm<Fvsx> %x0,%x1,%x3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_<Fs>")])
(define_expand "rs6000_get_timebase"
[(use (match_operand:DI 0 "gpc_reg_operand" ""))]
""
......
......@@ -316,40 +316,42 @@
"")
;; VSX scalar and vector floating point arithmetic instructions
;; VSX vector floating point arithmetic instructions. The VSX scalar
;; instructions are now combined with the insn for the traditional floating
;; point unit.
(define_insn "*vsx_add<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(plus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>add<VSs> %x0,%x1,%x2"
"xvadd<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "*vsx_sub<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(minus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>sub<VSs> %x0,%x1,%x2"
"xvsub<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "*vsx_mul<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(mult:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>mul<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_mul>")
"xvmul<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_mul>")])
(define_insn "*vsx_div<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(div:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>div<VSs> %x0,%x1,%x2"
"xvdiv<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_div>")
(set_attr "fp_type" "<VSfptype_div>")])
......@@ -392,94 +394,72 @@
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "vsx_fre<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")]
UNSPEC_FRES))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>re<VSs> %x0,%x1"
"xvre<VSs> %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "*vsx_neg<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(neg:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>neg<VSs> %x0,%x1"
"xvneg<VSs> %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "*vsx_abs<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(abs:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>abs<VSs> %x0,%x1"
"xvabs<VSs> %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "vsx_nabs<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(neg:VSX_B
(abs:VSX_B
(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa"))))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(neg:VSX_F
(abs:VSX_F
(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa"))))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>nabs<VSs> %x0,%x1"
"xvnabs<VSs> %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "vsx_smax<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(smax:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>max<VSs> %x0,%x1,%x2"
"xvmax<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "*vsx_smin<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(smin:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>min<VSs> %x0,%x1,%x2"
"xvmin<VSs> %x0,%x1,%x2"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
;; Special VSX version of smin/smax for single precision floating point. Since
;; both numbers are rounded to single precision, we can just use the DP version
;; of the instruction.
(define_insn "*vsx_smaxsf3"
[(set (match_operand:SF 0 "vsx_register_operand" "=f")
(smax:SF (match_operand:SF 1 "vsx_register_operand" "f")
(match_operand:SF 2 "vsx_register_operand" "f")))]
"VECTOR_UNIT_VSX_P (DFmode)"
"xsmaxdp %x0,%x1,%x2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")])
(define_insn "*vsx_sminsf3"
[(set (match_operand:SF 0 "vsx_register_operand" "=f")
(smin:SF (match_operand:SF 1 "vsx_register_operand" "f")
(match_operand:SF 2 "vsx_register_operand" "f")))]
"VECTOR_UNIT_VSX_P (DFmode)"
"xsmindp %x0,%x1,%x2"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_addsub_d")])
(define_insn "*vsx_sqrt<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(sqrt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>sqrt<VSs> %x0,%x1"
"xvsqrt<VSs> %x0,%x1"
[(set_attr "type" "<VStype_sqrt>")
(set_attr "fp_type" "<VSfptype_sqrt>")])
(define_insn "*vsx_rsqrte<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")]
UNSPEC_RSQRT))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>rsqrte<VSs> %x0,%x1"
"xvrsqrte<VSs> %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
......@@ -518,26 +498,10 @@
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
;; Fused vector multiply/add instructions Support the classical DF versions of
;; fma, which allows the target to be a separate register from the 3 inputs.
;; Under VSX, the target must be either the addend or the first multiply.
;; Where we can, also do the same for the Altivec V4SF fmas.
(define_insn "*vsx_fmadf4"
[(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d")
(fma:DF
(match_operand:DF 1 "vsx_register_operand" "%ws,ws,wa,wa,d")
(match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d")
(match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d")))]
"VECTOR_UNIT_VSX_P (DFmode)"
"@
xsmaddadp %x0,%x1,%x2
xsmaddmdp %x0,%x1,%x3
xsmaddadp %x0,%x1,%x2
xsmaddmdp %x0,%x1,%x3
fmadd %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
;; Fused vector multiply/add instructions. Support the classical Altivec
;; versions of fma, which allows the target to be a separate register from the
;; 3 inputs. Under VSX, the target must be either the addend or the first
;; multiply.
(define_insn "*vsx_fmav4sf4"
[(set (match_operand:V4SF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,v")
......@@ -568,23 +532,6 @@
xvmaddmdp %x0,%x1,%x3"
[(set_attr "type" "vecdouble")])
(define_insn "*vsx_fmsdf4"
[(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d")
(fma:DF
(match_operand:DF 1 "vsx_register_operand" "%ws,ws,wa,wa,d")
(match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d")
(neg:DF
(match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d"))))]
"VECTOR_UNIT_VSX_P (DFmode)"
"@
xsmsubadp %x0,%x1,%x2
xsmsubmdp %x0,%x1,%x3
xsmsubadp %x0,%x1,%x2
xsmsubmdp %x0,%x1,%x3
fmsub %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*vsx_fms<mode>4"
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
(fma:VSX_F
......@@ -594,29 +541,12 @@
(match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,wa"))))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"@
x<VSv>msuba<VSs> %x0,%x1,%x2
x<VSv>msubm<VSs> %x0,%x1,%x3
x<VSv>msuba<VSs> %x0,%x1,%x2
x<VSv>msubm<VSs> %x0,%x1,%x3"
xvmsuba<VSs> %x0,%x1,%x2
xvmsubm<VSs> %x0,%x1,%x3
xvmsuba<VSs> %x0,%x1,%x2
xvmsubm<VSs> %x0,%x1,%x3"
[(set_attr "type" "<VStype_mul>")])
(define_insn "*vsx_nfmadf4"
[(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d")
(neg:DF
(fma:DF
(match_operand:DF 1 "vsx_register_operand" "ws,ws,wa,wa,d")
(match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d")
(match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d"))))]
"VECTOR_UNIT_VSX_P (DFmode)"
"@
xsnmaddadp %x0,%x1,%x2
xsnmaddmdp %x0,%x1,%x3
xsnmaddadp %x0,%x1,%x2
xsnmaddmdp %x0,%x1,%x3
fnmadd %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*vsx_nfma<mode>4"
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa")
(neg:VSX_F
......@@ -626,31 +556,13 @@
(match_operand:VSX_F 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"
xvnmadda<VSs> %x0,%x1,%x2
xvnmaddm<VSs> %x0,%x1,%x3
xvnmadda<VSs> %x0,%x1,%x2
xvnmaddm<VSs> %x0,%x1,%x3"
[(set_attr "type" "<VStype_mul>")
(set_attr "fp_type" "<VSfptype_mul>")])
(define_insn "*vsx_nfmsdf4"
[(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d")
(neg:DF
(fma:DF
(match_operand:DF 1 "vsx_register_operand" "%ws,ws,wa,wa,d")
(match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d")
(neg:DF
(match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d")))))]
"VECTOR_UNIT_VSX_P (DFmode)"
"@
xsnmsubadp %x0,%x1,%x2
xsnmsubmdp %x0,%x1,%x3
xsnmsubadp %x0,%x1,%x2
xsnmsubmdp %x0,%x1,%x3
fnmsub %0,%1,%2,%3"
[(set_attr "type" "fp")
(set_attr "fp_type" "fp_maddsub_d")])
(define_insn "*vsx_nfmsv4sf4"
[(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,wf,?wa,?wa,v")
(neg:V4SF
......@@ -712,16 +624,6 @@
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
;; Floating point scalar compare
(define_insn "*vsx_cmpdf_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y,?y")
(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "ws,wa")
(match_operand:DF 2 "gpc_reg_operand" "ws,wa")))]
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
&& VECTOR_UNIT_VSX_P (DFmode)"
"xscmpudp %0,%x1,%x2"
[(set_attr "type" "fpcompare")])
;; Compare vectors producing a vector result and a predicate, setting CR6 to
;; indicate a combined status
(define_insn "*vsx_eq_<mode>_p"
......@@ -788,13 +690,13 @@
;; Copy sign
(define_insn "vsx_copysign<mode>3"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_B
[(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_F
[(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")
(match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")]
UNSPEC_COPYSIGN))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>cpsgn<VSs> %x0,%x2,%x1"
"xvcpsgn<VSs> %x0,%x2,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
......@@ -855,10 +757,10 @@
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "vsx_btrunc<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(fix:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>r<VSs>iz %x0,%x1"
"xvr<VSs>iz %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
......@@ -872,20 +774,20 @@
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "vsx_floor<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")]
UNSPEC_FRIM))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>r<VSs>im %x0,%x1"
"xvr<VSs>im %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
(define_insn "vsx_ceil<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")]
[(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa")
(unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa")]
UNSPEC_FRIP))]
"VECTOR_UNIT_VSX_P (<MODE>mode)"
"x<VSv>r<VSs>ip %x0,%x1"
"xvr<VSs>ip %x0,%x1"
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
......
2013-10-03 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/p8vector-fp.c: New test for floating point
scalar operations when using -mupper-regs-sf and -mupper-regs-df.
* gcc.target/powerpc/ppc-target-1.c: Update tests to allow either
VSX scalar operations or the traditional floating point form of
the instruction.
* gcc.target/powerpc/ppc-target-2.c: Likewise.
* gcc.target/powerpc/recip-3.c: Likewise.
* gcc.target/powerpc/recip-5.c: Likewise.
* gcc.target/powerpc/pr72747.c: Likewise.
* gcc.target/powerpc/vsx-builtin-3.c: Likewise.
2013-10-03 Marcus Shawcroft <marcus.shawcroft@arm.com>
PR target/58460
......
......@@ -5,8 +5,7 @@
/* { dg-final { scan-assembler-times "fabs" 3 } } */
/* { dg-final { scan-assembler-times "fnabs" 3 } } */
/* { dg-final { scan-assembler-times "fsel" 3 } } */
/* { dg-final { scan-assembler-times "fcpsgn" 3 } } */
/* { dg-final { scan-assembler-times "xscpsgndp" 1 } } */
/* { dg-final { scan-assembler-times "fcpsgn\|xscpsgndp" 4 } } */
double normal1 (double, double);
double power5 (double, double) __attribute__((__target__("cpu=power5")));
......
......@@ -5,8 +5,7 @@
/* { dg-final { scan-assembler-times "fabs" 3 } } */
/* { dg-final { scan-assembler-times "fnabs" 3 } } */
/* { dg-final { scan-assembler-times "fsel" 3 } } */
/* { dg-final { scan-assembler-times "fcpsgn" 3 } } */
/* { dg-final { scan-assembler-times "xscpsgndp" 1 } } */
/* { dg-final { scan-assembler-times "fcpsgn\|xscpsgndp" 4 } } */
/* fabs/fnabs/fsel */
double normal1 (double a, double b) { return __builtin_copysign (a, b); }
......
......@@ -5,4 +5,4 @@
double foo (double x) { return __builtin_sqrt (x); }
/* { dg-final { scan-assembler "xssqrtdp" } } */
/* { dg-final { scan-assembler "xssqrtdp\|fsqrt" } } */
/* { dg-do compile { target { { powerpc*-*-* } && { ! powerpc*-apple-darwin* } } } } */
/* { dg-require-effective-target powerpc_fprs } */
/* { dg-options "-O2 -mrecip -ffast-math -mcpu=power7" } */
/* { dg-final { scan-assembler-times "xsrsqrtedp" 1 } } */
/* { dg-final { scan-assembler-times "xsrsqrtedp\|frsqrte\ " 1 } } */
/* { dg-final { scan-assembler-times "xsmsub.dp\|fmsub\ " 1 } } */
/* { dg-final { scan-assembler-times "xsmuldp" 4 } } */
/* { dg-final { scan-assembler-times "xsmuldp\|fmul\ " 4 } } */
/* { dg-final { scan-assembler-times "xsnmsub.dp\|fnmsub\ " 2 } } */
/* { dg-final { scan-assembler-times "frsqrtes" 1 } } */
/* { dg-final { scan-assembler-times "fmsubs" 1 } } */
/* { dg-final { scan-assembler-times "fmuls" 2 } } */
/* { dg-final { scan-assembler-times "fnmsubs" 1 } } */
/* { dg-final { scan-assembler-times "xsrsqrtesp\|frsqrtes" 1 } } */
/* { dg-final { scan-assembler-times "xsmsub.sp\|fmsubs" 1 } } */
/* { dg-final { scan-assembler-times "xsmulsp\|fmuls" 2 } } */
/* { dg-final { scan-assembler-times "xsnmsub.sp\|fnmsubs" 1 } } */
double
rsqrt_d (double a)
......
......@@ -4,12 +4,12 @@
/* { dg-options "-O3 -ftree-vectorize -mrecip=all -ffast-math -mcpu=power7 -fno-unroll-loops" } */
/* { dg-final { scan-assembler-times "xvredp" 4 } } */
/* { dg-final { scan-assembler-times "xvresp" 5 } } */
/* { dg-final { scan-assembler-times "xsredp" 2 } } */
/* { dg-final { scan-assembler-times "fres" 2 } } */
/* { dg-final { scan-assembler-times "fmuls" 2 } } */
/* { dg-final { scan-assembler-times "fnmsubs" 2 } } */
/* { dg-final { scan-assembler-times "xsmuldp" 2 } } */
/* { dg-final { scan-assembler-times "xsnmsub.dp" 4 } } */
/* { dg-final { scan-assembler-times "xsredp\|fre\ " 2 } } */
/* { dg-final { scan-assembler-times "fres\|xsresp" 2 } } */
/* { dg-final { scan-assembler-times "fmuls\|xsmulsp" 2 } } */
/* { dg-final { scan-assembler-times "fnmsubs\|xsnmsub.sp" 2 } } */
/* { dg-final { scan-assembler-times "xsmuldp\|fmul\ " 2 } } */
/* { dg-final { scan-assembler-times "xsnmsub.dp\|fnmsub\ " 4 } } */
/* { dg-final { scan-assembler-times "xvmulsp" 7 } } */
/* { dg-final { scan-assembler-times "xvnmsub.sp" 5 } } */
/* { dg-final { scan-assembler-times "xvmuldp" 6 } } */
......
......@@ -16,9 +16,9 @@
/* { dg-final { scan-assembler "xvrspiz" } } */
/* { dg-final { scan-assembler "xsrdpi" } } */
/* { dg-final { scan-assembler "xsrdpic" } } */
/* { dg-final { scan-assembler "xsrdpim" } } */
/* { dg-final { scan-assembler "xsrdpip" } } */
/* { dg-final { scan-assembler "xsrdpiz" } } */
/* { dg-final { scan-assembler "xsrdpim\|frim" } } */
/* { dg-final { scan-assembler "xsrdpip\|frip" } } */
/* { dg-final { scan-assembler "xsrdpiz\|friz" } } */
/* { dg-final { scan-assembler "xsmaxdp" } } */
/* { dg-final { scan-assembler "xsmindp" } } */
/* { dg-final { scan-assembler "xxland" } } */
......
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