diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2013-10-03 16:08:53 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2013-10-03 16:08:53 +0000 |
commit | 0609bdf2114919b570e7a3c4ab273fdf16262a4b (patch) | |
tree | f2fb594bbcef47e806e79bd9aa1727c3528eaca8 /gcc | |
parent | 5bea0c6c8c3deb0b52aec49434484b35e75293f2 (diff) | |
download | gcc-0609bdf2114919b570e7a3c4ab273fdf16262a4b.zip gcc-0609bdf2114919b570e7a3c4ab273fdf16262a4b.tar.gz gcc-0609bdf2114919b570e7a3c4ab273fdf16262a4b.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 133 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-builtin.def | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 19 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 811 | ||||
-rw-r--r-- | gcc/config/rs6000/vsx.md | 246 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/ppc-target-1.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/ppc-target-2.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/pr42747.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/recip-3.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/recip-5.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c | 6 |
12 files changed, 603 insertions, 663 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 915d769..5d2b685 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,136 @@ +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> diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 6726044..3dab732 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -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) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3464703..c4d57d8 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 4bd3389..2160066 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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" ""))] "" diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 11d6b8b..988842f 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -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>")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 44628c5..6e84ea5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +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 diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-target-1.c b/gcc/testsuite/gcc.target/powerpc/ppc-target-1.c index c98666c..b39fe41 100644 --- a/gcc/testsuite/gcc.target/powerpc/ppc-target-1.c +++ b/gcc/testsuite/gcc.target/powerpc/ppc-target-1.c @@ -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"))); diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-target-2.c b/gcc/testsuite/gcc.target/powerpc/ppc-target-2.c index 8ef95b7..e8a2de3 100644 --- a/gcc/testsuite/gcc.target/powerpc/ppc-target-2.c +++ b/gcc/testsuite/gcc.target/powerpc/ppc-target-2.c @@ -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); } diff --git a/gcc/testsuite/gcc.target/powerpc/pr42747.c b/gcc/testsuite/gcc.target/powerpc/pr42747.c index 9e7310e..41362db 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr42747.c +++ b/gcc/testsuite/gcc.target/powerpc/pr42747.c @@ -5,4 +5,4 @@ double foo (double x) { return __builtin_sqrt (x); } -/* { dg-final { scan-assembler "xssqrtdp" } } */ +/* { dg-final { scan-assembler "xssqrtdp\|fsqrt" } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/recip-3.c b/gcc/testsuite/gcc.target/powerpc/recip-3.c index 56ab371..1f8e305 100644 --- a/gcc/testsuite/gcc.target/powerpc/recip-3.c +++ b/gcc/testsuite/gcc.target/powerpc/recip-3.c @@ -1,14 +1,14 @@ /* { 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) diff --git a/gcc/testsuite/gcc.target/powerpc/recip-5.c b/gcc/testsuite/gcc.target/powerpc/recip-5.c index 0e89075..11d125c 100644 --- a/gcc/testsuite/gcc.target/powerpc/recip-5.c +++ b/gcc/testsuite/gcc.target/powerpc/recip-5.c @@ -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 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c index 8450920..7aeba6c 100644 --- a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c +++ b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-3.c @@ -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" } } */ |