X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCInstrVSX.td;h=c97dfbf439ea4851bec0e6fb57f51e6f564d9f14;hb=1123a810092003f8dc1116d39a694d39a1967b67;hp=8593ad2eb193966cd68db5f3a655ad0d22264147;hpb=7363d2223e09fd78094fba652223785f0d63c196;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCInstrVSX.td b/lib/Target/PowerPC/PPCInstrVSX.td index 8593ad2eb19..c97dfbf439e 100644 --- a/lib/Target/PowerPC/PPCInstrVSX.td +++ b/lib/Target/PowerPC/PPCInstrVSX.td @@ -18,6 +18,30 @@ def vsrc : RegisterOperand { let ParserMatchClass = PPCRegVSRCAsmOperand; } +def PPCRegVSFRCAsmOperand : AsmOperandClass { + let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber"; +} +def vsfrc : RegisterOperand { + let ParserMatchClass = PPCRegVSFRCAsmOperand; +} + +// Little-endian-specific nodes. +def SDT_PPClxvd2x : SDTypeProfile<1, 1, [ + SDTCisVT<0, v2f64>, SDTCisPtrTy<1> +]>; +def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [ + SDTCisVT<0, v2f64>, SDTCisPtrTy<1> +]>; +def SDT_PPCxxswapd : SDTypeProfile<1, 1, [ + SDTCisSameAs<0, 1> +]>; + +def PPClxvd2x : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x, + [SDNPHasChain, SDNPMayLoad]>; +def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x, + [SDNPHasChain, SDNPMayStore]>; +def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>; + multiclass XX3Form_Rcr opcode, bits<7> xo, dag OOL, dag IOL, string asmbase, string asmstr, InstrItinClass itin, list pattern> { @@ -32,39 +56,41 @@ multiclass XX3Form_Rcr opcode, bits<7> xo, dag OOL, dag IOL, } } -def HasVSX : Predicate<"PPCSubTarget.hasVSX()">; +def HasVSX : Predicate<"PPCSubTarget->hasVSX()">; +def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">; +def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">; + let Predicates = [HasVSX] in { let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. -let neverHasSideEffects = 1 in { // VSX instructions don't have side effects. +let hasSideEffects = 0 in { // VSX instructions don't have side effects. let Uses = [RM] in { // Load indexed instructions let mayLoad = 1, canFoldAsLoad = 1 in { - def LXSDX : XForm_1<31, 588, - (outs vsrc:$XT), (ins memrr:$src), + def LXSDX : XX1Form<31, 588, + (outs vsfrc:$XT), (ins memrr:$src), "lxsdx $XT, $src", IIC_LdStLFD, [(set f64:$XT, (load xoaddr:$src))]>; - def LXVD2X : XForm_1<31, 844, + def LXVD2X : XX1Form<31, 844, (outs vsrc:$XT), (ins memrr:$src), "lxvd2x $XT, $src", IIC_LdStLFD, - [(set v2f64:$XT, (load xoaddr:$src))]>; + [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>; - def LXVDSX : XForm_1<31, 332, + def LXVDSX : XX1Form<31, 332, (outs vsrc:$XT), (ins memrr:$src), "lxvdsx $XT, $src", IIC_LdStLFD, []>; - // TODO: match load + splat to lxvdsx. - def LXVW4X : XForm_1<31, 780, + def LXVW4X : XX1Form<31, 780, (outs vsrc:$XT), (ins memrr:$src), "lxvw4x $XT, $src", IIC_LdStLFD, - [(set v4f32:$XT, (load xoaddr:$src))]>; + [(set v4i32:$XT, (int_ppc_vsx_lxvw4x xoaddr:$src))]>; } // Store indexed instructions let mayStore = 1 in { def STXSDX : XX1Form<31, 716, - (outs), (ins vsrc:$XT, memrr:$dst), + (outs), (ins vsfrc:$XT, memrr:$dst), "stxsdx $XT, $dst", IIC_LdStSTFD, [(store f64:$XT, xoaddr:$dst)]>; @@ -76,17 +102,17 @@ let Uses = [RM] in { def STXVW4X : XX1Form<31, 908, (outs), (ins vsrc:$XT, memrr:$dst), "stxvw4x $XT, $dst", IIC_LdStSTFD, - [(store v4f32:$XT, xoaddr:$dst)]>; + [(store v4i32:$XT, xoaddr:$dst)]>; } // Add/Mul Instructions let isCommutable = 1 in { def XSADDDP : XX3Form<60, 32, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xsadddp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>; def XSMULDP : XX3Form<60, 48, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xsmuldp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>; @@ -113,7 +139,7 @@ let Uses = [RM] in { // Subtract Instructions def XSSUBDP : XX3Form<60, 40, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xssubdp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>; @@ -130,14 +156,14 @@ let Uses = [RM] in { let BaseName = "XSMADDADP" in { let isCommutable = 1 in def XSMADDADP : XX3Form<60, 33, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsmaddadp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; let IsVSXFMAAlt = 1 in def XSMADDMDP : XX3Form<60, 41, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; @@ -146,14 +172,14 @@ let Uses = [RM] in { let BaseName = "XSMSUBADP" in { let isCommutable = 1 in def XSMSUBADP : XX3Form<60, 49, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsmsubadp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; let IsVSXFMAAlt = 1 in def XSMSUBMDP : XX3Form<60, 57, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; @@ -162,14 +188,14 @@ let Uses = [RM] in { let BaseName = "XSNMADDADP" in { let isCommutable = 1 in def XSNMADDADP : XX3Form<60, 161, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsnmaddadp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; let IsVSXFMAAlt = 1 in def XSNMADDMDP : XX3Form<60, 169, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; @@ -178,14 +204,14 @@ let Uses = [RM] in { let BaseName = "XSNMSUBADP" in { let isCommutable = 1 in def XSNMSUBADP : XX3Form<60, 177, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsnmsubadp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; let IsVSXFMAAlt = 1 in def XSNMSUBMDP : XX3Form<60, 185, - (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, AltVSXFMARel; @@ -321,61 +347,61 @@ let Uses = [RM] in { // Division Instructions def XSDIVDP : XX3Form<60, 56, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xsdivdp $XT, $XA, $XB", IIC_VecFP, + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), + "xsdivdp $XT, $XA, $XB", IIC_FPDivD, [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>; def XSSQRTDP : XX2Form<60, 75, - (outs vsrc:$XT), (ins vsrc:$XB), - "xssqrtdp $XT, $XB", IIC_VecFP, + (outs vsfrc:$XT), (ins vsfrc:$XB), + "xssqrtdp $XT, $XB", IIC_FPSqrtD, [(set f64:$XT, (fsqrt f64:$XB))]>; def XSREDP : XX2Form<60, 90, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsredp $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfre f64:$XB))]>; def XSRSQRTEDP : XX2Form<60, 74, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrsqrtedp $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfrsqrte f64:$XB))]>; def XSTDIVDP : XX3Form_1<60, 61, - (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), - "xstdivdp $crD, $XA, $XB", IIC_VecFP, []>; + (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), + "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>; def XSTSQRTDP : XX2Form_1<60, 106, - (outs crrc:$crD), (ins vsrc:$XB), - "xstsqrtdp $crD, $XB", IIC_VecFP, []>; + (outs crrc:$crD), (ins vsfrc:$XB), + "xstsqrtdp $crD, $XB", IIC_FPCompare, []>; def XVDIVDP : XX3Form<60, 120, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvdivdp $XT, $XA, $XB", IIC_VecFP, + "xvdivdp $XT, $XA, $XB", IIC_FPDivD, [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>; def XVDIVSP : XX3Form<60, 88, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvdivsp $XT, $XA, $XB", IIC_VecFP, + "xvdivsp $XT, $XA, $XB", IIC_FPDivS, [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>; def XVSQRTDP : XX2Form<60, 203, (outs vsrc:$XT), (ins vsrc:$XB), - "xvsqrtdp $XT, $XB", IIC_VecFP, + "xvsqrtdp $XT, $XB", IIC_FPSqrtD, [(set v2f64:$XT, (fsqrt v2f64:$XB))]>; def XVSQRTSP : XX2Form<60, 139, (outs vsrc:$XT), (ins vsrc:$XB), - "xvsqrtsp $XT, $XB", IIC_VecFP, + "xvsqrtsp $XT, $XB", IIC_FPSqrtS, [(set v4f32:$XT, (fsqrt v4f32:$XB))]>; def XVTDIVDP : XX3Form_1<60, 125, (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), - "xvtdivdp $crD, $XA, $XB", IIC_VecFP, []>; + "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>; def XVTDIVSP : XX3Form_1<60, 93, (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), - "xvtdivsp $crD, $XA, $XB", IIC_VecFP, []>; + "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>; def XVTSQRTDP : XX2Form_1<60, 234, (outs crrc:$crD), (ins vsrc:$XB), - "xvtsqrtdp $crD, $XB", IIC_VecFP, []>; + "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>; def XVTSQRTSP : XX2Form_1<60, 170, (outs crrc:$crD), (ins vsrc:$XB), - "xvtsqrtsp $crD, $XB", IIC_VecFP, []>; + "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>; def XVREDP : XX2Form<60, 218, (outs vsrc:$XT), (ins vsrc:$XB), @@ -397,11 +423,11 @@ let Uses = [RM] in { // Compare Instructions def XSCMPODP : XX3Form_1<60, 43, - (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), - "xscmpodp $crD, $XA, $XB", IIC_VecFPCompare, []>; + (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), + "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>; def XSCMPUDP : XX3Form_1<60, 35, - (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), - "xscmpudp $crD, $XA, $XB", IIC_VecFPCompare, []>; + (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), + "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>; defm XVCMPEQDP : XX3Form_Rcr<60, 99, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), @@ -424,19 +450,19 @@ let Uses = [RM] in { // Move Instructions def XSABSDP : XX2Form<60, 345, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsabsdp $XT, $XB", IIC_VecFP, [(set f64:$XT, (fabs f64:$XB))]>; def XSNABSDP : XX2Form<60, 361, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsnabsdp $XT, $XB", IIC_VecFP, [(set f64:$XT, (fneg (fabs f64:$XB)))]>; def XSNEGDP : XX2Form<60, 377, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsnegdp $XT, $XB", IIC_VecFP, [(set f64:$XT, (fneg f64:$XB))]>; def XSCPSGNDP : XX3Form<60, 176, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), "xscpsgndp $XT, $XA, $XB", IIC_VecFP, [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>; @@ -479,33 +505,33 @@ let Uses = [RM] in { // Conversion Instructions def XSCVDPSP : XX2Form<60, 265, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvdpsp $XT, $XB", IIC_VecFP, []>; def XSCVDPSXDS : XX2Form<60, 344, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvdpsxds $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfctidz f64:$XB))]>; def XSCVDPSXWS : XX2Form<60, 88, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvdpsxws $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfctiwz f64:$XB))]>; def XSCVDPUXDS : XX2Form<60, 328, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvdpuxds $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfctiduz f64:$XB))]>; def XSCVDPUXWS : XX2Form<60, 72, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvdpuxws $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfctiwuz f64:$XB))]>; def XSCVSPDP : XX2Form<60, 329, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvspdp $XT, $XB", IIC_VecFP, []>; def XSCVSXDDP : XX2Form<60, 376, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvsxddp $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfcfid f64:$XB))]>; def XSCVUXDDP : XX2Form<60, 360, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xscvuxddp $XT, $XB", IIC_VecFP, [(set f64:$XT, (PPCfcfidu f64:$XB))]>; @@ -514,13 +540,15 @@ let Uses = [RM] in { "xvcvdpsp $XT, $XB", IIC_VecFP, []>; def XVCVDPSXDS : XX2Form<60, 472, (outs vsrc:$XT), (ins vsrc:$XB), - "xvcvdpsxds $XT, $XB", IIC_VecFP, []>; + "xvcvdpsxds $XT, $XB", IIC_VecFP, + [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>; def XVCVDPSXWS : XX2Form<60, 216, (outs vsrc:$XT), (ins vsrc:$XB), "xvcvdpsxws $XT, $XB", IIC_VecFP, []>; def XVCVDPUXDS : XX2Form<60, 456, (outs vsrc:$XT), (ins vsrc:$XB), - "xvcvdpuxds $XT, $XB", IIC_VecFP, []>; + "xvcvdpuxds $XT, $XB", IIC_VecFP, + [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>; def XVCVDPUXWS : XX2Form<60, 200, (outs vsrc:$XT), (ins vsrc:$XB), "xvcvdpuxws $XT, $XB", IIC_VecFP, []>; @@ -542,7 +570,8 @@ let Uses = [RM] in { "xvcvspuxws $XT, $XB", IIC_VecFP, []>; def XVCVSXDDP : XX2Form<60, 504, (outs vsrc:$XT), (ins vsrc:$XB), - "xvcvsxddp $XT, $XB", IIC_VecFP, []>; + "xvcvsxddp $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>; def XVCVSXDSP : XX2Form<60, 440, (outs vsrc:$XT), (ins vsrc:$XB), "xvcvsxdsp $XT, $XB", IIC_VecFP, []>; @@ -554,7 +583,8 @@ let Uses = [RM] in { "xvcvsxwsp $XT, $XB", IIC_VecFP, []>; def XVCVUXDDP : XX2Form<60, 488, (outs vsrc:$XT), (ins vsrc:$XB), - "xvcvuxddp $XT, $XB", IIC_VecFP, []>; + "xvcvuxddp $XT, $XB", IIC_VecFP, + [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>; def XVCVUXDSP : XX2Form<60, 424, (outs vsrc:$XT), (ins vsrc:$XB), "xvcvuxdsp $XT, $XB", IIC_VecFP, []>; @@ -567,23 +597,23 @@ let Uses = [RM] in { // Rounding Instructions def XSRDPI : XX2Form<60, 73, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpi $XT, $XB", IIC_VecFP, [(set f64:$XT, (frnd f64:$XB))]>; def XSRDPIC : XX2Form<60, 107, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpic $XT, $XB", IIC_VecFP, [(set f64:$XT, (fnearbyint f64:$XB))]>; def XSRDPIM : XX2Form<60, 121, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpim $XT, $XB", IIC_VecFP, [(set f64:$XT, (ffloor f64:$XB))]>; def XSRDPIP : XX2Form<60, 105, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpip $XT, $XB", IIC_VecFP, [(set f64:$XT, (fceil f64:$XB))]>; def XSRDPIZ : XX2Form<60, 89, - (outs vsrc:$XT), (ins vsrc:$XB), + (outs vsfrc:$XT), (ins vsfrc:$XB), "xsrdpiz $XT, $XB", IIC_VecFP, [(set f64:$XT, (ftrunc f64:$XB))]>; @@ -632,25 +662,37 @@ let Uses = [RM] in { // Max/Min Instructions let isCommutable = 1 in { def XSMAXDP : XX3Form<60, 160, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xsmaxdp $XT, $XA, $XB", IIC_VecFP, []>; + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), + "xsmaxdp $XT, $XA, $XB", IIC_VecFP, + [(set vsfrc:$XT, + (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>; def XSMINDP : XX3Form<60, 168, - (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xsmindp $XT, $XA, $XB", IIC_VecFP, []>; + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), + "xsmindp $XT, $XA, $XB", IIC_VecFP, + [(set vsfrc:$XT, + (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>; def XVMAXDP : XX3Form<60, 224, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvmaxdp $XT, $XA, $XB", IIC_VecFP, []>; + "xvmaxdp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>; def XVMINDP : XX3Form<60, 232, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvmindp $XT, $XA, $XB", IIC_VecFP, []>; + "xvmindp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>; def XVMAXSP : XX3Form<60, 192, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvmaxsp $XT, $XA, $XB", IIC_VecFP, []>; + "xvmaxsp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>; def XVMINSP : XX3Form<60, 200, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), - "xvminsp $XT, $XA, $XB", IIC_VecFP, []>; + "xvminsp $XT, $XA, $XB", IIC_VecFP, + [(set vsrc:$XT, + (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; } // isCommutable } // Uses = [RM] @@ -675,6 +717,10 @@ let Uses = [RM] in { (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xxlor $XT, $XA, $XB", IIC_VecGeneral, [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>; + let isCodeGenOnly = 1 in + def XXLORf: XX3Form<60, 146, + (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), + "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>; def XXLXOR : XX3Form<60, 154, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), "xxlxor $XT, $XA, $XB", IIC_VecGeneral, @@ -702,7 +748,32 @@ let Uses = [RM] in { def XXSPLTW : XX2Form_2<60, 164, (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM), "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>; -} // neverHasSideEffects +} // hasSideEffects + +// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after +// instruction selection into a branch sequence. +let usesCustomInserter = 1, // Expanded after instruction selection. + PPC970_Single = 1 in { + + def SELECT_CC_VSRC: Pseudo<(outs vsrc:$dst), + (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC), + "#SELECT_CC_VSRC", + []>; + def SELECT_VSRC: Pseudo<(outs vsrc:$dst), + (ins crbitrc:$cond, vsrc:$T, vsrc:$F), + "#SELECT_VSRC", + [(set v2f64:$dst, + (select i1:$cond, v2f64:$T, v2f64:$F))]>; + def SELECT_CC_VSFRC: Pseudo<(outs f8rc:$dst), + (ins crrc:$cond, f8rc:$T, f8rc:$F, + i32imm:$BROPC), "#SELECT_CC_VSFRC", + []>; + def SELECT_VSFRC: Pseudo<(outs f8rc:$dst), + (ins crbitrc:$cond, f8rc:$T, f8rc:$F), + "#SELECT_VSFRC", + [(set f64:$dst, + (select i1:$cond, f64:$T, f64:$F))]>; +} // usesCustomInserter } // AddedComplexity def : InstAlias<"xvmovdp $XT, $XB", @@ -722,14 +793,27 @@ def : InstAlias<"xxswapd $XT, $XB", (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>; let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. + +let Predicates = [IsBigEndian] in { +def : Pat<(v2f64 (scalar_to_vector f64:$A)), + (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>; + +def : Pat<(f64 (vector_extract v2f64:$S, 0)), + (f64 (EXTRACT_SUBREG $S, sub_64))>; +def : Pat<(f64 (vector_extract v2f64:$S, 1)), + (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; +} + +let Predicates = [IsLittleEndian] in { def : Pat<(v2f64 (scalar_to_vector f64:$A)), - (INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), $A, sub_64)>; + (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64), + (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>; def : Pat<(f64 (vector_extract v2f64:$S, 0)), - (EXTRACT_SUBREG (v2f64 (COPY_TO_REGCLASS $S, VSLRC)), sub_64)>; + (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; def : Pat<(f64 (vector_extract v2f64:$S, 1)), - (EXTRACT_SUBREG (v2f64 (COPY_TO_REGCLASS (XXPERMDI $S, $S, 3), - VSLRC)), sub_64)>; + (f64 (EXTRACT_SUBREG $S, sub_64))>; +} // Additional fnmsub patterns: -a*c + b == -(a*c - b) def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), @@ -747,6 +831,8 @@ def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B), def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B), (XVNMSUBASP $B, $C, $A)>; +def : Pat<(v2f64 (bitconvert v4f32:$A)), + (COPY_TO_REGCLASS $A, VSRC)>; def : Pat<(v2f64 (bitconvert v4i32:$A)), (COPY_TO_REGCLASS $A, VSRC)>; def : Pat<(v2f64 (bitconvert v8i16:$A)), @@ -754,6 +840,8 @@ def : Pat<(v2f64 (bitconvert v8i16:$A)), def : Pat<(v2f64 (bitconvert v16i8:$A)), (COPY_TO_REGCLASS $A, VSRC)>; +def : Pat<(v4f32 (bitconvert v2f64:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; def : Pat<(v4i32 (bitconvert v2f64:$A)), (COPY_TO_REGCLASS $A, VRRC)>; def : Pat<(v8i16 (bitconvert v2f64:$A)), @@ -761,6 +849,8 @@ def : Pat<(v8i16 (bitconvert v2f64:$A)), def : Pat<(v16i8 (bitconvert v2f64:$A)), (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v2i64 (bitconvert v4f32:$A)), + (COPY_TO_REGCLASS $A, VSRC)>; def : Pat<(v2i64 (bitconvert v4i32:$A)), (COPY_TO_REGCLASS $A, VSRC)>; def : Pat<(v2i64 (bitconvert v8i16:$A)), @@ -768,6 +858,8 @@ def : Pat<(v2i64 (bitconvert v8i16:$A)), def : Pat<(v2i64 (bitconvert v16i8:$A)), (COPY_TO_REGCLASS $A, VSRC)>; +def : Pat<(v4f32 (bitconvert v2i64:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; def : Pat<(v4i32 (bitconvert v2i64:$A)), (COPY_TO_REGCLASS $A, VRRC)>; def : Pat<(v8i16 (bitconvert v2i64:$A)), @@ -775,6 +867,76 @@ def : Pat<(v8i16 (bitconvert v2i64:$A)), def : Pat<(v16i8 (bitconvert v2i64:$A)), (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v2f64 (bitconvert v2i64:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; +def : Pat<(v2i64 (bitconvert v2f64:$A)), + (COPY_TO_REGCLASS $A, VRRC)>; + +// sign extension patterns +// To extend "in place" from v2i32 to v2i64, we have input data like: +// | undef | i32 | undef | i32 | +// but xvcvsxwdp expects the input in big-Endian format: +// | i32 | undef | i32 | undef | +// so we need to shift everything to the left by one i32 (word) before +// the conversion. +def : Pat<(sext_inreg v2i64:$C, v2i32), + (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>; +def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))), + (XVCVSXWDP (XXSLDWI $C, $C, 1))>; + +// Loads. +def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; +def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; +def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>; +def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>; + +// Stores. +def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst), + (STXVD2X $rS, xoaddr:$dst)>; +def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; +def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst), + (STXVW4X $rS, xoaddr:$dst)>; +def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; + +// Permutes. +def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>; +def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>; +def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>; +def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>; + +// Selects. +def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)), + (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; +def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)), + (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; +def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)), + (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>; +def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)), + (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; +def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)), + (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; +def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)), + (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>; + +def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)), + (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; +def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)), + (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; +def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)), + (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>; +def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)), + (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; +def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)), + (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; +def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)), + (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>; + +// Divides. +def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B), + (XVDIVSP $A, $B)>; +def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B), + (XVDIVDP $A, $B)>; + } // AddedComplexity } // HasVSX