1*0b57cec5SDimitry Andric//===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===// 2*0b57cec5SDimitry Andric// 3*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric// 7*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric// 9*0b57cec5SDimitry Andric// This file describes the VSX extension to the PowerPC instruction set. 10*0b57cec5SDimitry Andric// 11*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric// *********************************** NOTE *********************************** 14*0b57cec5SDimitry Andric// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing ** 15*0b57cec5SDimitry Andric// ** which VMX and VSX instructions are lane-sensitive and which are not. ** 16*0b57cec5SDimitry Andric// ** A lane-sensitive instruction relies, implicitly or explicitly, on ** 17*0b57cec5SDimitry Andric// ** whether lanes are numbered from left to right. An instruction like ** 18*0b57cec5SDimitry Andric// ** VADDFP is not lane-sensitive, because each lane of the result vector ** 19*0b57cec5SDimitry Andric// ** relies only on the corresponding lane of the source vectors. However, ** 20*0b57cec5SDimitry Andric// ** an instruction like VMULESB is lane-sensitive, because "even" and ** 21*0b57cec5SDimitry Andric// ** "odd" lanes are different for big-endian and little-endian numbering. ** 22*0b57cec5SDimitry Andric// ** ** 23*0b57cec5SDimitry Andric// ** When adding new VMX and VSX instructions, please consider whether they ** 24*0b57cec5SDimitry Andric// ** are lane-sensitive. If so, they must be added to a switch statement ** 25*0b57cec5SDimitry Andric// ** in PPCVSXSwapRemoval::gatherVectorInstructions(). ** 26*0b57cec5SDimitry Andric// **************************************************************************** 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andricdef PPCRegVSRCAsmOperand : AsmOperandClass { 29*0b57cec5SDimitry Andric let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber"; 30*0b57cec5SDimitry Andric} 31*0b57cec5SDimitry Andricdef vsrc : RegisterOperand<VSRC> { 32*0b57cec5SDimitry Andric let ParserMatchClass = PPCRegVSRCAsmOperand; 33*0b57cec5SDimitry Andric} 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andricdef PPCRegVSFRCAsmOperand : AsmOperandClass { 36*0b57cec5SDimitry Andric let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber"; 37*0b57cec5SDimitry Andric} 38*0b57cec5SDimitry Andricdef vsfrc : RegisterOperand<VSFRC> { 39*0b57cec5SDimitry Andric let ParserMatchClass = PPCRegVSFRCAsmOperand; 40*0b57cec5SDimitry Andric} 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andricdef PPCRegVSSRCAsmOperand : AsmOperandClass { 43*0b57cec5SDimitry Andric let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber"; 44*0b57cec5SDimitry Andric} 45*0b57cec5SDimitry Andricdef vssrc : RegisterOperand<VSSRC> { 46*0b57cec5SDimitry Andric let ParserMatchClass = PPCRegVSSRCAsmOperand; 47*0b57cec5SDimitry Andric} 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andricdef PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass { 50*0b57cec5SDimitry Andric let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber"; 51*0b57cec5SDimitry Andric} 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andricdef spilltovsrrc : RegisterOperand<SPILLTOVSRRC> { 54*0b57cec5SDimitry Andric let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand; 55*0b57cec5SDimitry Andric} 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andricdef SDT_PPCldvsxlh : SDTypeProfile<1, 1, [ 58*0b57cec5SDimitry Andric SDTCisVT<0, v4f32>, SDTCisPtrTy<1> 59*0b57cec5SDimitry Andric]>; 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andricdef SDT_PPCfpextlh : SDTypeProfile<1, 1, [ 62*0b57cec5SDimitry Andric SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32> 63*0b57cec5SDimitry Andric]>; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric// Little-endian-specific nodes. 66*0b57cec5SDimitry Andricdef SDT_PPClxvd2x : SDTypeProfile<1, 1, [ 67*0b57cec5SDimitry Andric SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 68*0b57cec5SDimitry Andric]>; 69*0b57cec5SDimitry Andricdef SDT_PPCstxvd2x : SDTypeProfile<0, 2, [ 70*0b57cec5SDimitry Andric SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 71*0b57cec5SDimitry Andric]>; 72*0b57cec5SDimitry Andricdef SDT_PPCxxswapd : SDTypeProfile<1, 1, [ 73*0b57cec5SDimitry Andric SDTCisSameAs<0, 1> 74*0b57cec5SDimitry Andric]>; 75*0b57cec5SDimitry Andricdef SDTVecConv : SDTypeProfile<1, 2, [ 76*0b57cec5SDimitry Andric SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2> 77*0b57cec5SDimitry Andric]>; 78*0b57cec5SDimitry Andricdef SDTVabsd : SDTypeProfile<1, 3, [ 79*0b57cec5SDimitry Andric SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<3, i32> 80*0b57cec5SDimitry Andric]>; 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andricdef PPClxvd2x : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x, 84*0b57cec5SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 85*0b57cec5SDimitry Andricdef PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x, 86*0b57cec5SDimitry Andric [SDNPHasChain, SDNPMayStore]>; 87*0b57cec5SDimitry Andricdef PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>; 88*0b57cec5SDimitry Andricdef PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>; 89*0b57cec5SDimitry Andricdef PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>; 90*0b57cec5SDimitry Andricdef PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>; 91*0b57cec5SDimitry Andricdef PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>; 92*0b57cec5SDimitry Andricdef PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>; 93*0b57cec5SDimitry Andricdef PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>; 94*0b57cec5SDimitry Andricdef PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>; 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andricdef PPCfpextlh : SDNode<"PPCISD::FP_EXTEND_LH", SDT_PPCfpextlh, []>; 97*0b57cec5SDimitry Andricdef PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh, 98*0b57cec5SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase, 101*0b57cec5SDimitry Andric string asmstr, InstrItinClass itin, Intrinsic Int, 102*0b57cec5SDimitry Andric ValueType OutTy, ValueType InTy> { 103*0b57cec5SDimitry Andric let BaseName = asmbase in { 104*0b57cec5SDimitry Andric def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 105*0b57cec5SDimitry Andric !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 106*0b57cec5SDimitry Andric [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>; 107*0b57cec5SDimitry Andric let Defs = [CR6] in 108*0b57cec5SDimitry Andric def o : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 109*0b57cec5SDimitry Andric !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 110*0b57cec5SDimitry Andric [(set InTy:$XT, 111*0b57cec5SDimitry Andric (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>, 112*0b57cec5SDimitry Andric isDOT; 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric} 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as 117*0b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained 118*0b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained 119*0b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though 120*0b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction 121*0b57cec5SDimitry Andric// to use the same register for both inputs. 122*0b57cec5SDimitry Andric// For example, an output DAG such as this: 123*0b57cec5SDimitry Andric// (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0)) 124*0b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs 125*0b57cec5SDimitry Andric// to the XXPERMDI instruction. 126*0b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr, 127*0b57cec5SDimitry Andric InstrItinClass itin, list<dag> pattern> 128*0b57cec5SDimitry Andric : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> { 129*0b57cec5SDimitry Andric let XB = XA; 130*0b57cec5SDimitry Andric} 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andricdef HasVSX : Predicate<"PPCSubTarget->hasVSX()">; 133*0b57cec5SDimitry Andricdef IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">; 134*0b57cec5SDimitry Andricdef IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">; 135*0b57cec5SDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!PPCSubTarget->hasP9Vector()">; 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andriclet Predicates = [HasVSX] in { 138*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 139*0b57cec5SDimitry Andriclet hasSideEffects = 0 in { // VSX instructions don't have side effects. 140*0b57cec5SDimitry Andriclet Uses = [RM] in { 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric // Load indexed instructions 143*0b57cec5SDimitry Andric let mayLoad = 1, mayStore = 0 in { 144*0b57cec5SDimitry Andric let CodeSize = 3 in 145*0b57cec5SDimitry Andric def LXSDX : XX1Form_memOp<31, 588, 146*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins memrr:$src), 147*0b57cec5SDimitry Andric "lxsdx $XT, $src", IIC_LdStLFD, 148*0b57cec5SDimitry Andric []>; 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later 151*0b57cec5SDimitry Andric let CodeSize = 3 in 152*0b57cec5SDimitry Andric def XFLOADf64 : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), 153*0b57cec5SDimitry Andric "#XFLOADf64", 154*0b57cec5SDimitry Andric [(set f64:$XT, (load xoaddr:$src))]>; 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric let Predicates = [HasVSX, HasOnlySwappingMemOps] in 157*0b57cec5SDimitry Andric def LXVD2X : XX1Form_memOp<31, 844, 158*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins memrr:$src), 159*0b57cec5SDimitry Andric "lxvd2x $XT, $src", IIC_LdStLFD, 160*0b57cec5SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>; 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric def LXVDSX : XX1Form_memOp<31, 332, 163*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins memrr:$src), 164*0b57cec5SDimitry Andric "lxvdsx $XT, $src", IIC_LdStLFD, []>; 165*0b57cec5SDimitry Andric 166*0b57cec5SDimitry Andric let Predicates = [HasVSX, HasOnlySwappingMemOps] in 167*0b57cec5SDimitry Andric def LXVW4X : XX1Form_memOp<31, 780, 168*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins memrr:$src), 169*0b57cec5SDimitry Andric "lxvw4x $XT, $src", IIC_LdStLFD, 170*0b57cec5SDimitry Andric []>; 171*0b57cec5SDimitry Andric } // mayLoad 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric // Store indexed instructions 174*0b57cec5SDimitry Andric let mayStore = 1, mayLoad = 0 in { 175*0b57cec5SDimitry Andric let CodeSize = 3 in 176*0b57cec5SDimitry Andric def STXSDX : XX1Form_memOp<31, 716, 177*0b57cec5SDimitry Andric (outs), (ins vsfrc:$XT, memrr:$dst), 178*0b57cec5SDimitry Andric "stxsdx $XT, $dst", IIC_LdStSTFD, 179*0b57cec5SDimitry Andric []>; 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric // Pseudo instruction XFSTOREf64 will be expanded to STXSDX or STFDX later 182*0b57cec5SDimitry Andric let CodeSize = 3 in 183*0b57cec5SDimitry Andric def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst), 184*0b57cec5SDimitry Andric "#XFSTOREf64", 185*0b57cec5SDimitry Andric [(store f64:$XT, xoaddr:$dst)]>; 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric let Predicates = [HasVSX, HasOnlySwappingMemOps] in { 188*0b57cec5SDimitry Andric // The behaviour of this instruction is endianness-specific so we provide no 189*0b57cec5SDimitry Andric // pattern to match it without considering endianness. 190*0b57cec5SDimitry Andric def STXVD2X : XX1Form_memOp<31, 972, 191*0b57cec5SDimitry Andric (outs), (ins vsrc:$XT, memrr:$dst), 192*0b57cec5SDimitry Andric "stxvd2x $XT, $dst", IIC_LdStSTFD, 193*0b57cec5SDimitry Andric []>; 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric def STXVW4X : XX1Form_memOp<31, 908, 196*0b57cec5SDimitry Andric (outs), (ins vsrc:$XT, memrr:$dst), 197*0b57cec5SDimitry Andric "stxvw4x $XT, $dst", IIC_LdStSTFD, 198*0b57cec5SDimitry Andric []>; 199*0b57cec5SDimitry Andric } 200*0b57cec5SDimitry Andric } // mayStore 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric // Add/Mul Instructions 203*0b57cec5SDimitry Andric let isCommutable = 1 in { 204*0b57cec5SDimitry Andric def XSADDDP : XX3Form<60, 32, 205*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 206*0b57cec5SDimitry Andric "xsadddp $XT, $XA, $XB", IIC_VecFP, 207*0b57cec5SDimitry Andric [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>; 208*0b57cec5SDimitry Andric def XSMULDP : XX3Form<60, 48, 209*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 210*0b57cec5SDimitry Andric "xsmuldp $XT, $XA, $XB", IIC_VecFP, 211*0b57cec5SDimitry Andric [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>; 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric def XVADDDP : XX3Form<60, 96, 214*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 215*0b57cec5SDimitry Andric "xvadddp $XT, $XA, $XB", IIC_VecFP, 216*0b57cec5SDimitry Andric [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>; 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric def XVADDSP : XX3Form<60, 64, 219*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 220*0b57cec5SDimitry Andric "xvaddsp $XT, $XA, $XB", IIC_VecFP, 221*0b57cec5SDimitry Andric [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>; 222*0b57cec5SDimitry Andric 223*0b57cec5SDimitry Andric def XVMULDP : XX3Form<60, 112, 224*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 225*0b57cec5SDimitry Andric "xvmuldp $XT, $XA, $XB", IIC_VecFP, 226*0b57cec5SDimitry Andric [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>; 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric def XVMULSP : XX3Form<60, 80, 229*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 230*0b57cec5SDimitry Andric "xvmulsp $XT, $XA, $XB", IIC_VecFP, 231*0b57cec5SDimitry Andric [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>; 232*0b57cec5SDimitry Andric } 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric // Subtract Instructions 235*0b57cec5SDimitry Andric def XSSUBDP : XX3Form<60, 40, 236*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 237*0b57cec5SDimitry Andric "xssubdp $XT, $XA, $XB", IIC_VecFP, 238*0b57cec5SDimitry Andric [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>; 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric def XVSUBDP : XX3Form<60, 104, 241*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 242*0b57cec5SDimitry Andric "xvsubdp $XT, $XA, $XB", IIC_VecFP, 243*0b57cec5SDimitry Andric [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>; 244*0b57cec5SDimitry Andric def XVSUBSP : XX3Form<60, 72, 245*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 246*0b57cec5SDimitry Andric "xvsubsp $XT, $XA, $XB", IIC_VecFP, 247*0b57cec5SDimitry Andric [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>; 248*0b57cec5SDimitry Andric 249*0b57cec5SDimitry Andric // FMA Instructions 250*0b57cec5SDimitry Andric let BaseName = "XSMADDADP" in { 251*0b57cec5SDimitry Andric let isCommutable = 1 in 252*0b57cec5SDimitry Andric def XSMADDADP : XX3Form<60, 33, 253*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 254*0b57cec5SDimitry Andric "xsmaddadp $XT, $XA, $XB", IIC_VecFP, 255*0b57cec5SDimitry Andric [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>, 256*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 257*0b57cec5SDimitry Andric AltVSXFMARel; 258*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 259*0b57cec5SDimitry Andric def XSMADDMDP : XX3Form<60, 41, 260*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 261*0b57cec5SDimitry Andric "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 262*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 263*0b57cec5SDimitry Andric AltVSXFMARel; 264*0b57cec5SDimitry Andric } 265*0b57cec5SDimitry Andric 266*0b57cec5SDimitry Andric let BaseName = "XSMSUBADP" in { 267*0b57cec5SDimitry Andric let isCommutable = 1 in 268*0b57cec5SDimitry Andric def XSMSUBADP : XX3Form<60, 49, 269*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 270*0b57cec5SDimitry Andric "xsmsubadp $XT, $XA, $XB", IIC_VecFP, 271*0b57cec5SDimitry Andric [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>, 272*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 273*0b57cec5SDimitry Andric AltVSXFMARel; 274*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 275*0b57cec5SDimitry Andric def XSMSUBMDP : XX3Form<60, 57, 276*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 277*0b57cec5SDimitry Andric "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 278*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 279*0b57cec5SDimitry Andric AltVSXFMARel; 280*0b57cec5SDimitry Andric } 281*0b57cec5SDimitry Andric 282*0b57cec5SDimitry Andric let BaseName = "XSNMADDADP" in { 283*0b57cec5SDimitry Andric let isCommutable = 1 in 284*0b57cec5SDimitry Andric def XSNMADDADP : XX3Form<60, 161, 285*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 286*0b57cec5SDimitry Andric "xsnmaddadp $XT, $XA, $XB", IIC_VecFP, 287*0b57cec5SDimitry Andric [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>, 288*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 289*0b57cec5SDimitry Andric AltVSXFMARel; 290*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 291*0b57cec5SDimitry Andric def XSNMADDMDP : XX3Form<60, 169, 292*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 293*0b57cec5SDimitry Andric "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 294*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 295*0b57cec5SDimitry Andric AltVSXFMARel; 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric let BaseName = "XSNMSUBADP" in { 299*0b57cec5SDimitry Andric let isCommutable = 1 in 300*0b57cec5SDimitry Andric def XSNMSUBADP : XX3Form<60, 177, 301*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 302*0b57cec5SDimitry Andric "xsnmsubadp $XT, $XA, $XB", IIC_VecFP, 303*0b57cec5SDimitry Andric [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>, 304*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 305*0b57cec5SDimitry Andric AltVSXFMARel; 306*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 307*0b57cec5SDimitry Andric def XSNMSUBMDP : XX3Form<60, 185, 308*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 309*0b57cec5SDimitry Andric "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 310*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 311*0b57cec5SDimitry Andric AltVSXFMARel; 312*0b57cec5SDimitry Andric } 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric let BaseName = "XVMADDADP" in { 315*0b57cec5SDimitry Andric let isCommutable = 1 in 316*0b57cec5SDimitry Andric def XVMADDADP : XX3Form<60, 97, 317*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 318*0b57cec5SDimitry Andric "xvmaddadp $XT, $XA, $XB", IIC_VecFP, 319*0b57cec5SDimitry Andric [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>, 320*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 321*0b57cec5SDimitry Andric AltVSXFMARel; 322*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 323*0b57cec5SDimitry Andric def XVMADDMDP : XX3Form<60, 105, 324*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 325*0b57cec5SDimitry Andric "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 326*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 327*0b57cec5SDimitry Andric AltVSXFMARel; 328*0b57cec5SDimitry Andric } 329*0b57cec5SDimitry Andric 330*0b57cec5SDimitry Andric let BaseName = "XVMADDASP" in { 331*0b57cec5SDimitry Andric let isCommutable = 1 in 332*0b57cec5SDimitry Andric def XVMADDASP : XX3Form<60, 65, 333*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 334*0b57cec5SDimitry Andric "xvmaddasp $XT, $XA, $XB", IIC_VecFP, 335*0b57cec5SDimitry Andric [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>, 336*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 337*0b57cec5SDimitry Andric AltVSXFMARel; 338*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 339*0b57cec5SDimitry Andric def XVMADDMSP : XX3Form<60, 73, 340*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 341*0b57cec5SDimitry Andric "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 342*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 343*0b57cec5SDimitry Andric AltVSXFMARel; 344*0b57cec5SDimitry Andric } 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric let BaseName = "XVMSUBADP" in { 347*0b57cec5SDimitry Andric let isCommutable = 1 in 348*0b57cec5SDimitry Andric def XVMSUBADP : XX3Form<60, 113, 349*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 350*0b57cec5SDimitry Andric "xvmsubadp $XT, $XA, $XB", IIC_VecFP, 351*0b57cec5SDimitry Andric [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>, 352*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 353*0b57cec5SDimitry Andric AltVSXFMARel; 354*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 355*0b57cec5SDimitry Andric def XVMSUBMDP : XX3Form<60, 121, 356*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 357*0b57cec5SDimitry Andric "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 358*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 359*0b57cec5SDimitry Andric AltVSXFMARel; 360*0b57cec5SDimitry Andric } 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric let BaseName = "XVMSUBASP" in { 363*0b57cec5SDimitry Andric let isCommutable = 1 in 364*0b57cec5SDimitry Andric def XVMSUBASP : XX3Form<60, 81, 365*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 366*0b57cec5SDimitry Andric "xvmsubasp $XT, $XA, $XB", IIC_VecFP, 367*0b57cec5SDimitry Andric [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>, 368*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 369*0b57cec5SDimitry Andric AltVSXFMARel; 370*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 371*0b57cec5SDimitry Andric def XVMSUBMSP : XX3Form<60, 89, 372*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 373*0b57cec5SDimitry Andric "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 374*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 375*0b57cec5SDimitry Andric AltVSXFMARel; 376*0b57cec5SDimitry Andric } 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric let BaseName = "XVNMADDADP" in { 379*0b57cec5SDimitry Andric let isCommutable = 1 in 380*0b57cec5SDimitry Andric def XVNMADDADP : XX3Form<60, 225, 381*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 382*0b57cec5SDimitry Andric "xvnmaddadp $XT, $XA, $XB", IIC_VecFP, 383*0b57cec5SDimitry Andric [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>, 384*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 385*0b57cec5SDimitry Andric AltVSXFMARel; 386*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 387*0b57cec5SDimitry Andric def XVNMADDMDP : XX3Form<60, 233, 388*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 389*0b57cec5SDimitry Andric "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 390*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 391*0b57cec5SDimitry Andric AltVSXFMARel; 392*0b57cec5SDimitry Andric } 393*0b57cec5SDimitry Andric 394*0b57cec5SDimitry Andric let BaseName = "XVNMADDASP" in { 395*0b57cec5SDimitry Andric let isCommutable = 1 in 396*0b57cec5SDimitry Andric def XVNMADDASP : XX3Form<60, 193, 397*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 398*0b57cec5SDimitry Andric "xvnmaddasp $XT, $XA, $XB", IIC_VecFP, 399*0b57cec5SDimitry Andric [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>, 400*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 401*0b57cec5SDimitry Andric AltVSXFMARel; 402*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 403*0b57cec5SDimitry Andric def XVNMADDMSP : XX3Form<60, 201, 404*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 405*0b57cec5SDimitry Andric "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 406*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 407*0b57cec5SDimitry Andric AltVSXFMARel; 408*0b57cec5SDimitry Andric } 409*0b57cec5SDimitry Andric 410*0b57cec5SDimitry Andric let BaseName = "XVNMSUBADP" in { 411*0b57cec5SDimitry Andric let isCommutable = 1 in 412*0b57cec5SDimitry Andric def XVNMSUBADP : XX3Form<60, 241, 413*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 414*0b57cec5SDimitry Andric "xvnmsubadp $XT, $XA, $XB", IIC_VecFP, 415*0b57cec5SDimitry Andric [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>, 416*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 417*0b57cec5SDimitry Andric AltVSXFMARel; 418*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 419*0b57cec5SDimitry Andric def XVNMSUBMDP : XX3Form<60, 249, 420*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 421*0b57cec5SDimitry Andric "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 422*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 423*0b57cec5SDimitry Andric AltVSXFMARel; 424*0b57cec5SDimitry Andric } 425*0b57cec5SDimitry Andric 426*0b57cec5SDimitry Andric let BaseName = "XVNMSUBASP" in { 427*0b57cec5SDimitry Andric let isCommutable = 1 in 428*0b57cec5SDimitry Andric def XVNMSUBASP : XX3Form<60, 209, 429*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 430*0b57cec5SDimitry Andric "xvnmsubasp $XT, $XA, $XB", IIC_VecFP, 431*0b57cec5SDimitry Andric [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>, 432*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 433*0b57cec5SDimitry Andric AltVSXFMARel; 434*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 435*0b57cec5SDimitry Andric def XVNMSUBMSP : XX3Form<60, 217, 436*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 437*0b57cec5SDimitry Andric "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 438*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 439*0b57cec5SDimitry Andric AltVSXFMARel; 440*0b57cec5SDimitry Andric } 441*0b57cec5SDimitry Andric 442*0b57cec5SDimitry Andric // Division Instructions 443*0b57cec5SDimitry Andric def XSDIVDP : XX3Form<60, 56, 444*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 445*0b57cec5SDimitry Andric "xsdivdp $XT, $XA, $XB", IIC_FPDivD, 446*0b57cec5SDimitry Andric [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>; 447*0b57cec5SDimitry Andric def XSSQRTDP : XX2Form<60, 75, 448*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 449*0b57cec5SDimitry Andric "xssqrtdp $XT, $XB", IIC_FPSqrtD, 450*0b57cec5SDimitry Andric [(set f64:$XT, (fsqrt f64:$XB))]>; 451*0b57cec5SDimitry Andric 452*0b57cec5SDimitry Andric def XSREDP : XX2Form<60, 90, 453*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 454*0b57cec5SDimitry Andric "xsredp $XT, $XB", IIC_VecFP, 455*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfre f64:$XB))]>; 456*0b57cec5SDimitry Andric def XSRSQRTEDP : XX2Form<60, 74, 457*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 458*0b57cec5SDimitry Andric "xsrsqrtedp $XT, $XB", IIC_VecFP, 459*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfrsqrte f64:$XB))]>; 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric def XSTDIVDP : XX3Form_1<60, 61, 462*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 463*0b57cec5SDimitry Andric "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>; 464*0b57cec5SDimitry Andric def XSTSQRTDP : XX2Form_1<60, 106, 465*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XB), 466*0b57cec5SDimitry Andric "xstsqrtdp $crD, $XB", IIC_FPCompare, []>; 467*0b57cec5SDimitry Andric 468*0b57cec5SDimitry Andric def XVDIVDP : XX3Form<60, 120, 469*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 470*0b57cec5SDimitry Andric "xvdivdp $XT, $XA, $XB", IIC_FPDivD, 471*0b57cec5SDimitry Andric [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>; 472*0b57cec5SDimitry Andric def XVDIVSP : XX3Form<60, 88, 473*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 474*0b57cec5SDimitry Andric "xvdivsp $XT, $XA, $XB", IIC_FPDivS, 475*0b57cec5SDimitry Andric [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>; 476*0b57cec5SDimitry Andric 477*0b57cec5SDimitry Andric def XVSQRTDP : XX2Form<60, 203, 478*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 479*0b57cec5SDimitry Andric "xvsqrtdp $XT, $XB", IIC_FPSqrtD, 480*0b57cec5SDimitry Andric [(set v2f64:$XT, (fsqrt v2f64:$XB))]>; 481*0b57cec5SDimitry Andric def XVSQRTSP : XX2Form<60, 139, 482*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 483*0b57cec5SDimitry Andric "xvsqrtsp $XT, $XB", IIC_FPSqrtS, 484*0b57cec5SDimitry Andric [(set v4f32:$XT, (fsqrt v4f32:$XB))]>; 485*0b57cec5SDimitry Andric 486*0b57cec5SDimitry Andric def XVTDIVDP : XX3Form_1<60, 125, 487*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), 488*0b57cec5SDimitry Andric "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>; 489*0b57cec5SDimitry Andric def XVTDIVSP : XX3Form_1<60, 93, 490*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), 491*0b57cec5SDimitry Andric "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>; 492*0b57cec5SDimitry Andric 493*0b57cec5SDimitry Andric def XVTSQRTDP : XX2Form_1<60, 234, 494*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsrc:$XB), 495*0b57cec5SDimitry Andric "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>; 496*0b57cec5SDimitry Andric def XVTSQRTSP : XX2Form_1<60, 170, 497*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsrc:$XB), 498*0b57cec5SDimitry Andric "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>; 499*0b57cec5SDimitry Andric 500*0b57cec5SDimitry Andric def XVREDP : XX2Form<60, 218, 501*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 502*0b57cec5SDimitry Andric "xvredp $XT, $XB", IIC_VecFP, 503*0b57cec5SDimitry Andric [(set v2f64:$XT, (PPCfre v2f64:$XB))]>; 504*0b57cec5SDimitry Andric def XVRESP : XX2Form<60, 154, 505*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 506*0b57cec5SDimitry Andric "xvresp $XT, $XB", IIC_VecFP, 507*0b57cec5SDimitry Andric [(set v4f32:$XT, (PPCfre v4f32:$XB))]>; 508*0b57cec5SDimitry Andric 509*0b57cec5SDimitry Andric def XVRSQRTEDP : XX2Form<60, 202, 510*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 511*0b57cec5SDimitry Andric "xvrsqrtedp $XT, $XB", IIC_VecFP, 512*0b57cec5SDimitry Andric [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>; 513*0b57cec5SDimitry Andric def XVRSQRTESP : XX2Form<60, 138, 514*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 515*0b57cec5SDimitry Andric "xvrsqrtesp $XT, $XB", IIC_VecFP, 516*0b57cec5SDimitry Andric [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>; 517*0b57cec5SDimitry Andric 518*0b57cec5SDimitry Andric // Compare Instructions 519*0b57cec5SDimitry Andric def XSCMPODP : XX3Form_1<60, 43, 520*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 521*0b57cec5SDimitry Andric "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>; 522*0b57cec5SDimitry Andric def XSCMPUDP : XX3Form_1<60, 35, 523*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 524*0b57cec5SDimitry Andric "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>; 525*0b57cec5SDimitry Andric 526*0b57cec5SDimitry Andric defm XVCMPEQDP : XX3Form_Rcr<60, 99, 527*0b57cec5SDimitry Andric "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare, 528*0b57cec5SDimitry Andric int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>; 529*0b57cec5SDimitry Andric defm XVCMPEQSP : XX3Form_Rcr<60, 67, 530*0b57cec5SDimitry Andric "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare, 531*0b57cec5SDimitry Andric int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>; 532*0b57cec5SDimitry Andric defm XVCMPGEDP : XX3Form_Rcr<60, 115, 533*0b57cec5SDimitry Andric "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare, 534*0b57cec5SDimitry Andric int_ppc_vsx_xvcmpgedp, v2i64, v2f64>; 535*0b57cec5SDimitry Andric defm XVCMPGESP : XX3Form_Rcr<60, 83, 536*0b57cec5SDimitry Andric "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare, 537*0b57cec5SDimitry Andric int_ppc_vsx_xvcmpgesp, v4i32, v4f32>; 538*0b57cec5SDimitry Andric defm XVCMPGTDP : XX3Form_Rcr<60, 107, 539*0b57cec5SDimitry Andric "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare, 540*0b57cec5SDimitry Andric int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>; 541*0b57cec5SDimitry Andric defm XVCMPGTSP : XX3Form_Rcr<60, 75, 542*0b57cec5SDimitry Andric "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare, 543*0b57cec5SDimitry Andric int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>; 544*0b57cec5SDimitry Andric 545*0b57cec5SDimitry Andric // Move Instructions 546*0b57cec5SDimitry Andric def XSABSDP : XX2Form<60, 345, 547*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 548*0b57cec5SDimitry Andric "xsabsdp $XT, $XB", IIC_VecFP, 549*0b57cec5SDimitry Andric [(set f64:$XT, (fabs f64:$XB))]>; 550*0b57cec5SDimitry Andric def XSNABSDP : XX2Form<60, 361, 551*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 552*0b57cec5SDimitry Andric "xsnabsdp $XT, $XB", IIC_VecFP, 553*0b57cec5SDimitry Andric [(set f64:$XT, (fneg (fabs f64:$XB)))]>; 554*0b57cec5SDimitry Andric def XSNEGDP : XX2Form<60, 377, 555*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 556*0b57cec5SDimitry Andric "xsnegdp $XT, $XB", IIC_VecFP, 557*0b57cec5SDimitry Andric [(set f64:$XT, (fneg f64:$XB))]>; 558*0b57cec5SDimitry Andric def XSCPSGNDP : XX3Form<60, 176, 559*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 560*0b57cec5SDimitry Andric "xscpsgndp $XT, $XA, $XB", IIC_VecFP, 561*0b57cec5SDimitry Andric [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>; 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric def XVABSDP : XX2Form<60, 473, 564*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 565*0b57cec5SDimitry Andric "xvabsdp $XT, $XB", IIC_VecFP, 566*0b57cec5SDimitry Andric [(set v2f64:$XT, (fabs v2f64:$XB))]>; 567*0b57cec5SDimitry Andric 568*0b57cec5SDimitry Andric def XVABSSP : XX2Form<60, 409, 569*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 570*0b57cec5SDimitry Andric "xvabssp $XT, $XB", IIC_VecFP, 571*0b57cec5SDimitry Andric [(set v4f32:$XT, (fabs v4f32:$XB))]>; 572*0b57cec5SDimitry Andric 573*0b57cec5SDimitry Andric def XVCPSGNDP : XX3Form<60, 240, 574*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 575*0b57cec5SDimitry Andric "xvcpsgndp $XT, $XA, $XB", IIC_VecFP, 576*0b57cec5SDimitry Andric [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>; 577*0b57cec5SDimitry Andric def XVCPSGNSP : XX3Form<60, 208, 578*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 579*0b57cec5SDimitry Andric "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP, 580*0b57cec5SDimitry Andric [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>; 581*0b57cec5SDimitry Andric 582*0b57cec5SDimitry Andric def XVNABSDP : XX2Form<60, 489, 583*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 584*0b57cec5SDimitry Andric "xvnabsdp $XT, $XB", IIC_VecFP, 585*0b57cec5SDimitry Andric [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>; 586*0b57cec5SDimitry Andric def XVNABSSP : XX2Form<60, 425, 587*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 588*0b57cec5SDimitry Andric "xvnabssp $XT, $XB", IIC_VecFP, 589*0b57cec5SDimitry Andric [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>; 590*0b57cec5SDimitry Andric 591*0b57cec5SDimitry Andric def XVNEGDP : XX2Form<60, 505, 592*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 593*0b57cec5SDimitry Andric "xvnegdp $XT, $XB", IIC_VecFP, 594*0b57cec5SDimitry Andric [(set v2f64:$XT, (fneg v2f64:$XB))]>; 595*0b57cec5SDimitry Andric def XVNEGSP : XX2Form<60, 441, 596*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 597*0b57cec5SDimitry Andric "xvnegsp $XT, $XB", IIC_VecFP, 598*0b57cec5SDimitry Andric [(set v4f32:$XT, (fneg v4f32:$XB))]>; 599*0b57cec5SDimitry Andric 600*0b57cec5SDimitry Andric // Conversion Instructions 601*0b57cec5SDimitry Andric def XSCVDPSP : XX2Form<60, 265, 602*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 603*0b57cec5SDimitry Andric "xscvdpsp $XT, $XB", IIC_VecFP, []>; 604*0b57cec5SDimitry Andric def XSCVDPSXDS : XX2Form<60, 344, 605*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 606*0b57cec5SDimitry Andric "xscvdpsxds $XT, $XB", IIC_VecFP, 607*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfctidz f64:$XB))]>; 608*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 609*0b57cec5SDimitry Andric def XSCVDPSXDSs : XX2Form<60, 344, 610*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 611*0b57cec5SDimitry Andric "xscvdpsxds $XT, $XB", IIC_VecFP, 612*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfctidz f32:$XB))]>; 613*0b57cec5SDimitry Andric def XSCVDPSXWS : XX2Form<60, 88, 614*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 615*0b57cec5SDimitry Andric "xscvdpsxws $XT, $XB", IIC_VecFP, 616*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfctiwz f64:$XB))]>; 617*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 618*0b57cec5SDimitry Andric def XSCVDPSXWSs : XX2Form<60, 88, 619*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 620*0b57cec5SDimitry Andric "xscvdpsxws $XT, $XB", IIC_VecFP, 621*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfctiwz f32:$XB))]>; 622*0b57cec5SDimitry Andric def XSCVDPUXDS : XX2Form<60, 328, 623*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 624*0b57cec5SDimitry Andric "xscvdpuxds $XT, $XB", IIC_VecFP, 625*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfctiduz f64:$XB))]>; 626*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 627*0b57cec5SDimitry Andric def XSCVDPUXDSs : XX2Form<60, 328, 628*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 629*0b57cec5SDimitry Andric "xscvdpuxds $XT, $XB", IIC_VecFP, 630*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfctiduz f32:$XB))]>; 631*0b57cec5SDimitry Andric def XSCVDPUXWS : XX2Form<60, 72, 632*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 633*0b57cec5SDimitry Andric "xscvdpuxws $XT, $XB", IIC_VecFP, 634*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfctiwuz f64:$XB))]>; 635*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 636*0b57cec5SDimitry Andric def XSCVDPUXWSs : XX2Form<60, 72, 637*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 638*0b57cec5SDimitry Andric "xscvdpuxws $XT, $XB", IIC_VecFP, 639*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfctiwuz f32:$XB))]>; 640*0b57cec5SDimitry Andric def XSCVSPDP : XX2Form<60, 329, 641*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 642*0b57cec5SDimitry Andric "xscvspdp $XT, $XB", IIC_VecFP, []>; 643*0b57cec5SDimitry Andric def XSCVSXDDP : XX2Form<60, 376, 644*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 645*0b57cec5SDimitry Andric "xscvsxddp $XT, $XB", IIC_VecFP, 646*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfcfid f64:$XB))]>; 647*0b57cec5SDimitry Andric def XSCVUXDDP : XX2Form<60, 360, 648*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 649*0b57cec5SDimitry Andric "xscvuxddp $XT, $XB", IIC_VecFP, 650*0b57cec5SDimitry Andric [(set f64:$XT, (PPCfcfidu f64:$XB))]>; 651*0b57cec5SDimitry Andric 652*0b57cec5SDimitry Andric def XVCVDPSP : XX2Form<60, 393, 653*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 654*0b57cec5SDimitry Andric "xvcvdpsp $XT, $XB", IIC_VecFP, 655*0b57cec5SDimitry Andric [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>; 656*0b57cec5SDimitry Andric def XVCVDPSXDS : XX2Form<60, 472, 657*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 658*0b57cec5SDimitry Andric "xvcvdpsxds $XT, $XB", IIC_VecFP, 659*0b57cec5SDimitry Andric [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>; 660*0b57cec5SDimitry Andric def XVCVDPSXWS : XX2Form<60, 216, 661*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 662*0b57cec5SDimitry Andric "xvcvdpsxws $XT, $XB", IIC_VecFP, 663*0b57cec5SDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>; 664*0b57cec5SDimitry Andric def XVCVDPUXDS : XX2Form<60, 456, 665*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 666*0b57cec5SDimitry Andric "xvcvdpuxds $XT, $XB", IIC_VecFP, 667*0b57cec5SDimitry Andric [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>; 668*0b57cec5SDimitry Andric def XVCVDPUXWS : XX2Form<60, 200, 669*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 670*0b57cec5SDimitry Andric "xvcvdpuxws $XT, $XB", IIC_VecFP, 671*0b57cec5SDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>; 672*0b57cec5SDimitry Andric 673*0b57cec5SDimitry Andric def XVCVSPDP : XX2Form<60, 457, 674*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 675*0b57cec5SDimitry Andric "xvcvspdp $XT, $XB", IIC_VecFP, 676*0b57cec5SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>; 677*0b57cec5SDimitry Andric def XVCVSPSXDS : XX2Form<60, 408, 678*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 679*0b57cec5SDimitry Andric "xvcvspsxds $XT, $XB", IIC_VecFP, []>; 680*0b57cec5SDimitry Andric def XVCVSPSXWS : XX2Form<60, 152, 681*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 682*0b57cec5SDimitry Andric "xvcvspsxws $XT, $XB", IIC_VecFP, 683*0b57cec5SDimitry Andric [(set v4i32:$XT, (fp_to_sint v4f32:$XB))]>; 684*0b57cec5SDimitry Andric def XVCVSPUXDS : XX2Form<60, 392, 685*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 686*0b57cec5SDimitry Andric "xvcvspuxds $XT, $XB", IIC_VecFP, []>; 687*0b57cec5SDimitry Andric def XVCVSPUXWS : XX2Form<60, 136, 688*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 689*0b57cec5SDimitry Andric "xvcvspuxws $XT, $XB", IIC_VecFP, 690*0b57cec5SDimitry Andric [(set v4i32:$XT, (fp_to_uint v4f32:$XB))]>; 691*0b57cec5SDimitry Andric def XVCVSXDDP : XX2Form<60, 504, 692*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 693*0b57cec5SDimitry Andric "xvcvsxddp $XT, $XB", IIC_VecFP, 694*0b57cec5SDimitry Andric [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>; 695*0b57cec5SDimitry Andric def XVCVSXDSP : XX2Form<60, 440, 696*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 697*0b57cec5SDimitry Andric "xvcvsxdsp $XT, $XB", IIC_VecFP, 698*0b57cec5SDimitry Andric [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>; 699*0b57cec5SDimitry Andric def XVCVSXWDP : XX2Form<60, 248, 700*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 701*0b57cec5SDimitry Andric "xvcvsxwdp $XT, $XB", IIC_VecFP, 702*0b57cec5SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>; 703*0b57cec5SDimitry Andric def XVCVSXWSP : XX2Form<60, 184, 704*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 705*0b57cec5SDimitry Andric "xvcvsxwsp $XT, $XB", IIC_VecFP, 706*0b57cec5SDimitry Andric [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>; 707*0b57cec5SDimitry Andric def XVCVUXDDP : XX2Form<60, 488, 708*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 709*0b57cec5SDimitry Andric "xvcvuxddp $XT, $XB", IIC_VecFP, 710*0b57cec5SDimitry Andric [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>; 711*0b57cec5SDimitry Andric def XVCVUXDSP : XX2Form<60, 424, 712*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 713*0b57cec5SDimitry Andric "xvcvuxdsp $XT, $XB", IIC_VecFP, 714*0b57cec5SDimitry Andric [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>; 715*0b57cec5SDimitry Andric def XVCVUXWDP : XX2Form<60, 232, 716*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 717*0b57cec5SDimitry Andric "xvcvuxwdp $XT, $XB", IIC_VecFP, 718*0b57cec5SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>; 719*0b57cec5SDimitry Andric def XVCVUXWSP : XX2Form<60, 168, 720*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 721*0b57cec5SDimitry Andric "xvcvuxwsp $XT, $XB", IIC_VecFP, 722*0b57cec5SDimitry Andric [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>; 723*0b57cec5SDimitry Andric 724*0b57cec5SDimitry Andric // Rounding Instructions 725*0b57cec5SDimitry Andric def XSRDPI : XX2Form<60, 73, 726*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 727*0b57cec5SDimitry Andric "xsrdpi $XT, $XB", IIC_VecFP, 728*0b57cec5SDimitry Andric [(set f64:$XT, (fround f64:$XB))]>; 729*0b57cec5SDimitry Andric def XSRDPIC : XX2Form<60, 107, 730*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 731*0b57cec5SDimitry Andric "xsrdpic $XT, $XB", IIC_VecFP, 732*0b57cec5SDimitry Andric [(set f64:$XT, (fnearbyint f64:$XB))]>; 733*0b57cec5SDimitry Andric def XSRDPIM : XX2Form<60, 121, 734*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 735*0b57cec5SDimitry Andric "xsrdpim $XT, $XB", IIC_VecFP, 736*0b57cec5SDimitry Andric [(set f64:$XT, (ffloor f64:$XB))]>; 737*0b57cec5SDimitry Andric def XSRDPIP : XX2Form<60, 105, 738*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 739*0b57cec5SDimitry Andric "xsrdpip $XT, $XB", IIC_VecFP, 740*0b57cec5SDimitry Andric [(set f64:$XT, (fceil f64:$XB))]>; 741*0b57cec5SDimitry Andric def XSRDPIZ : XX2Form<60, 89, 742*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 743*0b57cec5SDimitry Andric "xsrdpiz $XT, $XB", IIC_VecFP, 744*0b57cec5SDimitry Andric [(set f64:$XT, (ftrunc f64:$XB))]>; 745*0b57cec5SDimitry Andric 746*0b57cec5SDimitry Andric def XVRDPI : XX2Form<60, 201, 747*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 748*0b57cec5SDimitry Andric "xvrdpi $XT, $XB", IIC_VecFP, 749*0b57cec5SDimitry Andric [(set v2f64:$XT, (fround v2f64:$XB))]>; 750*0b57cec5SDimitry Andric def XVRDPIC : XX2Form<60, 235, 751*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 752*0b57cec5SDimitry Andric "xvrdpic $XT, $XB", IIC_VecFP, 753*0b57cec5SDimitry Andric [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>; 754*0b57cec5SDimitry Andric def XVRDPIM : XX2Form<60, 249, 755*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 756*0b57cec5SDimitry Andric "xvrdpim $XT, $XB", IIC_VecFP, 757*0b57cec5SDimitry Andric [(set v2f64:$XT, (ffloor v2f64:$XB))]>; 758*0b57cec5SDimitry Andric def XVRDPIP : XX2Form<60, 233, 759*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 760*0b57cec5SDimitry Andric "xvrdpip $XT, $XB", IIC_VecFP, 761*0b57cec5SDimitry Andric [(set v2f64:$XT, (fceil v2f64:$XB))]>; 762*0b57cec5SDimitry Andric def XVRDPIZ : XX2Form<60, 217, 763*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 764*0b57cec5SDimitry Andric "xvrdpiz $XT, $XB", IIC_VecFP, 765*0b57cec5SDimitry Andric [(set v2f64:$XT, (ftrunc v2f64:$XB))]>; 766*0b57cec5SDimitry Andric 767*0b57cec5SDimitry Andric def XVRSPI : XX2Form<60, 137, 768*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 769*0b57cec5SDimitry Andric "xvrspi $XT, $XB", IIC_VecFP, 770*0b57cec5SDimitry Andric [(set v4f32:$XT, (fround v4f32:$XB))]>; 771*0b57cec5SDimitry Andric def XVRSPIC : XX2Form<60, 171, 772*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 773*0b57cec5SDimitry Andric "xvrspic $XT, $XB", IIC_VecFP, 774*0b57cec5SDimitry Andric [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>; 775*0b57cec5SDimitry Andric def XVRSPIM : XX2Form<60, 185, 776*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 777*0b57cec5SDimitry Andric "xvrspim $XT, $XB", IIC_VecFP, 778*0b57cec5SDimitry Andric [(set v4f32:$XT, (ffloor v4f32:$XB))]>; 779*0b57cec5SDimitry Andric def XVRSPIP : XX2Form<60, 169, 780*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 781*0b57cec5SDimitry Andric "xvrspip $XT, $XB", IIC_VecFP, 782*0b57cec5SDimitry Andric [(set v4f32:$XT, (fceil v4f32:$XB))]>; 783*0b57cec5SDimitry Andric def XVRSPIZ : XX2Form<60, 153, 784*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 785*0b57cec5SDimitry Andric "xvrspiz $XT, $XB", IIC_VecFP, 786*0b57cec5SDimitry Andric [(set v4f32:$XT, (ftrunc v4f32:$XB))]>; 787*0b57cec5SDimitry Andric 788*0b57cec5SDimitry Andric // Max/Min Instructions 789*0b57cec5SDimitry Andric let isCommutable = 1 in { 790*0b57cec5SDimitry Andric def XSMAXDP : XX3Form<60, 160, 791*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 792*0b57cec5SDimitry Andric "xsmaxdp $XT, $XA, $XB", IIC_VecFP, 793*0b57cec5SDimitry Andric [(set vsfrc:$XT, 794*0b57cec5SDimitry Andric (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>; 795*0b57cec5SDimitry Andric def XSMINDP : XX3Form<60, 168, 796*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 797*0b57cec5SDimitry Andric "xsmindp $XT, $XA, $XB", IIC_VecFP, 798*0b57cec5SDimitry Andric [(set vsfrc:$XT, 799*0b57cec5SDimitry Andric (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>; 800*0b57cec5SDimitry Andric 801*0b57cec5SDimitry Andric def XVMAXDP : XX3Form<60, 224, 802*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 803*0b57cec5SDimitry Andric "xvmaxdp $XT, $XA, $XB", IIC_VecFP, 804*0b57cec5SDimitry Andric [(set vsrc:$XT, 805*0b57cec5SDimitry Andric (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>; 806*0b57cec5SDimitry Andric def XVMINDP : XX3Form<60, 232, 807*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 808*0b57cec5SDimitry Andric "xvmindp $XT, $XA, $XB", IIC_VecFP, 809*0b57cec5SDimitry Andric [(set vsrc:$XT, 810*0b57cec5SDimitry Andric (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>; 811*0b57cec5SDimitry Andric 812*0b57cec5SDimitry Andric def XVMAXSP : XX3Form<60, 192, 813*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 814*0b57cec5SDimitry Andric "xvmaxsp $XT, $XA, $XB", IIC_VecFP, 815*0b57cec5SDimitry Andric [(set vsrc:$XT, 816*0b57cec5SDimitry Andric (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>; 817*0b57cec5SDimitry Andric def XVMINSP : XX3Form<60, 200, 818*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 819*0b57cec5SDimitry Andric "xvminsp $XT, $XA, $XB", IIC_VecFP, 820*0b57cec5SDimitry Andric [(set vsrc:$XT, 821*0b57cec5SDimitry Andric (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; 822*0b57cec5SDimitry Andric } // isCommutable 823*0b57cec5SDimitry Andric} // Uses = [RM] 824*0b57cec5SDimitry Andric 825*0b57cec5SDimitry Andric // Logical Instructions 826*0b57cec5SDimitry Andric let isCommutable = 1 in 827*0b57cec5SDimitry Andric def XXLAND : XX3Form<60, 130, 828*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 829*0b57cec5SDimitry Andric "xxland $XT, $XA, $XB", IIC_VecGeneral, 830*0b57cec5SDimitry Andric [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>; 831*0b57cec5SDimitry Andric def XXLANDC : XX3Form<60, 138, 832*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 833*0b57cec5SDimitry Andric "xxlandc $XT, $XA, $XB", IIC_VecGeneral, 834*0b57cec5SDimitry Andric [(set v4i32:$XT, (and v4i32:$XA, 835*0b57cec5SDimitry Andric (vnot_ppc v4i32:$XB)))]>; 836*0b57cec5SDimitry Andric let isCommutable = 1 in { 837*0b57cec5SDimitry Andric def XXLNOR : XX3Form<60, 162, 838*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 839*0b57cec5SDimitry Andric "xxlnor $XT, $XA, $XB", IIC_VecGeneral, 840*0b57cec5SDimitry Andric [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA, 841*0b57cec5SDimitry Andric v4i32:$XB)))]>; 842*0b57cec5SDimitry Andric def XXLOR : XX3Form<60, 146, 843*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 844*0b57cec5SDimitry Andric "xxlor $XT, $XA, $XB", IIC_VecGeneral, 845*0b57cec5SDimitry Andric [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>; 846*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 847*0b57cec5SDimitry Andric def XXLORf: XX3Form<60, 146, 848*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 849*0b57cec5SDimitry Andric "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>; 850*0b57cec5SDimitry Andric def XXLXOR : XX3Form<60, 154, 851*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 852*0b57cec5SDimitry Andric "xxlxor $XT, $XA, $XB", IIC_VecGeneral, 853*0b57cec5SDimitry Andric [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>; 854*0b57cec5SDimitry Andric } // isCommutable 855*0b57cec5SDimitry Andric 856*0b57cec5SDimitry Andric let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1, 857*0b57cec5SDimitry Andric isReMaterializable = 1 in { 858*0b57cec5SDimitry Andric def XXLXORz : XX3Form_Zero<60, 154, (outs vsrc:$XT), (ins), 859*0b57cec5SDimitry Andric "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 860*0b57cec5SDimitry Andric [(set v4i32:$XT, (v4i32 immAllZerosV))]>; 861*0b57cec5SDimitry Andric def XXLXORdpz : XX3Form_SetZero<60, 154, 862*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins), 863*0b57cec5SDimitry Andric "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 864*0b57cec5SDimitry Andric [(set f64:$XT, (fpimm0))]>; 865*0b57cec5SDimitry Andric def XXLXORspz : XX3Form_SetZero<60, 154, 866*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins), 867*0b57cec5SDimitry Andric "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 868*0b57cec5SDimitry Andric [(set f32:$XT, (fpimm0))]>; 869*0b57cec5SDimitry Andric } 870*0b57cec5SDimitry Andric 871*0b57cec5SDimitry Andric // Permutation Instructions 872*0b57cec5SDimitry Andric def XXMRGHW : XX3Form<60, 18, 873*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 874*0b57cec5SDimitry Andric "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>; 875*0b57cec5SDimitry Andric def XXMRGLW : XX3Form<60, 50, 876*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 877*0b57cec5SDimitry Andric "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>; 878*0b57cec5SDimitry Andric 879*0b57cec5SDimitry Andric def XXPERMDI : XX3Form_2<60, 10, 880*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM), 881*0b57cec5SDimitry Andric "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, 882*0b57cec5SDimitry Andric [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB, 883*0b57cec5SDimitry Andric imm32SExt16:$DM))]>; 884*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 885*0b57cec5SDimitry Andric def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM), 886*0b57cec5SDimitry Andric "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>; 887*0b57cec5SDimitry Andric def XXSEL : XX4Form<60, 3, 888*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC), 889*0b57cec5SDimitry Andric "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>; 890*0b57cec5SDimitry Andric 891*0b57cec5SDimitry Andric def XXSLDWI : XX3Form_2<60, 2, 892*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW), 893*0b57cec5SDimitry Andric "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm, 894*0b57cec5SDimitry Andric [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB, 895*0b57cec5SDimitry Andric imm32SExt16:$SHW))]>; 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 898*0b57cec5SDimitry Andric def XXSLDWIs : XX3Form_2s<60, 2, 899*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW), 900*0b57cec5SDimitry Andric "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>; 901*0b57cec5SDimitry Andric 902*0b57cec5SDimitry Andric def XXSPLTW : XX2Form_2<60, 164, 903*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM), 904*0b57cec5SDimitry Andric "xxspltw $XT, $XB, $UIM", IIC_VecPerm, 905*0b57cec5SDimitry Andric [(set v4i32:$XT, 906*0b57cec5SDimitry Andric (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>; 907*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 908*0b57cec5SDimitry Andric def XXSPLTWs : XX2Form_2<60, 164, 909*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM), 910*0b57cec5SDimitry Andric "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>; 911*0b57cec5SDimitry Andric 912*0b57cec5SDimitry Andric} // hasSideEffects 913*0b57cec5SDimitry Andric 914*0b57cec5SDimitry Andric// SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded after 915*0b57cec5SDimitry Andric// instruction selection into a branch sequence. 916*0b57cec5SDimitry Andriclet PPC970_Single = 1 in { 917*0b57cec5SDimitry Andric 918*0b57cec5SDimitry Andric def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst), 919*0b57cec5SDimitry Andric (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC), 920*0b57cec5SDimitry Andric "#SELECT_CC_VSRC", 921*0b57cec5SDimitry Andric []>; 922*0b57cec5SDimitry Andric def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst), 923*0b57cec5SDimitry Andric (ins crbitrc:$cond, vsrc:$T, vsrc:$F), 924*0b57cec5SDimitry Andric "#SELECT_VSRC", 925*0b57cec5SDimitry Andric [(set v2f64:$dst, 926*0b57cec5SDimitry Andric (select i1:$cond, v2f64:$T, v2f64:$F))]>; 927*0b57cec5SDimitry Andric def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst), 928*0b57cec5SDimitry Andric (ins crrc:$cond, f8rc:$T, f8rc:$F, 929*0b57cec5SDimitry Andric i32imm:$BROPC), "#SELECT_CC_VSFRC", 930*0b57cec5SDimitry Andric []>; 931*0b57cec5SDimitry Andric def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst), 932*0b57cec5SDimitry Andric (ins crbitrc:$cond, f8rc:$T, f8rc:$F), 933*0b57cec5SDimitry Andric "#SELECT_VSFRC", 934*0b57cec5SDimitry Andric [(set f64:$dst, 935*0b57cec5SDimitry Andric (select i1:$cond, f64:$T, f64:$F))]>; 936*0b57cec5SDimitry Andric def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst), 937*0b57cec5SDimitry Andric (ins crrc:$cond, f4rc:$T, f4rc:$F, 938*0b57cec5SDimitry Andric i32imm:$BROPC), "#SELECT_CC_VSSRC", 939*0b57cec5SDimitry Andric []>; 940*0b57cec5SDimitry Andric def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst), 941*0b57cec5SDimitry Andric (ins crbitrc:$cond, f4rc:$T, f4rc:$F), 942*0b57cec5SDimitry Andric "#SELECT_VSSRC", 943*0b57cec5SDimitry Andric [(set f32:$dst, 944*0b57cec5SDimitry Andric (select i1:$cond, f32:$T, f32:$F))]>; 945*0b57cec5SDimitry Andric} 946*0b57cec5SDimitry Andric} // AddedComplexity 947*0b57cec5SDimitry Andric 948*0b57cec5SDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB", 949*0b57cec5SDimitry Andric (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 950*0b57cec5SDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB", 951*0b57cec5SDimitry Andric (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 952*0b57cec5SDimitry Andric 953*0b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 0", 954*0b57cec5SDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>; 955*0b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 1", 956*0b57cec5SDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>; 957*0b57cec5SDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB", 958*0b57cec5SDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>; 959*0b57cec5SDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB", 960*0b57cec5SDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>; 961*0b57cec5SDimitry Andricdef : InstAlias<"xxswapd $XT, $XB", 962*0b57cec5SDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>; 963*0b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 0", 964*0b57cec5SDimitry Andric (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>; 965*0b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 1", 966*0b57cec5SDimitry Andric (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>; 967*0b57cec5SDimitry Andricdef : InstAlias<"xxswapd $XT, $XB", 968*0b57cec5SDimitry Andric (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>; 969*0b57cec5SDimitry Andric 970*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 971*0b57cec5SDimitry Andric 972*0b57cec5SDimitry Andricdef : Pat<(v4i32 (vnot_ppc v4i32:$A)), 973*0b57cec5SDimitry Andric (v4i32 (XXLNOR $A, $A))>; 974*0b57cec5SDimitry Andricdef : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A), 975*0b57cec5SDimitry Andric (and v4i32:$B, v4i32:$C))), 976*0b57cec5SDimitry Andric (v4i32 (XXSEL $A, $B, $C))>; 977*0b57cec5SDimitry Andric 978*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian] in { 979*0b57cec5SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)), 980*0b57cec5SDimitry Andric (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>; 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)), 983*0b57cec5SDimitry Andric (f64 (EXTRACT_SUBREG $S, sub_64))>; 984*0b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)), 985*0b57cec5SDimitry Andric (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 986*0b57cec5SDimitry Andric} 987*0b57cec5SDimitry Andric 988*0b57cec5SDimitry Andriclet Predicates = [IsLittleEndian] in { 989*0b57cec5SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)), 990*0b57cec5SDimitry Andric (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64), 991*0b57cec5SDimitry Andric (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>; 992*0b57cec5SDimitry Andric 993*0b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)), 994*0b57cec5SDimitry Andric (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 995*0b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)), 996*0b57cec5SDimitry Andric (f64 (EXTRACT_SUBREG $S, sub_64))>; 997*0b57cec5SDimitry Andric} 998*0b57cec5SDimitry Andric 999*0b57cec5SDimitry Andric// Additional fnmsub patterns: -a*c + b == -(a*c - b) 1000*0b57cec5SDimitry Andricdef : Pat<(fma (fneg f64:$A), f64:$C, f64:$B), 1001*0b57cec5SDimitry Andric (XSNMSUBADP $B, $C, $A)>; 1002*0b57cec5SDimitry Andricdef : Pat<(fma f64:$A, (fneg f64:$C), f64:$B), 1003*0b57cec5SDimitry Andric (XSNMSUBADP $B, $C, $A)>; 1004*0b57cec5SDimitry Andric 1005*0b57cec5SDimitry Andricdef : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B), 1006*0b57cec5SDimitry Andric (XVNMSUBADP $B, $C, $A)>; 1007*0b57cec5SDimitry Andricdef : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B), 1008*0b57cec5SDimitry Andric (XVNMSUBADP $B, $C, $A)>; 1009*0b57cec5SDimitry Andric 1010*0b57cec5SDimitry Andricdef : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B), 1011*0b57cec5SDimitry Andric (XVNMSUBASP $B, $C, $A)>; 1012*0b57cec5SDimitry Andricdef : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B), 1013*0b57cec5SDimitry Andric (XVNMSUBASP $B, $C, $A)>; 1014*0b57cec5SDimitry Andric 1015*0b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)), 1016*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1017*0b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)), 1018*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1019*0b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)), 1020*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1021*0b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)), 1022*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1023*0b57cec5SDimitry Andric 1024*0b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)), 1025*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1026*0b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)), 1027*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1028*0b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)), 1029*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1030*0b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)), 1031*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1032*0b57cec5SDimitry Andric 1033*0b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)), 1034*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1035*0b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)), 1036*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1037*0b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)), 1038*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1039*0b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)), 1040*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 1041*0b57cec5SDimitry Andric 1042*0b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)), 1043*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1044*0b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)), 1045*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1046*0b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)), 1047*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1048*0b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)), 1049*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1050*0b57cec5SDimitry Andric 1051*0b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)), 1052*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1053*0b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)), 1054*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1055*0b57cec5SDimitry Andric 1056*0b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)), 1057*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1058*0b57cec5SDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)), 1059*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1060*0b57cec5SDimitry Andric 1061*0b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)), 1062*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1063*0b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)), 1064*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1065*0b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)), 1066*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1067*0b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)), 1068*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 1069*0b57cec5SDimitry Andric 1070*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)), 1071*0b57cec5SDimitry Andric (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>; 1072*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)), 1073*0b57cec5SDimitry Andric (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>; 1074*0b57cec5SDimitry Andric 1075*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)), 1076*0b57cec5SDimitry Andric (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>; 1077*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)), 1078*0b57cec5SDimitry Andric (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>; 1079*0b57cec5SDimitry Andric 1080*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCfpextlh v4f32:$C)), (XVCVSPDP (XXMRGHW $C, $C))>; 1081*0b57cec5SDimitry Andric 1082*0b57cec5SDimitry Andric// Loads. 1083*0b57cec5SDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in { 1084*0b57cec5SDimitry Andric def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1085*0b57cec5SDimitry Andric 1086*0b57cec5SDimitry Andric // Stores. 1087*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst), 1088*0b57cec5SDimitry Andric (STXVD2X $rS, xoaddr:$dst)>; 1089*0b57cec5SDimitry Andric def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 1090*0b57cec5SDimitry Andric} 1091*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasVSX, HasOnlySwappingMemOps] in { 1092*0b57cec5SDimitry Andric def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1093*0b57cec5SDimitry Andric def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>; 1094*0b57cec5SDimitry Andric def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>; 1095*0b57cec5SDimitry Andric def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>; 1096*0b57cec5SDimitry Andric def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 1097*0b57cec5SDimitry Andric def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>; 1098*0b57cec5SDimitry Andric def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>; 1099*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst), 1100*0b57cec5SDimitry Andric (STXVW4X $rS, xoaddr:$dst)>; 1101*0b57cec5SDimitry Andric} 1102*0b57cec5SDimitry Andric 1103*0b57cec5SDimitry Andric// Permutes. 1104*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>; 1105*0b57cec5SDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>; 1106*0b57cec5SDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>; 1107*0b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>; 1108*0b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>; 1109*0b57cec5SDimitry Andric 1110*0b57cec5SDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and 1111*0b57cec5SDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable. 1112*0b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), (XXPERMDI $src, $src, 2)>; 1113*0b57cec5SDimitry Andric 1114*0b57cec5SDimitry Andric// Selects. 1115*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)), 1116*0b57cec5SDimitry Andric (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1117*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)), 1118*0b57cec5SDimitry Andric (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1119*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)), 1120*0b57cec5SDimitry Andric (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1121*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)), 1122*0b57cec5SDimitry Andric (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1123*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)), 1124*0b57cec5SDimitry Andric (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>; 1125*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)), 1126*0b57cec5SDimitry Andric (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1127*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)), 1128*0b57cec5SDimitry Andric (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1129*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)), 1130*0b57cec5SDimitry Andric (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1131*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)), 1132*0b57cec5SDimitry Andric (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1133*0b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)), 1134*0b57cec5SDimitry Andric (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 1135*0b57cec5SDimitry Andric 1136*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)), 1137*0b57cec5SDimitry Andric (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1138*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)), 1139*0b57cec5SDimitry Andric (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1140*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)), 1141*0b57cec5SDimitry Andric (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 1142*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)), 1143*0b57cec5SDimitry Andric (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 1144*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)), 1145*0b57cec5SDimitry Andric (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>; 1146*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)), 1147*0b57cec5SDimitry Andric (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 1148*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)), 1149*0b57cec5SDimitry Andric (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 1150*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)), 1151*0b57cec5SDimitry Andric (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1152*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)), 1153*0b57cec5SDimitry Andric (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1154*0b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)), 1155*0b57cec5SDimitry Andric (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>; 1156*0b57cec5SDimitry Andric 1157*0b57cec5SDimitry Andric// Divides. 1158*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B), 1159*0b57cec5SDimitry Andric (XVDIVSP $A, $B)>; 1160*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B), 1161*0b57cec5SDimitry Andric (XVDIVDP $A, $B)>; 1162*0b57cec5SDimitry Andric 1163*0b57cec5SDimitry Andric// Reciprocal estimate 1164*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A), 1165*0b57cec5SDimitry Andric (XVRESP $A)>; 1166*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A), 1167*0b57cec5SDimitry Andric (XVREDP $A)>; 1168*0b57cec5SDimitry Andric 1169*0b57cec5SDimitry Andric// Recip. square root estimate 1170*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A), 1171*0b57cec5SDimitry Andric (XVRSQRTESP $A)>; 1172*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A), 1173*0b57cec5SDimitry Andric (XVRSQRTEDP $A)>; 1174*0b57cec5SDimitry Andric 1175*0b57cec5SDimitry Andric// Vector selection 1176*0b57cec5SDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)), 1177*0b57cec5SDimitry Andric (COPY_TO_REGCLASS 1178*0b57cec5SDimitry Andric (XXSEL (COPY_TO_REGCLASS $vC, VSRC), 1179*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $vB, VSRC), 1180*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 1181*0b57cec5SDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)), 1182*0b57cec5SDimitry Andric (COPY_TO_REGCLASS 1183*0b57cec5SDimitry Andric (XXSEL (COPY_TO_REGCLASS $vC, VSRC), 1184*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $vB, VSRC), 1185*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 1186*0b57cec5SDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC), 1187*0b57cec5SDimitry Andric (XXSEL $vC, $vB, $vA)>; 1188*0b57cec5SDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC), 1189*0b57cec5SDimitry Andric (XXSEL $vC, $vB, $vA)>; 1190*0b57cec5SDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC), 1191*0b57cec5SDimitry Andric (XXSEL $vC, $vB, $vA)>; 1192*0b57cec5SDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC), 1193*0b57cec5SDimitry Andric (XXSEL $vC, $vB, $vA)>; 1194*0b57cec5SDimitry Andric 1195*0b57cec5SDimitry Andricdef : Pat<(v4f32 (fmaxnum v4f32:$src1, v4f32:$src2)), 1196*0b57cec5SDimitry Andric (v4f32 (XVMAXSP $src1, $src2))>; 1197*0b57cec5SDimitry Andricdef : Pat<(v4f32 (fminnum v4f32:$src1, v4f32:$src2)), 1198*0b57cec5SDimitry Andric (v4f32 (XVMINSP $src1, $src2))>; 1199*0b57cec5SDimitry Andricdef : Pat<(v2f64 (fmaxnum v2f64:$src1, v2f64:$src2)), 1200*0b57cec5SDimitry Andric (v2f64 (XVMAXDP $src1, $src2))>; 1201*0b57cec5SDimitry Andricdef : Pat<(v2f64 (fminnum v2f64:$src1, v2f64:$src2)), 1202*0b57cec5SDimitry Andric (v2f64 (XVMINDP $src1, $src2))>; 1203*0b57cec5SDimitry Andric 1204*0b57cec5SDimitry Andriclet Predicates = [IsLittleEndian] in { 1205*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1206*0b57cec5SDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1207*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1208*0b57cec5SDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 1209*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1210*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1211*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1212*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 1213*0b57cec5SDimitry Andric} // IsLittleEndian 1214*0b57cec5SDimitry Andric 1215*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian] in { 1216*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1217*0b57cec5SDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>; 1218*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1219*0b57cec5SDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1220*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 1221*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>; 1222*0b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 1223*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 1224*0b57cec5SDimitry Andric} // IsBigEndian 1225*0b57cec5SDimitry Andric 1226*0b57cec5SDimitry Andric} // AddedComplexity 1227*0b57cec5SDimitry Andric} // HasVSX 1228*0b57cec5SDimitry Andric 1229*0b57cec5SDimitry Andricdef ScalarLoads { 1230*0b57cec5SDimitry Andric dag Li8 = (i32 (extloadi8 xoaddr:$src)); 1231*0b57cec5SDimitry Andric dag ZELi8 = (i32 (zextloadi8 xoaddr:$src)); 1232*0b57cec5SDimitry Andric dag ZELi8i64 = (i64 (zextloadi8 xoaddr:$src)); 1233*0b57cec5SDimitry Andric dag SELi8 = (i32 (sext_inreg (extloadi8 xoaddr:$src), i8)); 1234*0b57cec5SDimitry Andric dag SELi8i64 = (i64 (sext_inreg (extloadi8 xoaddr:$src), i8)); 1235*0b57cec5SDimitry Andric 1236*0b57cec5SDimitry Andric dag Li16 = (i32 (extloadi16 xoaddr:$src)); 1237*0b57cec5SDimitry Andric dag ZELi16 = (i32 (zextloadi16 xoaddr:$src)); 1238*0b57cec5SDimitry Andric dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src)); 1239*0b57cec5SDimitry Andric dag SELi16 = (i32 (sextloadi16 xoaddr:$src)); 1240*0b57cec5SDimitry Andric dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src)); 1241*0b57cec5SDimitry Andric 1242*0b57cec5SDimitry Andric dag Li32 = (i32 (load xoaddr:$src)); 1243*0b57cec5SDimitry Andric} 1244*0b57cec5SDimitry Andric 1245*0b57cec5SDimitry Andricdef DWToSPExtractConv { 1246*0b57cec5SDimitry Andric dag El0US1 = (f32 (PPCfcfidus 1247*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0)))))); 1248*0b57cec5SDimitry Andric dag El1US1 = (f32 (PPCfcfidus 1249*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1)))))); 1250*0b57cec5SDimitry Andric dag El0US2 = (f32 (PPCfcfidus 1251*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0)))))); 1252*0b57cec5SDimitry Andric dag El1US2 = (f32 (PPCfcfidus 1253*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1)))))); 1254*0b57cec5SDimitry Andric dag El0SS1 = (f32 (PPCfcfids 1255*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0)))))); 1256*0b57cec5SDimitry Andric dag El1SS1 = (f32 (PPCfcfids 1257*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1)))))); 1258*0b57cec5SDimitry Andric dag El0SS2 = (f32 (PPCfcfids 1259*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0)))))); 1260*0b57cec5SDimitry Andric dag El1SS2 = (f32 (PPCfcfids 1261*0b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1)))))); 1262*0b57cec5SDimitry Andric dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2)); 1263*0b57cec5SDimitry Andric dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2)); 1264*0b57cec5SDimitry Andric} 1265*0b57cec5SDimitry Andric 1266*0b57cec5SDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07 1267*0b57cec5SDimitry Andric/* FIXME: if the operands are v2i64, these patterns will not match. 1268*0b57cec5SDimitry Andric we should define new patterns or otherwise match the same patterns 1269*0b57cec5SDimitry Andric when the elements are larger than i32. 1270*0b57cec5SDimitry Andric*/ 1271*0b57cec5SDimitry Andricdef HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">; 1272*0b57cec5SDimitry Andricdef HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">; 1273*0b57cec5SDimitry Andricdef NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">; 1274*0b57cec5SDimitry Andriclet Predicates = [HasP8Vector] in { 1275*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns. 1276*0b57cec5SDimitry Andric let isCommutable = 1 in { 1277*0b57cec5SDimitry Andric def XXLEQV : XX3Form<60, 186, 1278*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1279*0b57cec5SDimitry Andric "xxleqv $XT, $XA, $XB", IIC_VecGeneral, 1280*0b57cec5SDimitry Andric [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>; 1281*0b57cec5SDimitry Andric def XXLNAND : XX3Form<60, 178, 1282*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1283*0b57cec5SDimitry Andric "xxlnand $XT, $XA, $XB", IIC_VecGeneral, 1284*0b57cec5SDimitry Andric [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA, 1285*0b57cec5SDimitry Andric v4i32:$XB)))]>; 1286*0b57cec5SDimitry Andric } // isCommutable 1287*0b57cec5SDimitry Andric 1288*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B), 1289*0b57cec5SDimitry Andric (XXLEQV $A, $B)>; 1290*0b57cec5SDimitry Andric 1291*0b57cec5SDimitry Andric def XXLORC : XX3Form<60, 170, 1292*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1293*0b57cec5SDimitry Andric "xxlorc $XT, $XA, $XB", IIC_VecGeneral, 1294*0b57cec5SDimitry Andric [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>; 1295*0b57cec5SDimitry Andric 1296*0b57cec5SDimitry Andric // VSX scalar loads introduced in ISA 2.07 1297*0b57cec5SDimitry Andric let mayLoad = 1, mayStore = 0 in { 1298*0b57cec5SDimitry Andric let CodeSize = 3 in 1299*0b57cec5SDimitry Andric def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src), 1300*0b57cec5SDimitry Andric "lxsspx $XT, $src", IIC_LdStLFD, []>; 1301*0b57cec5SDimitry Andric def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src), 1302*0b57cec5SDimitry Andric "lxsiwax $XT, $src", IIC_LdStLFD, []>; 1303*0b57cec5SDimitry Andric def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src), 1304*0b57cec5SDimitry Andric "lxsiwzx $XT, $src", IIC_LdStLFD, []>; 1305*0b57cec5SDimitry Andric 1306*0b57cec5SDimitry Andric // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later 1307*0b57cec5SDimitry Andric let CodeSize = 3 in 1308*0b57cec5SDimitry Andric def XFLOADf32 : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src), 1309*0b57cec5SDimitry Andric "#XFLOADf32", 1310*0b57cec5SDimitry Andric [(set f32:$XT, (load xoaddr:$src))]>; 1311*0b57cec5SDimitry Andric // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later 1312*0b57cec5SDimitry Andric def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), 1313*0b57cec5SDimitry Andric "#LIWAX", 1314*0b57cec5SDimitry Andric [(set f64:$XT, (PPClfiwax xoaddr:$src))]>; 1315*0b57cec5SDimitry Andric // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later 1316*0b57cec5SDimitry Andric def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), 1317*0b57cec5SDimitry Andric "#LIWZX", 1318*0b57cec5SDimitry Andric [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>; 1319*0b57cec5SDimitry Andric } // mayLoad 1320*0b57cec5SDimitry Andric 1321*0b57cec5SDimitry Andric // VSX scalar stores introduced in ISA 2.07 1322*0b57cec5SDimitry Andric let mayStore = 1, mayLoad = 0 in { 1323*0b57cec5SDimitry Andric let CodeSize = 3 in 1324*0b57cec5SDimitry Andric def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst), 1325*0b57cec5SDimitry Andric "stxsspx $XT, $dst", IIC_LdStSTFD, []>; 1326*0b57cec5SDimitry Andric def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst), 1327*0b57cec5SDimitry Andric "stxsiwx $XT, $dst", IIC_LdStSTFD, []>; 1328*0b57cec5SDimitry Andric 1329*0b57cec5SDimitry Andric // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later 1330*0b57cec5SDimitry Andric let CodeSize = 3 in 1331*0b57cec5SDimitry Andric def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst), 1332*0b57cec5SDimitry Andric "#XFSTOREf32", 1333*0b57cec5SDimitry Andric [(store f32:$XT, xoaddr:$dst)]>; 1334*0b57cec5SDimitry Andric // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later 1335*0b57cec5SDimitry Andric def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst), 1336*0b57cec5SDimitry Andric "#STIWX", 1337*0b57cec5SDimitry Andric [(PPCstfiwx f64:$XT, xoaddr:$dst)]>; 1338*0b57cec5SDimitry Andric } // mayStore 1339*0b57cec5SDimitry Andric 1340*0b57cec5SDimitry Andric def : Pat<(f64 (extloadf32 xoaddr:$src)), 1341*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>; 1342*0b57cec5SDimitry Andric def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))), 1343*0b57cec5SDimitry Andric (f32 (XFLOADf32 xoaddr:$src))>; 1344*0b57cec5SDimitry Andric def : Pat<(f64 (fpextend f32:$src)), 1345*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $src, VSFRC)>; 1346*0b57cec5SDimitry Andric 1347*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)), 1348*0b57cec5SDimitry Andric (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1349*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)), 1350*0b57cec5SDimitry Andric (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1351*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)), 1352*0b57cec5SDimitry Andric (SELECT_VSSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1353*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)), 1354*0b57cec5SDimitry Andric (SELECT_VSSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1355*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)), 1356*0b57cec5SDimitry Andric (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>; 1357*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)), 1358*0b57cec5SDimitry Andric (SELECT_VSSRC (CRORC $rhs, $lhs), $tval, $fval)>; 1359*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)), 1360*0b57cec5SDimitry Andric (SELECT_VSSRC (CRORC $lhs, $rhs), $tval, $fval)>; 1361*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)), 1362*0b57cec5SDimitry Andric (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 1363*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)), 1364*0b57cec5SDimitry Andric (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 1365*0b57cec5SDimitry Andric def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)), 1366*0b57cec5SDimitry Andric (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 1367*0b57cec5SDimitry Andric 1368*0b57cec5SDimitry Andric // VSX Elementary Scalar FP arithmetic (SP) 1369*0b57cec5SDimitry Andric let isCommutable = 1 in { 1370*0b57cec5SDimitry Andric def XSADDSP : XX3Form<60, 0, 1371*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1372*0b57cec5SDimitry Andric "xsaddsp $XT, $XA, $XB", IIC_VecFP, 1373*0b57cec5SDimitry Andric [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>; 1374*0b57cec5SDimitry Andric def XSMULSP : XX3Form<60, 16, 1375*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1376*0b57cec5SDimitry Andric "xsmulsp $XT, $XA, $XB", IIC_VecFP, 1377*0b57cec5SDimitry Andric [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>; 1378*0b57cec5SDimitry Andric } // isCommutable 1379*0b57cec5SDimitry Andric def XSSUBSP : XX3Form<60, 8, 1380*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1381*0b57cec5SDimitry Andric "xssubsp $XT, $XA, $XB", IIC_VecFP, 1382*0b57cec5SDimitry Andric [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>; 1383*0b57cec5SDimitry Andric def XSDIVSP : XX3Form<60, 24, 1384*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 1385*0b57cec5SDimitry Andric "xsdivsp $XT, $XA, $XB", IIC_FPDivS, 1386*0b57cec5SDimitry Andric [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>; 1387*0b57cec5SDimitry Andric def XSRESP : XX2Form<60, 26, 1388*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 1389*0b57cec5SDimitry Andric "xsresp $XT, $XB", IIC_VecFP, 1390*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfre f32:$XB))]>; 1391*0b57cec5SDimitry Andric def XSRSP : XX2Form<60, 281, 1392*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vsfrc:$XB), 1393*0b57cec5SDimitry Andric "xsrsp $XT, $XB", IIC_VecFP, []>; 1394*0b57cec5SDimitry Andric def XSSQRTSP : XX2Form<60, 11, 1395*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 1396*0b57cec5SDimitry Andric "xssqrtsp $XT, $XB", IIC_FPSqrtS, 1397*0b57cec5SDimitry Andric [(set f32:$XT, (fsqrt f32:$XB))]>; 1398*0b57cec5SDimitry Andric def XSRSQRTESP : XX2Form<60, 10, 1399*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 1400*0b57cec5SDimitry Andric "xsrsqrtesp $XT, $XB", IIC_VecFP, 1401*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfrsqrte f32:$XB))]>; 1402*0b57cec5SDimitry Andric 1403*0b57cec5SDimitry Andric // FMA Instructions 1404*0b57cec5SDimitry Andric let BaseName = "XSMADDASP" in { 1405*0b57cec5SDimitry Andric let isCommutable = 1 in 1406*0b57cec5SDimitry Andric def XSMADDASP : XX3Form<60, 1, 1407*0b57cec5SDimitry Andric (outs vssrc:$XT), 1408*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1409*0b57cec5SDimitry Andric "xsmaddasp $XT, $XA, $XB", IIC_VecFP, 1410*0b57cec5SDimitry Andric [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>, 1411*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1412*0b57cec5SDimitry Andric AltVSXFMARel; 1413*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 1414*0b57cec5SDimitry Andric def XSMADDMSP : XX3Form<60, 9, 1415*0b57cec5SDimitry Andric (outs vssrc:$XT), 1416*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1417*0b57cec5SDimitry Andric "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 1418*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1419*0b57cec5SDimitry Andric AltVSXFMARel; 1420*0b57cec5SDimitry Andric } 1421*0b57cec5SDimitry Andric 1422*0b57cec5SDimitry Andric let BaseName = "XSMSUBASP" in { 1423*0b57cec5SDimitry Andric let isCommutable = 1 in 1424*0b57cec5SDimitry Andric def XSMSUBASP : XX3Form<60, 17, 1425*0b57cec5SDimitry Andric (outs vssrc:$XT), 1426*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1427*0b57cec5SDimitry Andric "xsmsubasp $XT, $XA, $XB", IIC_VecFP, 1428*0b57cec5SDimitry Andric [(set f32:$XT, (fma f32:$XA, f32:$XB, 1429*0b57cec5SDimitry Andric (fneg f32:$XTi)))]>, 1430*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1431*0b57cec5SDimitry Andric AltVSXFMARel; 1432*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 1433*0b57cec5SDimitry Andric def XSMSUBMSP : XX3Form<60, 25, 1434*0b57cec5SDimitry Andric (outs vssrc:$XT), 1435*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1436*0b57cec5SDimitry Andric "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 1437*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1438*0b57cec5SDimitry Andric AltVSXFMARel; 1439*0b57cec5SDimitry Andric } 1440*0b57cec5SDimitry Andric 1441*0b57cec5SDimitry Andric let BaseName = "XSNMADDASP" in { 1442*0b57cec5SDimitry Andric let isCommutable = 1 in 1443*0b57cec5SDimitry Andric def XSNMADDASP : XX3Form<60, 129, 1444*0b57cec5SDimitry Andric (outs vssrc:$XT), 1445*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1446*0b57cec5SDimitry Andric "xsnmaddasp $XT, $XA, $XB", IIC_VecFP, 1447*0b57cec5SDimitry Andric [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB, 1448*0b57cec5SDimitry Andric f32:$XTi)))]>, 1449*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1450*0b57cec5SDimitry Andric AltVSXFMARel; 1451*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 1452*0b57cec5SDimitry Andric def XSNMADDMSP : XX3Form<60, 137, 1453*0b57cec5SDimitry Andric (outs vssrc:$XT), 1454*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1455*0b57cec5SDimitry Andric "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 1456*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1457*0b57cec5SDimitry Andric AltVSXFMARel; 1458*0b57cec5SDimitry Andric } 1459*0b57cec5SDimitry Andric 1460*0b57cec5SDimitry Andric let BaseName = "XSNMSUBASP" in { 1461*0b57cec5SDimitry Andric let isCommutable = 1 in 1462*0b57cec5SDimitry Andric def XSNMSUBASP : XX3Form<60, 145, 1463*0b57cec5SDimitry Andric (outs vssrc:$XT), 1464*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1465*0b57cec5SDimitry Andric "xsnmsubasp $XT, $XA, $XB", IIC_VecFP, 1466*0b57cec5SDimitry Andric [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB, 1467*0b57cec5SDimitry Andric (fneg f32:$XTi))))]>, 1468*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1469*0b57cec5SDimitry Andric AltVSXFMARel; 1470*0b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 1471*0b57cec5SDimitry Andric def XSNMSUBMSP : XX3Form<60, 153, 1472*0b57cec5SDimitry Andric (outs vssrc:$XT), 1473*0b57cec5SDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 1474*0b57cec5SDimitry Andric "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 1475*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 1476*0b57cec5SDimitry Andric AltVSXFMARel; 1477*0b57cec5SDimitry Andric } 1478*0b57cec5SDimitry Andric 1479*0b57cec5SDimitry Andric // Single Precision Conversions (FP <-> INT) 1480*0b57cec5SDimitry Andric def XSCVSXDSP : XX2Form<60, 312, 1481*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vsfrc:$XB), 1482*0b57cec5SDimitry Andric "xscvsxdsp $XT, $XB", IIC_VecFP, 1483*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfcfids f64:$XB))]>; 1484*0b57cec5SDimitry Andric def XSCVUXDSP : XX2Form<60, 296, 1485*0b57cec5SDimitry Andric (outs vssrc:$XT), (ins vsfrc:$XB), 1486*0b57cec5SDimitry Andric "xscvuxdsp $XT, $XB", IIC_VecFP, 1487*0b57cec5SDimitry Andric [(set f32:$XT, (PPCfcfidus f64:$XB))]>; 1488*0b57cec5SDimitry Andric 1489*0b57cec5SDimitry Andric // Conversions between vector and scalar single precision 1490*0b57cec5SDimitry Andric def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB), 1491*0b57cec5SDimitry Andric "xscvdpspn $XT, $XB", IIC_VecFP, []>; 1492*0b57cec5SDimitry Andric def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB), 1493*0b57cec5SDimitry Andric "xscvspdpn $XT, $XB", IIC_VecFP, []>; 1494*0b57cec5SDimitry Andric 1495*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian] in { 1496*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El0SS1, 1497*0b57cec5SDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 1498*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El1SS1, 1499*0b57cec5SDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS 1500*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>; 1501*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El0US1, 1502*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 1503*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El1US1, 1504*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS 1505*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>; 1506*0b57cec5SDimitry Andric } 1507*0b57cec5SDimitry Andric 1508*0b57cec5SDimitry Andric let Predicates = [IsBigEndian] in { 1509*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El0SS1, 1510*0b57cec5SDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>; 1511*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El1SS1, 1512*0b57cec5SDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 1513*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El0US1, 1514*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>; 1515*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.El1US1, 1516*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 1517*0b57cec5SDimitry Andric } 1518*0b57cec5SDimitry Andric 1519*0b57cec5SDimitry Andric // Instructions for converting float to i64 feeding a store. 1520*0b57cec5SDimitry Andric let Predicates = [NoP9Vector] in { 1521*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 1522*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8), 1523*0b57cec5SDimitry Andric (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>; 1524*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 1525*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8), 1526*0b57cec5SDimitry Andric (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>; 1527*0b57cec5SDimitry Andric } 1528*0b57cec5SDimitry Andric 1529*0b57cec5SDimitry Andric // Instructions for converting float to i32 feeding a store. 1530*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 1531*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4), 1532*0b57cec5SDimitry Andric (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>; 1533*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 1534*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4), 1535*0b57cec5SDimitry Andric (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>; 1536*0b57cec5SDimitry Andric 1537*0b57cec5SDimitry Andric def : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)), 1538*0b57cec5SDimitry Andric (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC), 1539*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 1540*0b57cec5SDimitry Andric def : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)), 1541*0b57cec5SDimitry Andric (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC), 1542*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 1543*0b57cec5SDimitry Andric def : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)), 1544*0b57cec5SDimitry Andric (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC), 1545*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 1546*0b57cec5SDimitry Andric def : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)), 1547*0b57cec5SDimitry Andric (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC), 1548*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 1549*0b57cec5SDimitry Andric} // AddedComplexity = 400 1550*0b57cec5SDimitry Andric} // HasP8Vector 1551*0b57cec5SDimitry Andric 1552*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { 1553*0b57cec5SDimitry Andriclet Predicates = [HasDirectMove] in { 1554*0b57cec5SDimitry Andric // VSX direct move instructions 1555*0b57cec5SDimitry Andric def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT), 1556*0b57cec5SDimitry Andric "mfvsrd $rA, $XT", IIC_VecGeneral, 1557*0b57cec5SDimitry Andric [(set i64:$rA, (PPCmfvsr f64:$XT))]>, 1558*0b57cec5SDimitry Andric Requires<[In64BitMode]>; 1559*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in 1560*0b57cec5SDimitry Andric def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT), 1561*0b57cec5SDimitry Andric "mfvsrd $rA, $XT", IIC_VecGeneral, 1562*0b57cec5SDimitry Andric []>, 1563*0b57cec5SDimitry Andric Requires<[In64BitMode]>; 1564*0b57cec5SDimitry Andric def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT), 1565*0b57cec5SDimitry Andric "mfvsrwz $rA, $XT", IIC_VecGeneral, 1566*0b57cec5SDimitry Andric [(set i32:$rA, (PPCmfvsr f64:$XT))]>; 1567*0b57cec5SDimitry Andric def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA), 1568*0b57cec5SDimitry Andric "mtvsrd $XT, $rA", IIC_VecGeneral, 1569*0b57cec5SDimitry Andric [(set f64:$XT, (PPCmtvsra i64:$rA))]>, 1570*0b57cec5SDimitry Andric Requires<[In64BitMode]>; 1571*0b57cec5SDimitry Andric def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA), 1572*0b57cec5SDimitry Andric "mtvsrwa $XT, $rA", IIC_VecGeneral, 1573*0b57cec5SDimitry Andric [(set f64:$XT, (PPCmtvsra i32:$rA))]>; 1574*0b57cec5SDimitry Andric def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA), 1575*0b57cec5SDimitry Andric "mtvsrwz $XT, $rA", IIC_VecGeneral, 1576*0b57cec5SDimitry Andric [(set f64:$XT, (PPCmtvsrz i32:$rA))]>; 1577*0b57cec5SDimitry Andric} // HasDirectMove 1578*0b57cec5SDimitry Andric 1579*0b57cec5SDimitry Andriclet Predicates = [IsISA3_0, HasDirectMove] in { 1580*0b57cec5SDimitry Andric def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA), 1581*0b57cec5SDimitry Andric "mtvsrws $XT, $rA", IIC_VecGeneral, []>; 1582*0b57cec5SDimitry Andric 1583*0b57cec5SDimitry Andric def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB), 1584*0b57cec5SDimitry Andric "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral, 1585*0b57cec5SDimitry Andric []>, Requires<[In64BitMode]>; 1586*0b57cec5SDimitry Andric 1587*0b57cec5SDimitry Andric def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT), 1588*0b57cec5SDimitry Andric "mfvsrld $rA, $XT", IIC_VecGeneral, 1589*0b57cec5SDimitry Andric []>, Requires<[In64BitMode]>; 1590*0b57cec5SDimitry Andric 1591*0b57cec5SDimitry Andric} // IsISA3_0, HasDirectMove 1592*0b57cec5SDimitry Andric} // AddedComplexity = 400 1593*0b57cec5SDimitry Andric 1594*0b57cec5SDimitry Andric// We want to parse this from asm, but we don't want to emit this as it would 1595*0b57cec5SDimitry Andric// be emitted with a VSX reg. So leave Emit = 0 here. 1596*0b57cec5SDimitry Andricdef : InstAlias<"mfvrd $rA, $XT", 1597*0b57cec5SDimitry Andric (MFVRD g8rc:$rA, vrrc:$XT), 0>; 1598*0b57cec5SDimitry Andricdef : InstAlias<"mffprd $rA, $src", 1599*0b57cec5SDimitry Andric (MFVSRD g8rc:$rA, f8rc:$src)>; 1600*0b57cec5SDimitry Andric 1601*0b57cec5SDimitry Andric/* Direct moves of various widths from GPR's into VSR's. Each move lines 1602*0b57cec5SDimitry Andric the value up into element 0 (both BE and LE). Namely, entities smaller than 1603*0b57cec5SDimitry Andric a doubleword are shifted left and moved for BE. For LE, they're moved, then 1604*0b57cec5SDimitry Andric swapped to go into the least significant element of the VSR. 1605*0b57cec5SDimitry Andric*/ 1606*0b57cec5SDimitry Andricdef MovesToVSR { 1607*0b57cec5SDimitry Andric dag BE_BYTE_0 = 1608*0b57cec5SDimitry Andric (MTVSRD 1609*0b57cec5SDimitry Andric (RLDICR 1610*0b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7)); 1611*0b57cec5SDimitry Andric dag BE_HALF_0 = 1612*0b57cec5SDimitry Andric (MTVSRD 1613*0b57cec5SDimitry Andric (RLDICR 1614*0b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15)); 1615*0b57cec5SDimitry Andric dag BE_WORD_0 = 1616*0b57cec5SDimitry Andric (MTVSRD 1617*0b57cec5SDimitry Andric (RLDICR 1618*0b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31)); 1619*0b57cec5SDimitry Andric dag BE_DWORD_0 = (MTVSRD $A); 1620*0b57cec5SDimitry Andric 1621*0b57cec5SDimitry Andric dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32)); 1622*0b57cec5SDimitry Andric dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), 1623*0b57cec5SDimitry Andric LE_MTVSRW, sub_64)); 1624*0b57cec5SDimitry Andric dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2); 1625*0b57cec5SDimitry Andric dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), 1626*0b57cec5SDimitry Andric BE_DWORD_0, sub_64)); 1627*0b57cec5SDimitry Andric dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2); 1628*0b57cec5SDimitry Andric} 1629*0b57cec5SDimitry Andric 1630*0b57cec5SDimitry Andric/* Patterns for extracting elements out of vectors. Integer elements are 1631*0b57cec5SDimitry Andric extracted using direct move operations. Patterns for extracting elements 1632*0b57cec5SDimitry Andric whose indices are not available at compile time are also provided with 1633*0b57cec5SDimitry Andric various _VARIABLE_ patterns. 1634*0b57cec5SDimitry Andric The numbering for the DAG's is for LE, but when used on BE, the correct 1635*0b57cec5SDimitry Andric LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13). 1636*0b57cec5SDimitry Andric*/ 1637*0b57cec5SDimitry Andricdef VectorExtractions { 1638*0b57cec5SDimitry Andric // Doubleword extraction 1639*0b57cec5SDimitry Andric dag LE_DWORD_0 = 1640*0b57cec5SDimitry Andric (MFVSRD 1641*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1642*0b57cec5SDimitry Andric (XXPERMDI (COPY_TO_REGCLASS $S, VSRC), 1643*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $S, VSRC), 2), sub_64)); 1644*0b57cec5SDimitry Andric dag LE_DWORD_1 = (MFVSRD 1645*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1646*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64)); 1647*0b57cec5SDimitry Andric 1648*0b57cec5SDimitry Andric // Word extraction 1649*0b57cec5SDimitry Andric dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64)); 1650*0b57cec5SDimitry Andric dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64)); 1651*0b57cec5SDimitry Andric dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG 1652*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64)); 1653*0b57cec5SDimitry Andric dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64)); 1654*0b57cec5SDimitry Andric 1655*0b57cec5SDimitry Andric // Halfword extraction 1656*0b57cec5SDimitry Andric dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32)); 1657*0b57cec5SDimitry Andric dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32)); 1658*0b57cec5SDimitry Andric dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32)); 1659*0b57cec5SDimitry Andric dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32)); 1660*0b57cec5SDimitry Andric dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32)); 1661*0b57cec5SDimitry Andric dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32)); 1662*0b57cec5SDimitry Andric dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32)); 1663*0b57cec5SDimitry Andric dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32)); 1664*0b57cec5SDimitry Andric 1665*0b57cec5SDimitry Andric // Byte extraction 1666*0b57cec5SDimitry Andric dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32)); 1667*0b57cec5SDimitry Andric dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32)); 1668*0b57cec5SDimitry Andric dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32)); 1669*0b57cec5SDimitry Andric dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32)); 1670*0b57cec5SDimitry Andric dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32)); 1671*0b57cec5SDimitry Andric dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32)); 1672*0b57cec5SDimitry Andric dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32)); 1673*0b57cec5SDimitry Andric dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32)); 1674*0b57cec5SDimitry Andric dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32)); 1675*0b57cec5SDimitry Andric dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32)); 1676*0b57cec5SDimitry Andric dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32)); 1677*0b57cec5SDimitry Andric dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32)); 1678*0b57cec5SDimitry Andric dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32)); 1679*0b57cec5SDimitry Andric dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32)); 1680*0b57cec5SDimitry Andric dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32)); 1681*0b57cec5SDimitry Andric dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32)); 1682*0b57cec5SDimitry Andric 1683*0b57cec5SDimitry Andric /* Variable element number (BE and LE patterns must be specified separately) 1684*0b57cec5SDimitry Andric This is a rather involved process. 1685*0b57cec5SDimitry Andric 1686*0b57cec5SDimitry Andric Conceptually, this is how the move is accomplished: 1687*0b57cec5SDimitry Andric 1. Identify which doubleword contains the element 1688*0b57cec5SDimitry Andric 2. Shift in the VMX register so that the correct doubleword is correctly 1689*0b57cec5SDimitry Andric lined up for the MFVSRD 1690*0b57cec5SDimitry Andric 3. Perform the move so that the element (along with some extra stuff) 1691*0b57cec5SDimitry Andric is in the GPR 1692*0b57cec5SDimitry Andric 4. Right shift within the GPR so that the element is right-justified 1693*0b57cec5SDimitry Andric 1694*0b57cec5SDimitry Andric Of course, the index is an element number which has a different meaning 1695*0b57cec5SDimitry Andric on LE/BE so the patterns have to be specified separately. 1696*0b57cec5SDimitry Andric 1697*0b57cec5SDimitry Andric Note: The final result will be the element right-justified with high 1698*0b57cec5SDimitry Andric order bits being arbitrarily defined (namely, whatever was in the 1699*0b57cec5SDimitry Andric vector register to the left of the value originally). 1700*0b57cec5SDimitry Andric */ 1701*0b57cec5SDimitry Andric 1702*0b57cec5SDimitry Andric /* LE variable byte 1703*0b57cec5SDimitry Andric Number 1. above: 1704*0b57cec5SDimitry Andric - For elements 0-7, we shift left by 8 bytes since they're on the right 1705*0b57cec5SDimitry Andric - For elements 8-15, we need not shift (shift left by zero bytes) 1706*0b57cec5SDimitry Andric This is accomplished by inverting the bits of the index and AND-ing 1707*0b57cec5SDimitry Andric with 0x8 (i.e. clearing all bits of the index and inverting bit 60). 1708*0b57cec5SDimitry Andric */ 1709*0b57cec5SDimitry Andric dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx))); 1710*0b57cec5SDimitry Andric 1711*0b57cec5SDimitry Andric // Number 2. above: 1712*0b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 1713*0b57cec5SDimitry Andric dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC)); 1714*0b57cec5SDimitry Andric 1715*0b57cec5SDimitry Andric // Number 3. above: 1716*0b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 1717*0b57cec5SDimitry Andric dag LE_MV_VBYTE = (MFVSRD 1718*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1719*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)), 1720*0b57cec5SDimitry Andric sub_64)); 1721*0b57cec5SDimitry Andric 1722*0b57cec5SDimitry Andric /* Number 4. above: 1723*0b57cec5SDimitry Andric - Truncate the element number to the range 0-7 (8-15 are symmetrical 1724*0b57cec5SDimitry Andric and out of range values are truncated accordingly) 1725*0b57cec5SDimitry Andric - Multiply by 8 as we need to shift right by the number of bits, not bytes 1726*0b57cec5SDimitry Andric - Shift right in the GPR by the calculated value 1727*0b57cec5SDimitry Andric */ 1728*0b57cec5SDimitry Andric dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60), 1729*0b57cec5SDimitry Andric sub_32); 1730*0b57cec5SDimitry Andric dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT), 1731*0b57cec5SDimitry Andric sub_32); 1732*0b57cec5SDimitry Andric 1733*0b57cec5SDimitry Andric /* LE variable halfword 1734*0b57cec5SDimitry Andric Number 1. above: 1735*0b57cec5SDimitry Andric - For elements 0-3, we shift left by 8 since they're on the right 1736*0b57cec5SDimitry Andric - For elements 4-7, we need not shift (shift left by zero bytes) 1737*0b57cec5SDimitry Andric Similarly to the byte pattern, we invert the bits of the index, but we 1738*0b57cec5SDimitry Andric AND with 0x4 (i.e. clear all bits of the index and invert bit 61). 1739*0b57cec5SDimitry Andric Of course, the shift is still by 8 bytes, so we must multiply by 2. 1740*0b57cec5SDimitry Andric */ 1741*0b57cec5SDimitry Andric dag LE_VHALF_PERM_VEC = 1742*0b57cec5SDimitry Andric (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62))); 1743*0b57cec5SDimitry Andric 1744*0b57cec5SDimitry Andric // Number 2. above: 1745*0b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 1746*0b57cec5SDimitry Andric dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC)); 1747*0b57cec5SDimitry Andric 1748*0b57cec5SDimitry Andric // Number 3. above: 1749*0b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 1750*0b57cec5SDimitry Andric dag LE_MV_VHALF = (MFVSRD 1751*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1752*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)), 1753*0b57cec5SDimitry Andric sub_64)); 1754*0b57cec5SDimitry Andric 1755*0b57cec5SDimitry Andric /* Number 4. above: 1756*0b57cec5SDimitry Andric - Truncate the element number to the range 0-3 (4-7 are symmetrical 1757*0b57cec5SDimitry Andric and out of range values are truncated accordingly) 1758*0b57cec5SDimitry Andric - Multiply by 16 as we need to shift right by the number of bits 1759*0b57cec5SDimitry Andric - Shift right in the GPR by the calculated value 1760*0b57cec5SDimitry Andric */ 1761*0b57cec5SDimitry Andric dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59), 1762*0b57cec5SDimitry Andric sub_32); 1763*0b57cec5SDimitry Andric dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT), 1764*0b57cec5SDimitry Andric sub_32); 1765*0b57cec5SDimitry Andric 1766*0b57cec5SDimitry Andric /* LE variable word 1767*0b57cec5SDimitry Andric Number 1. above: 1768*0b57cec5SDimitry Andric - For elements 0-1, we shift left by 8 since they're on the right 1769*0b57cec5SDimitry Andric - For elements 2-3, we need not shift 1770*0b57cec5SDimitry Andric */ 1771*0b57cec5SDimitry Andric dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 1772*0b57cec5SDimitry Andric (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61))); 1773*0b57cec5SDimitry Andric 1774*0b57cec5SDimitry Andric // Number 2. above: 1775*0b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 1776*0b57cec5SDimitry Andric dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC)); 1777*0b57cec5SDimitry Andric 1778*0b57cec5SDimitry Andric // Number 3. above: 1779*0b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 1780*0b57cec5SDimitry Andric dag LE_MV_VWORD = (MFVSRD 1781*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1782*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)), 1783*0b57cec5SDimitry Andric sub_64)); 1784*0b57cec5SDimitry Andric 1785*0b57cec5SDimitry Andric /* Number 4. above: 1786*0b57cec5SDimitry Andric - Truncate the element number to the range 0-1 (2-3 are symmetrical 1787*0b57cec5SDimitry Andric and out of range values are truncated accordingly) 1788*0b57cec5SDimitry Andric - Multiply by 32 as we need to shift right by the number of bits 1789*0b57cec5SDimitry Andric - Shift right in the GPR by the calculated value 1790*0b57cec5SDimitry Andric */ 1791*0b57cec5SDimitry Andric dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58), 1792*0b57cec5SDimitry Andric sub_32); 1793*0b57cec5SDimitry Andric dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT), 1794*0b57cec5SDimitry Andric sub_32); 1795*0b57cec5SDimitry Andric 1796*0b57cec5SDimitry Andric /* LE variable doubleword 1797*0b57cec5SDimitry Andric Number 1. above: 1798*0b57cec5SDimitry Andric - For element 0, we shift left by 8 since it's on the right 1799*0b57cec5SDimitry Andric - For element 1, we need not shift 1800*0b57cec5SDimitry Andric */ 1801*0b57cec5SDimitry Andric dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 1802*0b57cec5SDimitry Andric (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60))); 1803*0b57cec5SDimitry Andric 1804*0b57cec5SDimitry Andric // Number 2. above: 1805*0b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 1806*0b57cec5SDimitry Andric dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC)); 1807*0b57cec5SDimitry Andric 1808*0b57cec5SDimitry Andric // Number 3. above: 1809*0b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 1810*0b57cec5SDimitry Andric // - Number 4. is not needed for the doubleword as the value is 64-bits 1811*0b57cec5SDimitry Andric dag LE_VARIABLE_DWORD = 1812*0b57cec5SDimitry Andric (MFVSRD (EXTRACT_SUBREG 1813*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)), 1814*0b57cec5SDimitry Andric sub_64)); 1815*0b57cec5SDimitry Andric 1816*0b57cec5SDimitry Andric /* LE variable float 1817*0b57cec5SDimitry Andric - Shift the vector to line up the desired element to BE Word 0 1818*0b57cec5SDimitry Andric - Convert 32-bit float to a 64-bit single precision float 1819*0b57cec5SDimitry Andric */ 1820*0b57cec5SDimitry Andric dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, 1821*0b57cec5SDimitry Andric (RLDICR (XOR8 (LI8 3), $Idx), 2, 61))); 1822*0b57cec5SDimitry Andric dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC); 1823*0b57cec5SDimitry Andric dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE); 1824*0b57cec5SDimitry Andric 1825*0b57cec5SDimitry Andric /* LE variable double 1826*0b57cec5SDimitry Andric Same as the LE doubleword except there is no move. 1827*0b57cec5SDimitry Andric */ 1828*0b57cec5SDimitry Andric dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 1829*0b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 1830*0b57cec5SDimitry Andric LE_VDWORD_PERM_VEC)); 1831*0b57cec5SDimitry Andric dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC); 1832*0b57cec5SDimitry Andric 1833*0b57cec5SDimitry Andric /* BE variable byte 1834*0b57cec5SDimitry Andric The algorithm here is the same as the LE variable byte except: 1835*0b57cec5SDimitry Andric - The shift in the VMX register is by 0/8 for opposite element numbers so 1836*0b57cec5SDimitry Andric we simply AND the element number with 0x8 1837*0b57cec5SDimitry Andric - The order of elements after the move to GPR is reversed, so we invert 1838*0b57cec5SDimitry Andric the bits of the index prior to truncating to the range 0-7 1839*0b57cec5SDimitry Andric */ 1840*0b57cec5SDimitry Andric dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDIo8 $Idx, 8))); 1841*0b57cec5SDimitry Andric dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC)); 1842*0b57cec5SDimitry Andric dag BE_MV_VBYTE = (MFVSRD 1843*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1844*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)), 1845*0b57cec5SDimitry Andric sub_64)); 1846*0b57cec5SDimitry Andric dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60), 1847*0b57cec5SDimitry Andric sub_32); 1848*0b57cec5SDimitry Andric dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT), 1849*0b57cec5SDimitry Andric sub_32); 1850*0b57cec5SDimitry Andric 1851*0b57cec5SDimitry Andric /* BE variable halfword 1852*0b57cec5SDimitry Andric The algorithm here is the same as the LE variable halfword except: 1853*0b57cec5SDimitry Andric - The shift in the VMX register is by 0/8 for opposite element numbers so 1854*0b57cec5SDimitry Andric we simply AND the element number with 0x4 and multiply by 2 1855*0b57cec5SDimitry Andric - The order of elements after the move to GPR is reversed, so we invert 1856*0b57cec5SDimitry Andric the bits of the index prior to truncating to the range 0-3 1857*0b57cec5SDimitry Andric */ 1858*0b57cec5SDimitry Andric dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8, 1859*0b57cec5SDimitry Andric (RLDICR (ANDIo8 $Idx, 4), 1, 62))); 1860*0b57cec5SDimitry Andric dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC)); 1861*0b57cec5SDimitry Andric dag BE_MV_VHALF = (MFVSRD 1862*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1863*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)), 1864*0b57cec5SDimitry Andric sub_64)); 1865*0b57cec5SDimitry Andric dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59), 1866*0b57cec5SDimitry Andric sub_32); 1867*0b57cec5SDimitry Andric dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT), 1868*0b57cec5SDimitry Andric sub_32); 1869*0b57cec5SDimitry Andric 1870*0b57cec5SDimitry Andric /* BE variable word 1871*0b57cec5SDimitry Andric The algorithm is the same as the LE variable word except: 1872*0b57cec5SDimitry Andric - The shift in the VMX register happens for opposite element numbers 1873*0b57cec5SDimitry Andric - The order of elements after the move to GPR is reversed, so we invert 1874*0b57cec5SDimitry Andric the bits of the index prior to truncating to the range 0-1 1875*0b57cec5SDimitry Andric */ 1876*0b57cec5SDimitry Andric dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 1877*0b57cec5SDimitry Andric (RLDICR (ANDIo8 $Idx, 2), 2, 61))); 1878*0b57cec5SDimitry Andric dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC)); 1879*0b57cec5SDimitry Andric dag BE_MV_VWORD = (MFVSRD 1880*0b57cec5SDimitry Andric (EXTRACT_SUBREG 1881*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)), 1882*0b57cec5SDimitry Andric sub_64)); 1883*0b57cec5SDimitry Andric dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58), 1884*0b57cec5SDimitry Andric sub_32); 1885*0b57cec5SDimitry Andric dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT), 1886*0b57cec5SDimitry Andric sub_32); 1887*0b57cec5SDimitry Andric 1888*0b57cec5SDimitry Andric /* BE variable doubleword 1889*0b57cec5SDimitry Andric Same as the LE doubleword except we shift in the VMX register for opposite 1890*0b57cec5SDimitry Andric element indices. 1891*0b57cec5SDimitry Andric */ 1892*0b57cec5SDimitry Andric dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 1893*0b57cec5SDimitry Andric (RLDICR (ANDIo8 $Idx, 1), 3, 60))); 1894*0b57cec5SDimitry Andric dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC)); 1895*0b57cec5SDimitry Andric dag BE_VARIABLE_DWORD = 1896*0b57cec5SDimitry Andric (MFVSRD (EXTRACT_SUBREG 1897*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)), 1898*0b57cec5SDimitry Andric sub_64)); 1899*0b57cec5SDimitry Andric 1900*0b57cec5SDimitry Andric /* BE variable float 1901*0b57cec5SDimitry Andric - Shift the vector to line up the desired element to BE Word 0 1902*0b57cec5SDimitry Andric - Convert 32-bit float to a 64-bit single precision float 1903*0b57cec5SDimitry Andric */ 1904*0b57cec5SDimitry Andric dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61))); 1905*0b57cec5SDimitry Andric dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC); 1906*0b57cec5SDimitry Andric dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE); 1907*0b57cec5SDimitry Andric 1908*0b57cec5SDimitry Andric /* BE variable double 1909*0b57cec5SDimitry Andric Same as the BE doubleword except there is no move. 1910*0b57cec5SDimitry Andric */ 1911*0b57cec5SDimitry Andric dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 1912*0b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 1913*0b57cec5SDimitry Andric BE_VDWORD_PERM_VEC)); 1914*0b57cec5SDimitry Andric dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC); 1915*0b57cec5SDimitry Andric} 1916*0b57cec5SDimitry Andric 1917*0b57cec5SDimitry Andricdef NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">; 1918*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { 1919*0b57cec5SDimitry Andric// v4f32 scalar <-> vector conversions (BE) 1920*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasP8Vector] in { 1921*0b57cec5SDimitry Andric def : Pat<(v4f32 (scalar_to_vector f32:$A)), 1922*0b57cec5SDimitry Andric (v4f32 (XSCVDPSPN $A))>; 1923*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 0)), 1924*0b57cec5SDimitry Andric (f32 (XSCVSPDPN $S))>; 1925*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 1)), 1926*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>; 1927*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 2)), 1928*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>; 1929*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 3)), 1930*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>; 1931*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)), 1932*0b57cec5SDimitry Andric (f32 VectorExtractions.BE_VARIABLE_FLOAT)>; 1933*0b57cec5SDimitry Andric} // IsBigEndian, HasP8Vector 1934*0b57cec5SDimitry Andric 1935*0b57cec5SDimitry Andric// Variable index vector_extract for v2f64 does not require P8Vector 1936*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasVSX] in 1937*0b57cec5SDimitry Andric def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 1938*0b57cec5SDimitry Andric (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>; 1939*0b57cec5SDimitry Andric 1940*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasDirectMove] in { 1941*0b57cec5SDimitry Andric // v16i8 scalar <-> vector conversions (BE) 1942*0b57cec5SDimitry Andric def : Pat<(v16i8 (scalar_to_vector i32:$A)), 1943*0b57cec5SDimitry Andric (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>; 1944*0b57cec5SDimitry Andric def : Pat<(v8i16 (scalar_to_vector i32:$A)), 1945*0b57cec5SDimitry Andric (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>; 1946*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector i32:$A)), 1947*0b57cec5SDimitry Andric (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>; 1948*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector i64:$A)), 1949*0b57cec5SDimitry Andric (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>; 1950*0b57cec5SDimitry Andric 1951*0b57cec5SDimitry Andric // v2i64 scalar <-> vector conversions (BE) 1952*0b57cec5SDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, 0)), 1953*0b57cec5SDimitry Andric (i64 VectorExtractions.LE_DWORD_1)>; 1954*0b57cec5SDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, 1)), 1955*0b57cec5SDimitry Andric (i64 VectorExtractions.LE_DWORD_0)>; 1956*0b57cec5SDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)), 1957*0b57cec5SDimitry Andric (i64 VectorExtractions.BE_VARIABLE_DWORD)>; 1958*0b57cec5SDimitry Andric} // IsBigEndian, HasDirectMove 1959*0b57cec5SDimitry Andric 1960*0b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in { 1961*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 0)), 1962*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_15)>; 1963*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 1)), 1964*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_14)>; 1965*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 2)), 1966*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_13)>; 1967*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 3)), 1968*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_12)>; 1969*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 4)), 1970*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_11)>; 1971*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 5)), 1972*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_10)>; 1973*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 6)), 1974*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_9)>; 1975*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 7)), 1976*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_8)>; 1977*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 8)), 1978*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_7)>; 1979*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 9)), 1980*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_6)>; 1981*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 10)), 1982*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_5)>; 1983*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 11)), 1984*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_4)>; 1985*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 12)), 1986*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_3)>; 1987*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 13)), 1988*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_2)>; 1989*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 14)), 1990*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_1)>; 1991*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 15)), 1992*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_0)>; 1993*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 1994*0b57cec5SDimitry Andric (i32 VectorExtractions.BE_VARIABLE_BYTE)>; 1995*0b57cec5SDimitry Andric 1996*0b57cec5SDimitry Andric // v8i16 scalar <-> vector conversions (BE) 1997*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 0)), 1998*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_7)>; 1999*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 1)), 2000*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_6)>; 2001*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 2)), 2002*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_5)>; 2003*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 3)), 2004*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_4)>; 2005*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 4)), 2006*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_3)>; 2007*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 5)), 2008*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_2)>; 2009*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2010*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_1)>; 2011*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 7)), 2012*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_0)>; 2013*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 2014*0b57cec5SDimitry Andric (i32 VectorExtractions.BE_VARIABLE_HALF)>; 2015*0b57cec5SDimitry Andric 2016*0b57cec5SDimitry Andric // v4i32 scalar <-> vector conversions (BE) 2017*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 0)), 2018*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_3)>; 2019*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 1)), 2020*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 2021*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 2)), 2022*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_1)>; 2023*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 3)), 2024*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_0)>; 2025*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 2026*0b57cec5SDimitry Andric (i32 VectorExtractions.BE_VARIABLE_WORD)>; 2027*0b57cec5SDimitry Andric} // IsBigEndian, HasDirectMove, NoP9Altivec 2028*0b57cec5SDimitry Andric 2029*0b57cec5SDimitry Andric// v4f32 scalar <-> vector conversions (LE) 2030*0b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasP8Vector] in { 2031*0b57cec5SDimitry Andric def : Pat<(v4f32 (scalar_to_vector f32:$A)), 2032*0b57cec5SDimitry Andric (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>; 2033*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 0)), 2034*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>; 2035*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 1)), 2036*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>; 2037*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 2)), 2038*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>; 2039*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, 3)), 2040*0b57cec5SDimitry Andric (f32 (XSCVSPDPN $S))>; 2041*0b57cec5SDimitry Andric def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)), 2042*0b57cec5SDimitry Andric (f32 VectorExtractions.LE_VARIABLE_FLOAT)>; 2043*0b57cec5SDimitry Andric} // IsLittleEndian, HasP8Vector 2044*0b57cec5SDimitry Andric 2045*0b57cec5SDimitry Andric// Variable index vector_extract for v2f64 does not require P8Vector 2046*0b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasVSX] in 2047*0b57cec5SDimitry Andric def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 2048*0b57cec5SDimitry Andric (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>; 2049*0b57cec5SDimitry Andric 2050*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst), 2051*0b57cec5SDimitry Andric (STXVD2X $rS, xoaddr:$dst)>; 2052*0b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst), 2053*0b57cec5SDimitry Andric (STXVW4X $rS, xoaddr:$dst)>; 2054*0b57cec5SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>; 2055*0b57cec5SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>; 2056*0b57cec5SDimitry Andric 2057*0b57cec5SDimitry Andric// Variable index unsigned vector_extract on Power9 2058*0b57cec5SDimitry Andriclet Predicates = [HasP9Altivec, IsLittleEndian] in { 2059*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))), 2060*0b57cec5SDimitry Andric (VEXTUBRX $Idx, $S)>; 2061*0b57cec5SDimitry Andric 2062*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))), 2063*0b57cec5SDimitry Andric (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>; 2064*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))), 2065*0b57cec5SDimitry Andric (VEXTUHRX (LI8 0), $S)>; 2066*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))), 2067*0b57cec5SDimitry Andric (VEXTUHRX (LI8 2), $S)>; 2068*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))), 2069*0b57cec5SDimitry Andric (VEXTUHRX (LI8 4), $S)>; 2070*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))), 2071*0b57cec5SDimitry Andric (VEXTUHRX (LI8 6), $S)>; 2072*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))), 2073*0b57cec5SDimitry Andric (VEXTUHRX (LI8 8), $S)>; 2074*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))), 2075*0b57cec5SDimitry Andric (VEXTUHRX (LI8 10), $S)>; 2076*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))), 2077*0b57cec5SDimitry Andric (VEXTUHRX (LI8 12), $S)>; 2078*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))), 2079*0b57cec5SDimitry Andric (VEXTUHRX (LI8 14), $S)>; 2080*0b57cec5SDimitry Andric 2081*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 2082*0b57cec5SDimitry Andric (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>; 2083*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))), 2084*0b57cec5SDimitry Andric (VEXTUWRX (LI8 0), $S)>; 2085*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))), 2086*0b57cec5SDimitry Andric (VEXTUWRX (LI8 4), $S)>; 2087*0b57cec5SDimitry Andric // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX 2088*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))), 2089*0b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2090*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32)>; 2091*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))), 2092*0b57cec5SDimitry Andric (VEXTUWRX (LI8 12), $S)>; 2093*0b57cec5SDimitry Andric 2094*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 2095*0b57cec5SDimitry Andric (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>; 2096*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))), 2097*0b57cec5SDimitry Andric (EXTSW (VEXTUWRX (LI8 0), $S))>; 2098*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))), 2099*0b57cec5SDimitry Andric (EXTSW (VEXTUWRX (LI8 4), $S))>; 2100*0b57cec5SDimitry Andric // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX 2101*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))), 2102*0b57cec5SDimitry Andric (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2103*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32))>; 2104*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))), 2105*0b57cec5SDimitry Andric (EXTSW (VEXTUWRX (LI8 12), $S))>; 2106*0b57cec5SDimitry Andric 2107*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 2108*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>; 2109*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 0)), 2110*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>; 2111*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 1)), 2112*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>; 2113*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 2)), 2114*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>; 2115*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 3)), 2116*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>; 2117*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 4)), 2118*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>; 2119*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 5)), 2120*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>; 2121*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 6)), 2122*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>; 2123*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 7)), 2124*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>; 2125*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 8)), 2126*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>; 2127*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 9)), 2128*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>; 2129*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 10)), 2130*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>; 2131*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 11)), 2132*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>; 2133*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 12)), 2134*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>; 2135*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 13)), 2136*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>; 2137*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 14)), 2138*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>; 2139*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 15)), 2140*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>; 2141*0b57cec5SDimitry Andric 2142*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 2143*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX 2144*0b57cec5SDimitry Andric (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>; 2145*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 0)), 2146*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>; 2147*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 1)), 2148*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>; 2149*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 2)), 2150*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>; 2151*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 3)), 2152*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>; 2153*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 4)), 2154*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>; 2155*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 5)), 2156*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>; 2157*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2158*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>; 2159*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2160*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>; 2161*0b57cec5SDimitry Andric 2162*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 2163*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX 2164*0b57cec5SDimitry Andric (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>; 2165*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 0)), 2166*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>; 2167*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 1)), 2168*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>; 2169*0b57cec5SDimitry Andric // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX 2170*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 2)), 2171*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 2172*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 3)), 2173*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>; 2174*0b57cec5SDimitry Andric} 2175*0b57cec5SDimitry Andric 2176*0b57cec5SDimitry Andriclet Predicates = [HasP9Altivec, IsBigEndian] in { 2177*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))), 2178*0b57cec5SDimitry Andric (VEXTUBLX $Idx, $S)>; 2179*0b57cec5SDimitry Andric 2180*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))), 2181*0b57cec5SDimitry Andric (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>; 2182*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))), 2183*0b57cec5SDimitry Andric (VEXTUHLX (LI8 0), $S)>; 2184*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))), 2185*0b57cec5SDimitry Andric (VEXTUHLX (LI8 2), $S)>; 2186*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))), 2187*0b57cec5SDimitry Andric (VEXTUHLX (LI8 4), $S)>; 2188*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))), 2189*0b57cec5SDimitry Andric (VEXTUHLX (LI8 6), $S)>; 2190*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))), 2191*0b57cec5SDimitry Andric (VEXTUHLX (LI8 8), $S)>; 2192*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))), 2193*0b57cec5SDimitry Andric (VEXTUHLX (LI8 10), $S)>; 2194*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))), 2195*0b57cec5SDimitry Andric (VEXTUHLX (LI8 12), $S)>; 2196*0b57cec5SDimitry Andric def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))), 2197*0b57cec5SDimitry Andric (VEXTUHLX (LI8 14), $S)>; 2198*0b57cec5SDimitry Andric 2199*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 2200*0b57cec5SDimitry Andric (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>; 2201*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))), 2202*0b57cec5SDimitry Andric (VEXTUWLX (LI8 0), $S)>; 2203*0b57cec5SDimitry Andric 2204*0b57cec5SDimitry Andric // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX 2205*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))), 2206*0b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2207*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32)>; 2208*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))), 2209*0b57cec5SDimitry Andric (VEXTUWLX (LI8 8), $S)>; 2210*0b57cec5SDimitry Andric def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))), 2211*0b57cec5SDimitry Andric (VEXTUWLX (LI8 12), $S)>; 2212*0b57cec5SDimitry Andric 2213*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 2214*0b57cec5SDimitry Andric (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>; 2215*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))), 2216*0b57cec5SDimitry Andric (EXTSW (VEXTUWLX (LI8 0), $S))>; 2217*0b57cec5SDimitry Andric // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX 2218*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))), 2219*0b57cec5SDimitry Andric (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2220*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32))>; 2221*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))), 2222*0b57cec5SDimitry Andric (EXTSW (VEXTUWLX (LI8 8), $S))>; 2223*0b57cec5SDimitry Andric def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))), 2224*0b57cec5SDimitry Andric (EXTSW (VEXTUWLX (LI8 12), $S))>; 2225*0b57cec5SDimitry Andric 2226*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 2227*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>; 2228*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 0)), 2229*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>; 2230*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 1)), 2231*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>; 2232*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 2)), 2233*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>; 2234*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 3)), 2235*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>; 2236*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 4)), 2237*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>; 2238*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 5)), 2239*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>; 2240*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 6)), 2241*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>; 2242*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 7)), 2243*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>; 2244*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 8)), 2245*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>; 2246*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 9)), 2247*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>; 2248*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 10)), 2249*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>; 2250*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 11)), 2251*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>; 2252*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 12)), 2253*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>; 2254*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 13)), 2255*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>; 2256*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 14)), 2257*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>; 2258*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 15)), 2259*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>; 2260*0b57cec5SDimitry Andric 2261*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 2262*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX 2263*0b57cec5SDimitry Andric (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>; 2264*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 0)), 2265*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>; 2266*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 1)), 2267*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>; 2268*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 2)), 2269*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>; 2270*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 3)), 2271*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>; 2272*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 4)), 2273*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>; 2274*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 5)), 2275*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>; 2276*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2277*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>; 2278*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2279*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>; 2280*0b57cec5SDimitry Andric 2281*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 2282*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX 2283*0b57cec5SDimitry Andric (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>; 2284*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 0)), 2285*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>; 2286*0b57cec5SDimitry Andric // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX 2287*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 1)), 2288*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 2289*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 2)), 2290*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>; 2291*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 3)), 2292*0b57cec5SDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>; 2293*0b57cec5SDimitry Andric} 2294*0b57cec5SDimitry Andric 2295*0b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasDirectMove] in { 2296*0b57cec5SDimitry Andric // v16i8 scalar <-> vector conversions (LE) 2297*0b57cec5SDimitry Andric def : Pat<(v16i8 (scalar_to_vector i32:$A)), 2298*0b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>; 2299*0b57cec5SDimitry Andric def : Pat<(v8i16 (scalar_to_vector i32:$A)), 2300*0b57cec5SDimitry Andric (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>; 2301*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector i32:$A)), 2302*0b57cec5SDimitry Andric (v4i32 MovesToVSR.LE_WORD_0)>; 2303*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector i64:$A)), 2304*0b57cec5SDimitry Andric (v2i64 MovesToVSR.LE_DWORD_0)>; 2305*0b57cec5SDimitry Andric // v2i64 scalar <-> vector conversions (LE) 2306*0b57cec5SDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, 0)), 2307*0b57cec5SDimitry Andric (i64 VectorExtractions.LE_DWORD_0)>; 2308*0b57cec5SDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, 1)), 2309*0b57cec5SDimitry Andric (i64 VectorExtractions.LE_DWORD_1)>; 2310*0b57cec5SDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)), 2311*0b57cec5SDimitry Andric (i64 VectorExtractions.LE_VARIABLE_DWORD)>; 2312*0b57cec5SDimitry Andric} // IsLittleEndian, HasDirectMove 2313*0b57cec5SDimitry Andric 2314*0b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in { 2315*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 0)), 2316*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_0)>; 2317*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 1)), 2318*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_1)>; 2319*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 2)), 2320*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_2)>; 2321*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 3)), 2322*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_3)>; 2323*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 4)), 2324*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_4)>; 2325*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 5)), 2326*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_5)>; 2327*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 6)), 2328*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_6)>; 2329*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 7)), 2330*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_7)>; 2331*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 8)), 2332*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_8)>; 2333*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 9)), 2334*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_9)>; 2335*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 10)), 2336*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_10)>; 2337*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 11)), 2338*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_11)>; 2339*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 12)), 2340*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_12)>; 2341*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 13)), 2342*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_13)>; 2343*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 14)), 2344*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_14)>; 2345*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, 15)), 2346*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_BYTE_15)>; 2347*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 2348*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_VARIABLE_BYTE)>; 2349*0b57cec5SDimitry Andric 2350*0b57cec5SDimitry Andric // v8i16 scalar <-> vector conversions (LE) 2351*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 0)), 2352*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_0)>; 2353*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 1)), 2354*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_1)>; 2355*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 2)), 2356*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_2)>; 2357*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 3)), 2358*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_3)>; 2359*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 4)), 2360*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_4)>; 2361*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 5)), 2362*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_5)>; 2363*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 6)), 2364*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_6)>; 2365*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, 7)), 2366*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_HALF_7)>; 2367*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 2368*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_VARIABLE_HALF)>; 2369*0b57cec5SDimitry Andric 2370*0b57cec5SDimitry Andric // v4i32 scalar <-> vector conversions (LE) 2371*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 0)), 2372*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_0)>; 2373*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 1)), 2374*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_1)>; 2375*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 2)), 2376*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 2377*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, 3)), 2378*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_WORD_3)>; 2379*0b57cec5SDimitry Andric def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 2380*0b57cec5SDimitry Andric (i32 VectorExtractions.LE_VARIABLE_WORD)>; 2381*0b57cec5SDimitry Andric} // IsLittleEndian, HasDirectMove, NoP9Altivec 2382*0b57cec5SDimitry Andric 2383*0b57cec5SDimitry Andriclet Predicates = [HasDirectMove, HasVSX] in { 2384*0b57cec5SDimitry Andric// bitconvert f32 -> i32 2385*0b57cec5SDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR) 2386*0b57cec5SDimitry Andricdef : Pat<(i32 (bitconvert f32:$S)), 2387*0b57cec5SDimitry Andric (i32 (MFVSRWZ (EXTRACT_SUBREG 2388*0b57cec5SDimitry Andric (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3), 2389*0b57cec5SDimitry Andric sub_64)))>; 2390*0b57cec5SDimitry Andric// bitconvert i32 -> f32 2391*0b57cec5SDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single) 2392*0b57cec5SDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)), 2393*0b57cec5SDimitry Andric (f32 (XSCVSPDPN 2394*0b57cec5SDimitry Andric (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>; 2395*0b57cec5SDimitry Andric 2396*0b57cec5SDimitry Andric// bitconvert f64 -> i64 2397*0b57cec5SDimitry Andric// (move to GPR, nothing else needed) 2398*0b57cec5SDimitry Andricdef : Pat<(i64 (bitconvert f64:$S)), 2399*0b57cec5SDimitry Andric (i64 (MFVSRD $S))>; 2400*0b57cec5SDimitry Andric 2401*0b57cec5SDimitry Andric// bitconvert i64 -> f64 2402*0b57cec5SDimitry Andric// (move to FPR, nothing else needed) 2403*0b57cec5SDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)), 2404*0b57cec5SDimitry Andric (f64 (MTVSRD $S))>; 2405*0b57cec5SDimitry Andric} 2406*0b57cec5SDimitry Andric 2407*0b57cec5SDimitry Andric// Materialize a zero-vector of long long 2408*0b57cec5SDimitry Andricdef : Pat<(v2i64 immAllZerosV), 2409*0b57cec5SDimitry Andric (v2i64 (XXLXORz))>; 2410*0b57cec5SDimitry Andric} 2411*0b57cec5SDimitry Andric 2412*0b57cec5SDimitry Andricdef AlignValues { 2413*0b57cec5SDimitry Andric dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3)); 2414*0b57cec5SDimitry Andric dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC); 2415*0b57cec5SDimitry Andric} 2416*0b57cec5SDimitry Andric 2417*0b57cec5SDimitry Andric// The following VSX instructions were introduced in Power ISA 3.0 2418*0b57cec5SDimitry Andricdef HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">; 2419*0b57cec5SDimitry Andriclet AddedComplexity = 400, Predicates = [HasP9Vector] in { 2420*0b57cec5SDimitry Andric 2421*0b57cec5SDimitry Andric // [PO VRT XO VRB XO /] 2422*0b57cec5SDimitry Andric class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2423*0b57cec5SDimitry Andric list<dag> pattern> 2424*0b57cec5SDimitry Andric : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB), 2425*0b57cec5SDimitry Andric !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 2426*0b57cec5SDimitry Andric 2427*0b57cec5SDimitry Andric // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /] 2428*0b57cec5SDimitry Andric class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2429*0b57cec5SDimitry Andric list<dag> pattern> 2430*0b57cec5SDimitry Andric : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT; 2431*0b57cec5SDimitry Andric 2432*0b57cec5SDimitry Andric // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less), 2433*0b57cec5SDimitry Andric // So we use different operand class for VRB 2434*0b57cec5SDimitry Andric class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2435*0b57cec5SDimitry Andric RegisterOperand vbtype, list<dag> pattern> 2436*0b57cec5SDimitry Andric : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB), 2437*0b57cec5SDimitry Andric !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 2438*0b57cec5SDimitry Andric 2439*0b57cec5SDimitry Andric // [PO VRT XO VRB XO /] 2440*0b57cec5SDimitry Andric class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2441*0b57cec5SDimitry Andric list<dag> pattern> 2442*0b57cec5SDimitry Andric : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB), 2443*0b57cec5SDimitry Andric !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 2444*0b57cec5SDimitry Andric 2445*0b57cec5SDimitry Andric // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /] 2446*0b57cec5SDimitry Andric class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2447*0b57cec5SDimitry Andric list<dag> pattern> 2448*0b57cec5SDimitry Andric : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isDOT; 2449*0b57cec5SDimitry Andric 2450*0b57cec5SDimitry Andric // [PO T XO B XO BX /] 2451*0b57cec5SDimitry Andric class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc, 2452*0b57cec5SDimitry Andric list<dag> pattern> 2453*0b57cec5SDimitry Andric : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB), 2454*0b57cec5SDimitry Andric !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>; 2455*0b57cec5SDimitry Andric 2456*0b57cec5SDimitry Andric // [PO T XO B XO BX TX] 2457*0b57cec5SDimitry Andric class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc, 2458*0b57cec5SDimitry Andric RegisterOperand vtype, list<dag> pattern> 2459*0b57cec5SDimitry Andric : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB), 2460*0b57cec5SDimitry Andric !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>; 2461*0b57cec5SDimitry Andric 2462*0b57cec5SDimitry Andric // [PO T A B XO AX BX TX], src and dest register use different operand class 2463*0b57cec5SDimitry Andric class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc, 2464*0b57cec5SDimitry Andric RegisterOperand xty, RegisterOperand aty, RegisterOperand bty, 2465*0b57cec5SDimitry Andric InstrItinClass itin, list<dag> pattern> 2466*0b57cec5SDimitry Andric : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB), 2467*0b57cec5SDimitry Andric !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>; 2468*0b57cec5SDimitry Andric 2469*0b57cec5SDimitry Andric // [PO VRT VRA VRB XO /] 2470*0b57cec5SDimitry Andric class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc, 2471*0b57cec5SDimitry Andric list<dag> pattern> 2472*0b57cec5SDimitry Andric : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB), 2473*0b57cec5SDimitry Andric !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>; 2474*0b57cec5SDimitry Andric 2475*0b57cec5SDimitry Andric // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /] 2476*0b57cec5SDimitry Andric class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc, 2477*0b57cec5SDimitry Andric list<dag> pattern> 2478*0b57cec5SDimitry Andric : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT; 2479*0b57cec5SDimitry Andric 2480*0b57cec5SDimitry Andric // [PO VRT VRA VRB XO /] 2481*0b57cec5SDimitry Andric class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc, 2482*0b57cec5SDimitry Andric list<dag> pattern> 2483*0b57cec5SDimitry Andric : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB), 2484*0b57cec5SDimitry Andric !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>, 2485*0b57cec5SDimitry Andric RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">; 2486*0b57cec5SDimitry Andric 2487*0b57cec5SDimitry Andric // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /] 2488*0b57cec5SDimitry Andric class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc, 2489*0b57cec5SDimitry Andric list<dag> pattern> 2490*0b57cec5SDimitry Andric : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isDOT; 2491*0b57cec5SDimitry Andric 2492*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2493*0b57cec5SDimitry Andric // Quad-Precision Scalar Move Instructions: 2494*0b57cec5SDimitry Andric 2495*0b57cec5SDimitry Andric // Copy Sign 2496*0b57cec5SDimitry Andric def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", 2497*0b57cec5SDimitry Andric [(set f128:$vT, 2498*0b57cec5SDimitry Andric (fcopysign f128:$vB, f128:$vA))]>; 2499*0b57cec5SDimitry Andric 2500*0b57cec5SDimitry Andric // Absolute/Negative-Absolute/Negate 2501*0b57cec5SDimitry Andric def XSABSQP : X_VT5_XO5_VB5<63, 0, 804, "xsabsqp", 2502*0b57cec5SDimitry Andric [(set f128:$vT, (fabs f128:$vB))]>; 2503*0b57cec5SDimitry Andric def XSNABSQP : X_VT5_XO5_VB5<63, 8, 804, "xsnabsqp", 2504*0b57cec5SDimitry Andric [(set f128:$vT, (fneg (fabs f128:$vB)))]>; 2505*0b57cec5SDimitry Andric def XSNEGQP : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp", 2506*0b57cec5SDimitry Andric [(set f128:$vT, (fneg f128:$vB))]>; 2507*0b57cec5SDimitry Andric 2508*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2509*0b57cec5SDimitry Andric // Quad-Precision Scalar Floating-Point Arithmetic Instructions: 2510*0b57cec5SDimitry Andric 2511*0b57cec5SDimitry Andric // Add/Divide/Multiply/Subtract 2512*0b57cec5SDimitry Andric let isCommutable = 1 in { 2513*0b57cec5SDimitry Andric def XSADDQP : X_VT5_VA5_VB5 <63, 4, "xsaddqp", 2514*0b57cec5SDimitry Andric [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>; 2515*0b57cec5SDimitry Andric def XSMULQP : X_VT5_VA5_VB5 <63, 36, "xsmulqp", 2516*0b57cec5SDimitry Andric [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>; 2517*0b57cec5SDimitry Andric } 2518*0b57cec5SDimitry Andric def XSSUBQP : X_VT5_VA5_VB5 <63, 516, "xssubqp" , 2519*0b57cec5SDimitry Andric [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>; 2520*0b57cec5SDimitry Andric def XSDIVQP : X_VT5_VA5_VB5 <63, 548, "xsdivqp", 2521*0b57cec5SDimitry Andric [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>; 2522*0b57cec5SDimitry Andric // Square-Root 2523*0b57cec5SDimitry Andric def XSSQRTQP : X_VT5_XO5_VB5 <63, 27, 804, "xssqrtqp", 2524*0b57cec5SDimitry Andric [(set f128:$vT, (fsqrt f128:$vB))]>; 2525*0b57cec5SDimitry Andric // (Negative) Multiply-{Add/Subtract} 2526*0b57cec5SDimitry Andric def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp", 2527*0b57cec5SDimitry Andric [(set f128:$vT, 2528*0b57cec5SDimitry Andric (fma f128:$vA, f128:$vB, 2529*0b57cec5SDimitry Andric f128:$vTi))]>; 2530*0b57cec5SDimitry Andric def XSMSUBQP : X_VT5_VA5_VB5_FMA <63, 420, "xsmsubqp" , 2531*0b57cec5SDimitry Andric [(set f128:$vT, 2532*0b57cec5SDimitry Andric (fma f128:$vA, f128:$vB, 2533*0b57cec5SDimitry Andric (fneg f128:$vTi)))]>; 2534*0b57cec5SDimitry Andric def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp", 2535*0b57cec5SDimitry Andric [(set f128:$vT, 2536*0b57cec5SDimitry Andric (fneg (fma f128:$vA, f128:$vB, 2537*0b57cec5SDimitry Andric f128:$vTi)))]>; 2538*0b57cec5SDimitry Andric def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp", 2539*0b57cec5SDimitry Andric [(set f128:$vT, 2540*0b57cec5SDimitry Andric (fneg (fma f128:$vA, f128:$vB, 2541*0b57cec5SDimitry Andric (fneg f128:$vTi))))]>; 2542*0b57cec5SDimitry Andric 2543*0b57cec5SDimitry Andric let isCommutable = 1 in { 2544*0b57cec5SDimitry Andric def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo", 2545*0b57cec5SDimitry Andric [(set f128:$vT, 2546*0b57cec5SDimitry Andric (int_ppc_addf128_round_to_odd 2547*0b57cec5SDimitry Andric f128:$vA, f128:$vB))]>; 2548*0b57cec5SDimitry Andric def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo", 2549*0b57cec5SDimitry Andric [(set f128:$vT, 2550*0b57cec5SDimitry Andric (int_ppc_mulf128_round_to_odd 2551*0b57cec5SDimitry Andric f128:$vA, f128:$vB))]>; 2552*0b57cec5SDimitry Andric } 2553*0b57cec5SDimitry Andric def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", 2554*0b57cec5SDimitry Andric [(set f128:$vT, 2555*0b57cec5SDimitry Andric (int_ppc_subf128_round_to_odd 2556*0b57cec5SDimitry Andric f128:$vA, f128:$vB))]>; 2557*0b57cec5SDimitry Andric def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", 2558*0b57cec5SDimitry Andric [(set f128:$vT, 2559*0b57cec5SDimitry Andric (int_ppc_divf128_round_to_odd 2560*0b57cec5SDimitry Andric f128:$vA, f128:$vB))]>; 2561*0b57cec5SDimitry Andric def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", 2562*0b57cec5SDimitry Andric [(set f128:$vT, 2563*0b57cec5SDimitry Andric (int_ppc_sqrtf128_round_to_odd f128:$vB))]>; 2564*0b57cec5SDimitry Andric 2565*0b57cec5SDimitry Andric 2566*0b57cec5SDimitry Andric def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo", 2567*0b57cec5SDimitry Andric [(set f128:$vT, 2568*0b57cec5SDimitry Andric (int_ppc_fmaf128_round_to_odd 2569*0b57cec5SDimitry Andric f128:$vA,f128:$vB,f128:$vTi))]>; 2570*0b57cec5SDimitry Andric 2571*0b57cec5SDimitry Andric def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" , 2572*0b57cec5SDimitry Andric [(set f128:$vT, 2573*0b57cec5SDimitry Andric (int_ppc_fmaf128_round_to_odd 2574*0b57cec5SDimitry Andric f128:$vA, f128:$vB, (fneg f128:$vTi)))]>; 2575*0b57cec5SDimitry Andric def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo", 2576*0b57cec5SDimitry Andric [(set f128:$vT, 2577*0b57cec5SDimitry Andric (fneg (int_ppc_fmaf128_round_to_odd 2578*0b57cec5SDimitry Andric f128:$vA, f128:$vB, f128:$vTi)))]>; 2579*0b57cec5SDimitry Andric def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo", 2580*0b57cec5SDimitry Andric [(set f128:$vT, 2581*0b57cec5SDimitry Andric (fneg (int_ppc_fmaf128_round_to_odd 2582*0b57cec5SDimitry Andric f128:$vA, f128:$vB, (fneg f128:$vTi))))]>; 2583*0b57cec5SDimitry Andric 2584*0b57cec5SDimitry Andric // Additional fnmsub patterns: -a*c + b == -(a*c - b) 2585*0b57cec5SDimitry Andric def : Pat<(fma (fneg f128:$A), f128:$C, f128:$B), (XSNMSUBQP $B, $C, $A)>; 2586*0b57cec5SDimitry Andric def : Pat<(fma f128:$A, (fneg f128:$C), f128:$B), (XSNMSUBQP $B, $C, $A)>; 2587*0b57cec5SDimitry Andric 2588*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2589*0b57cec5SDimitry Andric // Quad/Double-Precision Compare Instructions: 2590*0b57cec5SDimitry Andric 2591*0b57cec5SDimitry Andric // [PO BF // VRA VRB XO /] 2592*0b57cec5SDimitry Andric class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc, 2593*0b57cec5SDimitry Andric list<dag> pattern> 2594*0b57cec5SDimitry Andric : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB), 2595*0b57cec5SDimitry Andric !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> { 2596*0b57cec5SDimitry Andric let Pattern = pattern; 2597*0b57cec5SDimitry Andric } 2598*0b57cec5SDimitry Andric 2599*0b57cec5SDimitry Andric // QP Compare Ordered/Unordered 2600*0b57cec5SDimitry Andric def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>; 2601*0b57cec5SDimitry Andric def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>; 2602*0b57cec5SDimitry Andric 2603*0b57cec5SDimitry Andric // DP/QP Compare Exponents 2604*0b57cec5SDimitry Andric def XSCMPEXPDP : XX3Form_1<60, 59, 2605*0b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 2606*0b57cec5SDimitry Andric "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>; 2607*0b57cec5SDimitry Andric def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>; 2608*0b57cec5SDimitry Andric 2609*0b57cec5SDimitry Andric // DP Compare ==, >=, >, != 2610*0b57cec5SDimitry Andric // Use vsrc for XT, because the entire register of XT is set. 2611*0b57cec5SDimitry Andric // XT.dword[1] = 0x0000_0000_0000_0000 2612*0b57cec5SDimitry Andric def XSCMPEQDP : XX3_XT5_XA5_XB5<60, 3, "xscmpeqdp", vsrc, vsfrc, vsfrc, 2613*0b57cec5SDimitry Andric IIC_FPCompare, []>; 2614*0b57cec5SDimitry Andric def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc, 2615*0b57cec5SDimitry Andric IIC_FPCompare, []>; 2616*0b57cec5SDimitry Andric def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc, 2617*0b57cec5SDimitry Andric IIC_FPCompare, []>; 2618*0b57cec5SDimitry Andric 2619*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2620*0b57cec5SDimitry Andric // Quad-Precision Floating-Point Conversion Instructions: 2621*0b57cec5SDimitry Andric 2622*0b57cec5SDimitry Andric // Convert DP -> QP 2623*0b57cec5SDimitry Andric def XSCVDPQP : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, 2624*0b57cec5SDimitry Andric [(set f128:$vT, (fpextend f64:$vB))]>; 2625*0b57cec5SDimitry Andric 2626*0b57cec5SDimitry Andric // Round & Convert QP -> DP (dword[1] is set to zero) 2627*0b57cec5SDimitry Andric def XSCVQPDP : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>; 2628*0b57cec5SDimitry Andric def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo", 2629*0b57cec5SDimitry Andric [(set f64:$vT, 2630*0b57cec5SDimitry Andric (int_ppc_truncf128_round_to_odd 2631*0b57cec5SDimitry Andric f128:$vB))]>; 2632*0b57cec5SDimitry Andric 2633*0b57cec5SDimitry Andric // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero) 2634*0b57cec5SDimitry Andric def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>; 2635*0b57cec5SDimitry Andric def XSCVQPSWZ : X_VT5_XO5_VB5<63, 9, 836, "xscvqpswz", []>; 2636*0b57cec5SDimitry Andric def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>; 2637*0b57cec5SDimitry Andric def XSCVQPUWZ : X_VT5_XO5_VB5<63, 1, 836, "xscvqpuwz", []>; 2638*0b57cec5SDimitry Andric 2639*0b57cec5SDimitry Andric // Convert (Un)Signed DWord -> QP. 2640*0b57cec5SDimitry Andric def XSCVSDQP : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>; 2641*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp i64:$src)), 2642*0b57cec5SDimitry Andric (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 2643*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))), 2644*0b57cec5SDimitry Andric (f128 (XSCVSDQP $src))>; 2645*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))), 2646*0b57cec5SDimitry Andric (f128 (XSCVSDQP (VEXTSW2Ds $src)))>; 2647*0b57cec5SDimitry Andric 2648*0b57cec5SDimitry Andric def XSCVUDQP : X_VT5_XO5_VB5_TyVB<63, 2, 836, "xscvudqp", vfrc, []>; 2649*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp i64:$src)), 2650*0b57cec5SDimitry Andric (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 2651*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))), 2652*0b57cec5SDimitry Andric (f128 (XSCVUDQP $src))>; 2653*0b57cec5SDimitry Andric 2654*0b57cec5SDimitry Andric // Convert (Un)Signed Word -> QP. 2655*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp i32:$src)), 2656*0b57cec5SDimitry Andric (f128 (XSCVSDQP (MTVSRWA $src)))>; 2657*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))), 2658*0b57cec5SDimitry Andric (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>; 2659*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp i32:$src)), 2660*0b57cec5SDimitry Andric (f128 (XSCVUDQP (MTVSRWZ $src)))>; 2661*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))), 2662*0b57cec5SDimitry Andric (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>; 2663*0b57cec5SDimitry Andric 2664*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2665*0b57cec5SDimitry Andric // Round to Floating-Point Integer Instructions 2666*0b57cec5SDimitry Andric 2667*0b57cec5SDimitry Andric // (Round &) Convert DP <-> HP 2668*0b57cec5SDimitry Andric // Note! xscvdphp's src and dest register both use the left 64 bits, so we use 2669*0b57cec5SDimitry Andric // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits, 2670*0b57cec5SDimitry Andric // but we still use vsfrc for it. 2671*0b57cec5SDimitry Andric def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>; 2672*0b57cec5SDimitry Andric def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>; 2673*0b57cec5SDimitry Andric 2674*0b57cec5SDimitry Andric // Vector HP -> SP 2675*0b57cec5SDimitry Andric def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>; 2676*0b57cec5SDimitry Andric def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc, 2677*0b57cec5SDimitry Andric [(set v4f32:$XT, 2678*0b57cec5SDimitry Andric (int_ppc_vsx_xvcvsphp v4f32:$XB))]>; 2679*0b57cec5SDimitry Andric 2680*0b57cec5SDimitry Andric // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a 2681*0b57cec5SDimitry Andric // separate pattern so that it can convert the input register class from 2682*0b57cec5SDimitry Andric // VRRC(v8i16) to VSRC. 2683*0b57cec5SDimitry Andric def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)), 2684*0b57cec5SDimitry Andric (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>; 2685*0b57cec5SDimitry Andric 2686*0b57cec5SDimitry Andric class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc, 2687*0b57cec5SDimitry Andric list<dag> pattern> 2688*0b57cec5SDimitry Andric : Z23Form_8<opcode, xo, 2689*0b57cec5SDimitry Andric (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc), 2690*0b57cec5SDimitry Andric !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> { 2691*0b57cec5SDimitry Andric let RC = ex; 2692*0b57cec5SDimitry Andric } 2693*0b57cec5SDimitry Andric 2694*0b57cec5SDimitry Andric // Round to Quad-Precision Integer [with Inexact] 2695*0b57cec5SDimitry Andric def XSRQPI : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 0, "xsrqpi" , []>; 2696*0b57cec5SDimitry Andric def XSRQPIX : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 1, "xsrqpix", []>; 2697*0b57cec5SDimitry Andric 2698*0b57cec5SDimitry Andric // Use current rounding mode 2699*0b57cec5SDimitry Andric def : Pat<(f128 (fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>; 2700*0b57cec5SDimitry Andric // Round to nearest, ties away from zero 2701*0b57cec5SDimitry Andric def : Pat<(f128 (fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>; 2702*0b57cec5SDimitry Andric // Round towards Zero 2703*0b57cec5SDimitry Andric def : Pat<(f128 (ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>; 2704*0b57cec5SDimitry Andric // Round towards +Inf 2705*0b57cec5SDimitry Andric def : Pat<(f128 (fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>; 2706*0b57cec5SDimitry Andric // Round towards -Inf 2707*0b57cec5SDimitry Andric def : Pat<(f128 (ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>; 2708*0b57cec5SDimitry Andric 2709*0b57cec5SDimitry Andric // Use current rounding mode, [with Inexact] 2710*0b57cec5SDimitry Andric def : Pat<(f128 (frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>; 2711*0b57cec5SDimitry Andric 2712*0b57cec5SDimitry Andric // Round Quad-Precision to Double-Extended Precision (fp80) 2713*0b57cec5SDimitry Andric def XSRQPXP : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>; 2714*0b57cec5SDimitry Andric 2715*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2716*0b57cec5SDimitry Andric // Insert/Extract Instructions 2717*0b57cec5SDimitry Andric 2718*0b57cec5SDimitry Andric // Insert Exponent DP/QP 2719*0b57cec5SDimitry Andric // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU 2720*0b57cec5SDimitry Andric def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB), 2721*0b57cec5SDimitry Andric "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>; 2722*0b57cec5SDimitry Andric // vB NOTE: only vB.dword[0] is used, that's why we don't use 2723*0b57cec5SDimitry Andric // X_VT5_VA5_VB5 form 2724*0b57cec5SDimitry Andric def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB), 2725*0b57cec5SDimitry Andric "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>; 2726*0b57cec5SDimitry Andric 2727*0b57cec5SDimitry Andric def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)), 2728*0b57cec5SDimitry Andric (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>; 2729*0b57cec5SDimitry Andric 2730*0b57cec5SDimitry Andric // Extract Exponent/Significand DP/QP 2731*0b57cec5SDimitry Andric def XSXEXPDP : XX2_RT5_XO5_XB6<60, 0, 347, "xsxexpdp", []>; 2732*0b57cec5SDimitry Andric def XSXSIGDP : XX2_RT5_XO5_XB6<60, 1, 347, "xsxsigdp", []>; 2733*0b57cec5SDimitry Andric 2734*0b57cec5SDimitry Andric def XSXEXPQP : X_VT5_XO5_VB5 <63, 2, 804, "xsxexpqp", []>; 2735*0b57cec5SDimitry Andric def XSXSIGQP : X_VT5_XO5_VB5 <63, 18, 804, "xsxsigqp", []>; 2736*0b57cec5SDimitry Andric 2737*0b57cec5SDimitry Andric def : Pat<(i64 (int_ppc_scalar_extract_expq f128:$vA)), 2738*0b57cec5SDimitry Andric (i64 (MFVSRD (EXTRACT_SUBREG 2739*0b57cec5SDimitry Andric (v2i64 (XSXEXPQP $vA)), sub_64)))>; 2740*0b57cec5SDimitry Andric 2741*0b57cec5SDimitry Andric // Vector Insert Word 2742*0b57cec5SDimitry Andric // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB. 2743*0b57cec5SDimitry Andric def XXINSERTW : 2744*0b57cec5SDimitry Andric XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT), 2745*0b57cec5SDimitry Andric (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM), 2746*0b57cec5SDimitry Andric "xxinsertw $XT, $XB, $UIM", IIC_VecFP, 2747*0b57cec5SDimitry Andric [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB, 2748*0b57cec5SDimitry Andric imm32SExt16:$UIM))]>, 2749*0b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">; 2750*0b57cec5SDimitry Andric 2751*0b57cec5SDimitry Andric // Vector Extract Unsigned Word 2752*0b57cec5SDimitry Andric def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165, 2753*0b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM), 2754*0b57cec5SDimitry Andric "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>; 2755*0b57cec5SDimitry Andric 2756*0b57cec5SDimitry Andric // Vector Insert Exponent DP/SP 2757*0b57cec5SDimitry Andric def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc, 2758*0b57cec5SDimitry Andric IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>; 2759*0b57cec5SDimitry Andric def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc, 2760*0b57cec5SDimitry Andric IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>; 2761*0b57cec5SDimitry Andric 2762*0b57cec5SDimitry Andric // Vector Extract Exponent/Significand DP/SP 2763*0b57cec5SDimitry Andric def XVXEXPDP : XX2_XT6_XO5_XB6<60, 0, 475, "xvxexpdp", vsrc, 2764*0b57cec5SDimitry Andric [(set v2i64: $XT, 2765*0b57cec5SDimitry Andric (int_ppc_vsx_xvxexpdp v2f64:$XB))]>; 2766*0b57cec5SDimitry Andric def XVXEXPSP : XX2_XT6_XO5_XB6<60, 8, 475, "xvxexpsp", vsrc, 2767*0b57cec5SDimitry Andric [(set v4i32: $XT, 2768*0b57cec5SDimitry Andric (int_ppc_vsx_xvxexpsp v4f32:$XB))]>; 2769*0b57cec5SDimitry Andric def XVXSIGDP : XX2_XT6_XO5_XB6<60, 1, 475, "xvxsigdp", vsrc, 2770*0b57cec5SDimitry Andric [(set v2i64: $XT, 2771*0b57cec5SDimitry Andric (int_ppc_vsx_xvxsigdp v2f64:$XB))]>; 2772*0b57cec5SDimitry Andric def XVXSIGSP : XX2_XT6_XO5_XB6<60, 9, 475, "xvxsigsp", vsrc, 2773*0b57cec5SDimitry Andric [(set v4i32: $XT, 2774*0b57cec5SDimitry Andric (int_ppc_vsx_xvxsigsp v4f32:$XB))]>; 2775*0b57cec5SDimitry Andric 2776*0b57cec5SDimitry Andric let AddedComplexity = 400, Predicates = [HasP9Vector] in { 2777*0b57cec5SDimitry Andric // Extra patterns expanding to vector Extract Word/Insert Word 2778*0b57cec5SDimitry Andric def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)), 2779*0b57cec5SDimitry Andric (v4i32 (XXINSERTW $A, $B, imm:$IMM))>; 2780*0b57cec5SDimitry Andric def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)), 2781*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>; 2782*0b57cec5SDimitry Andric } // AddedComplexity = 400, HasP9Vector 2783*0b57cec5SDimitry Andric 2784*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2785*0b57cec5SDimitry Andric 2786*0b57cec5SDimitry Andric // Test Data Class SP/DP/QP 2787*0b57cec5SDimitry Andric def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298, 2788*0b57cec5SDimitry Andric (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), 2789*0b57cec5SDimitry Andric "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>; 2790*0b57cec5SDimitry Andric def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362, 2791*0b57cec5SDimitry Andric (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), 2792*0b57cec5SDimitry Andric "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>; 2793*0b57cec5SDimitry Andric def XSTSTDCQP : X_BF3_DCMX7_RS5 <63, 708, 2794*0b57cec5SDimitry Andric (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB), 2795*0b57cec5SDimitry Andric "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>; 2796*0b57cec5SDimitry Andric 2797*0b57cec5SDimitry Andric // Vector Test Data Class SP/DP 2798*0b57cec5SDimitry Andric def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5, 2799*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB), 2800*0b57cec5SDimitry Andric "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP, 2801*0b57cec5SDimitry Andric [(set v4i32: $XT, 2802*0b57cec5SDimitry Andric (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>; 2803*0b57cec5SDimitry Andric def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5, 2804*0b57cec5SDimitry Andric (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB), 2805*0b57cec5SDimitry Andric "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP, 2806*0b57cec5SDimitry Andric [(set v2i64: $XT, 2807*0b57cec5SDimitry Andric (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>; 2808*0b57cec5SDimitry Andric 2809*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2810*0b57cec5SDimitry Andric 2811*0b57cec5SDimitry Andric // Maximum/Minimum Type-C/Type-J DP 2812*0b57cec5SDimitry Andric // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT 2813*0b57cec5SDimitry Andric def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc, 2814*0b57cec5SDimitry Andric IIC_VecFP, []>; 2815*0b57cec5SDimitry Andric def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc, 2816*0b57cec5SDimitry Andric IIC_VecFP, []>; 2817*0b57cec5SDimitry Andric def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc, 2818*0b57cec5SDimitry Andric IIC_VecFP, []>; 2819*0b57cec5SDimitry Andric def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc, 2820*0b57cec5SDimitry Andric IIC_VecFP, []>; 2821*0b57cec5SDimitry Andric 2822*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2823*0b57cec5SDimitry Andric 2824*0b57cec5SDimitry Andric // Vector Byte-Reverse H/W/D/Q Word 2825*0b57cec5SDimitry Andric def XXBRH : XX2_XT6_XO5_XB6<60, 7, 475, "xxbrh", vsrc, []>; 2826*0b57cec5SDimitry Andric def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>; 2827*0b57cec5SDimitry Andric def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>; 2828*0b57cec5SDimitry Andric def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>; 2829*0b57cec5SDimitry Andric 2830*0b57cec5SDimitry Andric // Vector Reverse 2831*0b57cec5SDimitry Andric def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)), 2832*0b57cec5SDimitry Andric (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>; 2833*0b57cec5SDimitry Andric def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)), 2834*0b57cec5SDimitry Andric (v4i32 (XXBRW $A))>; 2835*0b57cec5SDimitry Andric def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)), 2836*0b57cec5SDimitry Andric (v2i64 (XXBRD $A))>; 2837*0b57cec5SDimitry Andric def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)), 2838*0b57cec5SDimitry Andric (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>; 2839*0b57cec5SDimitry Andric 2840*0b57cec5SDimitry Andric // Vector Permute 2841*0b57cec5SDimitry Andric def XXPERM : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc, 2842*0b57cec5SDimitry Andric IIC_VecPerm, []>; 2843*0b57cec5SDimitry Andric def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc, 2844*0b57cec5SDimitry Andric IIC_VecPerm, []>; 2845*0b57cec5SDimitry Andric 2846*0b57cec5SDimitry Andric // Vector Splat Immediate Byte 2847*0b57cec5SDimitry Andric def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8), 2848*0b57cec5SDimitry Andric "xxspltib $XT, $IMM8", IIC_VecPerm, []>; 2849*0b57cec5SDimitry Andric 2850*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 2851*0b57cec5SDimitry Andric // Vector/Scalar Load/Store Instructions 2852*0b57cec5SDimitry Andric 2853*0b57cec5SDimitry Andric // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in 2854*0b57cec5SDimitry Andric // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging. 2855*0b57cec5SDimitry Andric let mayLoad = 1, mayStore = 0 in { 2856*0b57cec5SDimitry Andric // Load Vector 2857*0b57cec5SDimitry Andric def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src), 2858*0b57cec5SDimitry Andric "lxv $XT, $src", IIC_LdStLFD, []>; 2859*0b57cec5SDimitry Andric // Load DWord 2860*0b57cec5SDimitry Andric def LXSD : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src), 2861*0b57cec5SDimitry Andric "lxsd $vD, $src", IIC_LdStLFD, []>; 2862*0b57cec5SDimitry Andric // Load SP from src, convert it to DP, and place in dword[0] 2863*0b57cec5SDimitry Andric def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src), 2864*0b57cec5SDimitry Andric "lxssp $vD, $src", IIC_LdStLFD, []>; 2865*0b57cec5SDimitry Andric 2866*0b57cec5SDimitry Andric // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different 2867*0b57cec5SDimitry Andric // "out" and "in" dag 2868*0b57cec5SDimitry Andric class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, 2869*0b57cec5SDimitry Andric RegisterOperand vtype, list<dag> pattern> 2870*0b57cec5SDimitry Andric : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src), 2871*0b57cec5SDimitry Andric !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>; 2872*0b57cec5SDimitry Andric 2873*0b57cec5SDimitry Andric // Load as Integer Byte/Halfword & Zero Indexed 2874*0b57cec5SDimitry Andric def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc, 2875*0b57cec5SDimitry Andric [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>; 2876*0b57cec5SDimitry Andric def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc, 2877*0b57cec5SDimitry Andric [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>; 2878*0b57cec5SDimitry Andric 2879*0b57cec5SDimitry Andric // Load Vector Halfword*8/Byte*16 Indexed 2880*0b57cec5SDimitry Andric def LXVH8X : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>; 2881*0b57cec5SDimitry Andric def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>; 2882*0b57cec5SDimitry Andric 2883*0b57cec5SDimitry Andric // Load Vector Indexed 2884*0b57cec5SDimitry Andric def LXVX : X_XT6_RA5_RB5<31, 268, "lxvx" , vsrc, 2885*0b57cec5SDimitry Andric [(set v2f64:$XT, (load xaddrX16:$src))]>; 2886*0b57cec5SDimitry Andric // Load Vector (Left-justified) with Length 2887*0b57cec5SDimitry Andric def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), 2888*0b57cec5SDimitry Andric "lxvl $XT, $src, $rB", IIC_LdStLoad, 2889*0b57cec5SDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>; 2890*0b57cec5SDimitry Andric def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), 2891*0b57cec5SDimitry Andric "lxvll $XT, $src, $rB", IIC_LdStLoad, 2892*0b57cec5SDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>; 2893*0b57cec5SDimitry Andric 2894*0b57cec5SDimitry Andric // Load Vector Word & Splat Indexed 2895*0b57cec5SDimitry Andric def LXVWSX : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>; 2896*0b57cec5SDimitry Andric } // mayLoad 2897*0b57cec5SDimitry Andric 2898*0b57cec5SDimitry Andric // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in 2899*0b57cec5SDimitry Andric // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging. 2900*0b57cec5SDimitry Andric let mayStore = 1, mayLoad = 0 in { 2901*0b57cec5SDimitry Andric // Store Vector 2902*0b57cec5SDimitry Andric def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst), 2903*0b57cec5SDimitry Andric "stxv $XT, $dst", IIC_LdStSTFD, []>; 2904*0b57cec5SDimitry Andric // Store DWord 2905*0b57cec5SDimitry Andric def STXSD : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst), 2906*0b57cec5SDimitry Andric "stxsd $vS, $dst", IIC_LdStSTFD, []>; 2907*0b57cec5SDimitry Andric // Convert DP of dword[0] to SP, and Store to dst 2908*0b57cec5SDimitry Andric def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst), 2909*0b57cec5SDimitry Andric "stxssp $vS, $dst", IIC_LdStSTFD, []>; 2910*0b57cec5SDimitry Andric 2911*0b57cec5SDimitry Andric // [PO S RA RB XO SX] 2912*0b57cec5SDimitry Andric class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, 2913*0b57cec5SDimitry Andric RegisterOperand vtype, list<dag> pattern> 2914*0b57cec5SDimitry Andric : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst), 2915*0b57cec5SDimitry Andric !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>; 2916*0b57cec5SDimitry Andric 2917*0b57cec5SDimitry Andric // Store as Integer Byte/Halfword Indexed 2918*0b57cec5SDimitry Andric def STXSIBX : X_XS6_RA5_RB5<31, 909, "stxsibx" , vsfrc, 2919*0b57cec5SDimitry Andric [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>; 2920*0b57cec5SDimitry Andric def STXSIHX : X_XS6_RA5_RB5<31, 941, "stxsihx" , vsfrc, 2921*0b57cec5SDimitry Andric [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>; 2922*0b57cec5SDimitry Andric let isCodeGenOnly = 1 in { 2923*0b57cec5SDimitry Andric def STXSIBXv : X_XS6_RA5_RB5<31, 909, "stxsibx" , vsrc, []>; 2924*0b57cec5SDimitry Andric def STXSIHXv : X_XS6_RA5_RB5<31, 941, "stxsihx" , vsrc, []>; 2925*0b57cec5SDimitry Andric } 2926*0b57cec5SDimitry Andric 2927*0b57cec5SDimitry Andric // Store Vector Halfword*8/Byte*16 Indexed 2928*0b57cec5SDimitry Andric def STXVH8X : X_XS6_RA5_RB5<31, 940, "stxvh8x" , vsrc, []>; 2929*0b57cec5SDimitry Andric def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>; 2930*0b57cec5SDimitry Andric 2931*0b57cec5SDimitry Andric // Store Vector Indexed 2932*0b57cec5SDimitry Andric def STXVX : X_XS6_RA5_RB5<31, 396, "stxvx" , vsrc, 2933*0b57cec5SDimitry Andric [(store v2f64:$XT, xaddrX16:$dst)]>; 2934*0b57cec5SDimitry Andric 2935*0b57cec5SDimitry Andric // Store Vector (Left-justified) with Length 2936*0b57cec5SDimitry Andric def STXVL : XX1Form_memOp<31, 397, (outs), 2937*0b57cec5SDimitry Andric (ins vsrc:$XT, memr:$dst, g8rc:$rB), 2938*0b57cec5SDimitry Andric "stxvl $XT, $dst, $rB", IIC_LdStLoad, 2939*0b57cec5SDimitry Andric [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, 2940*0b57cec5SDimitry Andric i64:$rB)]>; 2941*0b57cec5SDimitry Andric def STXVLL : XX1Form_memOp<31, 429, (outs), 2942*0b57cec5SDimitry Andric (ins vsrc:$XT, memr:$dst, g8rc:$rB), 2943*0b57cec5SDimitry Andric "stxvll $XT, $dst, $rB", IIC_LdStLoad, 2944*0b57cec5SDimitry Andric [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, 2945*0b57cec5SDimitry Andric i64:$rB)]>; 2946*0b57cec5SDimitry Andric } // mayStore 2947*0b57cec5SDimitry Andric 2948*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian] in { 2949*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 2950*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>; 2951*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 2952*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>; 2953*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 2954*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>; 2955*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 2956*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>; 2957*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 2958*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>; 2959*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 2960*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>; 2961*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 2962*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>; 2963*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 2964*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>; 2965*0b57cec5SDimitry Andric } 2966*0b57cec5SDimitry Andric 2967*0b57cec5SDimitry Andric let Predicates = [IsBigEndian] in { 2968*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 2969*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>; 2970*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 2971*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>; 2972*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 2973*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>; 2974*0b57cec5SDimitry Andric def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 2975*0b57cec5SDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>; 2976*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 2977*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>; 2978*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 2979*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>; 2980*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 2981*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>; 2982*0b57cec5SDimitry Andric def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 2983*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>; 2984*0b57cec5SDimitry Andric } 2985*0b57cec5SDimitry Andric 2986*0b57cec5SDimitry Andric // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead 2987*0b57cec5SDimitry Andric // of f64 2988*0b57cec5SDimitry Andric def : Pat<(v8i16 (PPCmtvsrz i32:$A)), 2989*0b57cec5SDimitry Andric (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>; 2990*0b57cec5SDimitry Andric def : Pat<(v16i8 (PPCmtvsrz i32:$A)), 2991*0b57cec5SDimitry Andric (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>; 2992*0b57cec5SDimitry Andric 2993*0b57cec5SDimitry Andric // Patterns for which instructions from ISA 3.0 are a better match 2994*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasP9Vector] in { 2995*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 2996*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>; 2997*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 2998*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>; 2999*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 3000*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>; 3001*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 3002*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>; 3003*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 3004*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>; 3005*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 3006*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>; 3007*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 3008*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>; 3009*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 3010*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>; 3011*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)), 3012*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>; 3013*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)), 3014*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>; 3015*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)), 3016*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>; 3017*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)), 3018*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>; 3019*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)), 3020*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>; 3021*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)), 3022*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>; 3023*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)), 3024*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>; 3025*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)), 3026*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>; 3027*0b57cec5SDimitry Andric } // IsLittleEndian, HasP9Vector 3028*0b57cec5SDimitry Andric 3029*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasP9Vector] in { 3030*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 3031*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>; 3032*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 3033*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>; 3034*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 3035*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>; 3036*0b57cec5SDimitry Andric def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 3037*0b57cec5SDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>; 3038*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 3039*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>; 3040*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 3041*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>; 3042*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 3043*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>; 3044*0b57cec5SDimitry Andric def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 3045*0b57cec5SDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>; 3046*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)), 3047*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>; 3048*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)), 3049*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>; 3050*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)), 3051*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>; 3052*0b57cec5SDimitry Andric def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)), 3053*0b57cec5SDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>; 3054*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)), 3055*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>; 3056*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)), 3057*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>; 3058*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)), 3059*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>; 3060*0b57cec5SDimitry Andric def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)), 3061*0b57cec5SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>; 3062*0b57cec5SDimitry Andric } // IsLittleEndian, HasP9Vector 3063*0b57cec5SDimitry Andric 3064*0b57cec5SDimitry Andric // D-Form Load/Store 3065*0b57cec5SDimitry Andric def : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>; 3066*0b57cec5SDimitry Andric def : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>; 3067*0b57cec5SDimitry Andric def : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>; 3068*0b57cec5SDimitry Andric def : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>; 3069*0b57cec5SDimitry Andric def : Pat<(f128 (quadwOffsetLoad iaddrX16:$src)), 3070*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>; 3071*0b57cec5SDimitry Andric def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>; 3072*0b57cec5SDimitry Andric def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>; 3073*0b57cec5SDimitry Andric 3074*0b57cec5SDimitry Andric def : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>; 3075*0b57cec5SDimitry Andric def : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>; 3076*0b57cec5SDimitry Andric def : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>; 3077*0b57cec5SDimitry Andric def : Pat<(quadwOffsetStore f128:$rS, iaddrX16:$dst), 3078*0b57cec5SDimitry Andric (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>; 3079*0b57cec5SDimitry Andric def : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>; 3080*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst), 3081*0b57cec5SDimitry Andric (STXV $rS, memrix16:$dst)>; 3082*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst), 3083*0b57cec5SDimitry Andric (STXV $rS, memrix16:$dst)>; 3084*0b57cec5SDimitry Andric 3085*0b57cec5SDimitry Andric 3086*0b57cec5SDimitry Andric def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 3087*0b57cec5SDimitry Andric def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 3088*0b57cec5SDimitry Andric def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 3089*0b57cec5SDimitry Andric def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>; 3090*0b57cec5SDimitry Andric def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>; 3091*0b57cec5SDimitry Andric def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>; 3092*0b57cec5SDimitry Andric def : Pat<(f128 (nonQuadwOffsetLoad xoaddr:$src)), 3093*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>; 3094*0b57cec5SDimitry Andric def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst), 3095*0b57cec5SDimitry Andric (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>; 3096*0b57cec5SDimitry Andric def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst), 3097*0b57cec5SDimitry Andric (STXVX $rS, xoaddr:$dst)>; 3098*0b57cec5SDimitry Andric def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst), 3099*0b57cec5SDimitry Andric (STXVX $rS, xoaddr:$dst)>; 3100*0b57cec5SDimitry Andric def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst), 3101*0b57cec5SDimitry Andric (STXVX $rS, xoaddr:$dst)>; 3102*0b57cec5SDimitry Andric def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst), 3103*0b57cec5SDimitry Andric (STXVX $rS, xoaddr:$dst)>; 3104*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst), 3105*0b57cec5SDimitry Andric (STXVX $rS, xoaddr:$dst)>; 3106*0b57cec5SDimitry Andric def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst), 3107*0b57cec5SDimitry Andric (STXVX $rS, xoaddr:$dst)>; 3108*0b57cec5SDimitry Andric 3109*0b57cec5SDimitry Andric let AddedComplexity = 400 in { 3110*0b57cec5SDimitry Andric // LIWAX - This instruction is used for sign extending i32 -> i64. 3111*0b57cec5SDimitry Andric // LIWZX - This instruction will be emitted for i32, f32, and when 3112*0b57cec5SDimitry Andric // zero-extending i32 to i64 (zext i32 -> i64). 3113*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian] in { 3114*0b57cec5SDimitry Andric 3115*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))), 3116*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs 3117*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC), 2))>; 3118*0b57cec5SDimitry Andric 3119*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))), 3120*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs 3121*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>; 3122*0b57cec5SDimitry Andric 3123*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))), 3124*0b57cec5SDimitry Andric (v4i32 (XXPERMDIs 3125*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>; 3126*0b57cec5SDimitry Andric 3127*0b57cec5SDimitry Andric def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))), 3128*0b57cec5SDimitry Andric (v4f32 (XXPERMDIs 3129*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>; 3130*0b57cec5SDimitry Andric } 3131*0b57cec5SDimitry Andric 3132*0b57cec5SDimitry Andric let Predicates = [IsBigEndian] in { 3133*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))), 3134*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>; 3135*0b57cec5SDimitry Andric 3136*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))), 3137*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>; 3138*0b57cec5SDimitry Andric 3139*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))), 3140*0b57cec5SDimitry Andric (v4i32 (XXSLDWIs 3141*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>; 3142*0b57cec5SDimitry Andric 3143*0b57cec5SDimitry Andric def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))), 3144*0b57cec5SDimitry Andric (v4f32 (XXSLDWIs 3145*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>; 3146*0b57cec5SDimitry Andric } 3147*0b57cec5SDimitry Andric 3148*0b57cec5SDimitry Andric } 3149*0b57cec5SDimitry Andric 3150*0b57cec5SDimitry Andric // Build vectors from i8 loads 3151*0b57cec5SDimitry Andric def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)), 3152*0b57cec5SDimitry Andric (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>; 3153*0b57cec5SDimitry Andric def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)), 3154*0b57cec5SDimitry Andric (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>; 3155*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)), 3156*0b57cec5SDimitry Andric (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>; 3157*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)), 3158*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>; 3159*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)), 3160*0b57cec5SDimitry Andric (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>; 3161*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)), 3162*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>; 3163*0b57cec5SDimitry Andric 3164*0b57cec5SDimitry Andric // Build vectors from i16 loads 3165*0b57cec5SDimitry Andric def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)), 3166*0b57cec5SDimitry Andric (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>; 3167*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)), 3168*0b57cec5SDimitry Andric (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>; 3169*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)), 3170*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>; 3171*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)), 3172*0b57cec5SDimitry Andric (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>; 3173*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)), 3174*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>; 3175*0b57cec5SDimitry Andric 3176*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasP9Vector] in { 3177*0b57cec5SDimitry Andric // Scalar stores of i8 3178*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst), 3179*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>; 3180*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst), 3181*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3182*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst), 3183*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>; 3184*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst), 3185*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3186*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst), 3187*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>; 3188*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst), 3189*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3190*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst), 3191*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>; 3192*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst), 3193*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3194*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst), 3195*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>; 3196*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst), 3197*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3198*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst), 3199*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>; 3200*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst), 3201*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3202*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst), 3203*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>; 3204*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst), 3205*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3206*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst), 3207*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>; 3208*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst), 3209*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3210*0b57cec5SDimitry Andric 3211*0b57cec5SDimitry Andric // Scalar stores of i16 3212*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst), 3213*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3214*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst), 3215*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3216*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst), 3217*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3218*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst), 3219*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3220*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst), 3221*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3222*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst), 3223*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3224*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst), 3225*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3226*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst), 3227*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3228*0b57cec5SDimitry Andric } // IsBigEndian, HasP9Vector 3229*0b57cec5SDimitry Andric 3230*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasP9Vector] in { 3231*0b57cec5SDimitry Andric // Scalar stores of i8 3232*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst), 3233*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3234*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst), 3235*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>; 3236*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst), 3237*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3238*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst), 3239*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>; 3240*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst), 3241*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3242*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst), 3243*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>; 3244*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst), 3245*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3246*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst), 3247*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>; 3248*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst), 3249*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3250*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst), 3251*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>; 3252*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst), 3253*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3254*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst), 3255*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>; 3256*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst), 3257*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3258*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst), 3259*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>; 3260*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst), 3261*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3262*0b57cec5SDimitry Andric def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst), 3263*0b57cec5SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>; 3264*0b57cec5SDimitry Andric 3265*0b57cec5SDimitry Andric // Scalar stores of i16 3266*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst), 3267*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>; 3268*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst), 3269*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>; 3270*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst), 3271*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>; 3272*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst), 3273*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>; 3274*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst), 3275*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>; 3276*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst), 3277*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>; 3278*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst), 3279*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>; 3280*0b57cec5SDimitry Andric def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst), 3281*0b57cec5SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>; 3282*0b57cec5SDimitry Andric } // IsLittleEndian, HasP9Vector 3283*0b57cec5SDimitry Andric 3284*0b57cec5SDimitry Andric 3285*0b57cec5SDimitry Andric // Vector sign extensions 3286*0b57cec5SDimitry Andric def : Pat<(f64 (PPCVexts f64:$A, 1)), 3287*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>; 3288*0b57cec5SDimitry Andric def : Pat<(f64 (PPCVexts f64:$A, 2)), 3289*0b57cec5SDimitry Andric (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>; 3290*0b57cec5SDimitry Andric 3291*0b57cec5SDimitry Andric def DFLOADf32 : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src), 3292*0b57cec5SDimitry Andric "#DFLOADf32", 3293*0b57cec5SDimitry Andric [(set f32:$XT, (load iaddrX4:$src))]>; 3294*0b57cec5SDimitry Andric def DFLOADf64 : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src), 3295*0b57cec5SDimitry Andric "#DFLOADf64", 3296*0b57cec5SDimitry Andric [(set f64:$XT, (load iaddrX4:$src))]>; 3297*0b57cec5SDimitry Andric def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst), 3298*0b57cec5SDimitry Andric "#DFSTOREf32", 3299*0b57cec5SDimitry Andric [(store f32:$XT, iaddrX4:$dst)]>; 3300*0b57cec5SDimitry Andric def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst), 3301*0b57cec5SDimitry Andric "#DFSTOREf64", 3302*0b57cec5SDimitry Andric [(store f64:$XT, iaddrX4:$dst)]>; 3303*0b57cec5SDimitry Andric 3304*0b57cec5SDimitry Andric def : Pat<(f64 (extloadf32 iaddrX4:$src)), 3305*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>; 3306*0b57cec5SDimitry Andric def : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))), 3307*0b57cec5SDimitry Andric (f32 (DFLOADf32 iaddrX4:$src))>; 3308*0b57cec5SDimitry Andric 3309*0b57cec5SDimitry Andric def : Pat<(v4f32 (PPCldvsxlh xaddr:$src)), 3310*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>; 3311*0b57cec5SDimitry Andric def : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)), 3312*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>; 3313*0b57cec5SDimitry Andric 3314*0b57cec5SDimitry Andric let AddedComplexity = 400 in { 3315*0b57cec5SDimitry Andric // The following pseudoinstructions are used to ensure the utilization 3316*0b57cec5SDimitry Andric // of all 64 VSX registers. 3317*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasP9Vector] in { 3318*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))), 3319*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs 3320*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>; 3321*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))), 3322*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs 3323*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>; 3324*0b57cec5SDimitry Andric 3325*0b57cec5SDimitry Andric def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))), 3326*0b57cec5SDimitry Andric (v2f64 (XXPERMDIs 3327*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>; 3328*0b57cec5SDimitry Andric def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))), 3329*0b57cec5SDimitry Andric (v2f64 (XXPERMDIs 3330*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>; 3331*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src), 3332*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3333*0b57cec5SDimitry Andric sub_64), xaddrX4:$src)>; 3334*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src), 3335*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3336*0b57cec5SDimitry Andric sub_64), xaddrX4:$src)>; 3337*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src), 3338*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3339*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src), 3340*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3341*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src), 3342*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3343*0b57cec5SDimitry Andric sub_64), iaddrX4:$src)>; 3344*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src), 3345*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3346*0b57cec5SDimitry Andric iaddrX4:$src)>; 3347*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src), 3348*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3349*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src), 3350*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3351*0b57cec5SDimitry Andric } // IsLittleEndian, HasP9Vector 3352*0b57cec5SDimitry Andric 3353*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasP9Vector] in { 3354*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))), 3355*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>; 3356*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))), 3357*0b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>; 3358*0b57cec5SDimitry Andric 3359*0b57cec5SDimitry Andric def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))), 3360*0b57cec5SDimitry Andric (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>; 3361*0b57cec5SDimitry Andric def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))), 3362*0b57cec5SDimitry Andric (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>; 3363*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src), 3364*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3365*0b57cec5SDimitry Andric sub_64), xaddrX4:$src)>; 3366*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src), 3367*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3368*0b57cec5SDimitry Andric sub_64), xaddrX4:$src)>; 3369*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src), 3370*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3371*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src), 3372*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>; 3373*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src), 3374*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3375*0b57cec5SDimitry Andric sub_64), iaddrX4:$src)>; 3376*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src), 3377*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 3378*0b57cec5SDimitry Andric sub_64), iaddrX4:$src)>; 3379*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src), 3380*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3381*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src), 3382*0b57cec5SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>; 3383*0b57cec5SDimitry Andric } // IsBigEndian, HasP9Vector 3384*0b57cec5SDimitry Andric } 3385*0b57cec5SDimitry Andric 3386*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasP9Vector] in { 3387*0b57cec5SDimitry Andric 3388*0b57cec5SDimitry Andric // (Un)Signed DWord vector extract -> QP 3389*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3390*0b57cec5SDimitry Andric (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3391*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3392*0b57cec5SDimitry Andric (f128 (XSCVSDQP 3393*0b57cec5SDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3394*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3395*0b57cec5SDimitry Andric (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3396*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3397*0b57cec5SDimitry Andric (f128 (XSCVUDQP 3398*0b57cec5SDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3399*0b57cec5SDimitry Andric 3400*0b57cec5SDimitry Andric // (Un)Signed Word vector extract -> QP 3401*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))), 3402*0b57cec5SDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>; 3403*0b57cec5SDimitry Andric foreach Idx = [0,2,3] in { 3404*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))), 3405*0b57cec5SDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 3406*0b57cec5SDimitry Andric (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>; 3407*0b57cec5SDimitry Andric } 3408*0b57cec5SDimitry Andric foreach Idx = 0-3 in { 3409*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))), 3410*0b57cec5SDimitry Andric (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>; 3411*0b57cec5SDimitry Andric } 3412*0b57cec5SDimitry Andric 3413*0b57cec5SDimitry Andric // (Un)Signed HWord vector extract -> QP 3414*0b57cec5SDimitry Andric foreach Idx = 0-7 in { 3415*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp 3416*0b57cec5SDimitry Andric (i32 (sext_inreg 3417*0b57cec5SDimitry Andric (vector_extract v8i16:$src, Idx), i16)))), 3418*0b57cec5SDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 3419*0b57cec5SDimitry Andric (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)), 3420*0b57cec5SDimitry Andric sub_64)))>; 3421*0b57cec5SDimitry Andric // The SDAG adds the `and` since an `i16` is being extracted as an `i32`. 3422*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp 3423*0b57cec5SDimitry Andric (and (i32 (vector_extract v8i16:$src, Idx)), 65535))), 3424*0b57cec5SDimitry Andric (f128 (XSCVUDQP (EXTRACT_SUBREG 3425*0b57cec5SDimitry Andric (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>; 3426*0b57cec5SDimitry Andric } 3427*0b57cec5SDimitry Andric 3428*0b57cec5SDimitry Andric // (Un)Signed Byte vector extract -> QP 3429*0b57cec5SDimitry Andric foreach Idx = 0-15 in { 3430*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp 3431*0b57cec5SDimitry Andric (i32 (sext_inreg (vector_extract v16i8:$src, Idx), 3432*0b57cec5SDimitry Andric i8)))), 3433*0b57cec5SDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 3434*0b57cec5SDimitry Andric (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>; 3435*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp 3436*0b57cec5SDimitry Andric (and (i32 (vector_extract v16i8:$src, Idx)), 255))), 3437*0b57cec5SDimitry Andric (f128 (XSCVUDQP 3438*0b57cec5SDimitry Andric (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>; 3439*0b57cec5SDimitry Andric } 3440*0b57cec5SDimitry Andric 3441*0b57cec5SDimitry Andric // Unsiged int in vsx register -> QP 3442*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), 3443*0b57cec5SDimitry Andric (f128 (XSCVUDQP 3444*0b57cec5SDimitry Andric (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>; 3445*0b57cec5SDimitry Andric } // IsBigEndian, HasP9Vector 3446*0b57cec5SDimitry Andric 3447*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasP9Vector] in { 3448*0b57cec5SDimitry Andric 3449*0b57cec5SDimitry Andric // (Un)Signed DWord vector extract -> QP 3450*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3451*0b57cec5SDimitry Andric (f128 (XSCVSDQP 3452*0b57cec5SDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3453*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3454*0b57cec5SDimitry Andric (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3455*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), 3456*0b57cec5SDimitry Andric (f128 (XSCVUDQP 3457*0b57cec5SDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 3458*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), 3459*0b57cec5SDimitry Andric (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3460*0b57cec5SDimitry Andric 3461*0b57cec5SDimitry Andric // (Un)Signed Word vector extract -> QP 3462*0b57cec5SDimitry Andric foreach Idx = [[0,3],[1,2],[3,0]] in { 3463*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))), 3464*0b57cec5SDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 3465*0b57cec5SDimitry Andric (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)), 3466*0b57cec5SDimitry Andric sub_64)))>; 3467*0b57cec5SDimitry Andric } 3468*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))), 3469*0b57cec5SDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>; 3470*0b57cec5SDimitry Andric 3471*0b57cec5SDimitry Andric foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in { 3472*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))), 3473*0b57cec5SDimitry Andric (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>; 3474*0b57cec5SDimitry Andric } 3475*0b57cec5SDimitry Andric 3476*0b57cec5SDimitry Andric // (Un)Signed HWord vector extract -> QP 3477*0b57cec5SDimitry Andric // The Nested foreach lists identifies the vector element and corresponding 3478*0b57cec5SDimitry Andric // register byte location. 3479*0b57cec5SDimitry Andric foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in { 3480*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp 3481*0b57cec5SDimitry Andric (i32 (sext_inreg 3482*0b57cec5SDimitry Andric (vector_extract v8i16:$src, !head(Idx)), i16)))), 3483*0b57cec5SDimitry Andric (f128 (XSCVSDQP 3484*0b57cec5SDimitry Andric (EXTRACT_SUBREG (VEXTSH2D 3485*0b57cec5SDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src)), 3486*0b57cec5SDimitry Andric sub_64)))>; 3487*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp 3488*0b57cec5SDimitry Andric (and (i32 (vector_extract v8i16:$src, !head(Idx))), 3489*0b57cec5SDimitry Andric 65535))), 3490*0b57cec5SDimitry Andric (f128 (XSCVUDQP (EXTRACT_SUBREG 3491*0b57cec5SDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>; 3492*0b57cec5SDimitry Andric } 3493*0b57cec5SDimitry Andric 3494*0b57cec5SDimitry Andric // (Un)Signed Byte vector extract -> QP 3495*0b57cec5SDimitry Andric foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7], 3496*0b57cec5SDimitry Andric [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in { 3497*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp 3498*0b57cec5SDimitry Andric (i32 (sext_inreg 3499*0b57cec5SDimitry Andric (vector_extract v16i8:$src, !head(Idx)), i8)))), 3500*0b57cec5SDimitry Andric (f128 (XSCVSDQP 3501*0b57cec5SDimitry Andric (EXTRACT_SUBREG 3502*0b57cec5SDimitry Andric (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)), 3503*0b57cec5SDimitry Andric sub_64)))>; 3504*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp 3505*0b57cec5SDimitry Andric (and (i32 (vector_extract v16i8:$src, !head(Idx))), 3506*0b57cec5SDimitry Andric 255))), 3507*0b57cec5SDimitry Andric (f128 (XSCVUDQP 3508*0b57cec5SDimitry Andric (EXTRACT_SUBREG 3509*0b57cec5SDimitry Andric (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>; 3510*0b57cec5SDimitry Andric } 3511*0b57cec5SDimitry Andric 3512*0b57cec5SDimitry Andric // Unsiged int in vsx register -> QP 3513*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), 3514*0b57cec5SDimitry Andric (f128 (XSCVUDQP 3515*0b57cec5SDimitry Andric (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>; 3516*0b57cec5SDimitry Andric } // IsLittleEndian, HasP9Vector 3517*0b57cec5SDimitry Andric 3518*0b57cec5SDimitry Andric // Convert (Un)Signed DWord in memory -> QP 3519*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))), 3520*0b57cec5SDimitry Andric (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>; 3521*0b57cec5SDimitry Andric def : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))), 3522*0b57cec5SDimitry Andric (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>; 3523*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))), 3524*0b57cec5SDimitry Andric (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>; 3525*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))), 3526*0b57cec5SDimitry Andric (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>; 3527*0b57cec5SDimitry Andric 3528*0b57cec5SDimitry Andric // Convert Unsigned HWord in memory -> QP 3529*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)), 3530*0b57cec5SDimitry Andric (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>; 3531*0b57cec5SDimitry Andric 3532*0b57cec5SDimitry Andric // Convert Unsigned Byte in memory -> QP 3533*0b57cec5SDimitry Andric def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)), 3534*0b57cec5SDimitry Andric (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>; 3535*0b57cec5SDimitry Andric 3536*0b57cec5SDimitry Andric // Truncate & Convert QP -> (Un)Signed (D)Word. 3537*0b57cec5SDimitry Andric def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>; 3538*0b57cec5SDimitry Andric def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>; 3539*0b57cec5SDimitry Andric def : Pat<(i32 (fp_to_sint f128:$src)), 3540*0b57cec5SDimitry Andric (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>; 3541*0b57cec5SDimitry Andric def : Pat<(i32 (fp_to_uint f128:$src)), 3542*0b57cec5SDimitry Andric (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>; 3543*0b57cec5SDimitry Andric 3544*0b57cec5SDimitry Andric // Instructions for store(fptosi). 3545*0b57cec5SDimitry Andric // The 8-byte version is repeated here due to availability of D-Form STXSD. 3546*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3547*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8), 3548*0b57cec5SDimitry Andric (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), 3549*0b57cec5SDimitry Andric xaddrX4:$dst)>; 3550*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3551*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8), 3552*0b57cec5SDimitry Andric (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), 3553*0b57cec5SDimitry Andric iaddrX4:$dst)>; 3554*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3555*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4), 3556*0b57cec5SDimitry Andric (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>; 3557*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3558*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2), 3559*0b57cec5SDimitry Andric (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>; 3560*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3561*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1), 3562*0b57cec5SDimitry Andric (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>; 3563*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3564*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8), 3565*0b57cec5SDimitry Andric (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>; 3566*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3567*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8), 3568*0b57cec5SDimitry Andric (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>; 3569*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3570*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2), 3571*0b57cec5SDimitry Andric (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>; 3572*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3573*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1), 3574*0b57cec5SDimitry Andric (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>; 3575*0b57cec5SDimitry Andric 3576*0b57cec5SDimitry Andric // Instructions for store(fptoui). 3577*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3578*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8), 3579*0b57cec5SDimitry Andric (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), 3580*0b57cec5SDimitry Andric xaddrX4:$dst)>; 3581*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3582*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8), 3583*0b57cec5SDimitry Andric (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), 3584*0b57cec5SDimitry Andric iaddrX4:$dst)>; 3585*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3586*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4), 3587*0b57cec5SDimitry Andric (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>; 3588*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3589*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2), 3590*0b57cec5SDimitry Andric (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>; 3591*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3592*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1), 3593*0b57cec5SDimitry Andric (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>; 3594*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3595*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8), 3596*0b57cec5SDimitry Andric (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>; 3597*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3598*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8), 3599*0b57cec5SDimitry Andric (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>; 3600*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3601*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2), 3602*0b57cec5SDimitry Andric (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>; 3603*0b57cec5SDimitry Andric def : Pat<(PPCstore_scal_int_from_vsr 3604*0b57cec5SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1), 3605*0b57cec5SDimitry Andric (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>; 3606*0b57cec5SDimitry Andric 3607*0b57cec5SDimitry Andric // Round & Convert QP -> DP/SP 3608*0b57cec5SDimitry Andric def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>; 3609*0b57cec5SDimitry Andric def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>; 3610*0b57cec5SDimitry Andric 3611*0b57cec5SDimitry Andric // Convert SP -> QP 3612*0b57cec5SDimitry Andric def : Pat<(f128 (fpextend f32:$src)), 3613*0b57cec5SDimitry Andric (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>; 3614*0b57cec5SDimitry Andric 3615*0b57cec5SDimitry Andric} // end HasP9Vector, AddedComplexity 3616*0b57cec5SDimitry Andric 3617*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { 3618*0b57cec5SDimitry Andric let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in { 3619*0b57cec5SDimitry Andric def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)), 3620*0b57cec5SDimitry Andric (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>; 3621*0b57cec5SDimitry Andric } 3622*0b57cec5SDimitry Andric let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in { 3623*0b57cec5SDimitry Andric def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)), 3624*0b57cec5SDimitry Andric (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>; 3625*0b57cec5SDimitry Andric } 3626*0b57cec5SDimitry Andric} 3627*0b57cec5SDimitry Andric 3628*0b57cec5SDimitry Andriclet Predicates = [HasP9Vector] in { 3629*0b57cec5SDimitry Andric let mayStore = 1 in { 3630*0b57cec5SDimitry Andric def SPILLTOVSR_STX : PseudoXFormMemOp<(outs), 3631*0b57cec5SDimitry Andric (ins spilltovsrrc:$XT, memrr:$dst), 3632*0b57cec5SDimitry Andric "#SPILLTOVSR_STX", []>; 3633*0b57cec5SDimitry Andric def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst), 3634*0b57cec5SDimitry Andric "#SPILLTOVSR_ST", []>; 3635*0b57cec5SDimitry Andric } 3636*0b57cec5SDimitry Andric let mayLoad = 1 in { 3637*0b57cec5SDimitry Andric def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT), 3638*0b57cec5SDimitry Andric (ins memrr:$src), 3639*0b57cec5SDimitry Andric "#SPILLTOVSR_LDX", []>; 3640*0b57cec5SDimitry Andric def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src), 3641*0b57cec5SDimitry Andric "#SPILLTOVSR_LD", []>; 3642*0b57cec5SDimitry Andric 3643*0b57cec5SDimitry Andric } 3644*0b57cec5SDimitry Andric} 3645*0b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64 3646*0b57cec5SDimitry Andricdef AnyExts { 3647*0b57cec5SDimitry Andric dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32); 3648*0b57cec5SDimitry Andric dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32); 3649*0b57cec5SDimitry Andric dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32); 3650*0b57cec5SDimitry Andric dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32); 3651*0b57cec5SDimitry Andric} 3652*0b57cec5SDimitry Andric 3653*0b57cec5SDimitry Andricdef DblToFlt { 3654*0b57cec5SDimitry Andric dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0)))); 3655*0b57cec5SDimitry Andric dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1)))); 3656*0b57cec5SDimitry Andric dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0)))); 3657*0b57cec5SDimitry Andric dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1)))); 3658*0b57cec5SDimitry Andric} 3659*0b57cec5SDimitry Andric 3660*0b57cec5SDimitry Andricdef ExtDbl { 3661*0b57cec5SDimitry Andric dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0)))))); 3662*0b57cec5SDimitry Andric dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1)))))); 3663*0b57cec5SDimitry Andric dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0)))))); 3664*0b57cec5SDimitry Andric dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1)))))); 3665*0b57cec5SDimitry Andric dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0)))))); 3666*0b57cec5SDimitry Andric dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1)))))); 3667*0b57cec5SDimitry Andric dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0)))))); 3668*0b57cec5SDimitry Andric dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1)))))); 3669*0b57cec5SDimitry Andric} 3670*0b57cec5SDimitry Andric 3671*0b57cec5SDimitry Andricdef ByteToWord { 3672*0b57cec5SDimitry Andric dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8)); 3673*0b57cec5SDimitry Andric dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8)); 3674*0b57cec5SDimitry Andric dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8)); 3675*0b57cec5SDimitry Andric dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8)); 3676*0b57cec5SDimitry Andric dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8)); 3677*0b57cec5SDimitry Andric dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8)); 3678*0b57cec5SDimitry Andric dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8)); 3679*0b57cec5SDimitry Andric dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8)); 3680*0b57cec5SDimitry Andric} 3681*0b57cec5SDimitry Andric 3682*0b57cec5SDimitry Andricdef ByteToDWord { 3683*0b57cec5SDimitry Andric dag LE_A0 = (i64 (sext_inreg 3684*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8)); 3685*0b57cec5SDimitry Andric dag LE_A1 = (i64 (sext_inreg 3686*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8)); 3687*0b57cec5SDimitry Andric dag BE_A0 = (i64 (sext_inreg 3688*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8)); 3689*0b57cec5SDimitry Andric dag BE_A1 = (i64 (sext_inreg 3690*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8)); 3691*0b57cec5SDimitry Andric} 3692*0b57cec5SDimitry Andric 3693*0b57cec5SDimitry Andricdef HWordToWord { 3694*0b57cec5SDimitry Andric dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16)); 3695*0b57cec5SDimitry Andric dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16)); 3696*0b57cec5SDimitry Andric dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16)); 3697*0b57cec5SDimitry Andric dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16)); 3698*0b57cec5SDimitry Andric dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16)); 3699*0b57cec5SDimitry Andric dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16)); 3700*0b57cec5SDimitry Andric dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16)); 3701*0b57cec5SDimitry Andric dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16)); 3702*0b57cec5SDimitry Andric} 3703*0b57cec5SDimitry Andric 3704*0b57cec5SDimitry Andricdef HWordToDWord { 3705*0b57cec5SDimitry Andric dag LE_A0 = (i64 (sext_inreg 3706*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16)); 3707*0b57cec5SDimitry Andric dag LE_A1 = (i64 (sext_inreg 3708*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16)); 3709*0b57cec5SDimitry Andric dag BE_A0 = (i64 (sext_inreg 3710*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16)); 3711*0b57cec5SDimitry Andric dag BE_A1 = (i64 (sext_inreg 3712*0b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16)); 3713*0b57cec5SDimitry Andric} 3714*0b57cec5SDimitry Andric 3715*0b57cec5SDimitry Andricdef WordToDWord { 3716*0b57cec5SDimitry Andric dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0)))); 3717*0b57cec5SDimitry Andric dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2)))); 3718*0b57cec5SDimitry Andric dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1)))); 3719*0b57cec5SDimitry Andric dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3)))); 3720*0b57cec5SDimitry Andric} 3721*0b57cec5SDimitry Andric 3722*0b57cec5SDimitry Andricdef FltToIntLoad { 3723*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A))))); 3724*0b57cec5SDimitry Andric} 3725*0b57cec5SDimitry Andricdef FltToUIntLoad { 3726*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A))))); 3727*0b57cec5SDimitry Andric} 3728*0b57cec5SDimitry Andricdef FltToLongLoad { 3729*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A))))); 3730*0b57cec5SDimitry Andric} 3731*0b57cec5SDimitry Andricdef FltToLongLoadP9 { 3732*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A))))); 3733*0b57cec5SDimitry Andric} 3734*0b57cec5SDimitry Andricdef FltToULongLoad { 3735*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A))))); 3736*0b57cec5SDimitry Andric} 3737*0b57cec5SDimitry Andricdef FltToULongLoadP9 { 3738*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A))))); 3739*0b57cec5SDimitry Andric} 3740*0b57cec5SDimitry Andricdef FltToLong { 3741*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A))))); 3742*0b57cec5SDimitry Andric} 3743*0b57cec5SDimitry Andricdef FltToULong { 3744*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A))))); 3745*0b57cec5SDimitry Andric} 3746*0b57cec5SDimitry Andricdef DblToInt { 3747*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A)))); 3748*0b57cec5SDimitry Andric dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B)))); 3749*0b57cec5SDimitry Andric dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C)))); 3750*0b57cec5SDimitry Andric dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D)))); 3751*0b57cec5SDimitry Andric} 3752*0b57cec5SDimitry Andricdef DblToUInt { 3753*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A)))); 3754*0b57cec5SDimitry Andric dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B)))); 3755*0b57cec5SDimitry Andric dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C)))); 3756*0b57cec5SDimitry Andric dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D)))); 3757*0b57cec5SDimitry Andric} 3758*0b57cec5SDimitry Andricdef DblToLong { 3759*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A)))); 3760*0b57cec5SDimitry Andric} 3761*0b57cec5SDimitry Andricdef DblToULong { 3762*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A)))); 3763*0b57cec5SDimitry Andric} 3764*0b57cec5SDimitry Andricdef DblToIntLoad { 3765*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A))))); 3766*0b57cec5SDimitry Andric} 3767*0b57cec5SDimitry Andricdef DblToIntLoadP9 { 3768*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A))))); 3769*0b57cec5SDimitry Andric} 3770*0b57cec5SDimitry Andricdef DblToUIntLoad { 3771*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A))))); 3772*0b57cec5SDimitry Andric} 3773*0b57cec5SDimitry Andricdef DblToUIntLoadP9 { 3774*0b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A))))); 3775*0b57cec5SDimitry Andric} 3776*0b57cec5SDimitry Andricdef DblToLongLoad { 3777*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A))))); 3778*0b57cec5SDimitry Andric} 3779*0b57cec5SDimitry Andricdef DblToULongLoad { 3780*0b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A))))); 3781*0b57cec5SDimitry Andric} 3782*0b57cec5SDimitry Andric 3783*0b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32) 3784*0b57cec5SDimitry Andricdef MrgFP { 3785*0b57cec5SDimitry Andric dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC), 3786*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $C, VSRC), 0)); 3787*0b57cec5SDimitry Andric dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC), 3788*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $D, VSRC), 0)); 3789*0b57cec5SDimitry Andric dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0)); 3790*0b57cec5SDimitry Andric dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3)); 3791*0b57cec5SDimitry Andric dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0)); 3792*0b57cec5SDimitry Andric dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3)); 3793*0b57cec5SDimitry Andric} 3794*0b57cec5SDimitry Andric 3795*0b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors. 3796*0b57cec5SDimitry Andricdef MrgWords { 3797*0b57cec5SDimitry Andric // For big endian, we merge low and hi doublewords (A, B). 3798*0b57cec5SDimitry Andric dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0)); 3799*0b57cec5SDimitry Andric dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3)); 3800*0b57cec5SDimitry Andric dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1)); 3801*0b57cec5SDimitry Andric dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0)); 3802*0b57cec5SDimitry Andric dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1)); 3803*0b57cec5SDimitry Andric dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0)); 3804*0b57cec5SDimitry Andric 3805*0b57cec5SDimitry Andric // For little endian, we merge low and hi doublewords (B, A). 3806*0b57cec5SDimitry Andric dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0)); 3807*0b57cec5SDimitry Andric dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3)); 3808*0b57cec5SDimitry Andric dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1)); 3809*0b57cec5SDimitry Andric dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0)); 3810*0b57cec5SDimitry Andric dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1)); 3811*0b57cec5SDimitry Andric dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0)); 3812*0b57cec5SDimitry Andric 3813*0b57cec5SDimitry Andric // For big endian, we merge hi doublewords of (A, C) and (B, D), convert 3814*0b57cec5SDimitry Andric // then merge. 3815*0b57cec5SDimitry Andric dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC), 3816*0b57cec5SDimitry Andric (COPY_TO_REGCLASS f64:$C, VSRC), 0)); 3817*0b57cec5SDimitry Andric dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC), 3818*0b57cec5SDimitry Andric (COPY_TO_REGCLASS f64:$D, VSRC), 0)); 3819*0b57cec5SDimitry Andric dag CVACS = (v4i32 (XVCVDPSXWS AC)); 3820*0b57cec5SDimitry Andric dag CVBDS = (v4i32 (XVCVDPSXWS BD)); 3821*0b57cec5SDimitry Andric dag CVACU = (v4i32 (XVCVDPUXWS AC)); 3822*0b57cec5SDimitry Andric dag CVBDU = (v4i32 (XVCVDPUXWS BD)); 3823*0b57cec5SDimitry Andric 3824*0b57cec5SDimitry Andric // For little endian, we merge hi doublewords of (D, B) and (C, A), convert 3825*0b57cec5SDimitry Andric // then merge. 3826*0b57cec5SDimitry Andric dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC), 3827*0b57cec5SDimitry Andric (COPY_TO_REGCLASS f64:$B, VSRC), 0)); 3828*0b57cec5SDimitry Andric dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC), 3829*0b57cec5SDimitry Andric (COPY_TO_REGCLASS f64:$A, VSRC), 0)); 3830*0b57cec5SDimitry Andric dag CVDBS = (v4i32 (XVCVDPSXWS DB)); 3831*0b57cec5SDimitry Andric dag CVCAS = (v4i32 (XVCVDPSXWS CA)); 3832*0b57cec5SDimitry Andric dag CVDBU = (v4i32 (XVCVDPUXWS DB)); 3833*0b57cec5SDimitry Andric dag CVCAU = (v4i32 (XVCVDPUXWS CA)); 3834*0b57cec5SDimitry Andric} 3835*0b57cec5SDimitry Andric 3836*0b57cec5SDimitry Andric// Patterns for BUILD_VECTOR nodes. 3837*0b57cec5SDimitry Andriclet AddedComplexity = 400 in { 3838*0b57cec5SDimitry Andric 3839*0b57cec5SDimitry Andric let Predicates = [HasVSX] in { 3840*0b57cec5SDimitry Andric // Build vectors of floating point converted to i32. 3841*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A, 3842*0b57cec5SDimitry Andric DblToInt.A, DblToInt.A)), 3843*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>; 3844*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A, 3845*0b57cec5SDimitry Andric DblToUInt.A, DblToUInt.A)), 3846*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>; 3847*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)), 3848*0b57cec5SDimitry Andric (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 3849*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>; 3850*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)), 3851*0b57cec5SDimitry Andric (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 3852*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>; 3853*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)), 3854*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3855*0b57cec5SDimitry Andric (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>; 3856*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)), 3857*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3858*0b57cec5SDimitry Andric (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>; 3859*0b57cec5SDimitry Andric def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)), 3860*0b57cec5SDimitry Andric (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>; 3861*0b57cec5SDimitry Andric 3862*0b57cec5SDimitry Andric // Build vectors of floating point converted to i64. 3863*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)), 3864*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs 3865*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>; 3866*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)), 3867*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs 3868*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>; 3869*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)), 3870*0b57cec5SDimitry Andric (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>; 3871*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)), 3872*0b57cec5SDimitry Andric (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>; 3873*0b57cec5SDimitry Andric } 3874*0b57cec5SDimitry Andric 3875*0b57cec5SDimitry Andric let Predicates = [HasVSX, NoP9Vector] in { 3876*0b57cec5SDimitry Andric // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads). 3877*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)), 3878*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3879*0b57cec5SDimitry Andric (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>; 3880*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)), 3881*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS 3882*0b57cec5SDimitry Andric (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>; 3883*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)), 3884*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS 3885*0b57cec5SDimitry Andric (XFLOADf32 xoaddr:$A), VSFRC)), 0))>; 3886*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)), 3887*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS 3888*0b57cec5SDimitry Andric (XFLOADf32 xoaddr:$A), VSFRC)), 0))>; 3889*0b57cec5SDimitry Andric } 3890*0b57cec5SDimitry Andric 3891*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasP8Vector] in { 3892*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.BVU, 3893*0b57cec5SDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3), 3894*0b57cec5SDimitry Andric (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>; 3895*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.BVS, 3896*0b57cec5SDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3), 3897*0b57cec5SDimitry Andric (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>; 3898*0b57cec5SDimitry Andric def : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src), 3899*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3900*0b57cec5SDimitry Andric def : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src), 3901*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3902*0b57cec5SDimitry Andric 3903*0b57cec5SDimitry Andric // Elements in a register on a BE system are in order <0, 1, 2, 3>. 3904*0b57cec5SDimitry Andric // The store instructions store the second word from the left. 3905*0b57cec5SDimitry Andric // So to align element zero, we need to modulo-left-shift by 3 words. 3906*0b57cec5SDimitry Andric // Similar logic applies for elements 2 and 3. 3907*0b57cec5SDimitry Andric foreach Idx = [ [0,3], [2,1], [3,2] ] in { 3908*0b57cec5SDimitry Andric def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src), 3909*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3910*0b57cec5SDimitry Andric sub_64), xoaddr:$src)>; 3911*0b57cec5SDimitry Andric def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src), 3912*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3913*0b57cec5SDimitry Andric sub_64), xoaddr:$src)>; 3914*0b57cec5SDimitry Andric } 3915*0b57cec5SDimitry Andric } 3916*0b57cec5SDimitry Andric 3917*0b57cec5SDimitry Andric let Predicates = [HasP8Vector, IsBigEndian, NoP9Vector] in { 3918*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src), 3919*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3920*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src), 3921*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3922*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src), 3923*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3924*0b57cec5SDimitry Andric xoaddr:$src)>; 3925*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src), 3926*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3927*0b57cec5SDimitry Andric xoaddr:$src)>; 3928*0b57cec5SDimitry Andric } 3929*0b57cec5SDimitry Andric 3930*0b57cec5SDimitry Andric // Big endian, available on all targets with VSX 3931*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasVSX] in { 3932*0b57cec5SDimitry Andric def : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 3933*0b57cec5SDimitry Andric (v2f64 (XXPERMDI 3934*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC), 3935*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $B, VSRC), 0))>; 3936*0b57cec5SDimitry Andric 3937*0b57cec5SDimitry Andric def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)), 3938*0b57cec5SDimitry Andric (VMRGEW MrgFP.AC, MrgFP.BD)>; 3939*0b57cec5SDimitry Andric def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 3940*0b57cec5SDimitry Andric DblToFlt.B0, DblToFlt.B1)), 3941*0b57cec5SDimitry Andric (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>; 3942*0b57cec5SDimitry Andric 3943*0b57cec5SDimitry Andric // Convert 4 doubles to a vector of ints. 3944*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B, 3945*0b57cec5SDimitry Andric DblToInt.C, DblToInt.D)), 3946*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>; 3947*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B, 3948*0b57cec5SDimitry Andric DblToUInt.C, DblToUInt.D)), 3949*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>; 3950*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S, 3951*0b57cec5SDimitry Andric ExtDbl.B0S, ExtDbl.B1S)), 3952*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>; 3953*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U, 3954*0b57cec5SDimitry Andric ExtDbl.B0U, ExtDbl.B1U)), 3955*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>; 3956*0b57cec5SDimitry Andric } 3957*0b57cec5SDimitry Andric 3958*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasP8Vector] in { 3959*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.BVU, 3960*0b57cec5SDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3), 3961*0b57cec5SDimitry Andric (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>; 3962*0b57cec5SDimitry Andric def : Pat<DWToSPExtractConv.BVS, 3963*0b57cec5SDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3), 3964*0b57cec5SDimitry Andric (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>; 3965*0b57cec5SDimitry Andric def : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src), 3966*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3967*0b57cec5SDimitry Andric def : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src), 3968*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3969*0b57cec5SDimitry Andric 3970*0b57cec5SDimitry Andric // Elements in a register on a LE system are in order <3, 2, 1, 0>. 3971*0b57cec5SDimitry Andric // The store instructions store the second word from the left. 3972*0b57cec5SDimitry Andric // So to align element 3, we need to modulo-left-shift by 3 words. 3973*0b57cec5SDimitry Andric // Similar logic applies for elements 0 and 1. 3974*0b57cec5SDimitry Andric foreach Idx = [ [0,2], [1,1], [3,3] ] in { 3975*0b57cec5SDimitry Andric def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src), 3976*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3977*0b57cec5SDimitry Andric sub_64), xoaddr:$src)>; 3978*0b57cec5SDimitry Andric def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src), 3979*0b57cec5SDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3980*0b57cec5SDimitry Andric sub_64), xoaddr:$src)>; 3981*0b57cec5SDimitry Andric } 3982*0b57cec5SDimitry Andric } 3983*0b57cec5SDimitry Andric 3984*0b57cec5SDimitry Andric let Predicates = [HasP8Vector, IsLittleEndian, NoP9Vector] in { 3985*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src), 3986*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3987*0b57cec5SDimitry Andric xoaddr:$src)>; 3988*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src), 3989*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3990*0b57cec5SDimitry Andric xoaddr:$src)>; 3991*0b57cec5SDimitry Andric def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src), 3992*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3993*0b57cec5SDimitry Andric def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src), 3994*0b57cec5SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>; 3995*0b57cec5SDimitry Andric } 3996*0b57cec5SDimitry Andric 3997*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasVSX] in { 3998*0b57cec5SDimitry Andric // Little endian, available on all targets with VSX 3999*0b57cec5SDimitry Andric def : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 4000*0b57cec5SDimitry Andric (v2f64 (XXPERMDI 4001*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $B, VSRC), 4002*0b57cec5SDimitry Andric (COPY_TO_REGCLASS $A, VSRC), 0))>; 4003*0b57cec5SDimitry Andric 4004*0b57cec5SDimitry Andric def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)), 4005*0b57cec5SDimitry Andric (VMRGEW MrgFP.AC, MrgFP.BD)>; 4006*0b57cec5SDimitry Andric def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 4007*0b57cec5SDimitry Andric DblToFlt.B0, DblToFlt.B1)), 4008*0b57cec5SDimitry Andric (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>; 4009*0b57cec5SDimitry Andric 4010*0b57cec5SDimitry Andric // Convert 4 doubles to a vector of ints. 4011*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B, 4012*0b57cec5SDimitry Andric DblToInt.C, DblToInt.D)), 4013*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>; 4014*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B, 4015*0b57cec5SDimitry Andric DblToUInt.C, DblToUInt.D)), 4016*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>; 4017*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S, 4018*0b57cec5SDimitry Andric ExtDbl.B0S, ExtDbl.B1S)), 4019*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>; 4020*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U, 4021*0b57cec5SDimitry Andric ExtDbl.B0U, ExtDbl.B1U)), 4022*0b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>; 4023*0b57cec5SDimitry Andric } 4024*0b57cec5SDimitry Andric 4025*0b57cec5SDimitry Andric let Predicates = [HasDirectMove] in { 4026*0b57cec5SDimitry Andric // Endianness-neutral constant splat on P8 and newer targets. The reason 4027*0b57cec5SDimitry Andric // for this pattern is that on targets with direct moves, we don't expand 4028*0b57cec5SDimitry Andric // BUILD_VECTOR nodes for v4i32. 4029*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A, 4030*0b57cec5SDimitry Andric immSExt5NonZero:$A, immSExt5NonZero:$A)), 4031*0b57cec5SDimitry Andric (v4i32 (VSPLTISW imm:$A))>; 4032*0b57cec5SDimitry Andric } 4033*0b57cec5SDimitry Andric 4034*0b57cec5SDimitry Andric let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in { 4035*0b57cec5SDimitry Andric // Big endian integer vectors using direct moves. 4036*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 4037*0b57cec5SDimitry Andric (v2i64 (XXPERMDI 4038*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 4039*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>; 4040*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4041*0b57cec5SDimitry Andric (XXPERMDI 4042*0b57cec5SDimitry Andric (COPY_TO_REGCLASS 4043*0b57cec5SDimitry Andric (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC), 4044*0b57cec5SDimitry Andric (COPY_TO_REGCLASS 4045*0b57cec5SDimitry Andric (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>; 4046*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 4047*0b57cec5SDimitry Andric (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>; 4048*0b57cec5SDimitry Andric } 4049*0b57cec5SDimitry Andric 4050*0b57cec5SDimitry Andric let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in { 4051*0b57cec5SDimitry Andric // Little endian integer vectors using direct moves. 4052*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 4053*0b57cec5SDimitry Andric (v2i64 (XXPERMDI 4054*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 4055*0b57cec5SDimitry Andric (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>; 4056*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4057*0b57cec5SDimitry Andric (XXPERMDI 4058*0b57cec5SDimitry Andric (COPY_TO_REGCLASS 4059*0b57cec5SDimitry Andric (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC), 4060*0b57cec5SDimitry Andric (COPY_TO_REGCLASS 4061*0b57cec5SDimitry Andric (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>; 4062*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 4063*0b57cec5SDimitry Andric (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>; 4064*0b57cec5SDimitry Andric } 4065*0b57cec5SDimitry Andric 4066*0b57cec5SDimitry Andric let Predicates = [HasP9Vector] in { 4067*0b57cec5SDimitry Andric // Endianness-neutral patterns for const splats with ISA 3.0 instructions. 4068*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector i32:$A)), 4069*0b57cec5SDimitry Andric (v4i32 (MTVSRWS $A))>; 4070*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 4071*0b57cec5SDimitry Andric (v4i32 (MTVSRWS $A))>; 4072*0b57cec5SDimitry Andric def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 4073*0b57cec5SDimitry Andric immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 4074*0b57cec5SDimitry Andric immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 4075*0b57cec5SDimitry Andric immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 4076*0b57cec5SDimitry Andric immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A, 4077*0b57cec5SDimitry Andric immAnyExt8:$A)), 4078*0b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>; 4079*0b57cec5SDimitry Andric def : Pat<(v16i8 immAllOnesV), 4080*0b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>; 4081*0b57cec5SDimitry Andric def : Pat<(v8i16 immAllOnesV), 4082*0b57cec5SDimitry Andric (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>; 4083*0b57cec5SDimitry Andric def : Pat<(v4i32 immAllOnesV), 4084*0b57cec5SDimitry Andric (v4i32 (XXSPLTIB 255))>; 4085*0b57cec5SDimitry Andric def : Pat<(v2i64 immAllOnesV), 4086*0b57cec5SDimitry Andric (v2i64 (XXSPLTIB 255))>; 4087*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)), 4088*0b57cec5SDimitry Andric (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>; 4089*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)), 4090*0b57cec5SDimitry Andric (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>; 4091*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)), 4092*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4093*0b57cec5SDimitry Andric (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>; 4094*0b57cec5SDimitry Andric def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)), 4095*0b57cec5SDimitry Andric (v4i32 (XXSPLTW (COPY_TO_REGCLASS 4096*0b57cec5SDimitry Andric (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>; 4097*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)), 4098*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS 4099*0b57cec5SDimitry Andric (DFLOADf32 iaddrX4:$A), 4100*0b57cec5SDimitry Andric VSFRC)), 0))>; 4101*0b57cec5SDimitry Andric def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)), 4102*0b57cec5SDimitry Andric (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS 4103*0b57cec5SDimitry Andric (DFLOADf32 iaddrX4:$A), 4104*0b57cec5SDimitry Andric VSFRC)), 0))>; 4105*0b57cec5SDimitry Andric } 4106*0b57cec5SDimitry Andric 4107*0b57cec5SDimitry Andric let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in { 4108*0b57cec5SDimitry Andric def : Pat<(i64 (extractelt v2i64:$A, 1)), 4109*0b57cec5SDimitry Andric (i64 (MFVSRLD $A))>; 4110*0b57cec5SDimitry Andric // Better way to build integer vectors if we have MTVSRDD. Big endian. 4111*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)), 4112*0b57cec5SDimitry Andric (v2i64 (MTVSRDD $rB, $rA))>; 4113*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4114*0b57cec5SDimitry Andric (MTVSRDD 4115*0b57cec5SDimitry Andric (RLDIMI AnyExts.B, AnyExts.A, 32, 0), 4116*0b57cec5SDimitry Andric (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>; 4117*0b57cec5SDimitry Andric } 4118*0b57cec5SDimitry Andric 4119*0b57cec5SDimitry Andric let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in { 4120*0b57cec5SDimitry Andric def : Pat<(i64 (extractelt v2i64:$A, 0)), 4121*0b57cec5SDimitry Andric (i64 (MFVSRLD $A))>; 4122*0b57cec5SDimitry Andric // Better way to build integer vectors if we have MTVSRDD. Little endian. 4123*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)), 4124*0b57cec5SDimitry Andric (v2i64 (MTVSRDD $rB, $rA))>; 4125*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 4126*0b57cec5SDimitry Andric (MTVSRDD 4127*0b57cec5SDimitry Andric (RLDIMI AnyExts.C, AnyExts.D, 32, 0), 4128*0b57cec5SDimitry Andric (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>; 4129*0b57cec5SDimitry Andric } 4130*0b57cec5SDimitry Andric // P9 Altivec instructions that can be used to build vectors. 4131*0b57cec5SDimitry Andric // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete 4132*0b57cec5SDimitry Andric // with complexities of existing build vector patterns in this file. 4133*0b57cec5SDimitry Andric let Predicates = [HasP9Altivec, IsLittleEndian] in { 4134*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)), 4135*0b57cec5SDimitry Andric (v2i64 (VEXTSW2D $A))>; 4136*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)), 4137*0b57cec5SDimitry Andric (v2i64 (VEXTSH2D $A))>; 4138*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1, 4139*0b57cec5SDimitry Andric HWordToWord.LE_A2, HWordToWord.LE_A3)), 4140*0b57cec5SDimitry Andric (v4i32 (VEXTSH2W $A))>; 4141*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1, 4142*0b57cec5SDimitry Andric ByteToWord.LE_A2, ByteToWord.LE_A3)), 4143*0b57cec5SDimitry Andric (v4i32 (VEXTSB2W $A))>; 4144*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)), 4145*0b57cec5SDimitry Andric (v2i64 (VEXTSB2D $A))>; 4146*0b57cec5SDimitry Andric } 4147*0b57cec5SDimitry Andric 4148*0b57cec5SDimitry Andric let Predicates = [HasP9Altivec, IsBigEndian] in { 4149*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)), 4150*0b57cec5SDimitry Andric (v2i64 (VEXTSW2D $A))>; 4151*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)), 4152*0b57cec5SDimitry Andric (v2i64 (VEXTSH2D $A))>; 4153*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1, 4154*0b57cec5SDimitry Andric HWordToWord.BE_A2, HWordToWord.BE_A3)), 4155*0b57cec5SDimitry Andric (v4i32 (VEXTSH2W $A))>; 4156*0b57cec5SDimitry Andric def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1, 4157*0b57cec5SDimitry Andric ByteToWord.BE_A2, ByteToWord.BE_A3)), 4158*0b57cec5SDimitry Andric (v4i32 (VEXTSB2W $A))>; 4159*0b57cec5SDimitry Andric def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)), 4160*0b57cec5SDimitry Andric (v2i64 (VEXTSB2D $A))>; 4161*0b57cec5SDimitry Andric } 4162*0b57cec5SDimitry Andric 4163*0b57cec5SDimitry Andric let Predicates = [HasP9Altivec] in { 4164*0b57cec5SDimitry Andric def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)), 4165*0b57cec5SDimitry Andric (v2i64 (VEXTSB2D $A))>; 4166*0b57cec5SDimitry Andric def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)), 4167*0b57cec5SDimitry Andric (v2i64 (VEXTSH2D $A))>; 4168*0b57cec5SDimitry Andric def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)), 4169*0b57cec5SDimitry Andric (v2i64 (VEXTSW2D $A))>; 4170*0b57cec5SDimitry Andric def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)), 4171*0b57cec5SDimitry Andric (v4i32 (VEXTSB2W $A))>; 4172*0b57cec5SDimitry Andric def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)), 4173*0b57cec5SDimitry Andric (v4i32 (VEXTSH2W $A))>; 4174*0b57cec5SDimitry Andric } 4175*0b57cec5SDimitry Andric} 4176*0b57cec5SDimitry Andric 4177*0b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be 4178*0b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef. 4179*0b57cec5SDimitry Andriclet Predicates = [HasP9Altivec] in { 4180*0b57cec5SDimitry Andric 4181*0b57cec5SDimitry Andric def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))), 4182*0b57cec5SDimitry Andric (v4i32 (VABSDUW $A, $B))>; 4183*0b57cec5SDimitry Andric 4184*0b57cec5SDimitry Andric def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))), 4185*0b57cec5SDimitry Andric (v8i16 (VABSDUH $A, $B))>; 4186*0b57cec5SDimitry Andric 4187*0b57cec5SDimitry Andric def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))), 4188*0b57cec5SDimitry Andric (v16i8 (VABSDUB $A, $B))>; 4189*0b57cec5SDimitry Andric 4190*0b57cec5SDimitry Andric // As PPCVABSD description, the last operand indicates whether do the 4191*0b57cec5SDimitry Andric // sign bit flip. 4192*0b57cec5SDimitry Andric def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))), 4193*0b57cec5SDimitry Andric (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>; 4194*0b57cec5SDimitry Andric} 4195