10b57cec5SDimitry Andric//===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric// 90b57cec5SDimitry Andric// This file describes the VSX extension to the PowerPC instruction set. 100b57cec5SDimitry Andric// 110b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric// *********************************** NOTE *********************************** 140b57cec5SDimitry Andric// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing ** 150b57cec5SDimitry Andric// ** which VMX and VSX instructions are lane-sensitive and which are not. ** 160b57cec5SDimitry Andric// ** A lane-sensitive instruction relies, implicitly or explicitly, on ** 170b57cec5SDimitry Andric// ** whether lanes are numbered from left to right. An instruction like ** 180b57cec5SDimitry Andric// ** VADDFP is not lane-sensitive, because each lane of the result vector ** 190b57cec5SDimitry Andric// ** relies only on the corresponding lane of the source vectors. However, ** 200b57cec5SDimitry Andric// ** an instruction like VMULESB is lane-sensitive, because "even" and ** 210b57cec5SDimitry Andric// ** "odd" lanes are different for big-endian and little-endian numbering. ** 220b57cec5SDimitry Andric// ** ** 230b57cec5SDimitry Andric// ** When adding new VMX and VSX instructions, please consider whether they ** 240b57cec5SDimitry Andric// ** are lane-sensitive. If so, they must be added to a switch statement ** 250b57cec5SDimitry Andric// ** in PPCVSXSwapRemoval::gatherVectorInstructions(). ** 260b57cec5SDimitry Andric// **************************************************************************** 270b57cec5SDimitry Andric 285ffd83dbSDimitry Andric// *********************************** NOTE *********************************** 295ffd83dbSDimitry Andric// ** When adding new anonymous patterns to this file, please add them to ** 305ffd83dbSDimitry Andric// ** the section titled Anonymous Patterns. Chances are that the existing ** 315ffd83dbSDimitry Andric// ** predicate blocks already contain a combination of features that you ** 325ffd83dbSDimitry Andric// ** are after. There is a list of blocks at the top of the section. If ** 335ffd83dbSDimitry Andric// ** you definitely need a new combination of predicates, please add that ** 345ffd83dbSDimitry Andric// ** combination to the list. ** 355ffd83dbSDimitry Andric// ** File Structure: ** 365ffd83dbSDimitry Andric// ** - Custom PPCISD node definitions ** 375ffd83dbSDimitry Andric// ** - Predicate definitions: predicates to specify the subtargets for ** 385ffd83dbSDimitry Andric// ** which an instruction or pattern can be emitted. ** 395ffd83dbSDimitry Andric// ** - Instruction formats: classes instantiated by the instructions. ** 405ffd83dbSDimitry Andric// ** These generally correspond to instruction formats in section 1.6 of ** 415ffd83dbSDimitry Andric// ** the ISA document. ** 425ffd83dbSDimitry Andric// ** - Instruction definitions: the actual definitions of the instructions ** 435ffd83dbSDimitry Andric// ** often including input patterns that they match. ** 445ffd83dbSDimitry Andric// ** - Helper DAG definitions: We define a number of dag objects to use as ** 455ffd83dbSDimitry Andric// ** input or output patterns for consciseness of the code. ** 465ffd83dbSDimitry Andric// ** - Anonymous patterns: input patterns that an instruction matches can ** 475ffd83dbSDimitry Andric// ** often not be specified as part of the instruction definition, so an ** 485ffd83dbSDimitry Andric// ** anonymous pattern must be specified mapping an input pattern to an ** 495ffd83dbSDimitry Andric// ** output pattern. These are generally guarded by subtarget predicates. ** 505ffd83dbSDimitry Andric// ** - Instruction aliases: used to define extended mnemonics for assembly ** 515ffd83dbSDimitry Andric// ** printing (for example: xxswapd for xxpermdi with 0x2 as the imm). ** 525ffd83dbSDimitry Andric// **************************************************************************** 535ffd83dbSDimitry Andric 540b57cec5SDimitry Andricdef SDT_PPCldvsxlh : SDTypeProfile<1, 1, [ 550b57cec5SDimitry Andric SDTCisVT<0, v4f32>, SDTCisPtrTy<1> 560b57cec5SDimitry Andric]>; 570b57cec5SDimitry Andric 588bcb0991SDimitry Andricdef SDT_PPCfpexth : SDTypeProfile<1, 2, [ 598bcb0991SDimitry Andric SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>, SDTCisPtrTy<2> 608bcb0991SDimitry Andric]>; 618bcb0991SDimitry Andric 628bcb0991SDimitry Andricdef SDT_PPCldsplat : SDTypeProfile<1, 1, [ 638bcb0991SDimitry Andric SDTCisVec<0>, SDTCisPtrTy<1> 640b57cec5SDimitry Andric]>; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric// Little-endian-specific nodes. 670b57cec5SDimitry Andricdef SDT_PPClxvd2x : SDTypeProfile<1, 1, [ 680b57cec5SDimitry Andric SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 690b57cec5SDimitry Andric]>; 700b57cec5SDimitry Andricdef SDT_PPCstxvd2x : SDTypeProfile<0, 2, [ 710b57cec5SDimitry Andric SDTCisVT<0, v2f64>, SDTCisPtrTy<1> 720b57cec5SDimitry Andric]>; 730b57cec5SDimitry Andricdef SDT_PPCxxswapd : SDTypeProfile<1, 1, [ 740b57cec5SDimitry Andric SDTCisSameAs<0, 1> 750b57cec5SDimitry Andric]>; 760b57cec5SDimitry Andricdef SDTVecConv : SDTypeProfile<1, 2, [ 770b57cec5SDimitry Andric SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2> 780b57cec5SDimitry Andric]>; 790b57cec5SDimitry Andricdef SDTVabsd : SDTypeProfile<1, 3, [ 800b57cec5SDimitry Andric SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<3, i32> 810b57cec5SDimitry Andric]>; 828bcb0991SDimitry Andricdef SDT_PPCld_vec_be : SDTypeProfile<1, 1, [ 838bcb0991SDimitry Andric SDTCisVec<0>, SDTCisPtrTy<1> 848bcb0991SDimitry Andric]>; 858bcb0991SDimitry Andricdef SDT_PPCst_vec_be : SDTypeProfile<0, 2, [ 868bcb0991SDimitry Andric SDTCisVec<0>, SDTCisPtrTy<1> 878bcb0991SDimitry Andric]>; 880b57cec5SDimitry Andric 89*bdd1243dSDimitry Andricdef SDT_PPCxxperm : SDTypeProfile<1, 3, [ 90*bdd1243dSDimitry Andric SDTCisVT<0, v2f64>, SDTCisVT<1, v2f64>, 91*bdd1243dSDimitry Andric SDTCisVT<2, v2f64>, SDTCisVT<3, v4i32>]>; 925ffd83dbSDimitry Andric//--------------------------- Custom PPC nodes -------------------------------// 930b57cec5SDimitry Andricdef PPClxvd2x : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x, 940b57cec5SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 950b57cec5SDimitry Andricdef PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x, 960b57cec5SDimitry Andric [SDNPHasChain, SDNPMayStore]>; 978bcb0991SDimitry Andricdef PPCld_vec_be : SDNode<"PPCISD::LOAD_VEC_BE", SDT_PPCld_vec_be, 988bcb0991SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 998bcb0991SDimitry Andricdef PPCst_vec_be : SDNode<"PPCISD::STORE_VEC_BE", SDT_PPCst_vec_be, 1008bcb0991SDimitry Andric [SDNPHasChain, SDNPMayStore]>; 1010b57cec5SDimitry Andricdef PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>; 1020b57cec5SDimitry Andricdef PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>; 1030b57cec5SDimitry Andricdef PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>; 1040b57cec5SDimitry Andricdef PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>; 1050b57cec5SDimitry Andricdef PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>; 1060b57cec5SDimitry Andricdef PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>; 1070b57cec5SDimitry Andricdef PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>; 1080b57cec5SDimitry Andricdef PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>; 1090b57cec5SDimitry Andric 1108bcb0991SDimitry Andricdef PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>; 1110b57cec5SDimitry Andricdef PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh, 1120b57cec5SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 1138bcb0991SDimitry Andricdef PPCldsplat : SDNode<"PPCISD::LD_SPLAT", SDT_PPCldsplat, 1148bcb0991SDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 115349cc55cSDimitry Andricdef PPCzextldsplat : SDNode<"PPCISD::ZEXT_LD_SPLAT", SDT_PPCldsplat, 116349cc55cSDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 117349cc55cSDimitry Andricdef PPCsextldsplat : SDNode<"PPCISD::SEXT_LD_SPLAT", SDT_PPCldsplat, 118349cc55cSDimitry Andric [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 1195ffd83dbSDimitry Andricdef PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED", 1205ffd83dbSDimitry Andric SDTypeProfile<1, 1, []>, []>; 1210b57cec5SDimitry Andric 122*bdd1243dSDimitry Andricdef PPCxxperm : SDNode<"PPCISD::XXPERM", SDT_PPCxxperm, []>; 1235ffd83dbSDimitry Andric//-------------------------- Predicate definitions ---------------------------// 1245ffd83dbSDimitry Andricdef HasVSX : Predicate<"Subtarget->hasVSX()">; 1255ffd83dbSDimitry Andricdef IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">; 1265ffd83dbSDimitry Andricdef IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">; 127e8d8bef9SDimitry Andricdef IsPPC64 : Predicate<"Subtarget->isPPC64()">; 1285ffd83dbSDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">; 1295ffd83dbSDimitry Andricdef HasP8Vector : Predicate<"Subtarget->hasP8Vector()">; 1305ffd83dbSDimitry Andricdef HasDirectMove : Predicate<"Subtarget->hasDirectMove()">; 1315ffd83dbSDimitry Andricdef NoP9Vector : Predicate<"!Subtarget->hasP9Vector()">; 1325ffd83dbSDimitry Andricdef HasP9Vector : Predicate<"Subtarget->hasP9Vector()">; 1335ffd83dbSDimitry Andricdef NoP9Altivec : Predicate<"!Subtarget->hasP9Altivec()">; 134fe6060f1SDimitry Andricdef NoP10Vector: Predicate<"!Subtarget->hasP10Vector()">; 1355ffd83dbSDimitry Andric 1360eae32dcSDimitry Andricdef PPCldsplatAlign16 : PatFrag<(ops node:$ptr), (PPCldsplat node:$ptr), [{ 1370eae32dcSDimitry Andric return cast<MemIntrinsicSDNode>(N)->getAlign() >= Align(16) && 1380eae32dcSDimitry Andric isOffsetMultipleOf(N, 16); 1390eae32dcSDimitry Andric}]>; 1400eae32dcSDimitry Andric 1415ffd83dbSDimitry Andric//--------------------- VSX-specific instruction formats ---------------------// 1425ffd83dbSDimitry Andric// By default, all VSX instructions are to be selected over their Altivec 1435ffd83dbSDimitry Andric// counter parts and they do not have unmodeled sideeffects. 1445ffd83dbSDimitry Andriclet AddedComplexity = 400, hasSideEffects = 0 in { 1450b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase, 1460b57cec5SDimitry Andric string asmstr, InstrItinClass itin, Intrinsic Int, 1470b57cec5SDimitry Andric ValueType OutTy, ValueType InTy> { 1480b57cec5SDimitry Andric let BaseName = asmbase in { 1490b57cec5SDimitry Andric def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1500b57cec5SDimitry Andric !strconcat(asmbase, !strconcat(" ", asmstr)), itin, 1510b57cec5SDimitry Andric [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>; 1520b57cec5SDimitry Andric let Defs = [CR6] in 153480093f4SDimitry Andric def _rec : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 1540b57cec5SDimitry Andric !strconcat(asmbase, !strconcat(". ", asmstr)), itin, 1550b57cec5SDimitry Andric [(set InTy:$XT, 156e8d8bef9SDimitry Andric (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>, 157480093f4SDimitry Andric isRecordForm; 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric} 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as 1620b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained 1630b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained 1640b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though 1650b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction 1660b57cec5SDimitry Andric// to use the same register for both inputs. 1670b57cec5SDimitry Andric// For example, an output DAG such as this: 1680b57cec5SDimitry Andric// (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0)) 1690b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs 1700b57cec5SDimitry Andric// to the XXPERMDI instruction. 1710b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr, 1720b57cec5SDimitry Andric InstrItinClass itin, list<dag> pattern> 1730b57cec5SDimitry Andric : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> { 1740b57cec5SDimitry Andric let XB = XA; 1750b57cec5SDimitry Andric} 1760b57cec5SDimitry Andric 1775ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in { 1785ffd83dbSDimitry Andricclass X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 1795ffd83dbSDimitry Andric list<dag> pattern> 1805ffd83dbSDimitry Andric : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB), 1815ffd83dbSDimitry Andric !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 1820b57cec5SDimitry Andric 1835ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /] 1845ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 1855ffd83dbSDimitry Andric list<dag> pattern> 1865ffd83dbSDimitry Andric : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm; 1875ffd83dbSDimitry Andric 1885ffd83dbSDimitry Andric// [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less), 1895ffd83dbSDimitry Andric// So we use different operand class for VRB 1905ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 1915ffd83dbSDimitry Andric RegisterOperand vbtype, list<dag> pattern> 1925ffd83dbSDimitry Andric : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB), 1935ffd83dbSDimitry Andric !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 1945ffd83dbSDimitry Andric 1955ffd83dbSDimitry Andric// [PO VRT XO VRB XO /] 1965ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 1975ffd83dbSDimitry Andric list<dag> pattern> 1985ffd83dbSDimitry Andric : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB), 1995ffd83dbSDimitry Andric !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>; 2005ffd83dbSDimitry Andric 2015ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /] 2025ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc, 2035ffd83dbSDimitry Andric list<dag> pattern> 2045ffd83dbSDimitry Andric : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm; 2055ffd83dbSDimitry Andric 2065ffd83dbSDimitry Andric// [PO T XO B XO BX /] 2075ffd83dbSDimitry Andricclass XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc, 2085ffd83dbSDimitry Andric list<dag> pattern> 2095ffd83dbSDimitry Andric : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB), 2105ffd83dbSDimitry Andric !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>; 2115ffd83dbSDimitry Andric 2125ffd83dbSDimitry Andric// [PO T XO B XO BX TX] 2135ffd83dbSDimitry Andricclass XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc, 2145ffd83dbSDimitry Andric RegisterOperand vtype, list<dag> pattern> 2155ffd83dbSDimitry Andric : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB), 2165ffd83dbSDimitry Andric !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>; 2175ffd83dbSDimitry Andric 2185ffd83dbSDimitry Andric// [PO T A B XO AX BX TX], src and dest register use different operand class 2195ffd83dbSDimitry Andricclass XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc, 2205ffd83dbSDimitry Andric RegisterOperand xty, RegisterOperand aty, RegisterOperand bty, 2215ffd83dbSDimitry Andric InstrItinClass itin, list<dag> pattern> 2225ffd83dbSDimitry Andric : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB), 2235ffd83dbSDimitry Andric !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>; 2245ffd83dbSDimitry Andric 2255ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /] 2265ffd83dbSDimitry Andricclass X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc, 2275ffd83dbSDimitry Andric list<dag> pattern> 2285ffd83dbSDimitry Andric : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB), 2295ffd83dbSDimitry Andric !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>; 2305ffd83dbSDimitry Andric 2315ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /] 2325ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc, 2335ffd83dbSDimitry Andric list<dag> pattern> 2345ffd83dbSDimitry Andric : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm; 2355ffd83dbSDimitry Andric 2365ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /] 2375ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc, 2385ffd83dbSDimitry Andric list<dag> pattern> 2395ffd83dbSDimitry Andric : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB), 2405ffd83dbSDimitry Andric !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>, 2415ffd83dbSDimitry Andric RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">; 2425ffd83dbSDimitry Andric 2435ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /] 2445ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc, 2455ffd83dbSDimitry Andric list<dag> pattern> 2465ffd83dbSDimitry Andric : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm; 2475ffd83dbSDimitry Andric 2485ffd83dbSDimitry Andricclass Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc, 2495ffd83dbSDimitry Andric list<dag> pattern> 2505ffd83dbSDimitry Andric : Z23Form_8<opcode, xo, 2515ffd83dbSDimitry Andric (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc), 2525ffd83dbSDimitry Andric !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> { 2535ffd83dbSDimitry Andric let RC = ex; 2545ffd83dbSDimitry Andric} 2555ffd83dbSDimitry Andric 2565ffd83dbSDimitry Andric// [PO BF // VRA VRB XO /] 2575ffd83dbSDimitry Andricclass X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc, 2585ffd83dbSDimitry Andric list<dag> pattern> 2595ffd83dbSDimitry Andric : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB), 2605ffd83dbSDimitry Andric !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> { 2615ffd83dbSDimitry Andric let Pattern = pattern; 2625ffd83dbSDimitry Andric} 2635ffd83dbSDimitry Andric 2645ffd83dbSDimitry Andric// [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different 2655ffd83dbSDimitry Andric// "out" and "in" dag 2665ffd83dbSDimitry Andricclass X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, 2675ffd83dbSDimitry Andric RegisterOperand vtype, list<dag> pattern> 2685ffd83dbSDimitry Andric : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src), 2695ffd83dbSDimitry Andric !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>; 2705ffd83dbSDimitry Andric 2715ffd83dbSDimitry Andric// [PO S RA RB XO SX] 2725ffd83dbSDimitry Andricclass X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc, 2735ffd83dbSDimitry Andric RegisterOperand vtype, list<dag> pattern> 2745ffd83dbSDimitry Andric : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst), 2755ffd83dbSDimitry Andric !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>; 2765ffd83dbSDimitry Andric} // Predicates = HasP9Vector 2775ffd83dbSDimitry Andric} // AddedComplexity = 400, hasSideEffects = 0 2785ffd83dbSDimitry Andric 2795ffd83dbSDimitry Andricmulticlass ScalToVecWPermute<ValueType Ty, dag In, dag NonPermOut, dag PermOut> { 2805ffd83dbSDimitry Andric def : Pat<(Ty (scalar_to_vector In)), (Ty NonPermOut)>; 2815ffd83dbSDimitry Andric def : Pat<(Ty (PPCSToV In)), (Ty PermOut)>; 2825ffd83dbSDimitry Andric} 2835ffd83dbSDimitry Andric 2845ffd83dbSDimitry Andric//-------------------------- Instruction definitions -------------------------// 2855ffd83dbSDimitry Andric// VSX instructions require the VSX feature, they are to be selected over 2865ffd83dbSDimitry Andric// equivalent Altivec patterns (as they address a larger register set) and 2875ffd83dbSDimitry Andric// they do not have unmodeled side effects. 2885ffd83dbSDimitry Andriclet Predicates = [HasVSX], AddedComplexity = 400 in { 2895ffd83dbSDimitry Andriclet hasSideEffects = 0 in { 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // Load indexed instructions 2920b57cec5SDimitry Andric let mayLoad = 1, mayStore = 0 in { 2930b57cec5SDimitry Andric let CodeSize = 3 in 2940b57cec5SDimitry Andric def LXSDX : XX1Form_memOp<31, 588, 2950b57cec5SDimitry Andric (outs vsfrc:$XT), (ins memrr:$src), 2960b57cec5SDimitry Andric "lxsdx $XT, $src", IIC_LdStLFD, 2970b57cec5SDimitry Andric []>; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later 3000b57cec5SDimitry Andric let CodeSize = 3 in 3010b57cec5SDimitry Andric def XFLOADf64 : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), 3020b57cec5SDimitry Andric "#XFLOADf64", 303fe6060f1SDimitry Andric [(set f64:$XT, (load XForm:$src))]>; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric let Predicates = [HasVSX, HasOnlySwappingMemOps] in 3060b57cec5SDimitry Andric def LXVD2X : XX1Form_memOp<31, 844, 3070b57cec5SDimitry Andric (outs vsrc:$XT), (ins memrr:$src), 3080b57cec5SDimitry Andric "lxvd2x $XT, $src", IIC_LdStLFD, 309fe6060f1SDimitry Andric []>; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric def LXVDSX : XX1Form_memOp<31, 332, 3120b57cec5SDimitry Andric (outs vsrc:$XT), (ins memrr:$src), 3130b57cec5SDimitry Andric "lxvdsx $XT, $src", IIC_LdStLFD, []>; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric let Predicates = [HasVSX, HasOnlySwappingMemOps] in 3160b57cec5SDimitry Andric def LXVW4X : XX1Form_memOp<31, 780, 3170b57cec5SDimitry Andric (outs vsrc:$XT), (ins memrr:$src), 3180b57cec5SDimitry Andric "lxvw4x $XT, $src", IIC_LdStLFD, 3190b57cec5SDimitry Andric []>; 3200b57cec5SDimitry Andric } // mayLoad 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric // Store indexed instructions 3230b57cec5SDimitry Andric let mayStore = 1, mayLoad = 0 in { 3240b57cec5SDimitry Andric let CodeSize = 3 in 3250b57cec5SDimitry Andric def STXSDX : XX1Form_memOp<31, 716, 3260b57cec5SDimitry Andric (outs), (ins vsfrc:$XT, memrr:$dst), 3270b57cec5SDimitry Andric "stxsdx $XT, $dst", IIC_LdStSTFD, 3280b57cec5SDimitry Andric []>; 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric // Pseudo instruction XFSTOREf64 will be expanded to STXSDX or STFDX later 3310b57cec5SDimitry Andric let CodeSize = 3 in 3320b57cec5SDimitry Andric def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst), 3330b57cec5SDimitry Andric "#XFSTOREf64", 334fe6060f1SDimitry Andric [(store f64:$XT, XForm:$dst)]>; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric let Predicates = [HasVSX, HasOnlySwappingMemOps] in { 3370b57cec5SDimitry Andric // The behaviour of this instruction is endianness-specific so we provide no 3380b57cec5SDimitry Andric // pattern to match it without considering endianness. 3390b57cec5SDimitry Andric def STXVD2X : XX1Form_memOp<31, 972, 3400b57cec5SDimitry Andric (outs), (ins vsrc:$XT, memrr:$dst), 3410b57cec5SDimitry Andric "stxvd2x $XT, $dst", IIC_LdStSTFD, 3420b57cec5SDimitry Andric []>; 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric def STXVW4X : XX1Form_memOp<31, 908, 3450b57cec5SDimitry Andric (outs), (ins vsrc:$XT, memrr:$dst), 3460b57cec5SDimitry Andric "stxvw4x $XT, $dst", IIC_LdStSTFD, 3470b57cec5SDimitry Andric []>; 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric } // mayStore 3500b57cec5SDimitry Andric 351e8d8bef9SDimitry Andric let mayRaiseFPException = 1 in { 352e8d8bef9SDimitry Andric let Uses = [RM] in { 3530b57cec5SDimitry Andric // Add/Mul Instructions 3540b57cec5SDimitry Andric let isCommutable = 1 in { 3550b57cec5SDimitry Andric def XSADDDP : XX3Form<60, 32, 3560b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 3570b57cec5SDimitry Andric "xsadddp $XT, $XA, $XB", IIC_VecFP, 3585ffd83dbSDimitry Andric [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>; 3590b57cec5SDimitry Andric def XSMULDP : XX3Form<60, 48, 3600b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 3610b57cec5SDimitry Andric "xsmuldp $XT, $XA, $XB", IIC_VecFP, 3625ffd83dbSDimitry Andric [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>; 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric def XVADDDP : XX3Form<60, 96, 3650b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 3660b57cec5SDimitry Andric "xvadddp $XT, $XA, $XB", IIC_VecFP, 3675ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>; 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric def XVADDSP : XX3Form<60, 64, 3700b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 3710b57cec5SDimitry Andric "xvaddsp $XT, $XA, $XB", IIC_VecFP, 3725ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>; 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric def XVMULDP : XX3Form<60, 112, 3750b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 3760b57cec5SDimitry Andric "xvmuldp $XT, $XA, $XB", IIC_VecFP, 3775ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric def XVMULSP : XX3Form<60, 80, 3800b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 3810b57cec5SDimitry Andric "xvmulsp $XT, $XA, $XB", IIC_VecFP, 3825ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric // Subtract Instructions 3860b57cec5SDimitry Andric def XSSUBDP : XX3Form<60, 40, 3870b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 3880b57cec5SDimitry Andric "xssubdp $XT, $XA, $XB", IIC_VecFP, 3895ffd83dbSDimitry Andric [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>; 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric def XVSUBDP : XX3Form<60, 104, 3920b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 3930b57cec5SDimitry Andric "xvsubdp $XT, $XA, $XB", IIC_VecFP, 3945ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>; 3950b57cec5SDimitry Andric def XVSUBSP : XX3Form<60, 72, 3960b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 3970b57cec5SDimitry Andric "xvsubsp $XT, $XA, $XB", IIC_VecFP, 3985ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // FMA Instructions 4010b57cec5SDimitry Andric let BaseName = "XSMADDADP" in { 4020b57cec5SDimitry Andric let isCommutable = 1 in 4030b57cec5SDimitry Andric def XSMADDADP : XX3Form<60, 33, 4040b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4050b57cec5SDimitry Andric "xsmaddadp $XT, $XA, $XB", IIC_VecFP, 4065ffd83dbSDimitry Andric [(set f64:$XT, (any_fma f64:$XA, f64:$XB, f64:$XTi))]>, 4070b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4080b57cec5SDimitry Andric AltVSXFMARel; 4090b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 4100b57cec5SDimitry Andric def XSMADDMDP : XX3Form<60, 41, 4110b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4120b57cec5SDimitry Andric "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 4130b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4140b57cec5SDimitry Andric AltVSXFMARel; 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric let BaseName = "XSMSUBADP" in { 4180b57cec5SDimitry Andric let isCommutable = 1 in 4190b57cec5SDimitry Andric def XSMSUBADP : XX3Form<60, 49, 4200b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4210b57cec5SDimitry Andric "xsmsubadp $XT, $XA, $XB", IIC_VecFP, 4225ffd83dbSDimitry Andric [(set f64:$XT, (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>, 4230b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4240b57cec5SDimitry Andric AltVSXFMARel; 4250b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 4260b57cec5SDimitry Andric def XSMSUBMDP : XX3Form<60, 57, 4270b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4280b57cec5SDimitry Andric "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 4290b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4300b57cec5SDimitry Andric AltVSXFMARel; 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric let BaseName = "XSNMADDADP" in { 4340b57cec5SDimitry Andric let isCommutable = 1 in 4350b57cec5SDimitry Andric def XSNMADDADP : XX3Form<60, 161, 4360b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4370b57cec5SDimitry Andric "xsnmaddadp $XT, $XA, $XB", IIC_VecFP, 4385ffd83dbSDimitry Andric [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, f64:$XTi)))]>, 4390b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4400b57cec5SDimitry Andric AltVSXFMARel; 4410b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 4420b57cec5SDimitry Andric def XSNMADDMDP : XX3Form<60, 169, 4430b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4440b57cec5SDimitry Andric "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 4450b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4460b57cec5SDimitry Andric AltVSXFMARel; 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric let BaseName = "XSNMSUBADP" in { 4500b57cec5SDimitry Andric let isCommutable = 1 in 4510b57cec5SDimitry Andric def XSNMSUBADP : XX3Form<60, 177, 4520b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4530b57cec5SDimitry Andric "xsnmsubadp $XT, $XA, $XB", IIC_VecFP, 4545ffd83dbSDimitry Andric [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>, 4550b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4560b57cec5SDimitry Andric AltVSXFMARel; 4570b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 4580b57cec5SDimitry Andric def XSNMSUBMDP : XX3Form<60, 185, 4590b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB), 4600b57cec5SDimitry Andric "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 4610b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4620b57cec5SDimitry Andric AltVSXFMARel; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric let BaseName = "XVMADDADP" in { 4660b57cec5SDimitry Andric let isCommutable = 1 in 4670b57cec5SDimitry Andric def XVMADDADP : XX3Form<60, 97, 4680b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 4690b57cec5SDimitry Andric "xvmaddadp $XT, $XA, $XB", IIC_VecFP, 4705ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>, 4710b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4720b57cec5SDimitry Andric AltVSXFMARel; 4730b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 4740b57cec5SDimitry Andric def XVMADDMDP : XX3Form<60, 105, 4750b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 4760b57cec5SDimitry Andric "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 4770b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4780b57cec5SDimitry Andric AltVSXFMARel; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric let BaseName = "XVMADDASP" in { 4820b57cec5SDimitry Andric let isCommutable = 1 in 4830b57cec5SDimitry Andric def XVMADDASP : XX3Form<60, 65, 4840b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 4850b57cec5SDimitry Andric "xvmaddasp $XT, $XA, $XB", IIC_VecFP, 4865ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>, 4870b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4880b57cec5SDimitry Andric AltVSXFMARel; 4890b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 4900b57cec5SDimitry Andric def XVMADDMSP : XX3Form<60, 73, 4910b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 4920b57cec5SDimitry Andric "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 4930b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 4940b57cec5SDimitry Andric AltVSXFMARel; 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric let BaseName = "XVMSUBADP" in { 4980b57cec5SDimitry Andric let isCommutable = 1 in 4990b57cec5SDimitry Andric def XVMSUBADP : XX3Form<60, 113, 5000b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5010b57cec5SDimitry Andric "xvmsubadp $XT, $XA, $XB", IIC_VecFP, 5025ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>, 5030b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5040b57cec5SDimitry Andric AltVSXFMARel; 5050b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 5060b57cec5SDimitry Andric def XVMSUBMDP : XX3Form<60, 121, 5070b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5080b57cec5SDimitry Andric "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 5090b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5100b57cec5SDimitry Andric AltVSXFMARel; 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric let BaseName = "XVMSUBASP" in { 5140b57cec5SDimitry Andric let isCommutable = 1 in 5150b57cec5SDimitry Andric def XVMSUBASP : XX3Form<60, 81, 5160b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5170b57cec5SDimitry Andric "xvmsubasp $XT, $XA, $XB", IIC_VecFP, 5185ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>, 5190b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5200b57cec5SDimitry Andric AltVSXFMARel; 5210b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 5220b57cec5SDimitry Andric def XVMSUBMSP : XX3Form<60, 89, 5230b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5240b57cec5SDimitry Andric "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 5250b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5260b57cec5SDimitry Andric AltVSXFMARel; 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric let BaseName = "XVNMADDADP" in { 5300b57cec5SDimitry Andric let isCommutable = 1 in 5310b57cec5SDimitry Andric def XVNMADDADP : XX3Form<60, 225, 5320b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5330b57cec5SDimitry Andric "xvnmaddadp $XT, $XA, $XB", IIC_VecFP, 5345ffd83dbSDimitry Andric [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>, 5350b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5360b57cec5SDimitry Andric AltVSXFMARel; 5370b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 5380b57cec5SDimitry Andric def XVNMADDMDP : XX3Form<60, 233, 5390b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5400b57cec5SDimitry Andric "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>, 5410b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5420b57cec5SDimitry Andric AltVSXFMARel; 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric let BaseName = "XVNMADDASP" in { 5460b57cec5SDimitry Andric let isCommutable = 1 in 5470b57cec5SDimitry Andric def XVNMADDASP : XX3Form<60, 193, 5480b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5490b57cec5SDimitry Andric "xvnmaddasp $XT, $XA, $XB", IIC_VecFP, 5500b57cec5SDimitry Andric [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>, 5510b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5520b57cec5SDimitry Andric AltVSXFMARel; 5530b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 5540b57cec5SDimitry Andric def XVNMADDMSP : XX3Form<60, 201, 5550b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5560b57cec5SDimitry Andric "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 5570b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5580b57cec5SDimitry Andric AltVSXFMARel; 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric let BaseName = "XVNMSUBADP" in { 5620b57cec5SDimitry Andric let isCommutable = 1 in 5630b57cec5SDimitry Andric def XVNMSUBADP : XX3Form<60, 241, 5640b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5650b57cec5SDimitry Andric "xvnmsubadp $XT, $XA, $XB", IIC_VecFP, 5665ffd83dbSDimitry Andric [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>, 5670b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5680b57cec5SDimitry Andric AltVSXFMARel; 5690b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 5700b57cec5SDimitry Andric def XVNMSUBMDP : XX3Form<60, 249, 5710b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5720b57cec5SDimitry Andric "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>, 5730b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5740b57cec5SDimitry Andric AltVSXFMARel; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric let BaseName = "XVNMSUBASP" in { 5780b57cec5SDimitry Andric let isCommutable = 1 in 5790b57cec5SDimitry Andric def XVNMSUBASP : XX3Form<60, 209, 5800b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5810b57cec5SDimitry Andric "xvnmsubasp $XT, $XA, $XB", IIC_VecFP, 5825ffd83dbSDimitry Andric [(set v4f32:$XT, (fneg (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>, 5830b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5840b57cec5SDimitry Andric AltVSXFMARel; 5850b57cec5SDimitry Andric let IsVSXFMAAlt = 1 in 5860b57cec5SDimitry Andric def XVNMSUBMSP : XX3Form<60, 217, 5870b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB), 5880b57cec5SDimitry Andric "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 5890b57cec5SDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 5900b57cec5SDimitry Andric AltVSXFMARel; 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric // Division Instructions 5940b57cec5SDimitry Andric def XSDIVDP : XX3Form<60, 56, 5950b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 5960b57cec5SDimitry Andric "xsdivdp $XT, $XA, $XB", IIC_FPDivD, 5975ffd83dbSDimitry Andric [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>; 5980b57cec5SDimitry Andric def XSSQRTDP : XX2Form<60, 75, 5990b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 6000b57cec5SDimitry Andric "xssqrtdp $XT, $XB", IIC_FPSqrtD, 6015ffd83dbSDimitry Andric [(set f64:$XT, (any_fsqrt f64:$XB))]>; 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric def XSREDP : XX2Form<60, 90, 6040b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 6050b57cec5SDimitry Andric "xsredp $XT, $XB", IIC_VecFP, 6060b57cec5SDimitry Andric [(set f64:$XT, (PPCfre f64:$XB))]>; 6070b57cec5SDimitry Andric def XSRSQRTEDP : XX2Form<60, 74, 6080b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 6090b57cec5SDimitry Andric "xsrsqrtedp $XT, $XB", IIC_VecFP, 6100b57cec5SDimitry Andric [(set f64:$XT, (PPCfrsqrte f64:$XB))]>; 6110b57cec5SDimitry Andric 612e8d8bef9SDimitry Andric let mayRaiseFPException = 0 in { 6130b57cec5SDimitry Andric def XSTDIVDP : XX3Form_1<60, 61, 6140b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 6150b57cec5SDimitry Andric "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>; 6160b57cec5SDimitry Andric def XSTSQRTDP : XX2Form_1<60, 106, 6170b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XB), 618e8d8bef9SDimitry Andric "xstsqrtdp $crD, $XB", IIC_FPCompare, 619e8d8bef9SDimitry Andric [(set i32:$crD, (PPCftsqrt f64:$XB))]>; 620e8d8bef9SDimitry Andric def XVTDIVDP : XX3Form_1<60, 125, 621e8d8bef9SDimitry Andric (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), 622e8d8bef9SDimitry Andric "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>; 623e8d8bef9SDimitry Andric def XVTDIVSP : XX3Form_1<60, 93, 624e8d8bef9SDimitry Andric (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB), 625e8d8bef9SDimitry Andric "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>; 626e8d8bef9SDimitry Andric 627e8d8bef9SDimitry Andric def XVTSQRTDP : XX2Form_1<60, 234, 628e8d8bef9SDimitry Andric (outs crrc:$crD), (ins vsrc:$XB), 629e8d8bef9SDimitry Andric "xvtsqrtdp $crD, $XB", IIC_FPCompare, 630e8d8bef9SDimitry Andric [(set i32:$crD, (PPCftsqrt v2f64:$XB))]>; 631e8d8bef9SDimitry Andric def XVTSQRTSP : XX2Form_1<60, 170, 632e8d8bef9SDimitry Andric (outs crrc:$crD), (ins vsrc:$XB), 633e8d8bef9SDimitry Andric "xvtsqrtsp $crD, $XB", IIC_FPCompare, 634e8d8bef9SDimitry Andric [(set i32:$crD, (PPCftsqrt v4f32:$XB))]>; 635e8d8bef9SDimitry Andric } 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric def XVDIVDP : XX3Form<60, 120, 6380b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 6390b57cec5SDimitry Andric "xvdivdp $XT, $XA, $XB", IIC_FPDivD, 6405ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>; 6410b57cec5SDimitry Andric def XVDIVSP : XX3Form<60, 88, 6420b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 6430b57cec5SDimitry Andric "xvdivsp $XT, $XA, $XB", IIC_FPDivS, 6445ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>; 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric def XVSQRTDP : XX2Form<60, 203, 6470b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 6480b57cec5SDimitry Andric "xvsqrtdp $XT, $XB", IIC_FPSqrtD, 6495ffd83dbSDimitry Andric [(set v2f64:$XT, (any_fsqrt v2f64:$XB))]>; 6500b57cec5SDimitry Andric def XVSQRTSP : XX2Form<60, 139, 6510b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 6520b57cec5SDimitry Andric "xvsqrtsp $XT, $XB", IIC_FPSqrtS, 6535ffd83dbSDimitry Andric [(set v4f32:$XT, (any_fsqrt v4f32:$XB))]>; 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric def XVREDP : XX2Form<60, 218, 6560b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 6570b57cec5SDimitry Andric "xvredp $XT, $XB", IIC_VecFP, 6580b57cec5SDimitry Andric [(set v2f64:$XT, (PPCfre v2f64:$XB))]>; 6590b57cec5SDimitry Andric def XVRESP : XX2Form<60, 154, 6600b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 6610b57cec5SDimitry Andric "xvresp $XT, $XB", IIC_VecFP, 6620b57cec5SDimitry Andric [(set v4f32:$XT, (PPCfre v4f32:$XB))]>; 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric def XVRSQRTEDP : XX2Form<60, 202, 6650b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 6660b57cec5SDimitry Andric "xvrsqrtedp $XT, $XB", IIC_VecFP, 6670b57cec5SDimitry Andric [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>; 6680b57cec5SDimitry Andric def XVRSQRTESP : XX2Form<60, 138, 6690b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 6700b57cec5SDimitry Andric "xvrsqrtesp $XT, $XB", IIC_VecFP, 6710b57cec5SDimitry Andric [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>; 6720b57cec5SDimitry Andric 6730b57cec5SDimitry Andric // Compare Instructions 6740b57cec5SDimitry Andric def XSCMPODP : XX3Form_1<60, 43, 6750b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 6760b57cec5SDimitry Andric "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>; 6770b57cec5SDimitry Andric def XSCMPUDP : XX3Form_1<60, 35, 6780b57cec5SDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 6790b57cec5SDimitry Andric "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>; 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric defm XVCMPEQDP : XX3Form_Rcr<60, 99, 6820b57cec5SDimitry Andric "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare, 6830b57cec5SDimitry Andric int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>; 6840b57cec5SDimitry Andric defm XVCMPEQSP : XX3Form_Rcr<60, 67, 6850b57cec5SDimitry Andric "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare, 6860b57cec5SDimitry Andric int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>; 6870b57cec5SDimitry Andric defm XVCMPGEDP : XX3Form_Rcr<60, 115, 6880b57cec5SDimitry Andric "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare, 6890b57cec5SDimitry Andric int_ppc_vsx_xvcmpgedp, v2i64, v2f64>; 6900b57cec5SDimitry Andric defm XVCMPGESP : XX3Form_Rcr<60, 83, 6910b57cec5SDimitry Andric "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare, 6920b57cec5SDimitry Andric int_ppc_vsx_xvcmpgesp, v4i32, v4f32>; 6930b57cec5SDimitry Andric defm XVCMPGTDP : XX3Form_Rcr<60, 107, 6940b57cec5SDimitry Andric "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare, 6950b57cec5SDimitry Andric int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>; 6960b57cec5SDimitry Andric defm XVCMPGTSP : XX3Form_Rcr<60, 75, 6970b57cec5SDimitry Andric "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare, 6980b57cec5SDimitry Andric int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>; 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric // Move Instructions 701e8d8bef9SDimitry Andric let mayRaiseFPException = 0 in { 7020b57cec5SDimitry Andric def XSABSDP : XX2Form<60, 345, 7030b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7040b57cec5SDimitry Andric "xsabsdp $XT, $XB", IIC_VecFP, 7050b57cec5SDimitry Andric [(set f64:$XT, (fabs f64:$XB))]>; 7060b57cec5SDimitry Andric def XSNABSDP : XX2Form<60, 361, 7070b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7080b57cec5SDimitry Andric "xsnabsdp $XT, $XB", IIC_VecFP, 7090b57cec5SDimitry Andric [(set f64:$XT, (fneg (fabs f64:$XB)))]>; 71081ad6265SDimitry Andric let isCodeGenOnly = 1 in 71181ad6265SDimitry Andric def XSNABSDPs : XX2Form<60, 361, 71281ad6265SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 71381ad6265SDimitry Andric "xsnabsdp $XT, $XB", IIC_VecFP, 71481ad6265SDimitry Andric [(set f32:$XT, (fneg (fabs f32:$XB)))]>; 7150b57cec5SDimitry Andric def XSNEGDP : XX2Form<60, 377, 7160b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7170b57cec5SDimitry Andric "xsnegdp $XT, $XB", IIC_VecFP, 7180b57cec5SDimitry Andric [(set f64:$XT, (fneg f64:$XB))]>; 7190b57cec5SDimitry Andric def XSCPSGNDP : XX3Form<60, 176, 7200b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 7210b57cec5SDimitry Andric "xscpsgndp $XT, $XA, $XB", IIC_VecFP, 7220b57cec5SDimitry Andric [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>; 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric def XVABSDP : XX2Form<60, 473, 7250b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 7260b57cec5SDimitry Andric "xvabsdp $XT, $XB", IIC_VecFP, 7270b57cec5SDimitry Andric [(set v2f64:$XT, (fabs v2f64:$XB))]>; 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric def XVABSSP : XX2Form<60, 409, 7300b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 7310b57cec5SDimitry Andric "xvabssp $XT, $XB", IIC_VecFP, 7320b57cec5SDimitry Andric [(set v4f32:$XT, (fabs v4f32:$XB))]>; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric def XVCPSGNDP : XX3Form<60, 240, 7350b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 7360b57cec5SDimitry Andric "xvcpsgndp $XT, $XA, $XB", IIC_VecFP, 7370b57cec5SDimitry Andric [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>; 7380b57cec5SDimitry Andric def XVCPSGNSP : XX3Form<60, 208, 7390b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 7400b57cec5SDimitry Andric "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP, 7410b57cec5SDimitry Andric [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>; 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric def XVNABSDP : XX2Form<60, 489, 7440b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 7450b57cec5SDimitry Andric "xvnabsdp $XT, $XB", IIC_VecFP, 7460b57cec5SDimitry Andric [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>; 7470b57cec5SDimitry Andric def XVNABSSP : XX2Form<60, 425, 7480b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 7490b57cec5SDimitry Andric "xvnabssp $XT, $XB", IIC_VecFP, 7500b57cec5SDimitry Andric [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>; 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric def XVNEGDP : XX2Form<60, 505, 7530b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 7540b57cec5SDimitry Andric "xvnegdp $XT, $XB", IIC_VecFP, 7550b57cec5SDimitry Andric [(set v2f64:$XT, (fneg v2f64:$XB))]>; 7560b57cec5SDimitry Andric def XVNEGSP : XX2Form<60, 441, 7570b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 7580b57cec5SDimitry Andric "xvnegsp $XT, $XB", IIC_VecFP, 7590b57cec5SDimitry Andric [(set v4f32:$XT, (fneg v4f32:$XB))]>; 760e8d8bef9SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric // Conversion Instructions 7630b57cec5SDimitry Andric def XSCVDPSP : XX2Form<60, 265, 7640b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7650b57cec5SDimitry Andric "xscvdpsp $XT, $XB", IIC_VecFP, []>; 7660b57cec5SDimitry Andric def XSCVDPSXDS : XX2Form<60, 344, 7670b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7680b57cec5SDimitry Andric "xscvdpsxds $XT, $XB", IIC_VecFP, 769e8d8bef9SDimitry Andric [(set f64:$XT, (PPCany_fctidz f64:$XB))]>; 7700b57cec5SDimitry Andric let isCodeGenOnly = 1 in 7710b57cec5SDimitry Andric def XSCVDPSXDSs : XX2Form<60, 344, 7720b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 7730b57cec5SDimitry Andric "xscvdpsxds $XT, $XB", IIC_VecFP, 774e8d8bef9SDimitry Andric [(set f32:$XT, (PPCany_fctidz f32:$XB))]>; 7750b57cec5SDimitry Andric def XSCVDPSXWS : XX2Form<60, 88, 7760b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7770b57cec5SDimitry Andric "xscvdpsxws $XT, $XB", IIC_VecFP, 778e8d8bef9SDimitry Andric [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>; 7790b57cec5SDimitry Andric let isCodeGenOnly = 1 in 7800b57cec5SDimitry Andric def XSCVDPSXWSs : XX2Form<60, 88, 7810b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 7820b57cec5SDimitry Andric "xscvdpsxws $XT, $XB", IIC_VecFP, 783e8d8bef9SDimitry Andric [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>; 7840b57cec5SDimitry Andric def XSCVDPUXDS : XX2Form<60, 328, 7850b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7860b57cec5SDimitry Andric "xscvdpuxds $XT, $XB", IIC_VecFP, 787e8d8bef9SDimitry Andric [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>; 7880b57cec5SDimitry Andric let isCodeGenOnly = 1 in 7890b57cec5SDimitry Andric def XSCVDPUXDSs : XX2Form<60, 328, 7900b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 7910b57cec5SDimitry Andric "xscvdpuxds $XT, $XB", IIC_VecFP, 792e8d8bef9SDimitry Andric [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>; 7930b57cec5SDimitry Andric def XSCVDPUXWS : XX2Form<60, 72, 7940b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 7950b57cec5SDimitry Andric "xscvdpuxws $XT, $XB", IIC_VecFP, 796e8d8bef9SDimitry Andric [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>; 7970b57cec5SDimitry Andric let isCodeGenOnly = 1 in 7980b57cec5SDimitry Andric def XSCVDPUXWSs : XX2Form<60, 72, 7990b57cec5SDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 8000b57cec5SDimitry Andric "xscvdpuxws $XT, $XB", IIC_VecFP, 801e8d8bef9SDimitry Andric [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>; 8020b57cec5SDimitry Andric def XSCVSPDP : XX2Form<60, 329, 8030b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 8040b57cec5SDimitry Andric "xscvspdp $XT, $XB", IIC_VecFP, []>; 8050b57cec5SDimitry Andric def XSCVSXDDP : XX2Form<60, 376, 8060b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 8070b57cec5SDimitry Andric "xscvsxddp $XT, $XB", IIC_VecFP, 808e8d8bef9SDimitry Andric [(set f64:$XT, (PPCany_fcfid f64:$XB))]>; 8090b57cec5SDimitry Andric def XSCVUXDDP : XX2Form<60, 360, 8100b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 8110b57cec5SDimitry Andric "xscvuxddp $XT, $XB", IIC_VecFP, 812e8d8bef9SDimitry Andric [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>; 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric def XVCVDPSP : XX2Form<60, 393, 8150b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8160b57cec5SDimitry Andric "xvcvdpsp $XT, $XB", IIC_VecFP, 8170b57cec5SDimitry Andric [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>; 8180b57cec5SDimitry Andric def XVCVDPSXDS : XX2Form<60, 472, 8190b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8200b57cec5SDimitry Andric "xvcvdpsxds $XT, $XB", IIC_VecFP, 821e8d8bef9SDimitry Andric [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>; 8220b57cec5SDimitry Andric def XVCVDPSXWS : XX2Form<60, 216, 8230b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8240b57cec5SDimitry Andric "xvcvdpsxws $XT, $XB", IIC_VecFP, 8250b57cec5SDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>; 8260b57cec5SDimitry Andric def XVCVDPUXDS : XX2Form<60, 456, 8270b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8280b57cec5SDimitry Andric "xvcvdpuxds $XT, $XB", IIC_VecFP, 829e8d8bef9SDimitry Andric [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>; 8300b57cec5SDimitry Andric def XVCVDPUXWS : XX2Form<60, 200, 8310b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8320b57cec5SDimitry Andric "xvcvdpuxws $XT, $XB", IIC_VecFP, 8330b57cec5SDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>; 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric def XVCVSPDP : XX2Form<60, 457, 8360b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8370b57cec5SDimitry Andric "xvcvspdp $XT, $XB", IIC_VecFP, 8380b57cec5SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>; 8390b57cec5SDimitry Andric def XVCVSPSXDS : XX2Form<60, 408, 8400b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 841fe6060f1SDimitry Andric "xvcvspsxds $XT, $XB", IIC_VecFP, 842fe6060f1SDimitry Andric [(set v2i64:$XT, (int_ppc_vsx_xvcvspsxds v4f32:$XB))]>; 8430b57cec5SDimitry Andric def XVCVSPSXWS : XX2Form<60, 152, 8440b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8450b57cec5SDimitry Andric "xvcvspsxws $XT, $XB", IIC_VecFP, 846e8d8bef9SDimitry Andric [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>; 8470b57cec5SDimitry Andric def XVCVSPUXDS : XX2Form<60, 392, 8480b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 849fe6060f1SDimitry Andric "xvcvspuxds $XT, $XB", IIC_VecFP, 850fe6060f1SDimitry Andric [(set v2i64:$XT, (int_ppc_vsx_xvcvspuxds v4f32:$XB))]>; 8510b57cec5SDimitry Andric def XVCVSPUXWS : XX2Form<60, 136, 8520b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8530b57cec5SDimitry Andric "xvcvspuxws $XT, $XB", IIC_VecFP, 854e8d8bef9SDimitry Andric [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>; 8550b57cec5SDimitry Andric def XVCVSXDDP : XX2Form<60, 504, 8560b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8570b57cec5SDimitry Andric "xvcvsxddp $XT, $XB", IIC_VecFP, 858e8d8bef9SDimitry Andric [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>; 8590b57cec5SDimitry Andric def XVCVSXDSP : XX2Form<60, 440, 8600b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8610b57cec5SDimitry Andric "xvcvsxdsp $XT, $XB", IIC_VecFP, 8620b57cec5SDimitry Andric [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>; 8630b57cec5SDimitry Andric def XVCVSXWSP : XX2Form<60, 184, 8640b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8650b57cec5SDimitry Andric "xvcvsxwsp $XT, $XB", IIC_VecFP, 866e8d8bef9SDimitry Andric [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>; 8670b57cec5SDimitry Andric def XVCVUXDDP : XX2Form<60, 488, 8680b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8690b57cec5SDimitry Andric "xvcvuxddp $XT, $XB", IIC_VecFP, 870e8d8bef9SDimitry Andric [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>; 8710b57cec5SDimitry Andric def XVCVUXDSP : XX2Form<60, 424, 8720b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8730b57cec5SDimitry Andric "xvcvuxdsp $XT, $XB", IIC_VecFP, 8740b57cec5SDimitry Andric [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>; 875e8d8bef9SDimitry Andric def XVCVUXWSP : XX2Form<60, 168, 876e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 877e8d8bef9SDimitry Andric "xvcvuxwsp $XT, $XB", IIC_VecFP, 878e8d8bef9SDimitry Andric [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>; 879e8d8bef9SDimitry Andric 880e8d8bef9SDimitry Andric let mayRaiseFPException = 0 in { 881e8d8bef9SDimitry Andric def XVCVSXWDP : XX2Form<60, 248, 882e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 883e8d8bef9SDimitry Andric "xvcvsxwdp $XT, $XB", IIC_VecFP, 884e8d8bef9SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>; 8850b57cec5SDimitry Andric def XVCVUXWDP : XX2Form<60, 232, 8860b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 8870b57cec5SDimitry Andric "xvcvuxwdp $XT, $XB", IIC_VecFP, 8880b57cec5SDimitry Andric [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>; 889e8d8bef9SDimitry Andric } 8900b57cec5SDimitry Andric 891e8d8bef9SDimitry Andric // Rounding Instructions respecting current rounding mode 8920b57cec5SDimitry Andric def XSRDPIC : XX2Form<60, 107, 8930b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 894349cc55cSDimitry Andric "xsrdpic $XT, $XB", IIC_VecFP, []>; 8950b57cec5SDimitry Andric def XVRDPIC : XX2Form<60, 235, 8960b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 897349cc55cSDimitry Andric "xvrdpic $XT, $XB", IIC_VecFP, []>; 8980b57cec5SDimitry Andric def XVRSPIC : XX2Form<60, 171, 8990b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 900349cc55cSDimitry Andric "xvrspic $XT, $XB", IIC_VecFP, []>; 9010b57cec5SDimitry Andric // Max/Min Instructions 9020b57cec5SDimitry Andric let isCommutable = 1 in { 9030b57cec5SDimitry Andric def XSMAXDP : XX3Form<60, 160, 9040b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 9050b57cec5SDimitry Andric "xsmaxdp $XT, $XA, $XB", IIC_VecFP, 9060b57cec5SDimitry Andric [(set vsfrc:$XT, 9070b57cec5SDimitry Andric (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>; 9080b57cec5SDimitry Andric def XSMINDP : XX3Form<60, 168, 9090b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 9100b57cec5SDimitry Andric "xsmindp $XT, $XA, $XB", IIC_VecFP, 9110b57cec5SDimitry Andric [(set vsfrc:$XT, 9120b57cec5SDimitry Andric (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>; 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric def XVMAXDP : XX3Form<60, 224, 9150b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 9160b57cec5SDimitry Andric "xvmaxdp $XT, $XA, $XB", IIC_VecFP, 9170b57cec5SDimitry Andric [(set vsrc:$XT, 9180b57cec5SDimitry Andric (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>; 9190b57cec5SDimitry Andric def XVMINDP : XX3Form<60, 232, 9200b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 9210b57cec5SDimitry Andric "xvmindp $XT, $XA, $XB", IIC_VecFP, 9220b57cec5SDimitry Andric [(set vsrc:$XT, 9230b57cec5SDimitry Andric (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>; 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andric def XVMAXSP : XX3Form<60, 192, 9260b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 9270b57cec5SDimitry Andric "xvmaxsp $XT, $XA, $XB", IIC_VecFP, 9280b57cec5SDimitry Andric [(set vsrc:$XT, 9290b57cec5SDimitry Andric (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>; 9300b57cec5SDimitry Andric def XVMINSP : XX3Form<60, 200, 9310b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 9320b57cec5SDimitry Andric "xvminsp $XT, $XA, $XB", IIC_VecFP, 9330b57cec5SDimitry Andric [(set vsrc:$XT, 9340b57cec5SDimitry Andric (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>; 9350b57cec5SDimitry Andric } // isCommutable 936e8d8bef9SDimitry Andric } // Uses = [RM] 937e8d8bef9SDimitry Andric 938e8d8bef9SDimitry Andric // Rounding Instructions with static direction. 939e8d8bef9SDimitry Andric def XSRDPI : XX2Form<60, 73, 940e8d8bef9SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 941e8d8bef9SDimitry Andric "xsrdpi $XT, $XB", IIC_VecFP, 942e8d8bef9SDimitry Andric [(set f64:$XT, (any_fround f64:$XB))]>; 943e8d8bef9SDimitry Andric def XSRDPIM : XX2Form<60, 121, 944e8d8bef9SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 945e8d8bef9SDimitry Andric "xsrdpim $XT, $XB", IIC_VecFP, 946e8d8bef9SDimitry Andric [(set f64:$XT, (any_ffloor f64:$XB))]>; 947e8d8bef9SDimitry Andric def XSRDPIP : XX2Form<60, 105, 948e8d8bef9SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 949e8d8bef9SDimitry Andric "xsrdpip $XT, $XB", IIC_VecFP, 950e8d8bef9SDimitry Andric [(set f64:$XT, (any_fceil f64:$XB))]>; 951e8d8bef9SDimitry Andric def XSRDPIZ : XX2Form<60, 89, 952e8d8bef9SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XB), 953e8d8bef9SDimitry Andric "xsrdpiz $XT, $XB", IIC_VecFP, 954e8d8bef9SDimitry Andric [(set f64:$XT, (any_ftrunc f64:$XB))]>; 955e8d8bef9SDimitry Andric 956e8d8bef9SDimitry Andric def XVRDPI : XX2Form<60, 201, 957e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 958e8d8bef9SDimitry Andric "xvrdpi $XT, $XB", IIC_VecFP, 959e8d8bef9SDimitry Andric [(set v2f64:$XT, (any_fround v2f64:$XB))]>; 960e8d8bef9SDimitry Andric def XVRDPIM : XX2Form<60, 249, 961e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 962e8d8bef9SDimitry Andric "xvrdpim $XT, $XB", IIC_VecFP, 963e8d8bef9SDimitry Andric [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>; 964e8d8bef9SDimitry Andric def XVRDPIP : XX2Form<60, 233, 965e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 966e8d8bef9SDimitry Andric "xvrdpip $XT, $XB", IIC_VecFP, 967e8d8bef9SDimitry Andric [(set v2f64:$XT, (any_fceil v2f64:$XB))]>; 968e8d8bef9SDimitry Andric def XVRDPIZ : XX2Form<60, 217, 969e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 970e8d8bef9SDimitry Andric "xvrdpiz $XT, $XB", IIC_VecFP, 971e8d8bef9SDimitry Andric [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>; 972e8d8bef9SDimitry Andric 973e8d8bef9SDimitry Andric def XVRSPI : XX2Form<60, 137, 974e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 975e8d8bef9SDimitry Andric "xvrspi $XT, $XB", IIC_VecFP, 976e8d8bef9SDimitry Andric [(set v4f32:$XT, (any_fround v4f32:$XB))]>; 977e8d8bef9SDimitry Andric def XVRSPIM : XX2Form<60, 185, 978e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 979e8d8bef9SDimitry Andric "xvrspim $XT, $XB", IIC_VecFP, 980e8d8bef9SDimitry Andric [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>; 981e8d8bef9SDimitry Andric def XVRSPIP : XX2Form<60, 169, 982e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 983e8d8bef9SDimitry Andric "xvrspip $XT, $XB", IIC_VecFP, 984e8d8bef9SDimitry Andric [(set v4f32:$XT, (any_fceil v4f32:$XB))]>; 985e8d8bef9SDimitry Andric def XVRSPIZ : XX2Form<60, 153, 986e8d8bef9SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB), 987e8d8bef9SDimitry Andric "xvrspiz $XT, $XB", IIC_VecFP, 988e8d8bef9SDimitry Andric [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>; 989e8d8bef9SDimitry Andric } // mayRaiseFPException 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric // Logical Instructions 9920b57cec5SDimitry Andric let isCommutable = 1 in 9930b57cec5SDimitry Andric def XXLAND : XX3Form<60, 130, 9940b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 9950b57cec5SDimitry Andric "xxland $XT, $XA, $XB", IIC_VecGeneral, 9960b57cec5SDimitry Andric [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>; 9970b57cec5SDimitry Andric def XXLANDC : XX3Form<60, 138, 9980b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 9990b57cec5SDimitry Andric "xxlandc $XT, $XA, $XB", IIC_VecGeneral, 10000b57cec5SDimitry Andric [(set v4i32:$XT, (and v4i32:$XA, 1001fe6060f1SDimitry Andric (vnot v4i32:$XB)))]>; 10020b57cec5SDimitry Andric let isCommutable = 1 in { 10030b57cec5SDimitry Andric def XXLNOR : XX3Form<60, 162, 10040b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10050b57cec5SDimitry Andric "xxlnor $XT, $XA, $XB", IIC_VecGeneral, 1006fe6060f1SDimitry Andric [(set v4i32:$XT, (vnot (or v4i32:$XA, 10070b57cec5SDimitry Andric v4i32:$XB)))]>; 10080b57cec5SDimitry Andric def XXLOR : XX3Form<60, 146, 10090b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10100b57cec5SDimitry Andric "xxlor $XT, $XA, $XB", IIC_VecGeneral, 10110b57cec5SDimitry Andric [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>; 10120b57cec5SDimitry Andric let isCodeGenOnly = 1 in 10130b57cec5SDimitry Andric def XXLORf: XX3Form<60, 146, 10140b57cec5SDimitry Andric (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB), 10150b57cec5SDimitry Andric "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>; 10160b57cec5SDimitry Andric def XXLXOR : XX3Form<60, 154, 10170b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10180b57cec5SDimitry Andric "xxlxor $XT, $XA, $XB", IIC_VecGeneral, 10190b57cec5SDimitry Andric [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>; 10200b57cec5SDimitry Andric } // isCommutable 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1, 10230b57cec5SDimitry Andric isReMaterializable = 1 in { 10248bcb0991SDimitry Andric def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins), 10250b57cec5SDimitry Andric "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 10260b57cec5SDimitry Andric [(set v4i32:$XT, (v4i32 immAllZerosV))]>; 10278bcb0991SDimitry Andric def XXLXORdpz : XX3Form_SameOp<60, 154, 10280b57cec5SDimitry Andric (outs vsfrc:$XT), (ins), 10290b57cec5SDimitry Andric "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 10300b57cec5SDimitry Andric [(set f64:$XT, (fpimm0))]>; 10318bcb0991SDimitry Andric def XXLXORspz : XX3Form_SameOp<60, 154, 10320b57cec5SDimitry Andric (outs vssrc:$XT), (ins), 10330b57cec5SDimitry Andric "xxlxor $XT, $XT, $XT", IIC_VecGeneral, 10340b57cec5SDimitry Andric [(set f32:$XT, (fpimm0))]>; 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric // Permutation Instructions 10380b57cec5SDimitry Andric def XXMRGHW : XX3Form<60, 18, 10390b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10400b57cec5SDimitry Andric "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>; 10410b57cec5SDimitry Andric def XXMRGLW : XX3Form<60, 50, 10420b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10430b57cec5SDimitry Andric "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>; 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric def XXPERMDI : XX3Form_2<60, 10, 10460b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM), 10470b57cec5SDimitry Andric "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, 10480b57cec5SDimitry Andric [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB, 10490b57cec5SDimitry Andric imm32SExt16:$DM))]>; 10500b57cec5SDimitry Andric let isCodeGenOnly = 1 in 1051349cc55cSDimitry Andric // Note that the input register class for `$XA` of XXPERMDIs is `vsfrc` which 1052349cc55cSDimitry Andric // is not the same with the input register class(`vsrc`) of XXPERMDI instruction. 1053349cc55cSDimitry Andric // We did this on purpose because: 1054349cc55cSDimitry Andric // 1: The input is primarily for loads that load a partial vector(LFIWZX, 1055349cc55cSDimitry Andric // etc.), no need for SUBREG_TO_REG. 1056349cc55cSDimitry Andric // 2: With `vsfrc` register class, in the final assembly, float registers 1057349cc55cSDimitry Andric // like `f0` are used instead of vector scalar register like `vs0`. This 1058349cc55cSDimitry Andric // helps readability. 10590b57cec5SDimitry Andric def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM), 10600b57cec5SDimitry Andric "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>; 10610b57cec5SDimitry Andric def XXSEL : XX4Form<60, 3, 10620b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC), 10630b57cec5SDimitry Andric "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>; 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric def XXSLDWI : XX3Form_2<60, 2, 10660b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW), 10670b57cec5SDimitry Andric "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm, 10680b57cec5SDimitry Andric [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB, 10690b57cec5SDimitry Andric imm32SExt16:$SHW))]>; 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric let isCodeGenOnly = 1 in 10720b57cec5SDimitry Andric def XXSLDWIs : XX3Form_2s<60, 2, 10730b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW), 10740b57cec5SDimitry Andric "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>; 10750b57cec5SDimitry Andric 10760b57cec5SDimitry Andric def XXSPLTW : XX2Form_2<60, 164, 10770b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM), 10780b57cec5SDimitry Andric "xxspltw $XT, $XB, $UIM", IIC_VecPerm, 10790b57cec5SDimitry Andric [(set v4i32:$XT, 10800b57cec5SDimitry Andric (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>; 10810b57cec5SDimitry Andric let isCodeGenOnly = 1 in 10820b57cec5SDimitry Andric def XXSPLTWs : XX2Form_2<60, 164, 10830b57cec5SDimitry Andric (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM), 10840b57cec5SDimitry Andric "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>; 10850b57cec5SDimitry Andric 10865ffd83dbSDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07 10875ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in { 10885ffd83dbSDimitry Andric let isCommutable = 1 in { 10895ffd83dbSDimitry Andric def XXLEQV : XX3Form<60, 186, 10905ffd83dbSDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10915ffd83dbSDimitry Andric "xxleqv $XT, $XA, $XB", IIC_VecGeneral, 1092fe6060f1SDimitry Andric [(set v4i32:$XT, (vnot (xor v4i32:$XA, v4i32:$XB)))]>; 10935ffd83dbSDimitry Andric def XXLNAND : XX3Form<60, 178, 10945ffd83dbSDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 10955ffd83dbSDimitry Andric "xxlnand $XT, $XA, $XB", IIC_VecGeneral, 1096fe6060f1SDimitry Andric [(set v4i32:$XT, (vnot (and v4i32:$XA, v4i32:$XB)))]>; 10975ffd83dbSDimitry Andric } // isCommutable 10980b57cec5SDimitry Andric 10995ffd83dbSDimitry Andric let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1, 11005ffd83dbSDimitry Andric isReMaterializable = 1 in { 11015ffd83dbSDimitry Andric def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins), 11025ffd83dbSDimitry Andric "xxleqv $XT, $XT, $XT", IIC_VecGeneral, 11035ffd83dbSDimitry Andric [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>; 11045ffd83dbSDimitry Andric } 11055ffd83dbSDimitry Andric 11065ffd83dbSDimitry Andric def XXLORC : XX3Form<60, 170, 11075ffd83dbSDimitry Andric (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB), 11085ffd83dbSDimitry Andric "xxlorc $XT, $XA, $XB", IIC_VecGeneral, 1109fe6060f1SDimitry Andric [(set v4i32:$XT, (or v4i32:$XA, (vnot v4i32:$XB)))]>; 11105ffd83dbSDimitry Andric 11115ffd83dbSDimitry Andric // VSX scalar loads introduced in ISA 2.07 11125ffd83dbSDimitry Andric let mayLoad = 1, mayStore = 0 in { 11135ffd83dbSDimitry Andric let CodeSize = 3 in 11145ffd83dbSDimitry Andric def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src), 11155ffd83dbSDimitry Andric "lxsspx $XT, $src", IIC_LdStLFD, []>; 11165ffd83dbSDimitry Andric def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src), 11175ffd83dbSDimitry Andric "lxsiwax $XT, $src", IIC_LdStLFD, []>; 11185ffd83dbSDimitry Andric def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src), 11195ffd83dbSDimitry Andric "lxsiwzx $XT, $src", IIC_LdStLFD, []>; 11205ffd83dbSDimitry Andric 11215ffd83dbSDimitry Andric // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later 11225ffd83dbSDimitry Andric let CodeSize = 3 in 11235ffd83dbSDimitry Andric def XFLOADf32 : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src), 11245ffd83dbSDimitry Andric "#XFLOADf32", 1125fe6060f1SDimitry Andric [(set f32:$XT, (load XForm:$src))]>; 11265ffd83dbSDimitry Andric // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later 11275ffd83dbSDimitry Andric def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), 11285ffd83dbSDimitry Andric "#LIWAX", 1129fe6060f1SDimitry Andric [(set f64:$XT, (PPClfiwax ForceXForm:$src))]>; 11305ffd83dbSDimitry Andric // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later 11315ffd83dbSDimitry Andric def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src), 11325ffd83dbSDimitry Andric "#LIWZX", 1133fe6060f1SDimitry Andric [(set f64:$XT, (PPClfiwzx ForceXForm:$src))]>; 11345ffd83dbSDimitry Andric } // mayLoad 11355ffd83dbSDimitry Andric 11365ffd83dbSDimitry Andric // VSX scalar stores introduced in ISA 2.07 11375ffd83dbSDimitry Andric let mayStore = 1, mayLoad = 0 in { 11385ffd83dbSDimitry Andric let CodeSize = 3 in 11395ffd83dbSDimitry Andric def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst), 11405ffd83dbSDimitry Andric "stxsspx $XT, $dst", IIC_LdStSTFD, []>; 11415ffd83dbSDimitry Andric def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst), 11425ffd83dbSDimitry Andric "stxsiwx $XT, $dst", IIC_LdStSTFD, []>; 11435ffd83dbSDimitry Andric 11445ffd83dbSDimitry Andric // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later 11455ffd83dbSDimitry Andric let CodeSize = 3 in 11465ffd83dbSDimitry Andric def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst), 11475ffd83dbSDimitry Andric "#XFSTOREf32", 1148fe6060f1SDimitry Andric [(store f32:$XT, XForm:$dst)]>; 11495ffd83dbSDimitry Andric // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later 11505ffd83dbSDimitry Andric def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst), 11515ffd83dbSDimitry Andric "#STIWX", 1152fe6060f1SDimitry Andric [(PPCstfiwx f64:$XT, ForceXForm:$dst)]>; 11535ffd83dbSDimitry Andric } // mayStore 11545ffd83dbSDimitry Andric 11555ffd83dbSDimitry Andric // VSX Elementary Scalar FP arithmetic (SP) 11565ffd83dbSDimitry Andric let mayRaiseFPException = 1 in { 11575ffd83dbSDimitry Andric let isCommutable = 1 in { 11585ffd83dbSDimitry Andric def XSADDSP : XX3Form<60, 0, 11595ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 11605ffd83dbSDimitry Andric "xsaddsp $XT, $XA, $XB", IIC_VecFP, 11615ffd83dbSDimitry Andric [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>; 11625ffd83dbSDimitry Andric def XSMULSP : XX3Form<60, 16, 11635ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 11645ffd83dbSDimitry Andric "xsmulsp $XT, $XA, $XB", IIC_VecFP, 11655ffd83dbSDimitry Andric [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>; 11665ffd83dbSDimitry Andric } // isCommutable 11675ffd83dbSDimitry Andric 11685ffd83dbSDimitry Andric def XSSUBSP : XX3Form<60, 8, 11695ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 11705ffd83dbSDimitry Andric "xssubsp $XT, $XA, $XB", IIC_VecFP, 11715ffd83dbSDimitry Andric [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>; 11725ffd83dbSDimitry Andric def XSDIVSP : XX3Form<60, 24, 11735ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB), 11745ffd83dbSDimitry Andric "xsdivsp $XT, $XA, $XB", IIC_FPDivS, 11755ffd83dbSDimitry Andric [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>; 11765ffd83dbSDimitry Andric 11775ffd83dbSDimitry Andric def XSRESP : XX2Form<60, 26, 11785ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 11795ffd83dbSDimitry Andric "xsresp $XT, $XB", IIC_VecFP, 11805ffd83dbSDimitry Andric [(set f32:$XT, (PPCfre f32:$XB))]>; 11815ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 1182e8d8bef9SDimitry Andric let hasSideEffects = 1 in 11835ffd83dbSDimitry Andric def XSRSP : XX2Form<60, 281, 11845ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vsfrc:$XB), 11855ffd83dbSDimitry Andric "xsrsp $XT, $XB", IIC_VecFP, 11865ffd83dbSDimitry Andric [(set f32:$XT, (any_fpround f64:$XB))]>; 11875ffd83dbSDimitry Andric def XSSQRTSP : XX2Form<60, 11, 11885ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 11895ffd83dbSDimitry Andric "xssqrtsp $XT, $XB", IIC_FPSqrtS, 11905ffd83dbSDimitry Andric [(set f32:$XT, (any_fsqrt f32:$XB))]>; 11915ffd83dbSDimitry Andric def XSRSQRTESP : XX2Form<60, 10, 11925ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vssrc:$XB), 11935ffd83dbSDimitry Andric "xsrsqrtesp $XT, $XB", IIC_VecFP, 11945ffd83dbSDimitry Andric [(set f32:$XT, (PPCfrsqrte f32:$XB))]>; 11955ffd83dbSDimitry Andric 11965ffd83dbSDimitry Andric // FMA Instructions 11975ffd83dbSDimitry Andric let BaseName = "XSMADDASP" in { 11985ffd83dbSDimitry Andric let isCommutable = 1 in 11995ffd83dbSDimitry Andric def XSMADDASP : XX3Form<60, 1, 12005ffd83dbSDimitry Andric (outs vssrc:$XT), 12015ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12025ffd83dbSDimitry Andric "xsmaddasp $XT, $XA, $XB", IIC_VecFP, 12035ffd83dbSDimitry Andric [(set f32:$XT, (any_fma f32:$XA, f32:$XB, f32:$XTi))]>, 12045ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12055ffd83dbSDimitry Andric AltVSXFMARel; 12065ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 12075ffd83dbSDimitry Andric let IsVSXFMAAlt = 1, hasSideEffects = 1 in 12085ffd83dbSDimitry Andric def XSMADDMSP : XX3Form<60, 9, 12095ffd83dbSDimitry Andric (outs vssrc:$XT), 12105ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12115ffd83dbSDimitry Andric "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 12125ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12135ffd83dbSDimitry Andric AltVSXFMARel; 12145ffd83dbSDimitry Andric } 12155ffd83dbSDimitry Andric 12165ffd83dbSDimitry Andric let BaseName = "XSMSUBASP" in { 12175ffd83dbSDimitry Andric let isCommutable = 1 in 12185ffd83dbSDimitry Andric def XSMSUBASP : XX3Form<60, 17, 12195ffd83dbSDimitry Andric (outs vssrc:$XT), 12205ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12215ffd83dbSDimitry Andric "xsmsubasp $XT, $XA, $XB", IIC_VecFP, 12225ffd83dbSDimitry Andric [(set f32:$XT, (any_fma f32:$XA, f32:$XB, 12235ffd83dbSDimitry Andric (fneg f32:$XTi)))]>, 12245ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12255ffd83dbSDimitry Andric AltVSXFMARel; 12265ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 12275ffd83dbSDimitry Andric let IsVSXFMAAlt = 1, hasSideEffects = 1 in 12285ffd83dbSDimitry Andric def XSMSUBMSP : XX3Form<60, 25, 12295ffd83dbSDimitry Andric (outs vssrc:$XT), 12305ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12315ffd83dbSDimitry Andric "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 12325ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12335ffd83dbSDimitry Andric AltVSXFMARel; 12345ffd83dbSDimitry Andric } 12355ffd83dbSDimitry Andric 12365ffd83dbSDimitry Andric let BaseName = "XSNMADDASP" in { 12375ffd83dbSDimitry Andric let isCommutable = 1 in 12385ffd83dbSDimitry Andric def XSNMADDASP : XX3Form<60, 129, 12395ffd83dbSDimitry Andric (outs vssrc:$XT), 12405ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12415ffd83dbSDimitry Andric "xsnmaddasp $XT, $XA, $XB", IIC_VecFP, 12425ffd83dbSDimitry Andric [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB, 12435ffd83dbSDimitry Andric f32:$XTi)))]>, 12445ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12455ffd83dbSDimitry Andric AltVSXFMARel; 12465ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 12475ffd83dbSDimitry Andric let IsVSXFMAAlt = 1, hasSideEffects = 1 in 12485ffd83dbSDimitry Andric def XSNMADDMSP : XX3Form<60, 137, 12495ffd83dbSDimitry Andric (outs vssrc:$XT), 12505ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12515ffd83dbSDimitry Andric "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>, 12525ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12535ffd83dbSDimitry Andric AltVSXFMARel; 12545ffd83dbSDimitry Andric } 12555ffd83dbSDimitry Andric 12565ffd83dbSDimitry Andric let BaseName = "XSNMSUBASP" in { 12575ffd83dbSDimitry Andric let isCommutable = 1 in 12585ffd83dbSDimitry Andric def XSNMSUBASP : XX3Form<60, 145, 12595ffd83dbSDimitry Andric (outs vssrc:$XT), 12605ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12615ffd83dbSDimitry Andric "xsnmsubasp $XT, $XA, $XB", IIC_VecFP, 12625ffd83dbSDimitry Andric [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB, 12635ffd83dbSDimitry Andric (fneg f32:$XTi))))]>, 12645ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12655ffd83dbSDimitry Andric AltVSXFMARel; 12665ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 12675ffd83dbSDimitry Andric let IsVSXFMAAlt = 1, hasSideEffects = 1 in 12685ffd83dbSDimitry Andric def XSNMSUBMSP : XX3Form<60, 153, 12695ffd83dbSDimitry Andric (outs vssrc:$XT), 12705ffd83dbSDimitry Andric (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB), 12715ffd83dbSDimitry Andric "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>, 12725ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">, 12735ffd83dbSDimitry Andric AltVSXFMARel; 12745ffd83dbSDimitry Andric } 12755ffd83dbSDimitry Andric 12765ffd83dbSDimitry Andric // Single Precision Conversions (FP <-> INT) 12775ffd83dbSDimitry Andric def XSCVSXDSP : XX2Form<60, 312, 12785ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vsfrc:$XB), 12795ffd83dbSDimitry Andric "xscvsxdsp $XT, $XB", IIC_VecFP, 1280e8d8bef9SDimitry Andric [(set f32:$XT, (PPCany_fcfids f64:$XB))]>; 12815ffd83dbSDimitry Andric def XSCVUXDSP : XX2Form<60, 296, 12825ffd83dbSDimitry Andric (outs vssrc:$XT), (ins vsfrc:$XB), 12835ffd83dbSDimitry Andric "xscvuxdsp $XT, $XB", IIC_VecFP, 1284e8d8bef9SDimitry Andric [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>; 1285e8d8bef9SDimitry Andric } // mayRaiseFPException 12865ffd83dbSDimitry Andric 12875ffd83dbSDimitry Andric // Conversions between vector and scalar single precision 12885ffd83dbSDimitry Andric def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB), 12895ffd83dbSDimitry Andric "xscvdpspn $XT, $XB", IIC_VecFP, []>; 12905ffd83dbSDimitry Andric def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB), 12915ffd83dbSDimitry Andric "xscvspdpn $XT, $XB", IIC_VecFP, []>; 12925ffd83dbSDimitry Andric 12935ffd83dbSDimitry Andric let Predicates = [HasVSX, HasDirectMove] in { 12945ffd83dbSDimitry Andric // VSX direct move instructions 12955ffd83dbSDimitry Andric def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT), 12965ffd83dbSDimitry Andric "mfvsrd $rA, $XT", IIC_VecGeneral, 12975ffd83dbSDimitry Andric [(set i64:$rA, (PPCmfvsr f64:$XT))]>, 12985ffd83dbSDimitry Andric Requires<[In64BitMode]>; 12995ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 13005ffd83dbSDimitry Andric let isCodeGenOnly = 1, hasSideEffects = 1 in 13015ffd83dbSDimitry Andric def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT), 13025ffd83dbSDimitry Andric "mfvsrd $rA, $XT", IIC_VecGeneral, 13035ffd83dbSDimitry Andric []>, 13045ffd83dbSDimitry Andric Requires<[In64BitMode]>; 13055ffd83dbSDimitry Andric def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT), 13065ffd83dbSDimitry Andric "mfvsrwz $rA, $XT", IIC_VecGeneral, 1307*bdd1243dSDimitry Andric [(set i32:$rA, (PPCmfvsr f64:$XT))]>, ZExt32To64; 13085ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 13095ffd83dbSDimitry Andric let isCodeGenOnly = 1, hasSideEffects = 1 in 13105ffd83dbSDimitry Andric def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT), 13115ffd83dbSDimitry Andric "mfvsrwz $rA, $XT", IIC_VecGeneral, 13125ffd83dbSDimitry Andric []>; 13135ffd83dbSDimitry Andric def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA), 13145ffd83dbSDimitry Andric "mtvsrd $XT, $rA", IIC_VecGeneral, 13155ffd83dbSDimitry Andric [(set f64:$XT, (PPCmtvsra i64:$rA))]>, 13165ffd83dbSDimitry Andric Requires<[In64BitMode]>; 13175ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 13185ffd83dbSDimitry Andric let isCodeGenOnly = 1, hasSideEffects = 1 in 13195ffd83dbSDimitry Andric def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA), 13205ffd83dbSDimitry Andric "mtvsrd $XT, $rA", IIC_VecGeneral, 13215ffd83dbSDimitry Andric []>, 13225ffd83dbSDimitry Andric Requires<[In64BitMode]>; 13235ffd83dbSDimitry Andric def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA), 13245ffd83dbSDimitry Andric "mtvsrwa $XT, $rA", IIC_VecGeneral, 13255ffd83dbSDimitry Andric [(set f64:$XT, (PPCmtvsra i32:$rA))]>; 13265ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 13275ffd83dbSDimitry Andric let isCodeGenOnly = 1, hasSideEffects = 1 in 13285ffd83dbSDimitry Andric def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA), 13295ffd83dbSDimitry Andric "mtvsrwa $XT, $rA", IIC_VecGeneral, 13305ffd83dbSDimitry Andric []>; 13315ffd83dbSDimitry Andric def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA), 13325ffd83dbSDimitry Andric "mtvsrwz $XT, $rA", IIC_VecGeneral, 13335ffd83dbSDimitry Andric [(set f64:$XT, (PPCmtvsrz i32:$rA))]>; 13345ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 13355ffd83dbSDimitry Andric let isCodeGenOnly = 1, hasSideEffects = 1 in 13365ffd83dbSDimitry Andric def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA), 13375ffd83dbSDimitry Andric "mtvsrwz $XT, $rA", IIC_VecGeneral, 13385ffd83dbSDimitry Andric []>; 13395ffd83dbSDimitry Andric } // HasDirectMove 13405ffd83dbSDimitry Andric 13415ffd83dbSDimitry Andric} // HasVSX, HasP8Vector 13425ffd83dbSDimitry Andric 13435ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove] in { 13445ffd83dbSDimitry Andricdef MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA), 13455ffd83dbSDimitry Andric "mtvsrws $XT, $rA", IIC_VecGeneral, []>; 13465ffd83dbSDimitry Andric 13475ffd83dbSDimitry Andricdef MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB), 13485ffd83dbSDimitry Andric "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral, 13495ffd83dbSDimitry Andric []>, Requires<[In64BitMode]>; 13505ffd83dbSDimitry Andric 13515ffd83dbSDimitry Andricdef MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT), 13525ffd83dbSDimitry Andric "mfvsrld $rA, $XT", IIC_VecGeneral, 13535ffd83dbSDimitry Andric []>, Requires<[In64BitMode]>; 13545ffd83dbSDimitry Andric 13555ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove 13565ffd83dbSDimitry Andric 13575ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in { 13585ffd83dbSDimitry Andric // Quad-Precision Scalar Move Instructions: 13595ffd83dbSDimitry Andric // Copy Sign 13605ffd83dbSDimitry Andric def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", 13615ffd83dbSDimitry Andric [(set f128:$vT, 13625ffd83dbSDimitry Andric (fcopysign f128:$vB, f128:$vA))]>; 13635ffd83dbSDimitry Andric 13645ffd83dbSDimitry Andric // Absolute/Negative-Absolute/Negate 13655ffd83dbSDimitry Andric def XSABSQP : X_VT5_XO5_VB5<63, 0, 804, "xsabsqp", 13665ffd83dbSDimitry Andric [(set f128:$vT, (fabs f128:$vB))]>; 13675ffd83dbSDimitry Andric def XSNABSQP : X_VT5_XO5_VB5<63, 8, 804, "xsnabsqp", 13685ffd83dbSDimitry Andric [(set f128:$vT, (fneg (fabs f128:$vB)))]>; 13695ffd83dbSDimitry Andric def XSNEGQP : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp", 13705ffd83dbSDimitry Andric [(set f128:$vT, (fneg f128:$vB))]>; 13715ffd83dbSDimitry Andric 13725ffd83dbSDimitry Andric //===--------------------------------------------------------------------===// 13735ffd83dbSDimitry Andric // Quad-Precision Scalar Floating-Point Arithmetic Instructions: 13745ffd83dbSDimitry Andric 13755ffd83dbSDimitry Andric // Add/Divide/Multiply/Subtract 13765ffd83dbSDimitry Andric let mayRaiseFPException = 1 in { 13775ffd83dbSDimitry Andric let isCommutable = 1 in { 13785ffd83dbSDimitry Andric def XSADDQP : X_VT5_VA5_VB5 <63, 4, "xsaddqp", 13795ffd83dbSDimitry Andric [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>; 13805ffd83dbSDimitry Andric def XSMULQP : X_VT5_VA5_VB5 <63, 36, "xsmulqp", 13815ffd83dbSDimitry Andric [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>; 13825ffd83dbSDimitry Andric } 13835ffd83dbSDimitry Andric def XSSUBQP : X_VT5_VA5_VB5 <63, 516, "xssubqp" , 13845ffd83dbSDimitry Andric [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>; 13855ffd83dbSDimitry Andric def XSDIVQP : X_VT5_VA5_VB5 <63, 548, "xsdivqp", 13865ffd83dbSDimitry Andric [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>; 13875ffd83dbSDimitry Andric // Square-Root 13885ffd83dbSDimitry Andric def XSSQRTQP : X_VT5_XO5_VB5 <63, 27, 804, "xssqrtqp", 13895ffd83dbSDimitry Andric [(set f128:$vT, (any_fsqrt f128:$vB))]>; 13905ffd83dbSDimitry Andric // (Negative) Multiply-{Add/Subtract} 13915ffd83dbSDimitry Andric def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp", 13925ffd83dbSDimitry Andric [(set f128:$vT, 13935ffd83dbSDimitry Andric (any_fma f128:$vA, f128:$vB, f128:$vTi))]>; 13945ffd83dbSDimitry Andric def XSMSUBQP : X_VT5_VA5_VB5_FMA <63, 420, "xsmsubqp" , 13955ffd83dbSDimitry Andric [(set f128:$vT, 13965ffd83dbSDimitry Andric (any_fma f128:$vA, f128:$vB, 13975ffd83dbSDimitry Andric (fneg f128:$vTi)))]>; 13985ffd83dbSDimitry Andric def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp", 13995ffd83dbSDimitry Andric [(set f128:$vT, 14005ffd83dbSDimitry Andric (fneg (any_fma f128:$vA, f128:$vB, 14015ffd83dbSDimitry Andric f128:$vTi)))]>; 14025ffd83dbSDimitry Andric def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp", 14035ffd83dbSDimitry Andric [(set f128:$vT, 14045ffd83dbSDimitry Andric (fneg (any_fma f128:$vA, f128:$vB, 14055ffd83dbSDimitry Andric (fneg f128:$vTi))))]>; 14065ffd83dbSDimitry Andric 14075ffd83dbSDimitry Andric let isCommutable = 1 in { 14085ffd83dbSDimitry Andric def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo", 14095ffd83dbSDimitry Andric [(set f128:$vT, 14105ffd83dbSDimitry Andric (int_ppc_addf128_round_to_odd 14115ffd83dbSDimitry Andric f128:$vA, f128:$vB))]>; 14125ffd83dbSDimitry Andric def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo", 14135ffd83dbSDimitry Andric [(set f128:$vT, 14145ffd83dbSDimitry Andric (int_ppc_mulf128_round_to_odd 14155ffd83dbSDimitry Andric f128:$vA, f128:$vB))]>; 14165ffd83dbSDimitry Andric } 14175ffd83dbSDimitry Andric def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", 14185ffd83dbSDimitry Andric [(set f128:$vT, 14195ffd83dbSDimitry Andric (int_ppc_subf128_round_to_odd 14205ffd83dbSDimitry Andric f128:$vA, f128:$vB))]>; 14215ffd83dbSDimitry Andric def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", 14225ffd83dbSDimitry Andric [(set f128:$vT, 14235ffd83dbSDimitry Andric (int_ppc_divf128_round_to_odd 14245ffd83dbSDimitry Andric f128:$vA, f128:$vB))]>; 14255ffd83dbSDimitry Andric def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", 14265ffd83dbSDimitry Andric [(set f128:$vT, 14275ffd83dbSDimitry Andric (int_ppc_sqrtf128_round_to_odd f128:$vB))]>; 14285ffd83dbSDimitry Andric 14295ffd83dbSDimitry Andric 14305ffd83dbSDimitry Andric def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo", 14315ffd83dbSDimitry Andric [(set f128:$vT, 14325ffd83dbSDimitry Andric (int_ppc_fmaf128_round_to_odd 14335ffd83dbSDimitry Andric f128:$vA,f128:$vB,f128:$vTi))]>; 14345ffd83dbSDimitry Andric 14355ffd83dbSDimitry Andric def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" , 14365ffd83dbSDimitry Andric [(set f128:$vT, 14375ffd83dbSDimitry Andric (int_ppc_fmaf128_round_to_odd 14385ffd83dbSDimitry Andric f128:$vA, f128:$vB, (fneg f128:$vTi)))]>; 14395ffd83dbSDimitry Andric def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo", 14405ffd83dbSDimitry Andric [(set f128:$vT, 14415ffd83dbSDimitry Andric (fneg (int_ppc_fmaf128_round_to_odd 14425ffd83dbSDimitry Andric f128:$vA, f128:$vB, f128:$vTi)))]>; 14435ffd83dbSDimitry Andric def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo", 14445ffd83dbSDimitry Andric [(set f128:$vT, 14455ffd83dbSDimitry Andric (fneg (int_ppc_fmaf128_round_to_odd 14465ffd83dbSDimitry Andric f128:$vA, f128:$vB, (fneg f128:$vTi))))]>; 14475ffd83dbSDimitry Andric } // mayRaiseFPException 14485ffd83dbSDimitry Andric 14495ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 14505ffd83dbSDimitry Andric // QP Compare Ordered/Unordered 14515ffd83dbSDimitry Andric let hasSideEffects = 1 in { 14525ffd83dbSDimitry Andric // DP/QP Compare Exponents 14535ffd83dbSDimitry Andric def XSCMPEXPDP : XX3Form_1<60, 59, 14545ffd83dbSDimitry Andric (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB), 14555ffd83dbSDimitry Andric "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>; 14565ffd83dbSDimitry Andric def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>; 14575ffd83dbSDimitry Andric 1458e8d8bef9SDimitry Andric let mayRaiseFPException = 1 in { 1459e8d8bef9SDimitry Andric def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>; 1460e8d8bef9SDimitry Andric def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>; 1461e8d8bef9SDimitry Andric 14625ffd83dbSDimitry Andric // DP Compare ==, >=, >, != 14635ffd83dbSDimitry Andric // Use vsrc for XT, because the entire register of XT is set. 14645ffd83dbSDimitry Andric // XT.dword[1] = 0x0000_0000_0000_0000 14655ffd83dbSDimitry Andric def XSCMPEQDP : XX3_XT5_XA5_XB5<60, 3, "xscmpeqdp", vsrc, vsfrc, vsfrc, 14665ffd83dbSDimitry Andric IIC_FPCompare, []>; 14675ffd83dbSDimitry Andric def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc, 14685ffd83dbSDimitry Andric IIC_FPCompare, []>; 14695ffd83dbSDimitry Andric def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc, 14705ffd83dbSDimitry Andric IIC_FPCompare, []>; 14715ffd83dbSDimitry Andric } 1472e8d8bef9SDimitry Andric } 14735ffd83dbSDimitry Andric 14745ffd83dbSDimitry Andric //===--------------------------------------------------------------------===// 14755ffd83dbSDimitry Andric // Quad-Precision Floating-Point Conversion Instructions: 14765ffd83dbSDimitry Andric 14775ffd83dbSDimitry Andric let mayRaiseFPException = 1 in { 14785ffd83dbSDimitry Andric // Convert DP -> QP 14795ffd83dbSDimitry Andric def XSCVDPQP : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, 14805ffd83dbSDimitry Andric [(set f128:$vT, (any_fpextend f64:$vB))]>; 14815ffd83dbSDimitry Andric 14825ffd83dbSDimitry Andric // Round & Convert QP -> DP (dword[1] is set to zero) 14835ffd83dbSDimitry Andric def XSCVQPDP : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>; 14845ffd83dbSDimitry Andric def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo", 14855ffd83dbSDimitry Andric [(set f64:$vT, 14865ffd83dbSDimitry Andric (int_ppc_truncf128_round_to_odd 14875ffd83dbSDimitry Andric f128:$vB))]>; 14885ffd83dbSDimitry Andric } 14895ffd83dbSDimitry Andric 14905ffd83dbSDimitry Andric // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero) 1491e8d8bef9SDimitry Andric let mayRaiseFPException = 1 in { 14925ffd83dbSDimitry Andric def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>; 14935ffd83dbSDimitry Andric def XSCVQPSWZ : X_VT5_XO5_VB5<63, 9, 836, "xscvqpswz", []>; 14945ffd83dbSDimitry Andric def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>; 14955ffd83dbSDimitry Andric def XSCVQPUWZ : X_VT5_XO5_VB5<63, 1, 836, "xscvqpuwz", []>; 14965ffd83dbSDimitry Andric } 14975ffd83dbSDimitry Andric 14985ffd83dbSDimitry Andric // Convert (Un)Signed DWord -> QP. 14995ffd83dbSDimitry Andric def XSCVSDQP : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>; 15005ffd83dbSDimitry Andric def XSCVUDQP : X_VT5_XO5_VB5_TyVB<63, 2, 836, "xscvudqp", vfrc, []>; 15015ffd83dbSDimitry Andric 15025ffd83dbSDimitry Andric // (Round &) Convert DP <-> HP 15035ffd83dbSDimitry Andric // Note! xscvdphp's src and dest register both use the left 64 bits, so we use 15045ffd83dbSDimitry Andric // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits, 15055ffd83dbSDimitry Andric // but we still use vsfrc for it. 15065ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 1507e8d8bef9SDimitry Andric let hasSideEffects = 1, mayRaiseFPException = 1 in { 15085ffd83dbSDimitry Andric def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>; 15095ffd83dbSDimitry Andric def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>; 15105ffd83dbSDimitry Andric } 15115ffd83dbSDimitry Andric 1512e8d8bef9SDimitry Andric let mayRaiseFPException = 1 in { 15135ffd83dbSDimitry Andric // Vector HP -> SP 15145ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 15155ffd83dbSDimitry Andric let hasSideEffects = 1 in 15165ffd83dbSDimitry Andric def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>; 15175ffd83dbSDimitry Andric def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc, 15185ffd83dbSDimitry Andric [(set v4f32:$XT, 15195ffd83dbSDimitry Andric (int_ppc_vsx_xvcvsphp v4f32:$XB))]>; 15205ffd83dbSDimitry Andric 15215ffd83dbSDimitry Andric // Round to Quad-Precision Integer [with Inexact] 15225ffd83dbSDimitry Andric def XSRQPI : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 0, "xsrqpi" , []>; 15235ffd83dbSDimitry Andric def XSRQPIX : Z23_VT5_R1_VB5_RMC2_EX1<63, 5, 1, "xsrqpix", []>; 15245ffd83dbSDimitry Andric 15255ffd83dbSDimitry Andric // Round Quad-Precision to Double-Extended Precision (fp80) 15265ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 15275ffd83dbSDimitry Andric let hasSideEffects = 1 in 15285ffd83dbSDimitry Andric def XSRQPXP : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>; 1529e8d8bef9SDimitry Andric } 15305ffd83dbSDimitry Andric 15315ffd83dbSDimitry Andric //===--------------------------------------------------------------------===// 15325ffd83dbSDimitry Andric // Insert/Extract Instructions 15335ffd83dbSDimitry Andric 15345ffd83dbSDimitry Andric // Insert Exponent DP/QP 15355ffd83dbSDimitry Andric // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU 15365ffd83dbSDimitry Andric def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB), 15375ffd83dbSDimitry Andric "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>; 1538fe6060f1SDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 1539fe6060f1SDimitry Andric let hasSideEffects = 1 in { 15405ffd83dbSDimitry Andric // vB NOTE: only vB.dword[0] is used, that's why we don't use 15415ffd83dbSDimitry Andric // X_VT5_VA5_VB5 form 15425ffd83dbSDimitry Andric def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB), 15435ffd83dbSDimitry Andric "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>; 15445ffd83dbSDimitry Andric } 15455ffd83dbSDimitry Andric 15465ffd83dbSDimitry Andric // Extract Exponent/Significand DP/QP 15475ffd83dbSDimitry Andric def XSXEXPDP : XX2_RT5_XO5_XB6<60, 0, 347, "xsxexpdp", []>; 15485ffd83dbSDimitry Andric def XSXSIGDP : XX2_RT5_XO5_XB6<60, 1, 347, "xsxsigdp", []>; 15495ffd83dbSDimitry Andric 1550fe6060f1SDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 1551fe6060f1SDimitry Andric let hasSideEffects = 1 in { 15525ffd83dbSDimitry Andric def XSXEXPQP : X_VT5_XO5_VB5 <63, 2, 804, "xsxexpqp", []>; 15535ffd83dbSDimitry Andric def XSXSIGQP : X_VT5_XO5_VB5 <63, 18, 804, "xsxsigqp", []>; 15545ffd83dbSDimitry Andric } 15555ffd83dbSDimitry Andric 15565ffd83dbSDimitry Andric // Vector Insert Word 15575ffd83dbSDimitry Andric // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB. 15585ffd83dbSDimitry Andric def XXINSERTW : 15595ffd83dbSDimitry Andric XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT), 15605ffd83dbSDimitry Andric (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM), 15615ffd83dbSDimitry Andric "xxinsertw $XT, $XB, $UIM", IIC_VecFP, 15625ffd83dbSDimitry Andric [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB, 15635ffd83dbSDimitry Andric imm32SExt16:$UIM))]>, 15645ffd83dbSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">; 15655ffd83dbSDimitry Andric 15665ffd83dbSDimitry Andric // Vector Extract Unsigned Word 15675ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 15685ffd83dbSDimitry Andric let hasSideEffects = 1 in 15695ffd83dbSDimitry Andric def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165, 15705ffd83dbSDimitry Andric (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM), 15715ffd83dbSDimitry Andric "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>; 15725ffd83dbSDimitry Andric 15735ffd83dbSDimitry Andric // Vector Insert Exponent DP/SP 15745ffd83dbSDimitry Andric def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc, 15755ffd83dbSDimitry Andric IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>; 15765ffd83dbSDimitry Andric def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc, 15775ffd83dbSDimitry Andric IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>; 15785ffd83dbSDimitry Andric 15795ffd83dbSDimitry Andric // Vector Extract Exponent/Significand DP/SP 15805ffd83dbSDimitry Andric def XVXEXPDP : XX2_XT6_XO5_XB6<60, 0, 475, "xvxexpdp", vsrc, 15815ffd83dbSDimitry Andric [(set v2i64: $XT, 15825ffd83dbSDimitry Andric (int_ppc_vsx_xvxexpdp v2f64:$XB))]>; 15835ffd83dbSDimitry Andric def XVXEXPSP : XX2_XT6_XO5_XB6<60, 8, 475, "xvxexpsp", vsrc, 15845ffd83dbSDimitry Andric [(set v4i32: $XT, 15855ffd83dbSDimitry Andric (int_ppc_vsx_xvxexpsp v4f32:$XB))]>; 15865ffd83dbSDimitry Andric def XVXSIGDP : XX2_XT6_XO5_XB6<60, 1, 475, "xvxsigdp", vsrc, 15875ffd83dbSDimitry Andric [(set v2i64: $XT, 15885ffd83dbSDimitry Andric (int_ppc_vsx_xvxsigdp v2f64:$XB))]>; 15895ffd83dbSDimitry Andric def XVXSIGSP : XX2_XT6_XO5_XB6<60, 9, 475, "xvxsigsp", vsrc, 15905ffd83dbSDimitry Andric [(set v4i32: $XT, 15915ffd83dbSDimitry Andric (int_ppc_vsx_xvxsigsp v4f32:$XB))]>; 15925ffd83dbSDimitry Andric 15935ffd83dbSDimitry Andric // Test Data Class SP/DP/QP 15945ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 15955ffd83dbSDimitry Andric let hasSideEffects = 1 in { 15965ffd83dbSDimitry Andric def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298, 15975ffd83dbSDimitry Andric (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), 15985ffd83dbSDimitry Andric "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>; 15995ffd83dbSDimitry Andric def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362, 16005ffd83dbSDimitry Andric (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB), 16015ffd83dbSDimitry Andric "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>; 16025ffd83dbSDimitry Andric def XSTSTDCQP : X_BF3_DCMX7_RS5 <63, 708, 16035ffd83dbSDimitry Andric (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB), 16045ffd83dbSDimitry Andric "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>; 16055ffd83dbSDimitry Andric } 16065ffd83dbSDimitry Andric 16075ffd83dbSDimitry Andric // Vector Test Data Class SP/DP 16085ffd83dbSDimitry Andric def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5, 16095ffd83dbSDimitry Andric (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB), 16105ffd83dbSDimitry Andric "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP, 16115ffd83dbSDimitry Andric [(set v4i32: $XT, 16125ffd83dbSDimitry Andric (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>; 16135ffd83dbSDimitry Andric def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5, 16145ffd83dbSDimitry Andric (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB), 16155ffd83dbSDimitry Andric "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP, 16165ffd83dbSDimitry Andric [(set v2i64: $XT, 16175ffd83dbSDimitry Andric (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>; 16185ffd83dbSDimitry Andric 16195ffd83dbSDimitry Andric // Maximum/Minimum Type-C/Type-J DP 1620e8d8bef9SDimitry Andric let mayRaiseFPException = 1 in { 16215ffd83dbSDimitry Andric def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc, 16225ffd83dbSDimitry Andric IIC_VecFP, 16235ffd83dbSDimitry Andric [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>; 16245ffd83dbSDimitry Andric def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc, 16255ffd83dbSDimitry Andric IIC_VecFP, 16265ffd83dbSDimitry Andric [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>; 16275ffd83dbSDimitry Andric 16285ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 16295ffd83dbSDimitry Andric let hasSideEffects = 1 in { 16305ffd83dbSDimitry Andric def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc, 16315ffd83dbSDimitry Andric IIC_VecFP, []>; 16325ffd83dbSDimitry Andric def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc, 16335ffd83dbSDimitry Andric IIC_VecFP, []>; 16345ffd83dbSDimitry Andric } 1635e8d8bef9SDimitry Andric } 16365ffd83dbSDimitry Andric 16375ffd83dbSDimitry Andric // Vector Byte-Reverse H/W/D/Q Word 16385ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 16395ffd83dbSDimitry Andric let hasSideEffects = 1 in 16405ffd83dbSDimitry Andric def XXBRH : XX2_XT6_XO5_XB6<60, 7, 475, "xxbrh", vsrc, []>; 16415ffd83dbSDimitry Andric def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, 16425ffd83dbSDimitry Andric [(set v4i32:$XT, (bswap v4i32:$XB))]>; 16435ffd83dbSDimitry Andric def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, 16445ffd83dbSDimitry Andric [(set v2i64:$XT, (bswap v2i64:$XB))]>; 16455ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 16465ffd83dbSDimitry Andric let hasSideEffects = 1 in 16475ffd83dbSDimitry Andric def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>; 16485ffd83dbSDimitry Andric 16495ffd83dbSDimitry Andric // Vector Permute 1650*bdd1243dSDimitry Andric def XXPERM : XX3Form<60, 26, (outs vsrc:$XT), 1651*bdd1243dSDimitry Andric (ins vsrc:$XA, vsrc:$XTi, vsrc:$XB), 1652*bdd1243dSDimitry Andric "xxperm $XT, $XA, $XB", IIC_VecPerm, []>, 1653*bdd1243dSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">; 1654*bdd1243dSDimitry Andric def XXPERMR : XX3Form<60, 58, (outs vsrc:$XT), 1655*bdd1243dSDimitry Andric (ins vsrc:$XA, vsrc:$XTi, vsrc:$XB), 1656*bdd1243dSDimitry Andric "xxpermr $XT, $XA, $XB", IIC_VecPerm, []>, 1657*bdd1243dSDimitry Andric RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">; 16585ffd83dbSDimitry Andric 16595ffd83dbSDimitry Andric // Vector Splat Immediate Byte 16605ffd83dbSDimitry Andric // FIXME: Setting the hasSideEffects flag here to match current behaviour. 16615ffd83dbSDimitry Andric let hasSideEffects = 1 in 16625ffd83dbSDimitry Andric def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8), 16635ffd83dbSDimitry Andric "xxspltib $XT, $IMM8", IIC_VecPerm, []>; 16645ffd83dbSDimitry Andric 16655ffd83dbSDimitry Andric // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in 16665ffd83dbSDimitry Andric // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging. 16675ffd83dbSDimitry Andric let mayLoad = 1, mayStore = 0 in { 16685ffd83dbSDimitry Andric // Load Vector 16695ffd83dbSDimitry Andric def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src), 16705ffd83dbSDimitry Andric "lxv $XT, $src", IIC_LdStLFD, []>; 16715ffd83dbSDimitry Andric // Load DWord 16725ffd83dbSDimitry Andric def LXSD : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src), 16735ffd83dbSDimitry Andric "lxsd $vD, $src", IIC_LdStLFD, []>; 16745ffd83dbSDimitry Andric // Load SP from src, convert it to DP, and place in dword[0] 16755ffd83dbSDimitry Andric def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src), 16765ffd83dbSDimitry Andric "lxssp $vD, $src", IIC_LdStLFD, []>; 16775ffd83dbSDimitry Andric 16785ffd83dbSDimitry Andric // Load as Integer Byte/Halfword & Zero Indexed 16795ffd83dbSDimitry Andric def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc, 1680fe6060f1SDimitry Andric [(set f64:$XT, (PPClxsizx ForceXForm:$src, 1))]>; 16815ffd83dbSDimitry Andric def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc, 1682fe6060f1SDimitry Andric [(set f64:$XT, (PPClxsizx ForceXForm:$src, 2))]>; 16835ffd83dbSDimitry Andric 16845ffd83dbSDimitry Andric // Load Vector Halfword*8/Byte*16 Indexed 16855ffd83dbSDimitry Andric def LXVH8X : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>; 16865ffd83dbSDimitry Andric def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>; 16875ffd83dbSDimitry Andric 16885ffd83dbSDimitry Andric // Load Vector Indexed 16895ffd83dbSDimitry Andric def LXVX : X_XT6_RA5_RB5<31, 268, "lxvx" , vsrc, 1690fe6060f1SDimitry Andric [(set v2f64:$XT, (load XForm:$src))]>; 16915ffd83dbSDimitry Andric // Load Vector (Left-justified) with Length 16925ffd83dbSDimitry Andric def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), 16935ffd83dbSDimitry Andric "lxvl $XT, $src, $rB", IIC_LdStLoad, 16945ffd83dbSDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>; 16955ffd83dbSDimitry Andric def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB), 16965ffd83dbSDimitry Andric "lxvll $XT, $src, $rB", IIC_LdStLoad, 16975ffd83dbSDimitry Andric [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>; 16985ffd83dbSDimitry Andric 16995ffd83dbSDimitry Andric // Load Vector Word & Splat Indexed 17005ffd83dbSDimitry Andric def LXVWSX : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>; 17015ffd83dbSDimitry Andric } // mayLoad 17025ffd83dbSDimitry Andric 17035ffd83dbSDimitry Andric // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in 17045ffd83dbSDimitry Andric // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging. 17055ffd83dbSDimitry Andric let mayStore = 1, mayLoad = 0 in { 17065ffd83dbSDimitry Andric // Store Vector 17075ffd83dbSDimitry Andric def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst), 17085ffd83dbSDimitry Andric "stxv $XT, $dst", IIC_LdStSTFD, []>; 17095ffd83dbSDimitry Andric // Store DWord 17105ffd83dbSDimitry Andric def STXSD : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst), 17115ffd83dbSDimitry Andric "stxsd $vS, $dst", IIC_LdStSTFD, []>; 17125ffd83dbSDimitry Andric // Convert DP of dword[0] to SP, and Store to dst 17135ffd83dbSDimitry Andric def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst), 17145ffd83dbSDimitry Andric "stxssp $vS, $dst", IIC_LdStSTFD, []>; 17155ffd83dbSDimitry Andric 17165ffd83dbSDimitry Andric // Store as Integer Byte/Halfword Indexed 17175ffd83dbSDimitry Andric def STXSIBX : X_XS6_RA5_RB5<31, 909, "stxsibx" , vsfrc, 1718fe6060f1SDimitry Andric [(PPCstxsix f64:$XT, ForceXForm:$dst, 1)]>; 17195ffd83dbSDimitry Andric def STXSIHX : X_XS6_RA5_RB5<31, 941, "stxsihx" , vsfrc, 1720fe6060f1SDimitry Andric [(PPCstxsix f64:$XT, ForceXForm:$dst, 2)]>; 17215ffd83dbSDimitry Andric let isCodeGenOnly = 1 in { 17225ffd83dbSDimitry Andric def STXSIBXv : X_XS6_RA5_RB5<31, 909, "stxsibx" , vsrc, []>; 17235ffd83dbSDimitry Andric def STXSIHXv : X_XS6_RA5_RB5<31, 941, "stxsihx" , vsrc, []>; 17245ffd83dbSDimitry Andric } 17255ffd83dbSDimitry Andric 17265ffd83dbSDimitry Andric // Store Vector Halfword*8/Byte*16 Indexed 17275ffd83dbSDimitry Andric def STXVH8X : X_XS6_RA5_RB5<31, 940, "stxvh8x" , vsrc, []>; 17285ffd83dbSDimitry Andric def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>; 17295ffd83dbSDimitry Andric 17305ffd83dbSDimitry Andric // Store Vector Indexed 17315ffd83dbSDimitry Andric def STXVX : X_XS6_RA5_RB5<31, 396, "stxvx" , vsrc, 1732fe6060f1SDimitry Andric [(store v2f64:$XT, XForm:$dst)]>; 17335ffd83dbSDimitry Andric 17345ffd83dbSDimitry Andric // Store Vector (Left-justified) with Length 17355ffd83dbSDimitry Andric def STXVL : XX1Form_memOp<31, 397, (outs), 17365ffd83dbSDimitry Andric (ins vsrc:$XT, memr:$dst, g8rc:$rB), 17375ffd83dbSDimitry Andric "stxvl $XT, $dst, $rB", IIC_LdStLoad, 17385ffd83dbSDimitry Andric [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, 17395ffd83dbSDimitry Andric i64:$rB)]>; 17405ffd83dbSDimitry Andric def STXVLL : XX1Form_memOp<31, 429, (outs), 17415ffd83dbSDimitry Andric (ins vsrc:$XT, memr:$dst, g8rc:$rB), 17425ffd83dbSDimitry Andric "stxvll $XT, $dst, $rB", IIC_LdStLoad, 17435ffd83dbSDimitry Andric [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, 17445ffd83dbSDimitry Andric i64:$rB)]>; 17455ffd83dbSDimitry Andric } // mayStore 17465ffd83dbSDimitry Andric 17475ffd83dbSDimitry Andric def DFLOADf32 : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src), 17485ffd83dbSDimitry Andric "#DFLOADf32", 1749fe6060f1SDimitry Andric [(set f32:$XT, (load DSForm:$src))]>; 17505ffd83dbSDimitry Andric def DFLOADf64 : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src), 17515ffd83dbSDimitry Andric "#DFLOADf64", 1752fe6060f1SDimitry Andric [(set f64:$XT, (load DSForm:$src))]>; 17535ffd83dbSDimitry Andric def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst), 17545ffd83dbSDimitry Andric "#DFSTOREf32", 1755fe6060f1SDimitry Andric [(store f32:$XT, DSForm:$dst)]>; 17565ffd83dbSDimitry Andric def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst), 17575ffd83dbSDimitry Andric "#DFSTOREf64", 1758fe6060f1SDimitry Andric [(store f64:$XT, DSForm:$dst)]>; 17595ffd83dbSDimitry Andric 17605ffd83dbSDimitry Andric let mayStore = 1 in { 17615ffd83dbSDimitry Andric def SPILLTOVSR_STX : PseudoXFormMemOp<(outs), 17625ffd83dbSDimitry Andric (ins spilltovsrrc:$XT, memrr:$dst), 17635ffd83dbSDimitry Andric "#SPILLTOVSR_STX", []>; 17645ffd83dbSDimitry Andric def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst), 17655ffd83dbSDimitry Andric "#SPILLTOVSR_ST", []>; 17665ffd83dbSDimitry Andric } 17675ffd83dbSDimitry Andric let mayLoad = 1 in { 17685ffd83dbSDimitry Andric def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT), 17695ffd83dbSDimitry Andric (ins memrr:$src), 17705ffd83dbSDimitry Andric "#SPILLTOVSR_LDX", []>; 17715ffd83dbSDimitry Andric def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src), 17725ffd83dbSDimitry Andric "#SPILLTOVSR_LD", []>; 17735ffd83dbSDimitry Andric 17745ffd83dbSDimitry Andric } 17755ffd83dbSDimitry Andric } // HasP9Vector 17765ffd83dbSDimitry Andric} // hasSideEffects = 0 17775ffd83dbSDimitry Andric 17785ffd83dbSDimitry Andriclet PPC970_Single = 1, AddedComplexity = 400 in { 17790b57cec5SDimitry Andric 17800b57cec5SDimitry Andric def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst), 17810b57cec5SDimitry Andric (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC), 17820b57cec5SDimitry Andric "#SELECT_CC_VSRC", 17830b57cec5SDimitry Andric []>; 17840b57cec5SDimitry Andric def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst), 17850b57cec5SDimitry Andric (ins crbitrc:$cond, vsrc:$T, vsrc:$F), 17860b57cec5SDimitry Andric "#SELECT_VSRC", 17870b57cec5SDimitry Andric [(set v2f64:$dst, 17880b57cec5SDimitry Andric (select i1:$cond, v2f64:$T, v2f64:$F))]>; 17890b57cec5SDimitry Andric def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst), 17900b57cec5SDimitry Andric (ins crrc:$cond, f8rc:$T, f8rc:$F, 17910b57cec5SDimitry Andric i32imm:$BROPC), "#SELECT_CC_VSFRC", 17920b57cec5SDimitry Andric []>; 17930b57cec5SDimitry Andric def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst), 17940b57cec5SDimitry Andric (ins crbitrc:$cond, f8rc:$T, f8rc:$F), 17950b57cec5SDimitry Andric "#SELECT_VSFRC", 17960b57cec5SDimitry Andric [(set f64:$dst, 17970b57cec5SDimitry Andric (select i1:$cond, f64:$T, f64:$F))]>; 17980b57cec5SDimitry Andric def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst), 17990b57cec5SDimitry Andric (ins crrc:$cond, f4rc:$T, f4rc:$F, 18000b57cec5SDimitry Andric i32imm:$BROPC), "#SELECT_CC_VSSRC", 18010b57cec5SDimitry Andric []>; 18020b57cec5SDimitry Andric def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst), 18030b57cec5SDimitry Andric (ins crbitrc:$cond, f4rc:$T, f4rc:$F), 18040b57cec5SDimitry Andric "#SELECT_VSSRC", 18050b57cec5SDimitry Andric [(set f32:$dst, 18060b57cec5SDimitry Andric (select i1:$cond, f32:$T, f32:$F))]>; 18070b57cec5SDimitry Andric} 18080b57cec5SDimitry Andric} 18090b57cec5SDimitry Andric 18105ffd83dbSDimitry Andric//----------------------------- DAG Definitions ------------------------------// 1811fe6060f1SDimitry Andric 1812fe6060f1SDimitry Andric// Output dag used to bitcast f32 to i32 and f64 to i64 1813fe6060f1SDimitry Andricdef Bitcast { 1814fe6060f1SDimitry Andric dag FltToInt = (i32 (MFVSRWZ (EXTRACT_SUBREG (XSCVDPSPN $A), sub_64))); 1815fe6060f1SDimitry Andric dag DblToLong = (i64 (MFVSRD $A)); 1816fe6060f1SDimitry Andric} 1817fe6060f1SDimitry Andric 1818480093f4SDimitry Andricdef FpMinMax { 1819480093f4SDimitry Andric dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC), 1820480093f4SDimitry Andric (COPY_TO_REGCLASS $B, VSFRC)), 1821480093f4SDimitry Andric VSSRC); 1822480093f4SDimitry Andric dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC), 1823480093f4SDimitry Andric (COPY_TO_REGCLASS $B, VSFRC)), 1824480093f4SDimitry Andric VSSRC); 1825480093f4SDimitry Andric} 1826480093f4SDimitry Andric 18270b57cec5SDimitry Andricdef ScalarLoads { 1828fe6060f1SDimitry Andric dag Li8 = (i32 (extloadi8 ForceXForm:$src)); 1829fe6060f1SDimitry Andric dag ZELi8 = (i32 (zextloadi8 ForceXForm:$src)); 1830fe6060f1SDimitry Andric dag ZELi8i64 = (i64 (zextloadi8 ForceXForm:$src)); 1831fe6060f1SDimitry Andric dag SELi8 = (i32 (sext_inreg (extloadi8 ForceXForm:$src), i8)); 1832fe6060f1SDimitry Andric dag SELi8i64 = (i64 (sext_inreg (extloadi8 ForceXForm:$src), i8)); 18330b57cec5SDimitry Andric 1834fe6060f1SDimitry Andric dag Li16 = (i32 (extloadi16 ForceXForm:$src)); 1835fe6060f1SDimitry Andric dag ZELi16 = (i32 (zextloadi16 ForceXForm:$src)); 1836fe6060f1SDimitry Andric dag ZELi16i64 = (i64 (zextloadi16 ForceXForm:$src)); 1837fe6060f1SDimitry Andric dag SELi16 = (i32 (sextloadi16 ForceXForm:$src)); 1838fe6060f1SDimitry Andric dag SELi16i64 = (i64 (sextloadi16 ForceXForm:$src)); 18390b57cec5SDimitry Andric 1840fe6060f1SDimitry Andric dag Li32 = (i32 (load ForceXForm:$src)); 18410b57cec5SDimitry Andric} 18420b57cec5SDimitry Andric 18430b57cec5SDimitry Andricdef DWToSPExtractConv { 18440b57cec5SDimitry Andric dag El0US1 = (f32 (PPCfcfidus 18450b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0)))))); 18460b57cec5SDimitry Andric dag El1US1 = (f32 (PPCfcfidus 18470b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1)))))); 18480b57cec5SDimitry Andric dag El0US2 = (f32 (PPCfcfidus 18490b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0)))))); 18500b57cec5SDimitry Andric dag El1US2 = (f32 (PPCfcfidus 18510b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1)))))); 18520b57cec5SDimitry Andric dag El0SS1 = (f32 (PPCfcfids 18530b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0)))))); 18540b57cec5SDimitry Andric dag El1SS1 = (f32 (PPCfcfids 18550b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1)))))); 18560b57cec5SDimitry Andric dag El0SS2 = (f32 (PPCfcfids 18570b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0)))))); 18580b57cec5SDimitry Andric dag El1SS2 = (f32 (PPCfcfids 18590b57cec5SDimitry Andric (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1)))))); 18600b57cec5SDimitry Andric dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2)); 18610b57cec5SDimitry Andric dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2)); 18620b57cec5SDimitry Andric} 18630b57cec5SDimitry Andric 18645ffd83dbSDimitry Andricdef WToDPExtractConv { 18655ffd83dbSDimitry Andric dag El0S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 0)))); 18665ffd83dbSDimitry Andric dag El1S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 1)))); 18675ffd83dbSDimitry Andric dag El2S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 2)))); 18685ffd83dbSDimitry Andric dag El3S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 3)))); 18695ffd83dbSDimitry Andric dag El0U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 0)))); 18705ffd83dbSDimitry Andric dag El1U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 1)))); 18715ffd83dbSDimitry Andric dag El2U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 2)))); 18725ffd83dbSDimitry Andric dag El3U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 3)))); 18735ffd83dbSDimitry Andric dag BV02S = (v2f64 (build_vector El0S, El2S)); 18745ffd83dbSDimitry Andric dag BV13S = (v2f64 (build_vector El1S, El3S)); 18755ffd83dbSDimitry Andric dag BV02U = (v2f64 (build_vector El0U, El2U)); 18765ffd83dbSDimitry Andric dag BV13U = (v2f64 (build_vector El1U, El3U)); 18778bcb0991SDimitry Andric} 18788bcb0991SDimitry Andric 18790b57cec5SDimitry Andric/* Direct moves of various widths from GPR's into VSR's. Each move lines 18800b57cec5SDimitry Andric the value up into element 0 (both BE and LE). Namely, entities smaller than 18810b57cec5SDimitry Andric a doubleword are shifted left and moved for BE. For LE, they're moved, then 18820b57cec5SDimitry Andric swapped to go into the least significant element of the VSR. 18830b57cec5SDimitry Andric*/ 18840b57cec5SDimitry Andricdef MovesToVSR { 18850b57cec5SDimitry Andric dag BE_BYTE_0 = 18860b57cec5SDimitry Andric (MTVSRD 18870b57cec5SDimitry Andric (RLDICR 18880b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7)); 18890b57cec5SDimitry Andric dag BE_HALF_0 = 18900b57cec5SDimitry Andric (MTVSRD 18910b57cec5SDimitry Andric (RLDICR 18920b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15)); 18930b57cec5SDimitry Andric dag BE_WORD_0 = 18940b57cec5SDimitry Andric (MTVSRD 18950b57cec5SDimitry Andric (RLDICR 18960b57cec5SDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31)); 18970b57cec5SDimitry Andric dag BE_DWORD_0 = (MTVSRD $A); 18980b57cec5SDimitry Andric 18990b57cec5SDimitry Andric dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32)); 19000b57cec5SDimitry Andric dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), 19010b57cec5SDimitry Andric LE_MTVSRW, sub_64)); 19020b57cec5SDimitry Andric dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2); 19030b57cec5SDimitry Andric dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)), 19040b57cec5SDimitry Andric BE_DWORD_0, sub_64)); 19050b57cec5SDimitry Andric dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2); 19060b57cec5SDimitry Andric} 19070b57cec5SDimitry Andric 19080b57cec5SDimitry Andric/* Patterns for extracting elements out of vectors. Integer elements are 19090b57cec5SDimitry Andric extracted using direct move operations. Patterns for extracting elements 19100b57cec5SDimitry Andric whose indices are not available at compile time are also provided with 19110b57cec5SDimitry Andric various _VARIABLE_ patterns. 19120b57cec5SDimitry Andric The numbering for the DAG's is for LE, but when used on BE, the correct 19130b57cec5SDimitry Andric LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13). 19140b57cec5SDimitry Andric*/ 19150b57cec5SDimitry Andricdef VectorExtractions { 19160b57cec5SDimitry Andric // Doubleword extraction 19170b57cec5SDimitry Andric dag LE_DWORD_0 = 19180b57cec5SDimitry Andric (MFVSRD 19190b57cec5SDimitry Andric (EXTRACT_SUBREG 19200b57cec5SDimitry Andric (XXPERMDI (COPY_TO_REGCLASS $S, VSRC), 19210b57cec5SDimitry Andric (COPY_TO_REGCLASS $S, VSRC), 2), sub_64)); 19220b57cec5SDimitry Andric dag LE_DWORD_1 = (MFVSRD 19230b57cec5SDimitry Andric (EXTRACT_SUBREG 19240b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64)); 19250b57cec5SDimitry Andric 19260b57cec5SDimitry Andric // Word extraction 19270b57cec5SDimitry Andric dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64)); 19280b57cec5SDimitry Andric dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64)); 19290b57cec5SDimitry Andric dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG 19300b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64)); 19310b57cec5SDimitry Andric dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64)); 19320b57cec5SDimitry Andric 19330b57cec5SDimitry Andric // Halfword extraction 19340b57cec5SDimitry Andric dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32)); 19350b57cec5SDimitry Andric dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32)); 19360b57cec5SDimitry Andric dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32)); 19370b57cec5SDimitry Andric dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32)); 19380b57cec5SDimitry Andric dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32)); 19390b57cec5SDimitry Andric dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32)); 19400b57cec5SDimitry Andric dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32)); 19410b57cec5SDimitry Andric dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32)); 19420b57cec5SDimitry Andric 19430b57cec5SDimitry Andric // Byte extraction 19440b57cec5SDimitry Andric dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32)); 19450b57cec5SDimitry Andric dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32)); 19460b57cec5SDimitry Andric dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32)); 19470b57cec5SDimitry Andric dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32)); 19480b57cec5SDimitry Andric dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32)); 19490b57cec5SDimitry Andric dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32)); 19500b57cec5SDimitry Andric dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32)); 19510b57cec5SDimitry Andric dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32)); 19520b57cec5SDimitry Andric dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32)); 19530b57cec5SDimitry Andric dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32)); 19540b57cec5SDimitry Andric dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32)); 19550b57cec5SDimitry Andric dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32)); 19560b57cec5SDimitry Andric dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32)); 19570b57cec5SDimitry Andric dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32)); 19580b57cec5SDimitry Andric dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32)); 19590b57cec5SDimitry Andric dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32)); 19600b57cec5SDimitry Andric 19610b57cec5SDimitry Andric /* Variable element number (BE and LE patterns must be specified separately) 19620b57cec5SDimitry Andric This is a rather involved process. 19630b57cec5SDimitry Andric 19640b57cec5SDimitry Andric Conceptually, this is how the move is accomplished: 19650b57cec5SDimitry Andric 1. Identify which doubleword contains the element 19660b57cec5SDimitry Andric 2. Shift in the VMX register so that the correct doubleword is correctly 19670b57cec5SDimitry Andric lined up for the MFVSRD 19680b57cec5SDimitry Andric 3. Perform the move so that the element (along with some extra stuff) 19690b57cec5SDimitry Andric is in the GPR 19700b57cec5SDimitry Andric 4. Right shift within the GPR so that the element is right-justified 19710b57cec5SDimitry Andric 19720b57cec5SDimitry Andric Of course, the index is an element number which has a different meaning 19730b57cec5SDimitry Andric on LE/BE so the patterns have to be specified separately. 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andric Note: The final result will be the element right-justified with high 19760b57cec5SDimitry Andric order bits being arbitrarily defined (namely, whatever was in the 19770b57cec5SDimitry Andric vector register to the left of the value originally). 19780b57cec5SDimitry Andric */ 19790b57cec5SDimitry Andric 19800b57cec5SDimitry Andric /* LE variable byte 19810b57cec5SDimitry Andric Number 1. above: 19820b57cec5SDimitry Andric - For elements 0-7, we shift left by 8 bytes since they're on the right 19830b57cec5SDimitry Andric - For elements 8-15, we need not shift (shift left by zero bytes) 19840b57cec5SDimitry Andric This is accomplished by inverting the bits of the index and AND-ing 19850b57cec5SDimitry Andric with 0x8 (i.e. clearing all bits of the index and inverting bit 60). 19860b57cec5SDimitry Andric */ 19870b57cec5SDimitry Andric dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx))); 19880b57cec5SDimitry Andric 19890b57cec5SDimitry Andric // Number 2. above: 19900b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 19910b57cec5SDimitry Andric dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC)); 19920b57cec5SDimitry Andric 19930b57cec5SDimitry Andric // Number 3. above: 19940b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 19950b57cec5SDimitry Andric dag LE_MV_VBYTE = (MFVSRD 19960b57cec5SDimitry Andric (EXTRACT_SUBREG 19970b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)), 19980b57cec5SDimitry Andric sub_64)); 19990b57cec5SDimitry Andric 20000b57cec5SDimitry Andric /* Number 4. above: 20010b57cec5SDimitry Andric - Truncate the element number to the range 0-7 (8-15 are symmetrical 20020b57cec5SDimitry Andric and out of range values are truncated accordingly) 20030b57cec5SDimitry Andric - Multiply by 8 as we need to shift right by the number of bits, not bytes 20040b57cec5SDimitry Andric - Shift right in the GPR by the calculated value 20050b57cec5SDimitry Andric */ 20060b57cec5SDimitry Andric dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60), 20070b57cec5SDimitry Andric sub_32); 20080b57cec5SDimitry Andric dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT), 20090b57cec5SDimitry Andric sub_32); 20100b57cec5SDimitry Andric 20110b57cec5SDimitry Andric /* LE variable halfword 20120b57cec5SDimitry Andric Number 1. above: 20130b57cec5SDimitry Andric - For elements 0-3, we shift left by 8 since they're on the right 20140b57cec5SDimitry Andric - For elements 4-7, we need not shift (shift left by zero bytes) 20150b57cec5SDimitry Andric Similarly to the byte pattern, we invert the bits of the index, but we 20160b57cec5SDimitry Andric AND with 0x4 (i.e. clear all bits of the index and invert bit 61). 20170b57cec5SDimitry Andric Of course, the shift is still by 8 bytes, so we must multiply by 2. 20180b57cec5SDimitry Andric */ 20190b57cec5SDimitry Andric dag LE_VHALF_PERM_VEC = 20200b57cec5SDimitry Andric (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62))); 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andric // Number 2. above: 20230b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 20240b57cec5SDimitry Andric dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC)); 20250b57cec5SDimitry Andric 20260b57cec5SDimitry Andric // Number 3. above: 20270b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 20280b57cec5SDimitry Andric dag LE_MV_VHALF = (MFVSRD 20290b57cec5SDimitry Andric (EXTRACT_SUBREG 20300b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)), 20310b57cec5SDimitry Andric sub_64)); 20320b57cec5SDimitry Andric 20330b57cec5SDimitry Andric /* Number 4. above: 20340b57cec5SDimitry Andric - Truncate the element number to the range 0-3 (4-7 are symmetrical 20350b57cec5SDimitry Andric and out of range values are truncated accordingly) 20360b57cec5SDimitry Andric - Multiply by 16 as we need to shift right by the number of bits 20370b57cec5SDimitry Andric - Shift right in the GPR by the calculated value 20380b57cec5SDimitry Andric */ 20390b57cec5SDimitry Andric dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59), 20400b57cec5SDimitry Andric sub_32); 20410b57cec5SDimitry Andric dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT), 20420b57cec5SDimitry Andric sub_32); 20430b57cec5SDimitry Andric 20440b57cec5SDimitry Andric /* LE variable word 20450b57cec5SDimitry Andric Number 1. above: 20460b57cec5SDimitry Andric - For elements 0-1, we shift left by 8 since they're on the right 20470b57cec5SDimitry Andric - For elements 2-3, we need not shift 20480b57cec5SDimitry Andric */ 20490b57cec5SDimitry Andric dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 20500b57cec5SDimitry Andric (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61))); 20510b57cec5SDimitry Andric 20520b57cec5SDimitry Andric // Number 2. above: 20530b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 20540b57cec5SDimitry Andric dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC)); 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andric // Number 3. above: 20570b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 20580b57cec5SDimitry Andric dag LE_MV_VWORD = (MFVSRD 20590b57cec5SDimitry Andric (EXTRACT_SUBREG 20600b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)), 20610b57cec5SDimitry Andric sub_64)); 20620b57cec5SDimitry Andric 20630b57cec5SDimitry Andric /* Number 4. above: 20640b57cec5SDimitry Andric - Truncate the element number to the range 0-1 (2-3 are symmetrical 20650b57cec5SDimitry Andric and out of range values are truncated accordingly) 20660b57cec5SDimitry Andric - Multiply by 32 as we need to shift right by the number of bits 20670b57cec5SDimitry Andric - Shift right in the GPR by the calculated value 20680b57cec5SDimitry Andric */ 20690b57cec5SDimitry Andric dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58), 20700b57cec5SDimitry Andric sub_32); 20710b57cec5SDimitry Andric dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT), 20720b57cec5SDimitry Andric sub_32); 20730b57cec5SDimitry Andric 20740b57cec5SDimitry Andric /* LE variable doubleword 20750b57cec5SDimitry Andric Number 1. above: 20760b57cec5SDimitry Andric - For element 0, we shift left by 8 since it's on the right 20770b57cec5SDimitry Andric - For element 1, we need not shift 20780b57cec5SDimitry Andric */ 20790b57cec5SDimitry Andric dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 20800b57cec5SDimitry Andric (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60))); 20810b57cec5SDimitry Andric 20820b57cec5SDimitry Andric // Number 2. above: 20830b57cec5SDimitry Andric // - Now that we set up the shift amount, we shift in the VMX register 20840b57cec5SDimitry Andric dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC)); 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andric // Number 3. above: 20870b57cec5SDimitry Andric // - The doubleword containing our element is moved to a GPR 20880b57cec5SDimitry Andric // - Number 4. is not needed for the doubleword as the value is 64-bits 20890b57cec5SDimitry Andric dag LE_VARIABLE_DWORD = 20900b57cec5SDimitry Andric (MFVSRD (EXTRACT_SUBREG 20910b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)), 20920b57cec5SDimitry Andric sub_64)); 20930b57cec5SDimitry Andric 20940b57cec5SDimitry Andric /* LE variable float 20950b57cec5SDimitry Andric - Shift the vector to line up the desired element to BE Word 0 20960b57cec5SDimitry Andric - Convert 32-bit float to a 64-bit single precision float 20970b57cec5SDimitry Andric */ 20980b57cec5SDimitry Andric dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, 20990b57cec5SDimitry Andric (RLDICR (XOR8 (LI8 3), $Idx), 2, 61))); 21000b57cec5SDimitry Andric dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC); 21010b57cec5SDimitry Andric dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE); 21020b57cec5SDimitry Andric 21030b57cec5SDimitry Andric /* LE variable double 21040b57cec5SDimitry Andric Same as the LE doubleword except there is no move. 21050b57cec5SDimitry Andric */ 21060b57cec5SDimitry Andric dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 21070b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 21080b57cec5SDimitry Andric LE_VDWORD_PERM_VEC)); 21090b57cec5SDimitry Andric dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC); 21100b57cec5SDimitry Andric 21110b57cec5SDimitry Andric /* BE variable byte 21120b57cec5SDimitry Andric The algorithm here is the same as the LE variable byte except: 21130b57cec5SDimitry Andric - The shift in the VMX register is by 0/8 for opposite element numbers so 21140b57cec5SDimitry Andric we simply AND the element number with 0x8 21150b57cec5SDimitry Andric - The order of elements after the move to GPR is reversed, so we invert 21160b57cec5SDimitry Andric the bits of the index prior to truncating to the range 0-7 21170b57cec5SDimitry Andric */ 2118480093f4SDimitry Andric dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8))); 21190b57cec5SDimitry Andric dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC)); 21200b57cec5SDimitry Andric dag BE_MV_VBYTE = (MFVSRD 21210b57cec5SDimitry Andric (EXTRACT_SUBREG 21220b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)), 21230b57cec5SDimitry Andric sub_64)); 21240b57cec5SDimitry Andric dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60), 21250b57cec5SDimitry Andric sub_32); 21260b57cec5SDimitry Andric dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT), 21270b57cec5SDimitry Andric sub_32); 21280b57cec5SDimitry Andric 21290b57cec5SDimitry Andric /* BE variable halfword 21300b57cec5SDimitry Andric The algorithm here is the same as the LE variable halfword except: 21310b57cec5SDimitry Andric - The shift in the VMX register is by 0/8 for opposite element numbers so 21320b57cec5SDimitry Andric we simply AND the element number with 0x4 and multiply by 2 21330b57cec5SDimitry Andric - The order of elements after the move to GPR is reversed, so we invert 21340b57cec5SDimitry Andric the bits of the index prior to truncating to the range 0-3 21350b57cec5SDimitry Andric */ 21360b57cec5SDimitry Andric dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8, 2137480093f4SDimitry Andric (RLDICR (ANDI8_rec $Idx, 4), 1, 62))); 21380b57cec5SDimitry Andric dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC)); 21390b57cec5SDimitry Andric dag BE_MV_VHALF = (MFVSRD 21400b57cec5SDimitry Andric (EXTRACT_SUBREG 21410b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)), 21420b57cec5SDimitry Andric sub_64)); 21430b57cec5SDimitry Andric dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59), 21440b57cec5SDimitry Andric sub_32); 21450b57cec5SDimitry Andric dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT), 21460b57cec5SDimitry Andric sub_32); 21470b57cec5SDimitry Andric 21480b57cec5SDimitry Andric /* BE variable word 21490b57cec5SDimitry Andric The algorithm is the same as the LE variable word except: 21500b57cec5SDimitry Andric - The shift in the VMX register happens for opposite element numbers 21510b57cec5SDimitry Andric - The order of elements after the move to GPR is reversed, so we invert 21520b57cec5SDimitry Andric the bits of the index prior to truncating to the range 0-1 21530b57cec5SDimitry Andric */ 21540b57cec5SDimitry Andric dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 2155480093f4SDimitry Andric (RLDICR (ANDI8_rec $Idx, 2), 2, 61))); 21560b57cec5SDimitry Andric dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC)); 21570b57cec5SDimitry Andric dag BE_MV_VWORD = (MFVSRD 21580b57cec5SDimitry Andric (EXTRACT_SUBREG 21590b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)), 21600b57cec5SDimitry Andric sub_64)); 21610b57cec5SDimitry Andric dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58), 21620b57cec5SDimitry Andric sub_32); 21630b57cec5SDimitry Andric dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT), 21640b57cec5SDimitry Andric sub_32); 21650b57cec5SDimitry Andric 21660b57cec5SDimitry Andric /* BE variable doubleword 21670b57cec5SDimitry Andric Same as the LE doubleword except we shift in the VMX register for opposite 21680b57cec5SDimitry Andric element indices. 21690b57cec5SDimitry Andric */ 21700b57cec5SDimitry Andric dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8, 2171480093f4SDimitry Andric (RLDICR (ANDI8_rec $Idx, 1), 3, 60))); 21720b57cec5SDimitry Andric dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC)); 21730b57cec5SDimitry Andric dag BE_VARIABLE_DWORD = 21740b57cec5SDimitry Andric (MFVSRD (EXTRACT_SUBREG 21750b57cec5SDimitry Andric (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)), 21760b57cec5SDimitry Andric sub_64)); 21770b57cec5SDimitry Andric 21780b57cec5SDimitry Andric /* BE variable float 21790b57cec5SDimitry Andric - Shift the vector to line up the desired element to BE Word 0 21800b57cec5SDimitry Andric - Convert 32-bit float to a 64-bit single precision float 21810b57cec5SDimitry Andric */ 21820b57cec5SDimitry Andric dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61))); 21830b57cec5SDimitry Andric dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC); 21840b57cec5SDimitry Andric dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE); 21850b57cec5SDimitry Andric 2186fe6060f1SDimitry Andric // BE variable float 32-bit version 2187fe6060f1SDimitry Andric dag BE_32B_VFLOAT_PERM_VEC = (v16i8 (LVSL (i32 ZERO), (RLWINM $Idx, 2, 0, 29))); 2188fe6060f1SDimitry Andric dag BE_32B_VFLOAT_PERMUTE = (VPERM $S, $S, BE_32B_VFLOAT_PERM_VEC); 2189fe6060f1SDimitry Andric dag BE_32B_VARIABLE_FLOAT = (XSCVSPDPN BE_32B_VFLOAT_PERMUTE); 2190fe6060f1SDimitry Andric 21910b57cec5SDimitry Andric /* BE variable double 21920b57cec5SDimitry Andric Same as the BE doubleword except there is no move. 21930b57cec5SDimitry Andric */ 21940b57cec5SDimitry Andric dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 21950b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 21960b57cec5SDimitry Andric BE_VDWORD_PERM_VEC)); 21970b57cec5SDimitry Andric dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC); 2198fe6060f1SDimitry Andric 2199fe6060f1SDimitry Andric // BE variable double 32-bit version 2200fe6060f1SDimitry Andric dag BE_32B_VDWORD_PERM_VEC = (v16i8 (LVSL (i32 ZERO), 2201fe6060f1SDimitry Andric (RLWINM (ANDI_rec $Idx, 1), 3, 0, 28))); 2202fe6060f1SDimitry Andric dag BE_32B_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 2203fe6060f1SDimitry Andric (v16i8 (COPY_TO_REGCLASS $S, VRRC)), 2204fe6060f1SDimitry Andric BE_32B_VDWORD_PERM_VEC)); 2205fe6060f1SDimitry Andric dag BE_32B_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_32B_VDOUBLE_PERMUTE, VSRC); 22060b57cec5SDimitry Andric} 22070b57cec5SDimitry Andric 22080b57cec5SDimitry Andricdef AlignValues { 2209fe6060f1SDimitry Andric dag F32_TO_BE_WORD1 = (v4f32 (XSCVDPSPN $B)); 2210fe6060f1SDimitry Andric dag I32_TO_BE_WORD1 = (SUBREG_TO_REG (i64 1), (MTVSRWZ $B), sub_64); 22110b57cec5SDimitry Andric} 22120b57cec5SDimitry Andric 22130b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64 22140b57cec5SDimitry Andricdef AnyExts { 22150b57cec5SDimitry Andric dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32); 22160b57cec5SDimitry Andric dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32); 22170b57cec5SDimitry Andric dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32); 22180b57cec5SDimitry Andric dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32); 22190b57cec5SDimitry Andric} 22200b57cec5SDimitry Andric 22210b57cec5SDimitry Andricdef DblToFlt { 22225ffd83dbSDimitry Andric dag A0 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 0)))); 22235ffd83dbSDimitry Andric dag A1 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 1)))); 22245ffd83dbSDimitry Andric dag B0 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 0)))); 22255ffd83dbSDimitry Andric dag B1 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 1)))); 22260b57cec5SDimitry Andric} 22270b57cec5SDimitry Andric 22280b57cec5SDimitry Andricdef ExtDbl { 22290b57cec5SDimitry Andric dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0)))))); 22300b57cec5SDimitry Andric dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1)))))); 22310b57cec5SDimitry Andric dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0)))))); 22320b57cec5SDimitry Andric dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1)))))); 22330b57cec5SDimitry Andric dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0)))))); 22340b57cec5SDimitry Andric dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1)))))); 22350b57cec5SDimitry Andric dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0)))))); 22360b57cec5SDimitry Andric dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1)))))); 22370b57cec5SDimitry Andric} 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andricdef ByteToWord { 22400b57cec5SDimitry Andric dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8)); 22410b57cec5SDimitry Andric dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8)); 22420b57cec5SDimitry Andric dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8)); 22430b57cec5SDimitry Andric dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8)); 22440b57cec5SDimitry Andric dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8)); 22450b57cec5SDimitry Andric dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8)); 22460b57cec5SDimitry Andric dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8)); 22470b57cec5SDimitry Andric dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8)); 22480b57cec5SDimitry Andric} 22490b57cec5SDimitry Andric 22500b57cec5SDimitry Andricdef ByteToDWord { 22510b57cec5SDimitry Andric dag LE_A0 = (i64 (sext_inreg 22520b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8)); 22530b57cec5SDimitry Andric dag LE_A1 = (i64 (sext_inreg 22540b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8)); 22550b57cec5SDimitry Andric dag BE_A0 = (i64 (sext_inreg 22560b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8)); 22570b57cec5SDimitry Andric dag BE_A1 = (i64 (sext_inreg 22580b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8)); 22590b57cec5SDimitry Andric} 22600b57cec5SDimitry Andric 22610b57cec5SDimitry Andricdef HWordToWord { 22620b57cec5SDimitry Andric dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16)); 22630b57cec5SDimitry Andric dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16)); 22640b57cec5SDimitry Andric dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16)); 22650b57cec5SDimitry Andric dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16)); 22660b57cec5SDimitry Andric dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16)); 22670b57cec5SDimitry Andric dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16)); 22680b57cec5SDimitry Andric dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16)); 22690b57cec5SDimitry Andric dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16)); 22700b57cec5SDimitry Andric} 22710b57cec5SDimitry Andric 22720b57cec5SDimitry Andricdef HWordToDWord { 22730b57cec5SDimitry Andric dag LE_A0 = (i64 (sext_inreg 22740b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16)); 22750b57cec5SDimitry Andric dag LE_A1 = (i64 (sext_inreg 22760b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16)); 22770b57cec5SDimitry Andric dag BE_A0 = (i64 (sext_inreg 22780b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16)); 22790b57cec5SDimitry Andric dag BE_A1 = (i64 (sext_inreg 22800b57cec5SDimitry Andric (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16)); 22810b57cec5SDimitry Andric} 22820b57cec5SDimitry Andric 22830b57cec5SDimitry Andricdef WordToDWord { 22840b57cec5SDimitry Andric dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0)))); 22850b57cec5SDimitry Andric dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2)))); 22860b57cec5SDimitry Andric dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1)))); 22870b57cec5SDimitry Andric dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3)))); 22880b57cec5SDimitry Andric} 22890b57cec5SDimitry Andric 22900b57cec5SDimitry Andricdef FltToIntLoad { 2291fe6060f1SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 ForceXForm:$A))))); 22920b57cec5SDimitry Andric} 22930b57cec5SDimitry Andricdef FltToUIntLoad { 2294fe6060f1SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 ForceXForm:$A))))); 22950b57cec5SDimitry Andric} 22960b57cec5SDimitry Andricdef FltToLongLoad { 2297fe6060f1SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ForceXForm:$A))))); 22980b57cec5SDimitry Andric} 22990b57cec5SDimitry Andricdef FltToLongLoadP9 { 2300fe6060f1SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 DSForm:$A))))); 23010b57cec5SDimitry Andric} 23020b57cec5SDimitry Andricdef FltToULongLoad { 2303fe6060f1SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ForceXForm:$A))))); 23040b57cec5SDimitry Andric} 23050b57cec5SDimitry Andricdef FltToULongLoadP9 { 2306fe6060f1SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 DSForm:$A))))); 23070b57cec5SDimitry Andric} 23080b57cec5SDimitry Andricdef FltToLong { 23090b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A))))); 23100b57cec5SDimitry Andric} 23110b57cec5SDimitry Andricdef FltToULong { 23120b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A))))); 23130b57cec5SDimitry Andric} 23140b57cec5SDimitry Andricdef DblToInt { 23150b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A)))); 23160b57cec5SDimitry Andric dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B)))); 23170b57cec5SDimitry Andric dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C)))); 23180b57cec5SDimitry Andric dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D)))); 23190b57cec5SDimitry Andric} 23200b57cec5SDimitry Andricdef DblToUInt { 23210b57cec5SDimitry Andric dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A)))); 23220b57cec5SDimitry Andric dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B)))); 23230b57cec5SDimitry Andric dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C)))); 23240b57cec5SDimitry Andric dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D)))); 23250b57cec5SDimitry Andric} 23260b57cec5SDimitry Andricdef DblToLong { 23270b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A)))); 23280b57cec5SDimitry Andric} 23290b57cec5SDimitry Andricdef DblToULong { 23300b57cec5SDimitry Andric dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A)))); 23310b57cec5SDimitry Andric} 23320b57cec5SDimitry Andricdef DblToIntLoad { 2333fe6060f1SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ForceXForm:$A))))); 23340b57cec5SDimitry Andric} 23350b57cec5SDimitry Andricdef DblToIntLoadP9 { 2336fe6060f1SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load DSForm:$A))))); 23370b57cec5SDimitry Andric} 23380b57cec5SDimitry Andricdef DblToUIntLoad { 2339fe6060f1SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ForceXForm:$A))))); 23400b57cec5SDimitry Andric} 23410b57cec5SDimitry Andricdef DblToUIntLoadP9 { 2342fe6060f1SDimitry Andric dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load DSForm:$A))))); 23430b57cec5SDimitry Andric} 23440b57cec5SDimitry Andricdef DblToLongLoad { 2345fe6060f1SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load ForceXForm:$A))))); 23460b57cec5SDimitry Andric} 23470b57cec5SDimitry Andricdef DblToULongLoad { 2348fe6060f1SDimitry Andric dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load ForceXForm:$A))))); 23490b57cec5SDimitry Andric} 23500b57cec5SDimitry Andric 2351480093f4SDimitry Andric// FP load dags (for f32 -> v4f32) 2352480093f4SDimitry Andricdef LoadFP { 2353fe6060f1SDimitry Andric dag A = (f32 (load ForceXForm:$A)); 2354fe6060f1SDimitry Andric dag B = (f32 (load ForceXForm:$B)); 2355fe6060f1SDimitry Andric dag C = (f32 (load ForceXForm:$C)); 2356fe6060f1SDimitry Andric dag D = (f32 (load ForceXForm:$D)); 2357480093f4SDimitry Andric} 2358480093f4SDimitry Andric 23590b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32) 23600b57cec5SDimitry Andricdef MrgFP { 2361fe6060f1SDimitry Andric dag LD32A = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64); 2362fe6060f1SDimitry Andric dag LD32B = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$B), sub_64); 2363fe6060f1SDimitry Andric dag LD32C = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$C), sub_64); 2364fe6060f1SDimitry Andric dag LD32D = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$D), sub_64); 2365fe6060f1SDimitry Andric dag AC = (XVCVDPSP (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64), 2366fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), $C, sub_64), 0)); 2367fe6060f1SDimitry Andric dag BD = (XVCVDPSP (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), 2368fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), $D, sub_64), 0)); 23690b57cec5SDimitry Andric dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0)); 23700b57cec5SDimitry Andric dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3)); 23710b57cec5SDimitry Andric dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0)); 23720b57cec5SDimitry Andric dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3)); 23730b57cec5SDimitry Andric} 23740b57cec5SDimitry Andric 23750b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors. 23760b57cec5SDimitry Andricdef MrgWords { 23770b57cec5SDimitry Andric // For big endian, we merge low and hi doublewords (A, B). 23780b57cec5SDimitry Andric dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0)); 23790b57cec5SDimitry Andric dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3)); 23800b57cec5SDimitry Andric dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1)); 23810b57cec5SDimitry Andric dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0)); 23820b57cec5SDimitry Andric dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1)); 23830b57cec5SDimitry Andric dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0)); 23840b57cec5SDimitry Andric 23850b57cec5SDimitry Andric // For little endian, we merge low and hi doublewords (B, A). 23860b57cec5SDimitry Andric dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0)); 23870b57cec5SDimitry Andric dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3)); 23880b57cec5SDimitry Andric dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1)); 23890b57cec5SDimitry Andric dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0)); 23900b57cec5SDimitry Andric dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1)); 23910b57cec5SDimitry Andric dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0)); 23920b57cec5SDimitry Andric 23930b57cec5SDimitry Andric // For big endian, we merge hi doublewords of (A, C) and (B, D), convert 23940b57cec5SDimitry Andric // then merge. 2395fe6060f1SDimitry Andric dag AC = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$A, sub_64), 2396fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), f64:$C, sub_64), 0)); 2397fe6060f1SDimitry Andric dag BD = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$B, sub_64), 2398fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), f64:$D, sub_64), 0)); 23990b57cec5SDimitry Andric dag CVACS = (v4i32 (XVCVDPSXWS AC)); 24000b57cec5SDimitry Andric dag CVBDS = (v4i32 (XVCVDPSXWS BD)); 24010b57cec5SDimitry Andric dag CVACU = (v4i32 (XVCVDPUXWS AC)); 24020b57cec5SDimitry Andric dag CVBDU = (v4i32 (XVCVDPUXWS BD)); 24030b57cec5SDimitry Andric 24040b57cec5SDimitry Andric // For little endian, we merge hi doublewords of (D, B) and (C, A), convert 24050b57cec5SDimitry Andric // then merge. 2406fe6060f1SDimitry Andric dag DB = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$D, sub_64), 2407fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), f64:$B, sub_64), 0)); 2408fe6060f1SDimitry Andric dag CA = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$C, sub_64), 2409fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), f64:$A, sub_64), 0)); 24100b57cec5SDimitry Andric dag CVDBS = (v4i32 (XVCVDPSXWS DB)); 24110b57cec5SDimitry Andric dag CVCAS = (v4i32 (XVCVDPSXWS CA)); 24120b57cec5SDimitry Andric dag CVDBU = (v4i32 (XVCVDPUXWS DB)); 24130b57cec5SDimitry Andric dag CVCAU = (v4i32 (XVCVDPUXWS CA)); 24140b57cec5SDimitry Andric} 24150b57cec5SDimitry Andric 2416fe6060f1SDimitry Andricdef DblwdCmp { 2417fe6060f1SDimitry Andric dag SGTW = (v2i64 (v2i64 (VCMPGTSW v2i64:$vA, v2i64:$vB))); 2418fe6060f1SDimitry Andric dag UGTW = (v2i64 (v2i64 (VCMPGTUW v2i64:$vA, v2i64:$vB))); 2419fe6060f1SDimitry Andric dag EQW = (v2i64 (v2i64 (VCMPEQUW v2i64:$vA, v2i64:$vB))); 2420fe6060f1SDimitry Andric dag UGTWSHAND = (v2i64 (XXLAND (v2i64 (XXSLDWI UGTW, UGTW, 1)), EQW)); 2421fe6060f1SDimitry Andric dag EQWSHAND = (v2i64 (XXLAND (v2i64 (XXSLDWI EQW, EQW, 1)), EQW)); 2422fe6060f1SDimitry Andric dag SGTWOR = (v2i64 (XXLOR SGTW, UGTWSHAND)); 2423fe6060f1SDimitry Andric dag UGTWOR = (v2i64 (XXLOR UGTW, UGTWSHAND)); 2424fe6060f1SDimitry Andric dag MRGSGT = (v2i64 (XXPERMDI (v2i64 (XXSPLTW SGTWOR, 0)), 2425fe6060f1SDimitry Andric (v2i64 (XXSPLTW SGTWOR, 2)), 0)); 2426fe6060f1SDimitry Andric dag MRGUGT = (v2i64 (XXPERMDI (v2i64 (XXSPLTW UGTWOR, 0)), 2427fe6060f1SDimitry Andric (v2i64 (XXSPLTW UGTWOR, 2)), 0)); 2428fe6060f1SDimitry Andric dag MRGEQ = (v2i64 (XXPERMDI (v2i64 (XXSPLTW EQWSHAND, 0)), 2429fe6060f1SDimitry Andric (v2i64 (XXSPLTW EQWSHAND, 2)), 0)); 2430fe6060f1SDimitry Andric} 2431fe6060f1SDimitry Andric 24325ffd83dbSDimitry Andric//---------------------------- Anonymous Patterns ----------------------------// 24335ffd83dbSDimitry Andric// Predicate combinations are kept in roughly chronological order in terms of 24345ffd83dbSDimitry Andric// instruction availability in the architecture. For example, VSX came in with 24355ffd83dbSDimitry Andric// ISA 2.06 (Power7). There have since been additions in ISA 2.07 (Power8) and 24365ffd83dbSDimitry Andric// ISA 3.0 (Power9). However, the granularity of features on later subtargets 24375ffd83dbSDimitry Andric// is finer for various reasons. For example, we have Power8Vector, 24385ffd83dbSDimitry Andric// Power8Altivec, DirectMove that all came in with ISA 2.07. The situation is 24395ffd83dbSDimitry Andric// similar with ISA 3.0 with Power9Vector, Power9Altivec, IsISA3_0. Then there 24405ffd83dbSDimitry Andric// are orthogonal predicates such as endianness for which the order was 24415ffd83dbSDimitry Andric// arbitrarily chosen to be Big, Little. 24425ffd83dbSDimitry Andric// 24435ffd83dbSDimitry Andric// Predicate combinations available: 2444e8d8bef9SDimitry Andric// [HasVSX, IsLittleEndian, HasP8Altivec] Altivec patterns using VSX instr. 2445e8d8bef9SDimitry Andric// [HasVSX, IsBigEndian, HasP8Altivec] Altivec patterns using VSX instr. 24465ffd83dbSDimitry Andric// [HasVSX] 24475ffd83dbSDimitry Andric// [HasVSX, IsBigEndian] 24485ffd83dbSDimitry Andric// [HasVSX, IsLittleEndian] 24495ffd83dbSDimitry Andric// [HasVSX, NoP9Vector] 2450e8d8bef9SDimitry Andric// [HasVSX, NoP9Vector, IsLittleEndian] 2451fe6060f1SDimitry Andric// [HasVSX, NoP9Vector, IsBigEndian] 24525ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps] 24535ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps, IsBigEndian] 24545ffd83dbSDimitry Andric// [HasVSX, HasP8Vector] 2455fe6060f1SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian] 2456e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] 24575ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, IsLittleEndian] 2458e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] 24595ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] 24604824e7fdSDimitry Andric// [HasVSX, HasP8Altivec] 24615ffd83dbSDimitry Andric// [HasVSX, HasDirectMove] 24625ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsBigEndian] 24635ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsLittleEndian] 2464e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian, IsPPC64] 2465e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] 24665ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] 24675ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] 24685ffd83dbSDimitry Andric// [HasVSX, HasP9Vector] 2469fe6060f1SDimitry Andric// [HasVSX, HasP9Vector, NoP10Vector] 2470fe6060f1SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian] 2471e8d8bef9SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] 24725ffd83dbSDimitry Andric// [HasVSX, HasP9Vector, IsLittleEndian] 24735ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec] 2474e8d8bef9SDimitry Andric// [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] 24755ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec, IsLittleEndian] 2476e8d8bef9SDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] 24775ffd83dbSDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] 24780b57cec5SDimitry Andric 2479e8d8bef9SDimitry Andric// These Altivec patterns are here because we need a VSX instruction to match 2480e8d8bef9SDimitry Andric// the intrinsic (but only for little endian system). 2481e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsLittleEndian, HasP8Altivec] in 2482e8d8bef9SDimitry Andric def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a, 2483e8d8bef9SDimitry Andric v16i8:$b, v16i8:$c)), 2484e8d8bef9SDimitry Andric (v16i8 (VPERMXOR $a, $b, (XXLNOR (COPY_TO_REGCLASS $c, VSRC), 2485e8d8bef9SDimitry Andric (COPY_TO_REGCLASS $c, VSRC))))>; 2486e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsBigEndian, HasP8Altivec] in 2487e8d8bef9SDimitry Andric def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a, 2488e8d8bef9SDimitry Andric v16i8:$b, v16i8:$c)), 2489e8d8bef9SDimitry Andric (v16i8 (VPERMXOR $a, $b, $c))>; 24904824e7fdSDimitry Andriclet Predicates = [HasVSX, HasP8Altivec] in 24914824e7fdSDimitry Andric def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor_be v16i8:$a, 24924824e7fdSDimitry Andric v16i8:$b, v16i8:$c)), 24934824e7fdSDimitry Andric (v16i8 (VPERMXOR $a, $b, $c))>; 2494e8d8bef9SDimitry Andric 24955ffd83dbSDimitry Andriclet AddedComplexity = 400 in { 24965ffd83dbSDimitry Andric// Valid for any VSX subtarget, regardless of endianness. 24970b57cec5SDimitry Andriclet Predicates = [HasVSX] in { 2498fe6060f1SDimitry Andricdef : Pat<(v4i32 (vnot v4i32:$A)), 24995ffd83dbSDimitry Andric (v4i32 (XXLNOR $A, $A))>; 2500fe6060f1SDimitry Andricdef : Pat<(v4i32 (or (and (vnot v4i32:$C), v4i32:$A), 25015ffd83dbSDimitry Andric (and v4i32:$B, v4i32:$C))), 25025ffd83dbSDimitry Andric (v4i32 (XXSEL $A, $B, $C))>; 25035ffd83dbSDimitry Andric 2504*bdd1243dSDimitry Andricdef : Pat<(f64 (fpimm0neg)), 2505*bdd1243dSDimitry Andric (f64 (XSNEGDP (XXLXORdpz)))>; 2506*bdd1243dSDimitry Andric 2507*bdd1243dSDimitry Andricdef : Pat<(f32 (fpimm0neg)), 2508*bdd1243dSDimitry Andric (f32 (COPY_TO_REGCLASS (XSNEGDP (XXLXORdpz)), VSSRC))>; 2509*bdd1243dSDimitry Andric 2510*bdd1243dSDimitry Andricdef : Pat<(f64 (nzFPImmExactInti5:$A)), 2511*bdd1243dSDimitry Andric (COPY_TO_REGCLASS (XVCVSXWDP (COPY_TO_REGCLASS 2512*bdd1243dSDimitry Andric (VSPLTISW (getFPAs5BitExactInt fpimm:$A)), VSRC)), VSFRC)>; 2513*bdd1243dSDimitry Andric 2514*bdd1243dSDimitry Andricdef : Pat<(f32 (nzFPImmExactInti5:$A)), 2515*bdd1243dSDimitry Andric (COPY_TO_REGCLASS (XVCVSXWDP (COPY_TO_REGCLASS 2516*bdd1243dSDimitry Andric (VSPLTISW (getFPAs5BitExactInt fpimm:$A)), VSRC)), VSSRC)>; 2517*bdd1243dSDimitry Andric 25185ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode 25195ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C), 25205ffd83dbSDimitry Andric (XSNMSUBADP $C, $A, $B)>; 25215ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)), 25225ffd83dbSDimitry Andric (XSMSUBADP $C, $A, $B)>; 25235ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)), 25245ffd83dbSDimitry Andric (XSNMADDADP $C, $A, $B)>; 25255ffd83dbSDimitry Andric 25265ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C), 25275ffd83dbSDimitry Andric (XVNMSUBADP $C, $A, $B)>; 25285ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)), 25295ffd83dbSDimitry Andric (XVMSUBADP $C, $A, $B)>; 25305ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)), 25315ffd83dbSDimitry Andric (XVNMADDADP $C, $A, $B)>; 25325ffd83dbSDimitry Andric 25335ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C), 25345ffd83dbSDimitry Andric (XVNMSUBASP $C, $A, $B)>; 25355ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)), 25365ffd83dbSDimitry Andric (XVMSUBASP $C, $A, $B)>; 25375ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)), 25385ffd83dbSDimitry Andric (XVNMADDASP $C, $A, $B)>; 25395ffd83dbSDimitry Andric 2540e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt f64:$frA), (XSSQRTDP $frA)>; 2541e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v2f64:$frA), (XVSQRTDP $frA)>; 2542e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v4f32:$frA), (XVSQRTSP $frA)>; 2543e8d8bef9SDimitry Andric 25445ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)), 25455ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25465ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)), 25475ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25485ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)), 25495ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25505ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)), 25515ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25525ffd83dbSDimitry Andric 25535ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)), 25545ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25555ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)), 25565ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25575ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)), 25585ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25595ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)), 25605ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25615ffd83dbSDimitry Andric 25625ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)), 25635ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25645ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)), 25655ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25665ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)), 25675ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25685ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)), 25695ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VSRC)>; 25705ffd83dbSDimitry Andric 25715ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)), 25725ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25735ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)), 25745ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25755ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)), 25765ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25775ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)), 25785ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25795ffd83dbSDimitry Andric 25805ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)), 25815ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25825ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)), 25835ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25845ffd83dbSDimitry Andric 25855ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)), 25865ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25875ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)), 25885ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25895ffd83dbSDimitry Andric 25905ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)), 25915ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25925ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)), 25935ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25945ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)), 25955ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25965ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)), 25975ffd83dbSDimitry Andric (COPY_TO_REGCLASS $A, VRRC)>; 25985ffd83dbSDimitry Andric 25995ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)), 26005ffd83dbSDimitry Andric (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>; 26015ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)), 26025ffd83dbSDimitry Andric (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>; 26035ffd83dbSDimitry Andric 26045ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)), 26055ffd83dbSDimitry Andric (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>; 26065ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)), 26075ffd83dbSDimitry Andric (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>; 26085ffd83dbSDimitry Andric 26095ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>; 26105ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>; 26115ffd83dbSDimitry Andric 26125ffd83dbSDimitry Andric// Permutes. 26135ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>; 26145ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>; 26155ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>; 26165ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>; 26175ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>; 26185ffd83dbSDimitry Andric 26195ffd83dbSDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and 26205ffd83dbSDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable. 26215ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), 26225ffd83dbSDimitry Andric (XXPERMDI $src, $src, 2)>; 26235ffd83dbSDimitry Andric 26245ffd83dbSDimitry Andric// Selects. 26255ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)), 26265ffd83dbSDimitry Andric (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 26275ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)), 26285ffd83dbSDimitry Andric (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 26295ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)), 26305ffd83dbSDimitry Andric (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 26315ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)), 26325ffd83dbSDimitry Andric (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 26335ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)), 26345ffd83dbSDimitry Andric (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>; 26355ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)), 26365ffd83dbSDimitry Andric (SELECT_VSRC (CRORC $rhs, $lhs), $tval, $fval)>; 26375ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)), 26385ffd83dbSDimitry Andric (SELECT_VSRC (CRORC $lhs, $rhs), $tval, $fval)>; 26395ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)), 26405ffd83dbSDimitry Andric (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 26415ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)), 26425ffd83dbSDimitry Andric (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 26435ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)), 26445ffd83dbSDimitry Andric (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 26455ffd83dbSDimitry Andric 26465ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)), 26475ffd83dbSDimitry Andric (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 26485ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)), 26495ffd83dbSDimitry Andric (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 26505ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)), 26515ffd83dbSDimitry Andric (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 26525ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)), 26535ffd83dbSDimitry Andric (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 26545ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)), 26555ffd83dbSDimitry Andric (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>; 26565ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)), 26575ffd83dbSDimitry Andric (SELECT_VSFRC (CRORC $rhs, $lhs), $tval, $fval)>; 26585ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)), 26595ffd83dbSDimitry Andric (SELECT_VSFRC (CRORC $lhs, $rhs), $tval, $fval)>; 26605ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)), 26615ffd83dbSDimitry Andric (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>; 26625ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)), 26635ffd83dbSDimitry Andric (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>; 26645ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)), 26655ffd83dbSDimitry Andric (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>; 26665ffd83dbSDimitry Andric 26675ffd83dbSDimitry Andric// Divides. 26685ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B), 26695ffd83dbSDimitry Andric (XVDIVSP $A, $B)>; 26705ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B), 26715ffd83dbSDimitry Andric (XVDIVDP $A, $B)>; 26725ffd83dbSDimitry Andric 2673e8d8bef9SDimitry Andric// Vector test for software divide and sqrt. 2674e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)), 2675e8d8bef9SDimitry Andric (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>; 2676e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)), 2677e8d8bef9SDimitry Andric (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>; 2678e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)), 2679e8d8bef9SDimitry Andric (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>; 2680e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)), 2681e8d8bef9SDimitry Andric (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>; 2682e8d8bef9SDimitry Andric 26835ffd83dbSDimitry Andric// Reciprocal estimate 26845ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A), 26855ffd83dbSDimitry Andric (XVRESP $A)>; 26865ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A), 26875ffd83dbSDimitry Andric (XVREDP $A)>; 26885ffd83dbSDimitry Andric 26895ffd83dbSDimitry Andric// Recip. square root estimate 26905ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A), 26915ffd83dbSDimitry Andric (XVRSQRTESP $A)>; 26925ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A), 26935ffd83dbSDimitry Andric (XVRSQRTEDP $A)>; 26945ffd83dbSDimitry Andric 26955ffd83dbSDimitry Andric// Vector selection 26965ffd83dbSDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)), 26975ffd83dbSDimitry Andric (COPY_TO_REGCLASS 26985ffd83dbSDimitry Andric (XXSEL (COPY_TO_REGCLASS $vC, VSRC), 26995ffd83dbSDimitry Andric (COPY_TO_REGCLASS $vB, VSRC), 27005ffd83dbSDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 27015ffd83dbSDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)), 27025ffd83dbSDimitry Andric (COPY_TO_REGCLASS 27035ffd83dbSDimitry Andric (XXSEL (COPY_TO_REGCLASS $vC, VSRC), 27045ffd83dbSDimitry Andric (COPY_TO_REGCLASS $vB, VSRC), 27055ffd83dbSDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 27065ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC), 27075ffd83dbSDimitry Andric (XXSEL $vC, $vB, $vA)>; 27085ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC), 27095ffd83dbSDimitry Andric (XXSEL $vC, $vB, $vA)>; 27105ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC), 27115ffd83dbSDimitry Andric (XXSEL $vC, $vB, $vA)>; 27125ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC), 27135ffd83dbSDimitry Andric (XXSEL $vC, $vB, $vA)>; 2714fe6060f1SDimitry Andricdef : Pat<(v1i128 (vselect v1i128:$vA, v1i128:$vB, v1i128:$vC)), 2715fe6060f1SDimitry Andric (COPY_TO_REGCLASS 2716fe6060f1SDimitry Andric (XXSEL (COPY_TO_REGCLASS $vC, VSRC), 2717fe6060f1SDimitry Andric (COPY_TO_REGCLASS $vB, VSRC), 2718fe6060f1SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 27195ffd83dbSDimitry Andric 27205ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fmaxnum v4f32:$src1, v4f32:$src2)), 27215ffd83dbSDimitry Andric (v4f32 (XVMAXSP $src1, $src2))>; 27225ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fminnum v4f32:$src1, v4f32:$src2)), 27235ffd83dbSDimitry Andric (v4f32 (XVMINSP $src1, $src2))>; 27245ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fmaxnum v2f64:$src1, v2f64:$src2)), 27255ffd83dbSDimitry Andric (v2f64 (XVMAXDP $src1, $src2))>; 27265ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fminnum v2f64:$src1, v2f64:$src2)), 27275ffd83dbSDimitry Andric (v2f64 (XVMINDP $src1, $src2))>; 27285ffd83dbSDimitry Andric 27295ffd83dbSDimitry Andric// f32 abs 27305ffd83dbSDimitry Andricdef : Pat<(f32 (fabs f32:$S)), 27315ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSABSDP 27325ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 27335ffd83dbSDimitry Andric 27345ffd83dbSDimitry Andric// f32 nabs 27355ffd83dbSDimitry Andricdef : Pat<(f32 (fneg (fabs f32:$S))), 27365ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSNABSDP 27375ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 27385ffd83dbSDimitry Andric 27395ffd83dbSDimitry Andric// f32 Min. 27405ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)), 27415ffd83dbSDimitry Andric (f32 FpMinMax.F32Min)>; 27425ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)), 27435ffd83dbSDimitry Andric (f32 FpMinMax.F32Min)>; 27445ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))), 27455ffd83dbSDimitry Andric (f32 FpMinMax.F32Min)>; 27465ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))), 27475ffd83dbSDimitry Andric (f32 FpMinMax.F32Min)>; 27485ffd83dbSDimitry Andric// F32 Max. 27495ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)), 27505ffd83dbSDimitry Andric (f32 FpMinMax.F32Max)>; 27515ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)), 27525ffd83dbSDimitry Andric (f32 FpMinMax.F32Max)>; 27535ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))), 27545ffd83dbSDimitry Andric (f32 FpMinMax.F32Max)>; 27555ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))), 27565ffd83dbSDimitry Andric (f32 FpMinMax.F32Max)>; 27575ffd83dbSDimitry Andric 27585ffd83dbSDimitry Andric// f64 Min. 27595ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)), 27605ffd83dbSDimitry Andric (f64 (XSMINDP $A, $B))>; 27615ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)), 27625ffd83dbSDimitry Andric (f64 (XSMINDP $A, $B))>; 27635ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))), 27645ffd83dbSDimitry Andric (f64 (XSMINDP $A, $B))>; 27655ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))), 27665ffd83dbSDimitry Andric (f64 (XSMINDP $A, $B))>; 27675ffd83dbSDimitry Andric// f64 Max. 27685ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)), 27695ffd83dbSDimitry Andric (f64 (XSMAXDP $A, $B))>; 27705ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)), 27715ffd83dbSDimitry Andric (f64 (XSMAXDP $A, $B))>; 27725ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))), 27735ffd83dbSDimitry Andric (f64 (XSMAXDP $A, $B))>; 27745ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))), 27755ffd83dbSDimitry Andric (f64 (XSMAXDP $A, $B))>; 27765ffd83dbSDimitry Andric 2777fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, ForceXForm:$dst), 2778fe6060f1SDimitry Andric (STXVD2X $rS, ForceXForm:$dst)>; 2779fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, ForceXForm:$dst), 2780fe6060f1SDimitry Andric (STXVW4X $rS, ForceXForm:$dst)>; 2781fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>; 2782fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>; 27835ffd83dbSDimitry Andric 27845ffd83dbSDimitry Andric// Rounding for single precision. 27855ffd83dbSDimitry Andricdef : Pat<(f32 (any_fround f32:$S)), 27865ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSRDPI 27875ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 27885ffd83dbSDimitry Andricdef : Pat<(f32 (any_ffloor f32:$S)), 27895ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSRDPIM 27905ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 27915ffd83dbSDimitry Andricdef : Pat<(f32 (any_fceil f32:$S)), 27925ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSRDPIP 27935ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 27945ffd83dbSDimitry Andricdef : Pat<(f32 (any_ftrunc f32:$S)), 27955ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSRDPIZ 27965ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 27975ffd83dbSDimitry Andricdef : Pat<(f32 (any_frint f32:$S)), 27985ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSRDPIC 27995ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 2800e8d8bef9SDimitry Andricdef : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>; 28015ffd83dbSDimitry Andric 28025ffd83dbSDimitry Andric// Rounding for double precision. 2803e8d8bef9SDimitry Andricdef : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>; 2804e8d8bef9SDimitry Andricdef : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>; 28055ffd83dbSDimitry Andric 2806349cc55cSDimitry Andric// Rounding without exceptions (nearbyint). Due to strange tblgen behaviour, 2807349cc55cSDimitry Andric// these need to be defined after the any_frint versions so ISEL will correctly 2808349cc55cSDimitry Andric// add the chain to the strict versions. 2809349cc55cSDimitry Andricdef : Pat<(f32 (fnearbyint f32:$S)), 2810349cc55cSDimitry Andric (f32 (COPY_TO_REGCLASS (XSRDPIC 2811349cc55cSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 2812349cc55cSDimitry Andricdef : Pat<(f64 (fnearbyint f64:$S)), 2813349cc55cSDimitry Andric (f64 (XSRDPIC $S))>; 2814349cc55cSDimitry Andricdef : Pat<(v2f64 (fnearbyint v2f64:$S)), 2815349cc55cSDimitry Andric (v2f64 (XVRDPIC $S))>; 2816349cc55cSDimitry Andricdef : Pat<(v4f32 (fnearbyint v4f32:$S)), 2817349cc55cSDimitry Andric (v4f32 (XVRSPIC $S))>; 2818349cc55cSDimitry Andric 28195ffd83dbSDimitry Andric// Materialize a zero-vector of long long 28205ffd83dbSDimitry Andricdef : Pat<(v2i64 immAllZerosV), 28215ffd83dbSDimitry Andric (v2i64 (XXLXORz))>; 28225ffd83dbSDimitry Andric 28230b57cec5SDimitry Andric// Build vectors of floating point converted to i32. 28240b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A, 28250b57cec5SDimitry Andric DblToInt.A, DblToInt.A)), 2826fe6060f1SDimitry Andric (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS $A), sub_64), 1))>; 28270b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A, 28280b57cec5SDimitry Andric DblToUInt.A, DblToUInt.A)), 2829fe6060f1SDimitry Andric (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS $A), sub_64), 1))>; 28300b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)), 2831fe6060f1SDimitry Andric (v2i64 (XXPERMDI (SUBREG_TO_REG (i64 1), (XSCVDPSXDS $A), sub_64), 2832fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSXDS $A), sub_64), 0))>; 28330b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)), 2834fe6060f1SDimitry Andric (v2i64 (XXPERMDI (SUBREG_TO_REG (i64 1), (XSCVDPUXDS $A), sub_64), 2835fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPUXDS $A), sub_64), 0))>; 2836349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCSToV DblToInt.A)), 2837349cc55cSDimitry Andric (v4i32 (SUBREG_TO_REG (i64 1), (XSCVDPSXWS f64:$A), sub_64))>; 2838349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCSToV DblToUInt.A)), 2839349cc55cSDimitry Andric (v4i32 (SUBREG_TO_REG (i64 1), (XSCVDPUXWS f64:$A), sub_64))>; 28405ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 28415ffd83dbSDimitry Andric v4i32, FltToIntLoad.A, 2842fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWSs (XFLOADf32 ForceXForm:$A)), sub_64), 1), 2843fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSXWSs (XFLOADf32 ForceXForm:$A)), sub_64)>; 28445ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 28455ffd83dbSDimitry Andric v4i32, FltToUIntLoad.A, 2846fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWSs (XFLOADf32 ForceXForm:$A)), sub_64), 1), 2847fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPUXWSs (XFLOADf32 ForceXForm:$A)), sub_64)>; 2848fe6060f1SDimitry Andricdef : Pat<(v4f32 (build_vector (f32 (fpround f64:$A)), (f32 (fpround f64:$A)), 2849fe6060f1SDimitry Andric (f32 (fpround f64:$A)), (f32 (fpround f64:$A)))), 2850fe6060f1SDimitry Andric (v4f32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$A), sub_64), 0))>; 2851fe6060f1SDimitry Andric 28520b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)), 28530b57cec5SDimitry Andric (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>; 2854349cc55cSDimitry Andric 2855349cc55cSDimitry Andric// Splat loads. 2856fe6060f1SDimitry Andricdef : Pat<(v2f64 (PPCldsplat ForceXForm:$A)), 2857fe6060f1SDimitry Andric (v2f64 (LXVDSX ForceXForm:$A))>; 2858349cc55cSDimitry Andricdef : Pat<(v4f32 (PPCldsplat ForceXForm:$A)), 2859349cc55cSDimitry Andric (v4f32 (XXSPLTW (SUBREG_TO_REG (i64 1), (LFIWZX ForceXForm:$A), sub_64), 1))>; 2860fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCldsplat ForceXForm:$A)), 2861fe6060f1SDimitry Andric (v2i64 (LXVDSX ForceXForm:$A))>; 2862349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCldsplat ForceXForm:$A)), 2863349cc55cSDimitry Andric (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (LFIWZX ForceXForm:$A), sub_64), 1))>; 2864349cc55cSDimitry Andricdef : Pat<(v2i64 (PPCzextldsplat ForceXForm:$A)), 2865349cc55cSDimitry Andric (v2i64 (XXPERMDIs (LFIWZX ForceXForm:$A), 0))>; 2866349cc55cSDimitry Andricdef : Pat<(v2i64 (PPCsextldsplat ForceXForm:$A)), 2867349cc55cSDimitry Andric (v2i64 (XXPERMDIs (LFIWAX ForceXForm:$A), 0))>; 28680b57cec5SDimitry Andric 28690b57cec5SDimitry Andric// Build vectors of floating point converted to i64. 28700b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)), 28710b57cec5SDimitry Andric (v2i64 (XXPERMDIs 28720b57cec5SDimitry Andric (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>; 28730b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)), 28740b57cec5SDimitry Andric (v2i64 (XXPERMDIs 28750b57cec5SDimitry Andric (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>; 28765ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 28775ffd83dbSDimitry Andric v2i64, DblToLongLoad.A, 2878fe6060f1SDimitry Andric (XVCVDPSXDS (LXVDSX ForceXForm:$A)), (XVCVDPSXDS (LXVDSX ForceXForm:$A))>; 28795ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 28805ffd83dbSDimitry Andric v2i64, DblToULongLoad.A, 2881fe6060f1SDimitry Andric (XVCVDPUXDS (LXVDSX ForceXForm:$A)), (XVCVDPUXDS (LXVDSX ForceXForm:$A))>; 2882fe6060f1SDimitry Andric 2883fe6060f1SDimitry Andric// Doubleword vector predicate comparisons without Power8. 2884fe6060f1SDimitry Andriclet AddedComplexity = 0 in { 2885fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 967)), 2886fe6060f1SDimitry Andric (VCMPGTUB_rec DblwdCmp.MRGSGT, (v2i64 (XXLXORz)))>; 2887fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 711)), 2888fe6060f1SDimitry Andric (VCMPGTUB_rec DblwdCmp.MRGUGT, (v2i64 (XXLXORz)))>; 2889fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 199)), 2890fe6060f1SDimitry Andric (VCMPGTUB_rec DblwdCmp.MRGEQ, (v2i64 (XXLXORz)))>; 2891fe6060f1SDimitry Andric} // AddedComplexity = 0 2892fe6060f1SDimitry Andric 2893fe6060f1SDimitry Andric// XL Compat builtins. 2894fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsub f64:$A, f64:$B, f64:$C), (XSMSUBMDP $A, $B, $C)>; 2895fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (XSNMADDMDP $A, $B, $C)>; 2896fe6060f1SDimitry Andricdef : Pat<(int_ppc_fre f64:$A), (XSREDP $A)>; 2897fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrte vsfrc:$XB), (XSRSQRTEDP $XB)>; 289881ad6265SDimitry Andricdef : Pat<(int_ppc_fnabs f64:$A), (XSNABSDP $A)>; 289981ad6265SDimitry Andricdef : Pat<(int_ppc_fnabss f32:$A), (XSNABSDPs $A)>; 290081ad6265SDimitry Andric 290181ad6265SDimitry Andric// XXMRG[LH]W is a direct replacement for VMRG[LH]W respectively. 290281ad6265SDimitry Andric// Prefer the VSX form for greater register range. 290381ad6265SDimitry Andricdef:Pat<(vmrglw_unary_shuffle v16i8:$vA, undef), 290481ad6265SDimitry Andric (COPY_TO_REGCLASS (XXMRGLW (COPY_TO_REGCLASS $vA, VSRC), 290581ad6265SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 290681ad6265SDimitry Andricdef:Pat<(vmrghw_unary_shuffle v16i8:$vA, undef), 290781ad6265SDimitry Andric (COPY_TO_REGCLASS (XXMRGHW (COPY_TO_REGCLASS $vA, VSRC), 290881ad6265SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 290981ad6265SDimitry Andricdef:Pat<(vmrglw_shuffle v16i8:$vA, v16i8:$vB), 291081ad6265SDimitry Andric (COPY_TO_REGCLASS (XXMRGLW (COPY_TO_REGCLASS $vA, VSRC), 291181ad6265SDimitry Andric (COPY_TO_REGCLASS $vB, VSRC)), VRRC)>; 291281ad6265SDimitry Andricdef:Pat<(vmrghw_shuffle v16i8:$vA, v16i8:$vB), 291381ad6265SDimitry Andric (COPY_TO_REGCLASS (XXMRGHW (COPY_TO_REGCLASS $vA, VSRC), 291481ad6265SDimitry Andric (COPY_TO_REGCLASS $vB, VSRC)), VRRC)>; 291581ad6265SDimitry Andricdef:Pat<(vmrglw_swapped_shuffle v16i8:$vA, v16i8:$vB), 291681ad6265SDimitry Andric (COPY_TO_REGCLASS (XXMRGLW (COPY_TO_REGCLASS $vB, VSRC), 291781ad6265SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 291881ad6265SDimitry Andricdef:Pat<(vmrghw_swapped_shuffle v16i8:$vA, v16i8:$vB), 291981ad6265SDimitry Andric (COPY_TO_REGCLASS (XXMRGHW (COPY_TO_REGCLASS $vB, VSRC), 292081ad6265SDimitry Andric (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>; 29215ffd83dbSDimitry Andric} // HasVSX 29220b57cec5SDimitry Andric 29235ffd83dbSDimitry Andric// Any big endian VSX subtarget. 29245ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsBigEndian] in { 29255ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)), 29265ffd83dbSDimitry Andric (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>; 29270b57cec5SDimitry Andric 29285ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)), 29295ffd83dbSDimitry Andric (f64 (EXTRACT_SUBREG $S, sub_64))>; 29305ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)), 29315ffd83dbSDimitry Andric (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 29325ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 29335ffd83dbSDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>; 29345ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 29355ffd83dbSDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 29365ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 29375ffd83dbSDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>; 29385ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 29395ffd83dbSDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 29400b57cec5SDimitry Andric 29415ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 29425ffd83dbSDimitry Andric (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>; 29430b57cec5SDimitry Andric 29440b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 29450b57cec5SDimitry Andric (v2f64 (XXPERMDI 2946fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), $A, sub_64), 2947fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>; 2948480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency 2949480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency 2950480093f4SDimitry Andric// XXPERMDI for 2 reasons: 2951480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high, 2952480093f4SDimitry Andric// so we want to use the latter as it has access to all 64 VSX registers. 2953480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the 2954480093f4SDimitry Andric// allocation of Altivec registers even for the loads which in turn would 2955480093f4SDimitry Andric// force the use of LXSIWZX for the loads, adding a cycle of latency to 2956480093f4SDimitry Andric// each of the loads which would otherwise be able to use LFIWZX. 2957480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)), 2958480093f4SDimitry Andric (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B), 2959480093f4SDimitry Andric (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>; 29600b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)), 29610b57cec5SDimitry Andric (VMRGEW MrgFP.AC, MrgFP.BD)>; 29620b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 29630b57cec5SDimitry Andric DblToFlt.B0, DblToFlt.B1)), 29640b57cec5SDimitry Andric (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>; 29650b57cec5SDimitry Andric 29660b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints. 29670b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B, 29680b57cec5SDimitry Andric DblToInt.C, DblToInt.D)), 29690b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>; 29700b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B, 29710b57cec5SDimitry Andric DblToUInt.C, DblToUInt.D)), 29720b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>; 29730b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S, 29740b57cec5SDimitry Andric ExtDbl.B0S, ExtDbl.B1S)), 29750b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>; 29760b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U, 29770b57cec5SDimitry Andric ExtDbl.B0U, ExtDbl.B1U)), 29780b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>; 29795ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 29805ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 1))))), 29815ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>; 29825ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 29835ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 0))))), 29845ffd83dbSDimitry Andric (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)), 29855ffd83dbSDimitry Andric (XVCVSPDP (XXMRGHW $A, $A)), 2))>; 29865ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 29875ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2))))), 29885ffd83dbSDimitry Andric (v2f64 (XVCVSPDP $A))>; 29895ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 29905ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3))))), 29915ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>; 29925ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))), 29935ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3))))), 29945ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>; 29955ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 29965ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2))))), 29975ffd83dbSDimitry Andric (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)), 29985ffd83dbSDimitry Andric (XVCVSPDP (XXMRGLW $A, $A)), 2))>; 29995ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 30005ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$B, 0))))), 30015ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>; 30025ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 30035ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$B, 3))))), 30045ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3), 30055ffd83dbSDimitry Andric (XXPERMDI $A, $B, 3), 1)))>; 3006fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint 3007fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 3008fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2)))))), 3009fe6060f1SDimitry Andric (v2i64 (XVCVSPSXDS $A))>; 3010fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint 3011fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 3012fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2)))))), 3013fe6060f1SDimitry Andric (v2i64 (XVCVSPUXDS $A))>; 3014fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint 3015fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 3016fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3)))))), 3017fe6060f1SDimitry Andric (v2i64 (XVCVSPSXDS (XXSLDWI $A, $A, 1)))>; 3018fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint 3019fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 3020fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3)))))), 3021fe6060f1SDimitry Andric (v2i64 (XVCVSPUXDS (XXSLDWI $A, $A, 1)))>; 30225ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S, 30235ffd83dbSDimitry Andric (v2f64 (XVCVSXWDP $A))>; 30245ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S, 3025349cc55cSDimitry Andric (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>; 30265ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U, 30275ffd83dbSDimitry Andric (v2f64 (XVCVUXWDP $A))>; 30285ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U, 3029349cc55cSDimitry Andric (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>; 3030fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 0)), 3031fe6060f1SDimitry Andric (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), $A, 1))>; 3032fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 1)), 3033fe6060f1SDimitry Andric (v2f64 (XXPERMDI $A, (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>; 30345ffd83dbSDimitry Andric} // HasVSX, IsBigEndian 30350b57cec5SDimitry Andric 30365ffd83dbSDimitry Andric// Any little endian VSX subtarget. 30375ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsLittleEndian] in { 30385ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2f64, (f64 f64:$A), 30395ffd83dbSDimitry Andric (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64), 30405ffd83dbSDimitry Andric (SUBREG_TO_REG (i64 1), $A, sub_64), 0), 30415ffd83dbSDimitry Andric (SUBREG_TO_REG (i64 1), $A, sub_64)>; 30420b57cec5SDimitry Andric 30435ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)), 30445ffd83dbSDimitry Andric (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>; 30455ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)), 30465ffd83dbSDimitry Andric (f64 (EXTRACT_SUBREG $S, sub_64))>; 30470b57cec5SDimitry Andric 3048fe6060f1SDimitry Andricdef : Pat<(v2f64 (PPCld_vec_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>; 3049fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>; 3050fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCld_vec_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>; 3051fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v4f32:$rS, ForceXForm:$dst), (STXVW4X $rS, ForceXForm:$dst)>; 3052fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCld_vec_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>; 3053fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v2i64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>; 3054fe6060f1SDimitry Andricdef : Pat<(v4i32 (PPCld_vec_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>; 3055fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v4i32:$rS, ForceXForm:$dst), (STXVW4X $rS, ForceXForm:$dst)>; 30565ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 30575ffd83dbSDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 30585ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 30595ffd83dbSDimitry Andric (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 30605ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))), 30615ffd83dbSDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>; 30625ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))), 30635ffd83dbSDimitry Andric (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>; 30640b57cec5SDimitry Andric 30655ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)), 30665ffd83dbSDimitry Andric (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>; 30675ffd83dbSDimitry Andric 30680b57cec5SDimitry Andric// Little endian, available on all targets with VSX 30690b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)), 30700b57cec5SDimitry Andric (v2f64 (XXPERMDI 3071fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), $B, sub_64), 3072fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>; 3073480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency 3074480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency 3075480093f4SDimitry Andric// XXPERMDI for 2 reasons: 3076480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high, 3077480093f4SDimitry Andric// so we want to use the latter as it has access to all 64 VSX registers. 3078480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the 3079480093f4SDimitry Andric// allocation of Altivec registers even for the loads which in turn would 3080480093f4SDimitry Andric// force the use of LXSIWZX for the loads, adding a cycle of latency to 3081480093f4SDimitry Andric// each of the loads which would otherwise be able to use LFIWZX. 3082480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)), 3083480093f4SDimitry Andric (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C), 3084480093f4SDimitry Andric (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>; 30850b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)), 30860b57cec5SDimitry Andric (VMRGEW MrgFP.AC, MrgFP.BD)>; 30870b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1, 30880b57cec5SDimitry Andric DblToFlt.B0, DblToFlt.B1)), 30890b57cec5SDimitry Andric (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>; 30900b57cec5SDimitry Andric 30910b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints. 30920b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B, 30930b57cec5SDimitry Andric DblToInt.C, DblToInt.D)), 30940b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>; 30950b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B, 30960b57cec5SDimitry Andric DblToUInt.C, DblToUInt.D)), 30970b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>; 30980b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S, 30990b57cec5SDimitry Andric ExtDbl.B0S, ExtDbl.B1S)), 31000b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>; 31010b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U, 31020b57cec5SDimitry Andric ExtDbl.B0U, ExtDbl.B1U)), 31030b57cec5SDimitry Andric (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>; 31045ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 31055ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 1))))), 31065ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>; 31075ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 31085ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 0))))), 31095ffd83dbSDimitry Andric (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)), 31105ffd83dbSDimitry Andric (XVCVSPDP (XXMRGLW $A, $A)), 2))>; 31115ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 31125ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2))))), 31135ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>; 31145ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 31155ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3))))), 31165ffd83dbSDimitry Andric (v2f64 (XVCVSPDP $A))>; 31175ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))), 31185ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3))))), 31195ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>; 31205ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 31215ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2))))), 31225ffd83dbSDimitry Andric (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)), 31235ffd83dbSDimitry Andric (XVCVSPDP (XXMRGHW $A, $A)), 2))>; 31245ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 31255ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$B, 0))))), 31265ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3), 31275ffd83dbSDimitry Andric (XXPERMDI $B, $A, 3), 1)))>; 31285ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))), 31295ffd83dbSDimitry Andric (f64 (fpextend (extractelt v4f32:$B, 3))))), 31305ffd83dbSDimitry Andric (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>; 3131fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint 3132fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 3133fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3)))))), 3134fe6060f1SDimitry Andric (v2i64 (XVCVSPSXDS $A))>; 3135fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint 3136fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))), 3137fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 3)))))), 3138fe6060f1SDimitry Andric (v2i64 (XVCVSPUXDS $A))>; 3139fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint 3140fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 3141fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2)))))), 3142fe6060f1SDimitry Andric (v2i64 (XVCVSPSXDS (XXSLDWI $A, $A, 1)))>; 3143fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint 3144fe6060f1SDimitry Andric (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))), 3145fe6060f1SDimitry Andric (f64 (fpextend (extractelt v4f32:$A, 2)))))), 3146fe6060f1SDimitry Andric (v2i64 (XVCVSPUXDS (XXSLDWI $A, $A, 1)))>; 31475ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S, 31485ffd83dbSDimitry Andric (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>; 31495ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S, 31505ffd83dbSDimitry Andric (v2f64 (XVCVSXWDP $A))>; 31515ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U, 31525ffd83dbSDimitry Andric (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>; 31535ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U, 31545ffd83dbSDimitry Andric (v2f64 (XVCVUXWDP $A))>; 3155fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 0)), 3156fe6060f1SDimitry Andric (v2f64 (XXPERMDI $A, (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>; 3157fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 1)), 3158fe6060f1SDimitry Andric (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), $A, 1))>; 31595ffd83dbSDimitry Andric} // HasVSX, IsLittleEndian 31600b57cec5SDimitry Andric 31615ffd83dbSDimitry Andric// Any pre-Power9 VSX subtarget. 31625ffd83dbSDimitry Andriclet Predicates = [HasVSX, NoP9Vector] in { 31635ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 3164fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 8), 3165fe6060f1SDimitry Andric (STXSDX (XSCVDPSXDS f64:$src), ForceXForm:$dst)>; 31665ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 3167fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 8), 3168fe6060f1SDimitry Andric (STXSDX (XSCVDPUXDS f64:$src), ForceXForm:$dst)>; 31695ffd83dbSDimitry Andric 31705ffd83dbSDimitry Andric// Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads). 31715ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 31725ffd83dbSDimitry Andric v4i32, DblToIntLoad.A, 3173fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (XFLOADf64 ForceXForm:$A)), sub_64), 1), 3174fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (XFLOADf64 ForceXForm:$A)), sub_64)>; 31755ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 31765ffd83dbSDimitry Andric v4i32, DblToUIntLoad.A, 3177fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (XFLOADf64 ForceXForm:$A)), sub_64), 1), 3178fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (XFLOADf64 ForceXForm:$A)), sub_64)>; 31795ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 31805ffd83dbSDimitry Andric v2i64, FltToLongLoad.A, 3181fe6060f1SDimitry Andric (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), VSFRC)), 0), 3182fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), 31835ffd83dbSDimitry Andric VSFRC)), sub_64)>; 31845ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 31855ffd83dbSDimitry Andric v2i64, FltToULongLoad.A, 3186fe6060f1SDimitry Andric (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), VSFRC)), 0), 3187fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), 31885ffd83dbSDimitry Andric VSFRC)), sub_64)>; 31895ffd83dbSDimitry Andric} // HasVSX, NoP9Vector 31905ffd83dbSDimitry Andric 3191e8d8bef9SDimitry Andric// Any little endian pre-Power9 VSX subtarget. 3192e8d8bef9SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsLittleEndian] in { 3193e8d8bef9SDimitry Andric// Load-and-splat using only X-Form VSX loads. 3194e8d8bef9SDimitry Andricdefm : ScalToVecWPermute< 3195fe6060f1SDimitry Andric v2i64, (i64 (load ForceXForm:$src)), 3196fe6060f1SDimitry Andric (XXPERMDIs (XFLOADf64 ForceXForm:$src), 2), 3197fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>; 3198e8d8bef9SDimitry Andricdefm : ScalToVecWPermute< 3199fe6060f1SDimitry Andric v2f64, (f64 (load ForceXForm:$src)), 3200fe6060f1SDimitry Andric (XXPERMDIs (XFLOADf64 ForceXForm:$src), 2), 3201fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>; 32020eae32dcSDimitry Andric 32030eae32dcSDimitry Andric// Splat loads. 32040eae32dcSDimitry Andricdef : Pat<(v8i16 (PPCldsplatAlign16 ForceXForm:$A)), 32050eae32dcSDimitry Andric (v8i16 (VSPLTH 7, (LVX ForceXForm:$A)))>; 32060eae32dcSDimitry Andricdef : Pat<(v16i8 (PPCldsplatAlign16 ForceXForm:$A)), 32070eae32dcSDimitry Andric (v16i8 (VSPLTB 15, (LVX ForceXForm:$A)))>; 3208e8d8bef9SDimitry Andric} // HasVSX, NoP9Vector, IsLittleEndian 3209e8d8bef9SDimitry Andric 3210fe6060f1SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsBigEndian] in { 3211fe6060f1SDimitry Andric def : Pat<(v2f64 (int_ppc_vsx_lxvd2x ForceXForm:$src)), 3212fe6060f1SDimitry Andric (LXVD2X ForceXForm:$src)>; 3213fe6060f1SDimitry Andric def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, ForceXForm:$dst), 3214fe6060f1SDimitry Andric (STXVD2X $rS, ForceXForm:$dst)>; 32150eae32dcSDimitry Andric 32160eae32dcSDimitry Andric // Splat loads. 32170eae32dcSDimitry Andric def : Pat<(v8i16 (PPCldsplatAlign16 ForceXForm:$A)), 32180eae32dcSDimitry Andric (v8i16 (VSPLTH 0, (LVX ForceXForm:$A)))>; 32190eae32dcSDimitry Andric def : Pat<(v16i8 (PPCldsplatAlign16 ForceXForm:$A)), 32200eae32dcSDimitry Andric (v16i8 (VSPLTB 0, (LVX ForceXForm:$A)))>; 3221fe6060f1SDimitry Andric} // HasVSX, NoP9Vector, IsBigEndian 3222fe6060f1SDimitry Andric 32235ffd83dbSDimitry Andric// Any VSX subtarget that only has loads and stores that load in big endian 32245ffd83dbSDimitry Andric// order regardless of endianness. This is really pre-Power9 subtargets. 32255ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in { 3226fe6060f1SDimitry Andric def : Pat<(v2f64 (PPClxvd2x ForceXForm:$src)), (LXVD2X ForceXForm:$src)>; 32275ffd83dbSDimitry Andric 32285ffd83dbSDimitry Andric // Stores. 3229fe6060f1SDimitry Andric def : Pat<(PPCstxvd2x v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>; 32305ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps 32315ffd83dbSDimitry Andric 3232e8d8bef9SDimitry Andric// Big endian VSX subtarget that only has loads and stores that always 3233e8d8bef9SDimitry Andric// load in big endian order. Really big endian pre-Power9 subtargets. 32345ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in { 3235fe6060f1SDimitry Andric def : Pat<(v2f64 (load ForceXForm:$src)), (LXVD2X ForceXForm:$src)>; 3236fe6060f1SDimitry Andric def : Pat<(v2i64 (load ForceXForm:$src)), (LXVD2X ForceXForm:$src)>; 3237fe6060f1SDimitry Andric def : Pat<(v4i32 (load ForceXForm:$src)), (LXVW4X ForceXForm:$src)>; 3238fe6060f1SDimitry Andric def : Pat<(v4i32 (int_ppc_vsx_lxvw4x ForceXForm:$src)), (LXVW4X ForceXForm:$src)>; 3239fe6060f1SDimitry Andric def : Pat<(store v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>; 3240fe6060f1SDimitry Andric def : Pat<(store v2i64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>; 3241fe6060f1SDimitry Andric def : Pat<(store v4i32:$XT, ForceXForm:$dst), (STXVW4X $XT, ForceXForm:$dst)>; 3242fe6060f1SDimitry Andric def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, ForceXForm:$dst), 3243fe6060f1SDimitry Andric (STXVW4X $rS, ForceXForm:$dst)>; 3244fe6060f1SDimitry Andric def : Pat<(v2i64 (scalar_to_vector (i64 (load ForceXForm:$src)))), 3245fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>; 32465ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps, IsBigEndian 32475ffd83dbSDimitry Andric 32485ffd83dbSDimitry Andric// Any Power8 VSX subtarget. 32495ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in { 32505ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B), 32515ffd83dbSDimitry Andric (XXLEQV $A, $B)>; 3252fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 XForm:$src)), 3253fe6060f1SDimitry Andric (COPY_TO_REGCLASS (XFLOADf32 XForm:$src), VSFRC)>; 3254fe6060f1SDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 ForceXForm:$src)))), 3255fe6060f1SDimitry Andric (f32 (XFLOADf32 ForceXForm:$src))>; 32565ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpextend f32:$src)), 32575ffd83dbSDimitry Andric (COPY_TO_REGCLASS $src, VSFRC)>; 32585ffd83dbSDimitry Andric 32595ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)), 32605ffd83dbSDimitry Andric (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 32615ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)), 32625ffd83dbSDimitry Andric (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 32635ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)), 32645ffd83dbSDimitry Andric (SELECT_VSSRC (CRORC $lhs, $rhs), $tval, $fval)>; 32655ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)), 32665ffd83dbSDimitry Andric (SELECT_VSSRC (CRORC $rhs, $lhs), $tval, $fval)>; 32675ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)), 32685ffd83dbSDimitry Andric (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>; 32695ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)), 32705ffd83dbSDimitry Andric (SELECT_VSSRC (CRORC $rhs, $lhs), $tval, $fval)>; 32715ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)), 32725ffd83dbSDimitry Andric (SELECT_VSSRC (CRORC $lhs, $rhs), $tval, $fval)>; 32735ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)), 32745ffd83dbSDimitry Andric (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>; 32755ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)), 32765ffd83dbSDimitry Andric (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>; 32775ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)), 32785ffd83dbSDimitry Andric (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>; 32795ffd83dbSDimitry Andric 32805ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode 32815ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C), 32825ffd83dbSDimitry Andric (XSNMSUBASP $C, $A, $B)>; 32835ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)), 32845ffd83dbSDimitry Andric (XSMSUBASP $C, $A, $B)>; 32855ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)), 32865ffd83dbSDimitry Andric (XSNMADDASP $C, $A, $B)>; 32875ffd83dbSDimitry Andric 32885ffd83dbSDimitry Andric// f32 neg 32895ffd83dbSDimitry Andric// Although XSNEGDP is available in P7, we want to select it starting from P8, 32905ffd83dbSDimitry Andric// so that FNMSUBS can be selected for fneg-fmsub pattern on P7. (VSX version, 32915ffd83dbSDimitry Andric// XSNMSUBASP, is available since P8) 32925ffd83dbSDimitry Andricdef : Pat<(f32 (fneg f32:$S)), 32935ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSNEGDP 32945ffd83dbSDimitry Andric (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; 32955ffd83dbSDimitry Andric 32965ffd83dbSDimitry Andric// Instructions for converting float to i32 feeding a store. 32975ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 3298fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 4), 3299fe6060f1SDimitry Andric (STIWX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>; 33005ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 3301fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 4), 3302fe6060f1SDimitry Andric (STIWX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>; 33035ffd83dbSDimitry Andric 33045ffd83dbSDimitry Andricdef : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)), 33055ffd83dbSDimitry Andric (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC), 33065ffd83dbSDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 33075ffd83dbSDimitry Andricdef : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)), 33085ffd83dbSDimitry Andric (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC), 33095ffd83dbSDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 33105ffd83dbSDimitry Andricdef : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)), 33115ffd83dbSDimitry Andric (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC), 33125ffd83dbSDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 33135ffd83dbSDimitry Andricdef : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)), 33145ffd83dbSDimitry Andric (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC), 33155ffd83dbSDimitry Andric (COPY_TO_REGCLASS $src2, VRRC)))>; 33165ffd83dbSDimitry Andric 33175ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))), 33185ffd83dbSDimitry Andric (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 33195ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))), 33205ffd83dbSDimitry Andric (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 33215ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))), 33225ffd83dbSDimitry Andric (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 33235ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))), 33245ffd83dbSDimitry Andric (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>; 3325fe6060f1SDimitry Andric 3326fe6060f1SDimitry Andric// XL Compat builtins. 3327fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsubs f32:$A, f32:$B, f32:$C), (XSMSUBMSP $A, $B, $C)>; 3328fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadds f32:$A, f32:$B, f32:$C), (XSNMADDMSP $A, $B, $C)>; 3329fe6060f1SDimitry Andricdef : Pat<(int_ppc_fres f32:$A), (XSRESP $A)>; 3330fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_extract_exp f64:$A)), 3331fe6060f1SDimitry Andric (EXTRACT_SUBREG (XSXEXPDP (COPY_TO_REGCLASS $A, VSFRC)), sub_32)>; 3332fe6060f1SDimitry Andricdef : Pat<(int_ppc_extract_sig f64:$A), 3333fe6060f1SDimitry Andric (XSXSIGDP (COPY_TO_REGCLASS $A, VSFRC))>; 3334fe6060f1SDimitry Andricdef : Pat<(f64 (int_ppc_insert_exp f64:$A, i64:$B)), 3335fe6060f1SDimitry Andric (COPY_TO_REGCLASS (XSIEXPDP (COPY_TO_REGCLASS $A, G8RC), $B), F8RC)>; 3336fe6060f1SDimitry Andric 3337fe6060f1SDimitry Andricdef : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT), 3338fe6060f1SDimitry Andric (STXSIWX f64:$XT, ForceXForm:$dst)>; 3339fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrtes vssrc:$XB), (XSRSQRTESP $XB)>; 33405ffd83dbSDimitry Andric} // HasVSX, HasP8Vector 33415ffd83dbSDimitry Andric 3342fe6060f1SDimitry Andric// Any big endian Power8 VSX subtarget. 3343fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian] in { 33445ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1, 33455ffd83dbSDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>; 33465ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1, 33475ffd83dbSDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 33485ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1, 33495ffd83dbSDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>; 33505ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1, 33515ffd83dbSDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 33525ffd83dbSDimitry Andric 33535ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (BE) 3354fe6060f1SDimitry Andricdefm : ScalToVecWPermute<v4f32, (f32 f32:$A), (XSCVDPSPN $A), (XSCVDPSPN $A)>; 33555ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)), 33565ffd83dbSDimitry Andric (f32 (XSCVSPDPN $S))>; 33575ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)), 33585ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>; 33595ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)), 33605ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>; 33615ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)), 33625ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>; 33635ffd83dbSDimitry Andric 33645ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 33655ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>; 33665ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 33675ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>; 33685ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 33695ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>; 33705ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 33715ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>; 33725ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 33735ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>; 33745ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 33755ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>; 33765ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 33775ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>; 33785ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 33795ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>; 33805ffd83dbSDimitry Andric 3381fe6060f1SDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i32:$Idx)), 3382fe6060f1SDimitry Andric (f32 VectorExtractions.BE_32B_VARIABLE_FLOAT)>; 3383fe6060f1SDimitry Andric 3384fe6060f1SDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i32:$Idx)), 3385fe6060f1SDimitry Andric (f64 VectorExtractions.BE_32B_VARIABLE_DOUBLE)>; 338681ad6265SDimitry Andric 338781ad6265SDimitry Andricdefm : ScalToVecWPermute< 338881ad6265SDimitry Andric v4i32, (i32 (load ForceXForm:$src)), 338981ad6265SDimitry Andric (XXSLDWIs (LIWZX ForceXForm:$src), 1), 339081ad6265SDimitry Andric (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>; 339181ad6265SDimitry Andricdefm : ScalToVecWPermute< 339281ad6265SDimitry Andric v4f32, (f32 (load ForceXForm:$src)), 339381ad6265SDimitry Andric (XXSLDWIs (LIWZX ForceXForm:$src), 1), 339481ad6265SDimitry Andric (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>; 3395fe6060f1SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian 3396fe6060f1SDimitry Andric 3397fe6060f1SDimitry Andric// Big endian Power8 64Bit VSX subtarget. 3398fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] in { 3399fe6060f1SDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)), 3400fe6060f1SDimitry Andric (f32 VectorExtractions.BE_VARIABLE_FLOAT)>; 3401fe6060f1SDimitry Andric 34025ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64. 34035ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when 34045ffd83dbSDimitry Andric// zero-extending i32 to i64 (zext i32 -> i64). 3405fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 ForceXForm:$src)))), 3406fe6060f1SDimitry Andric (v2i64 (SUBREG_TO_REG (i64 1), (LIWAX ForceXForm:$src), sub_64))>; 3407fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 ForceXForm:$src)))), 3408fe6060f1SDimitry Andric (v2i64 (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64))>; 34095ffd83dbSDimitry Andric 34105ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU, 34115ffd83dbSDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3), 34125ffd83dbSDimitry Andric (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>; 34135ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS, 34145ffd83dbSDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3), 34155ffd83dbSDimitry Andric (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>; 3416fe6060f1SDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 1)), ForceXForm:$src), 3417fe6060f1SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 3418fe6060f1SDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 1)), ForceXForm:$src), 3419fe6060f1SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 34205ffd83dbSDimitry Andric 34215ffd83dbSDimitry Andric// Elements in a register on a BE system are in order <0, 1, 2, 3>. 34225ffd83dbSDimitry Andric// The store instructions store the second word from the left. 34235ffd83dbSDimitry Andric// So to align element zero, we need to modulo-left-shift by 3 words. 34245ffd83dbSDimitry Andric// Similar logic applies for elements 2 and 3. 34255ffd83dbSDimitry Andricforeach Idx = [ [0,3], [2,1], [3,2] ] in { 3426fe6060f1SDimitry Andric def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), ForceXForm:$src), 34275ffd83dbSDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3428fe6060f1SDimitry Andric sub_64), ForceXForm:$src)>; 3429fe6060f1SDimitry Andric def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), ForceXForm:$src), 34305ffd83dbSDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3431fe6060f1SDimitry Andric sub_64), ForceXForm:$src)>; 34325ffd83dbSDimitry Andric} 3433e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian, IsPPC64 34345ffd83dbSDimitry Andric 34355ffd83dbSDimitry Andric// Little endian Power8 VSX subtarget. 34365ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in { 34375ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1, 34385ffd83dbSDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 34395ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1, 34405ffd83dbSDimitry Andric (f32 (XSCVSXDSP (COPY_TO_REGCLASS 34415ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>; 34425ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1, 34435ffd83dbSDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>; 34445ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1, 34455ffd83dbSDimitry Andric (f32 (XSCVUXDSP (COPY_TO_REGCLASS 34465ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>; 34475ffd83dbSDimitry Andric 34485ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (LE) 34495ffd83dbSDimitry Andric defm : ScalToVecWPermute<v4f32, (f32 f32:$A), 34505ffd83dbSDimitry Andric (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1), 3451fe6060f1SDimitry Andric (XSCVDPSPN $A)>; 34525ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)), 34535ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>; 34545ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)), 34555ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>; 34565ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)), 34575ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>; 34585ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)), 34595ffd83dbSDimitry Andric (f32 (XSCVSPDPN $S))>; 34605ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)), 34615ffd83dbSDimitry Andric (f32 VectorExtractions.LE_VARIABLE_FLOAT)>; 34625ffd83dbSDimitry Andric 34635ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 34645ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>; 34655ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 34665ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>; 34675ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 34685ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>; 34695ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 34705ffd83dbSDimitry Andric (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>; 34715ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))), 34725ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>; 34735ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))), 34745ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>; 34755ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))), 34765ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>; 34775ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))), 34785ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>; 34795ffd83dbSDimitry Andric 34805ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64. 34815ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when 34825ffd83dbSDimitry Andric// zero-extending i32 to i64 (zext i32 -> i64). 34835ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 3484fe6060f1SDimitry Andric v2i64, (i64 (sextloadi32 ForceXForm:$src)), 3485fe6060f1SDimitry Andric (XXPERMDIs (LIWAX ForceXForm:$src), 2), 3486fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LIWAX ForceXForm:$src), sub_64)>; 34875ffd83dbSDimitry Andric 34885ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 3489fe6060f1SDimitry Andric v2i64, (i64 (zextloadi32 ForceXForm:$src)), 3490fe6060f1SDimitry Andric (XXPERMDIs (LIWZX ForceXForm:$src), 2), 3491fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>; 34925ffd83dbSDimitry Andric 34935ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 3494fe6060f1SDimitry Andric v4i32, (i32 (load ForceXForm:$src)), 3495fe6060f1SDimitry Andric (XXPERMDIs (LIWZX ForceXForm:$src), 2), 3496fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>; 34975ffd83dbSDimitry Andric 34985ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 3499fe6060f1SDimitry Andric v4f32, (f32 (load ForceXForm:$src)), 3500fe6060f1SDimitry Andric (XXPERMDIs (LIWZX ForceXForm:$src), 2), 3501fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>; 35025ffd83dbSDimitry Andric 35035ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU, 35045ffd83dbSDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3), 35055ffd83dbSDimitry Andric (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>; 35065ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS, 35075ffd83dbSDimitry Andric (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3), 35085ffd83dbSDimitry Andric (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>; 3509fe6060f1SDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 2)), ForceXForm:$src), 3510fe6060f1SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 3511fe6060f1SDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 2)), ForceXForm:$src), 3512fe6060f1SDimitry Andric (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 35135ffd83dbSDimitry Andric 35145ffd83dbSDimitry Andric// Elements in a register on a LE system are in order <3, 2, 1, 0>. 35155ffd83dbSDimitry Andric// The store instructions store the second word from the left. 35165ffd83dbSDimitry Andric// So to align element 3, we need to modulo-left-shift by 3 words. 35175ffd83dbSDimitry Andric// Similar logic applies for elements 0 and 1. 35185ffd83dbSDimitry Andricforeach Idx = [ [0,2], [1,1], [3,3] ] in { 3519fe6060f1SDimitry Andric def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), ForceXForm:$src), 35205ffd83dbSDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3521fe6060f1SDimitry Andric sub_64), ForceXForm:$src)>; 3522fe6060f1SDimitry Andric def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), ForceXForm:$src), 35235ffd83dbSDimitry Andric (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))), 3524fe6060f1SDimitry Andric sub_64), ForceXForm:$src)>; 35255ffd83dbSDimitry Andric} 35265ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, IsLittleEndian 35275ffd83dbSDimitry Andric 35285ffd83dbSDimitry Andric// Big endian pre-Power9 VSX subtarget. 3529e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] in { 3530fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), ForceXForm:$src), 3531fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 3532fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), ForceXForm:$src), 3533fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 3534fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), ForceXForm:$src), 35355ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3536fe6060f1SDimitry Andric ForceXForm:$src)>; 3537fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), ForceXForm:$src), 35385ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3539fe6060f1SDimitry Andric ForceXForm:$src)>; 3540e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64 35415ffd83dbSDimitry Andric 35425ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget. 35435ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in { 3544fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), ForceXForm:$src), 35455ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3546fe6060f1SDimitry Andric ForceXForm:$src)>; 3547fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), ForceXForm:$src), 35485ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 3549fe6060f1SDimitry Andric ForceXForm:$src)>; 3550fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), ForceXForm:$src), 3551fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 3552fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), ForceXForm:$src), 3553fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>; 35545ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian 35555ffd83dbSDimitry Andric 35565ffd83dbSDimitry Andric// Any VSX target with direct moves. 35575ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove] in { 35585ffd83dbSDimitry Andric// bitconvert f32 -> i32 35595ffd83dbSDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR) 3560fe6060f1SDimitry Andricdef : Pat<(i32 (bitconvert f32:$A)), Bitcast.FltToInt>; 3561fe6060f1SDimitry Andric 35625ffd83dbSDimitry Andric// bitconvert i32 -> f32 35635ffd83dbSDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single) 35645ffd83dbSDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)), 35655ffd83dbSDimitry Andric (f32 (XSCVSPDPN 35665ffd83dbSDimitry Andric (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>; 35675ffd83dbSDimitry Andric 35685ffd83dbSDimitry Andric// bitconvert f64 -> i64 35695ffd83dbSDimitry Andric// (move to GPR, nothing else needed) 3570fe6060f1SDimitry Andricdef : Pat<(i64 (bitconvert f64:$A)), Bitcast.DblToLong>; 35715ffd83dbSDimitry Andric 35725ffd83dbSDimitry Andric// bitconvert i64 -> f64 35735ffd83dbSDimitry Andric// (move to FPR, nothing else needed) 35745ffd83dbSDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)), 35755ffd83dbSDimitry Andric (f64 (MTVSRD $S))>; 35765ffd83dbSDimitry Andric 35775ffd83dbSDimitry Andric// Rounding to integer. 35785ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f64:$S)), 35795ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID $S)))>; 35805ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f32:$S)), 35815ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>; 35825ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f64:$S)), 35835ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID $S)))>; 35845ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f32:$S)), 35855ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>; 35865ffd83dbSDimitry Andricdef : Pat<(i64 (lround f64:$S)), 35875ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID (XSRDPI $S))))>; 35885ffd83dbSDimitry Andricdef : Pat<(i64 (lround f32:$S)), 35895ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>; 35905ffd83dbSDimitry Andricdef : Pat<(i64 (llround f64:$S)), 35915ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID (XSRDPI $S))))>; 35925ffd83dbSDimitry Andricdef : Pat<(i64 (llround f32:$S)), 35935ffd83dbSDimitry Andric (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>; 35945ffd83dbSDimitry Andric 35955ffd83dbSDimitry Andric// Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead 35965ffd83dbSDimitry Andric// of f64 35975ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCmtvsrz i32:$A)), 35985ffd83dbSDimitry Andric (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>; 35995ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCmtvsrz i32:$A)), 36005ffd83dbSDimitry Andric (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>; 36015ffd83dbSDimitry Andric 36020b57cec5SDimitry Andric// Endianness-neutral constant splat on P8 and newer targets. The reason 36030b57cec5SDimitry Andric// for this pattern is that on targets with direct moves, we don't expand 36040b57cec5SDimitry Andric// BUILD_VECTOR nodes for v4i32. 36050b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A, 36060b57cec5SDimitry Andric immSExt5NonZero:$A, immSExt5NonZero:$A)), 36070b57cec5SDimitry Andric (v4i32 (VSPLTISW imm:$A))>; 3608349cc55cSDimitry Andric 3609349cc55cSDimitry Andric// Splat loads. 3610349cc55cSDimitry Andricdef : Pat<(v8i16 (PPCldsplat ForceXForm:$A)), 3611349cc55cSDimitry Andric (v8i16 (VSPLTHs 3, (MTVSRWZ (LHZX ForceXForm:$A))))>; 3612349cc55cSDimitry Andricdef : Pat<(v16i8 (PPCldsplat ForceXForm:$A)), 3613349cc55cSDimitry Andric (v16i8 (VSPLTBs 7, (MTVSRWZ (LBZX ForceXForm:$A))))>; 36145ffd83dbSDimitry Andric} // HasVSX, HasDirectMove 36150b57cec5SDimitry Andric 36165ffd83dbSDimitry Andric// Big endian VSX subtarget with direct moves. 36175ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsBigEndian] in { 36185ffd83dbSDimitry Andric// v16i8 scalar <-> vector conversions (BE) 3619fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3620fe6060f1SDimitry Andric v16i8, (i32 i32:$A), 3621fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64), 3622fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>; 3623fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3624fe6060f1SDimitry Andric v8i16, (i32 i32:$A), 3625349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64), 3626fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>; 3627fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3628fe6060f1SDimitry Andric v4i32, (i32 i32:$A), 3629fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64), 3630fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>; 36315ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector i64:$A)), 36325ffd83dbSDimitry Andric (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>; 36335ffd83dbSDimitry Andric 36345ffd83dbSDimitry Andric// v2i64 scalar <-> vector conversions (BE) 36355ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 0)), 36365ffd83dbSDimitry Andric (i64 VectorExtractions.LE_DWORD_1)>; 36375ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 1)), 36385ffd83dbSDimitry Andric (i64 VectorExtractions.LE_DWORD_0)>; 36395ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)), 36405ffd83dbSDimitry Andric (i64 VectorExtractions.BE_VARIABLE_DWORD)>; 36415ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsBigEndian 36425ffd83dbSDimitry Andric 36435ffd83dbSDimitry Andric// Little endian VSX subtarget with direct moves. 36445ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsLittleEndian] in { 36455ffd83dbSDimitry Andric // v16i8 scalar <-> vector conversions (LE) 36465ffd83dbSDimitry Andric defm : ScalToVecWPermute<v16i8, (i32 i32:$A), 36475ffd83dbSDimitry Andric (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC), 36485ffd83dbSDimitry Andric (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>; 36495ffd83dbSDimitry Andric defm : ScalToVecWPermute<v8i16, (i32 i32:$A), 36505ffd83dbSDimitry Andric (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC), 36515ffd83dbSDimitry Andric (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>; 36525ffd83dbSDimitry Andric defm : ScalToVecWPermute<v4i32, (i32 i32:$A), MovesToVSR.LE_WORD_0, 36535ffd83dbSDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>; 36545ffd83dbSDimitry Andric defm : ScalToVecWPermute<v2i64, (i64 i64:$A), MovesToVSR.LE_DWORD_0, 36555ffd83dbSDimitry Andric MovesToVSR.LE_DWORD_1>; 36565ffd83dbSDimitry Andric 36575ffd83dbSDimitry Andric // v2i64 scalar <-> vector conversions (LE) 36585ffd83dbSDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, 0)), 36595ffd83dbSDimitry Andric (i64 VectorExtractions.LE_DWORD_0)>; 36605ffd83dbSDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, 1)), 36615ffd83dbSDimitry Andric (i64 VectorExtractions.LE_DWORD_1)>; 36625ffd83dbSDimitry Andric def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)), 36635ffd83dbSDimitry Andric (i64 VectorExtractions.LE_VARIABLE_DWORD)>; 36645ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsLittleEndian 36655ffd83dbSDimitry Andric 36665ffd83dbSDimitry Andric// Big endian pre-P9 VSX subtarget with direct moves. 36675ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian] in { 36685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)), 36695ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_15)>; 36705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)), 36715ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_14)>; 36725ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)), 36735ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_13)>; 36745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)), 36755ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_12)>; 36765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)), 36775ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_11)>; 36785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)), 36795ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_10)>; 36805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)), 36815ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_9)>; 36825ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)), 36835ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_8)>; 36845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)), 36855ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_7)>; 36865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)), 36875ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_6)>; 36885ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)), 36895ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_5)>; 36905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)), 36915ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_4)>; 36925ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)), 36935ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_3)>; 36945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)), 36955ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_2)>; 36965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)), 36975ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_1)>; 36985ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)), 36995ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_0)>; 37005ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 37015ffd83dbSDimitry Andric (i32 VectorExtractions.BE_VARIABLE_BYTE)>; 37025ffd83dbSDimitry Andric 37035ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (BE) 37045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)), 37055ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_7)>; 37065ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)), 37075ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_6)>; 37085ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)), 37095ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_5)>; 37105ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)), 37115ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_4)>; 37125ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)), 37135ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_3)>; 37145ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)), 37155ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_2)>; 37165ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)), 37175ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_1)>; 37185ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)), 37195ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_0)>; 37205ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 37215ffd83dbSDimitry Andric (i32 VectorExtractions.BE_VARIABLE_HALF)>; 37225ffd83dbSDimitry Andric 37235ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (BE) 37245ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)), 37255ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_3)>; 37265ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)), 37275ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 37285ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)), 37295ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_1)>; 37305ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)), 37315ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_0)>; 37325ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 37335ffd83dbSDimitry Andric (i32 VectorExtractions.BE_VARIABLE_WORD)>; 37345ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian 37355ffd83dbSDimitry Andric 37365ffd83dbSDimitry Andric// Little endian pre-P9 VSX subtarget with direct moves. 37375ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] in { 37385ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)), 37395ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_0)>; 37405ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)), 37415ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_1)>; 37425ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)), 37435ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_2)>; 37445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)), 37455ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_3)>; 37465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)), 37475ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_4)>; 37485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)), 37495ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_5)>; 37505ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)), 37515ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_6)>; 37525ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)), 37535ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_7)>; 37545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)), 37555ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_8)>; 37565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)), 37575ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_9)>; 37585ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)), 37595ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_10)>; 37605ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)), 37615ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_11)>; 37625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)), 37635ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_12)>; 37645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)), 37655ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_13)>; 37665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)), 37675ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_14)>; 37685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)), 37695ffd83dbSDimitry Andric (i32 VectorExtractions.LE_BYTE_15)>; 37705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 37715ffd83dbSDimitry Andric (i32 VectorExtractions.LE_VARIABLE_BYTE)>; 37725ffd83dbSDimitry Andric 37735ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (LE) 37745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)), 37755ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_0)>; 37765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)), 37775ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_1)>; 37785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)), 37795ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_2)>; 37805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)), 37815ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_3)>; 37825ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)), 37835ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_4)>; 37845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)), 37855ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_5)>; 37865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)), 37875ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_6)>; 37885ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)), 37895ffd83dbSDimitry Andric (i32 VectorExtractions.LE_HALF_7)>; 37905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 37915ffd83dbSDimitry Andric (i32 VectorExtractions.LE_VARIABLE_HALF)>; 37925ffd83dbSDimitry Andric 37935ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (LE) 37945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)), 37955ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_0)>; 37965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)), 37975ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_1)>; 37985ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)), 37995ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 38005ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)), 38015ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_3)>; 38025ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 38035ffd83dbSDimitry Andric (i32 VectorExtractions.LE_VARIABLE_WORD)>; 38045ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian 38055ffd83dbSDimitry Andric 3806e8d8bef9SDimitry Andric// Big endian pre-Power9 64Bit VSX subtarget that has direct moves. 3807e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] in { 38080b57cec5SDimitry Andric// Big endian integer vectors using direct moves. 38090b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 38100b57cec5SDimitry Andric (v2i64 (XXPERMDI 3811fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRD $A), sub_64), 3812fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRD $B), sub_64), 0))>; 38130b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 38140b57cec5SDimitry Andric (XXPERMDI 3815fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), 3816fe6060f1SDimitry Andric (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), sub_64), 3817fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), 3818fe6060f1SDimitry Andric (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), sub_64), 0)>; 38190b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 3820fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64), 1)>; 3821e8d8bef9SDimitry Andric} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64 38220b57cec5SDimitry Andric 38235ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget that has direct moves. 38245ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in { 38250b57cec5SDimitry Andric// Little endian integer vectors using direct moves. 38260b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)), 38270b57cec5SDimitry Andric (v2i64 (XXPERMDI 3828fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRD $B), sub_64), 3829fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRD $A), sub_64), 0))>; 38300b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 38310b57cec5SDimitry Andric (XXPERMDI 3832fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), 3833fe6060f1SDimitry Andric (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), sub_64), 3834fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), 3835fe6060f1SDimitry Andric (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), sub_64), 0)>; 38360b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 3837fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64), 1)>; 38380b57cec5SDimitry Andric} 38390b57cec5SDimitry Andric 38405ffd83dbSDimitry Andric// Any Power9 VSX subtarget. 38415ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in { 38425ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode 38435ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C), 38445ffd83dbSDimitry Andric (XSNMSUBQP $C, $A, $B)>; 38455ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)), 38465ffd83dbSDimitry Andric (XSMSUBQP $C, $A, $B)>; 38475ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)), 38485ffd83dbSDimitry Andric (XSNMADDQP $C, $A, $B)>; 38498bcb0991SDimitry Andric 3850e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i64:$src)), 38515ffd83dbSDimitry Andric (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3852e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))), 38535ffd83dbSDimitry Andric (f128 (XSCVSDQP $src))>; 3854e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))), 38555ffd83dbSDimitry Andric (f128 (XSCVSDQP (VEXTSW2Ds $src)))>; 3856e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i64:$src)), 38575ffd83dbSDimitry Andric (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 3858e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))), 38595ffd83dbSDimitry Andric (f128 (XSCVUDQP $src))>; 38605ffd83dbSDimitry Andric 38615ffd83dbSDimitry Andric// Convert (Un)Signed Word -> QP. 3862e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i32:$src)), 38635ffd83dbSDimitry Andric (f128 (XSCVSDQP (MTVSRWA $src)))>; 3864fe6060f1SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (load ForceXForm:$src)))), 3865fe6060f1SDimitry Andric (f128 (XSCVSDQP (LIWAX ForceXForm:$src)))>; 3866e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i32:$src)), 38675ffd83dbSDimitry Andric (f128 (XSCVUDQP (MTVSRWZ $src)))>; 3868fe6060f1SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i32 (load ForceXForm:$src)))), 3869fe6060f1SDimitry Andric (f128 (XSCVUDQP (LIWZX ForceXForm:$src)))>; 38705ffd83dbSDimitry Andric 38715ffd83dbSDimitry Andric// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a 38725ffd83dbSDimitry Andric// separate pattern so that it can convert the input register class from 38735ffd83dbSDimitry Andric// VRRC(v8i16) to VSRC. 38745ffd83dbSDimitry Andricdef : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)), 38755ffd83dbSDimitry Andric (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>; 38765ffd83dbSDimitry Andric 38775ffd83dbSDimitry Andric// Use current rounding mode 38785ffd83dbSDimitry Andricdef : Pat<(f128 (any_fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>; 38795ffd83dbSDimitry Andric// Round to nearest, ties away from zero 38805ffd83dbSDimitry Andricdef : Pat<(f128 (any_fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>; 38815ffd83dbSDimitry Andric// Round towards Zero 38825ffd83dbSDimitry Andricdef : Pat<(f128 (any_ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>; 38835ffd83dbSDimitry Andric// Round towards +Inf 38845ffd83dbSDimitry Andricdef : Pat<(f128 (any_fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>; 38855ffd83dbSDimitry Andric// Round towards -Inf 38865ffd83dbSDimitry Andricdef : Pat<(f128 (any_ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>; 38875ffd83dbSDimitry Andric// Use current rounding mode, [with Inexact] 38885ffd83dbSDimitry Andricdef : Pat<(f128 (any_frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>; 38895ffd83dbSDimitry Andric 38905ffd83dbSDimitry Andricdef : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)), 38915ffd83dbSDimitry Andric (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>; 38925ffd83dbSDimitry Andric 38935ffd83dbSDimitry Andricdef : Pat<(i64 (int_ppc_scalar_extract_expq f128:$vA)), 38945ffd83dbSDimitry Andric (i64 (MFVSRD (EXTRACT_SUBREG 38955ffd83dbSDimitry Andric (v2i64 (XSXEXPQP $vA)), sub_64)))>; 38965ffd83dbSDimitry Andric 38975ffd83dbSDimitry Andric// Extra patterns expanding to vector Extract Word/Insert Word 38985ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)), 38995ffd83dbSDimitry Andric (v4i32 (XXINSERTW $A, $B, imm:$IMM))>; 39005ffd83dbSDimitry Andricdef : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)), 39015ffd83dbSDimitry Andric (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>; 39025ffd83dbSDimitry Andric 39035ffd83dbSDimitry Andric// Vector Reverse 39045ffd83dbSDimitry Andricdef : Pat<(v8i16 (bswap v8i16 :$A)), 39055ffd83dbSDimitry Andric (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>; 39065ffd83dbSDimitry Andricdef : Pat<(v1i128 (bswap v1i128 :$A)), 39075ffd83dbSDimitry Andric (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>; 39085ffd83dbSDimitry Andric 39095ffd83dbSDimitry Andric// D-Form Load/Store 3910fe6060f1SDimitry Andricforeach Ty = [v4i32, v4f32, v2i64, v2f64] in { 3911fe6060f1SDimitry Andric def : Pat<(Ty (load DQForm:$src)), (LXV memrix16:$src)>; 3912fe6060f1SDimitry Andric def : Pat<(Ty (load XForm:$src)), (LXVX XForm:$src)>; 3913fe6060f1SDimitry Andric def : Pat<(store Ty:$rS, DQForm:$dst), (STXV $rS, memrix16:$dst)>; 3914fe6060f1SDimitry Andric def : Pat<(store Ty:$rS, XForm:$dst), (STXVX $rS, XForm:$dst)>; 3915fe6060f1SDimitry Andric} 3916fe6060f1SDimitry Andric 3917fe6060f1SDimitry Andricdef : Pat<(f128 (load DQForm:$src)), 39185ffd83dbSDimitry Andric (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>; 3919fe6060f1SDimitry Andricdef : Pat<(f128 (load XForm:$src)), 3920fe6060f1SDimitry Andric (COPY_TO_REGCLASS (LXVX XForm:$src), VRRC)>; 3921fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x DQForm:$src)), (LXV memrix16:$src)>; 3922fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x DQForm:$src)), (LXV memrix16:$src)>; 3923fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x XForm:$src)), (LXVX XForm:$src)>; 3924fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x XForm:$src)), (LXVX XForm:$src)>; 39255ffd83dbSDimitry Andric 3926fe6060f1SDimitry Andricdef : Pat<(store f128:$rS, DQForm:$dst), 39275ffd83dbSDimitry Andric (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>; 3928fe6060f1SDimitry Andricdef : Pat<(store f128:$rS, XForm:$dst), 3929fe6060f1SDimitry Andric (STXVX (COPY_TO_REGCLASS $rS, VSRC), XForm:$dst)>; 3930fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, DQForm:$dst), 39315ffd83dbSDimitry Andric (STXV $rS, memrix16:$dst)>; 3932fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, DQForm:$dst), 39335ffd83dbSDimitry Andric (STXV $rS, memrix16:$dst)>; 3934fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, XForm:$dst), 3935fe6060f1SDimitry Andric (STXVX $rS, XForm:$dst)>; 3936fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, XForm:$dst), 3937fe6060f1SDimitry Andric (STXVX $rS, XForm:$dst)>; 39385ffd83dbSDimitry Andric 39395ffd83dbSDimitry Andric// Build vectors from i8 loads 39405ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.ZELi8, 3941fe6060f1SDimitry Andric (VSPLTHs 3, (LXSIBZX ForceXForm:$src)), 3942fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>; 39435ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi8, 3944fe6060f1SDimitry Andric (XXSPLTWs (LXSIBZX ForceXForm:$src), 1), 3945fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>; 39465ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi8i64, 3947fe6060f1SDimitry Andric (XXPERMDIs (LXSIBZX ForceXForm:$src), 0), 3948fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>; 3949fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3950fe6060f1SDimitry Andric v4i32, ScalarLoads.SELi8, 3951fe6060f1SDimitry Andric (XXSPLTWs (VEXTSB2Ws (LXSIBZX ForceXForm:$src)), 1), 3952fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (VEXTSB2Ws (LXSIBZX ForceXForm:$src)), sub_64)>; 3953fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3954fe6060f1SDimitry Andric v2i64, ScalarLoads.SELi8i64, 3955fe6060f1SDimitry Andric (XXPERMDIs (VEXTSB2Ds (LXSIBZX ForceXForm:$src)), 0), 3956fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (VEXTSB2Ds (LXSIBZX ForceXForm:$src)), sub_64)>; 39575ffd83dbSDimitry Andric 39585ffd83dbSDimitry Andric// Build vectors from i16 loads 3959fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3960fe6060f1SDimitry Andric v4i32, ScalarLoads.ZELi16, 3961fe6060f1SDimitry Andric (XXSPLTWs (LXSIHZX ForceXForm:$src), 1), 3962fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>; 3963fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3964fe6060f1SDimitry Andric v2i64, ScalarLoads.ZELi16i64, 3965fe6060f1SDimitry Andric (XXPERMDIs (LXSIHZX ForceXForm:$src), 0), 3966fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>; 3967fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3968fe6060f1SDimitry Andric v4i32, ScalarLoads.SELi16, 3969fe6060f1SDimitry Andric (XXSPLTWs (VEXTSH2Ws (LXSIHZX ForceXForm:$src)), 1), 3970fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (VEXTSH2Ws (LXSIHZX ForceXForm:$src)), sub_64)>; 3971fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 3972fe6060f1SDimitry Andric v2i64, ScalarLoads.SELi16i64, 3973fe6060f1SDimitry Andric (XXPERMDIs (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), 0), 3974fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), sub_64)>; 39755ffd83dbSDimitry Andric 39765ffd83dbSDimitry Andric// Load/convert and convert/store patterns for f16. 3977fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf16 ForceXForm:$src)), 3978fe6060f1SDimitry Andric (f64 (XSCVHPDP (LXSIHZX ForceXForm:$src)))>; 3979fe6060f1SDimitry Andricdef : Pat<(truncstoref16 f64:$src, ForceXForm:$dst), 3980fe6060f1SDimitry Andric (STXSIHX (XSCVDPHP $src), ForceXForm:$dst)>; 3981fe6060f1SDimitry Andricdef : Pat<(f32 (extloadf16 ForceXForm:$src)), 3982fe6060f1SDimitry Andric (f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX ForceXForm:$src)), VSSRC))>; 3983fe6060f1SDimitry Andricdef : Pat<(truncstoref16 f32:$src, ForceXForm:$dst), 3984fe6060f1SDimitry Andric (STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), ForceXForm:$dst)>; 39855ffd83dbSDimitry Andricdef : Pat<(f64 (f16_to_fp i32:$A)), 39865ffd83dbSDimitry Andric (f64 (XSCVHPDP (MTVSRWZ $A)))>; 39875ffd83dbSDimitry Andricdef : Pat<(f32 (f16_to_fp i32:$A)), 39885ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSCVHPDP (MTVSRWZ $A)), VSSRC))>; 39895ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f32:$A)), 39905ffd83dbSDimitry Andric (i32 (MFVSRWZ (XSCVDPHP (COPY_TO_REGCLASS $A, VSFRC))))>; 39915ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f64:$A)), (i32 (MFVSRWZ (XSCVDPHP $A)))>; 39925ffd83dbSDimitry Andric 39935ffd83dbSDimitry Andric// Vector sign extensions 39945ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 1)), 39955ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>; 39965ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 2)), 39975ffd83dbSDimitry Andric (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>; 39985ffd83dbSDimitry Andric 3999fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 DSForm:$src)), 4000fe6060f1SDimitry Andric (COPY_TO_REGCLASS (DFLOADf32 DSForm:$src), VSFRC)>; 4001fe6060f1SDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 DSForm:$src)))), 4002fe6060f1SDimitry Andric (f32 (DFLOADf32 DSForm:$src))>; 40035ffd83dbSDimitry Andric 4004fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh XForm:$src)), 4005fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>; 4006fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh DSForm:$src)), 4007fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>; 40085ffd83dbSDimitry Andric 40095ffd83dbSDimitry Andric// Convert (Un)Signed DWord in memory -> QP 4010fe6060f1SDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load XForm:$src)))), 4011fe6060f1SDimitry Andric (f128 (XSCVSDQP (LXSDX XForm:$src)))>; 4012fe6060f1SDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load DSForm:$src)))), 4013fe6060f1SDimitry Andric (f128 (XSCVSDQP (LXSD DSForm:$src)))>; 4014fe6060f1SDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load XForm:$src)))), 4015fe6060f1SDimitry Andric (f128 (XSCVUDQP (LXSDX XForm:$src)))>; 4016fe6060f1SDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load DSForm:$src)))), 4017fe6060f1SDimitry Andric (f128 (XSCVUDQP (LXSD DSForm:$src)))>; 40185ffd83dbSDimitry Andric 40195ffd83dbSDimitry Andric// Convert Unsigned HWord in memory -> QP 40205ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)), 4021fe6060f1SDimitry Andric (f128 (XSCVUDQP (LXSIHZX XForm:$src)))>; 40225ffd83dbSDimitry Andric 40235ffd83dbSDimitry Andric// Convert Unsigned Byte in memory -> QP 40245ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)), 4025fe6060f1SDimitry Andric (f128 (XSCVUDQP (LXSIBZX ForceXForm:$src)))>; 40265ffd83dbSDimitry Andric 40275ffd83dbSDimitry Andric// Truncate & Convert QP -> (Un)Signed (D)Word. 4028e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>; 4029e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>; 4030e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_sint f128:$src)), 40315ffd83dbSDimitry Andric (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>; 4032e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_uint f128:$src)), 40335ffd83dbSDimitry Andric (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>; 40345ffd83dbSDimitry Andric 40355ffd83dbSDimitry Andric// Instructions for store(fptosi). 40365ffd83dbSDimitry Andric// The 8-byte version is repeated here due to availability of D-Form STXSD. 40375ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4038fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), XForm:$dst, 8), 40395ffd83dbSDimitry Andric (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), 4040fe6060f1SDimitry Andric XForm:$dst)>; 40415ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4042fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), DSForm:$dst, 8), 40435ffd83dbSDimitry Andric (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC), 4044fe6060f1SDimitry Andric DSForm:$dst)>; 40455ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4046fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 4), 4047fe6060f1SDimitry Andric (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>; 40485ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4049fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 2), 4050fe6060f1SDimitry Andric (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>; 40515ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4052fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 1), 4053fe6060f1SDimitry Andric (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>; 40545ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4055fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), XForm:$dst, 8), 4056fe6060f1SDimitry Andric (STXSDX (XSCVDPSXDS f64:$src), XForm:$dst)>; 40575ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4058fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), DSForm:$dst, 8), 4059fe6060f1SDimitry Andric (STXSD (XSCVDPSXDS f64:$src), DSForm:$dst)>; 40605ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4061fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 2), 4062fe6060f1SDimitry Andric (STXSIHX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>; 40635ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4064fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 1), 4065fe6060f1SDimitry Andric (STXSIBX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>; 40665ffd83dbSDimitry Andric 40675ffd83dbSDimitry Andric// Instructions for store(fptoui). 40685ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4069fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), XForm:$dst, 8), 40705ffd83dbSDimitry Andric (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), 4071fe6060f1SDimitry Andric XForm:$dst)>; 40725ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4073fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), DSForm:$dst, 8), 40745ffd83dbSDimitry Andric (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC), 4075fe6060f1SDimitry Andric DSForm:$dst)>; 40765ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4077fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 4), 4078fe6060f1SDimitry Andric (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>; 40795ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4080fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 2), 4081fe6060f1SDimitry Andric (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>; 40825ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4083fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 1), 4084fe6060f1SDimitry Andric (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>; 40855ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4086fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), XForm:$dst, 8), 4087fe6060f1SDimitry Andric (STXSDX (XSCVDPUXDS f64:$src), XForm:$dst)>; 40885ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4089fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), DSForm:$dst, 8), 4090fe6060f1SDimitry Andric (STXSD (XSCVDPUXDS f64:$src), DSForm:$dst)>; 40915ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4092fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 2), 4093fe6060f1SDimitry Andric (STXSIHX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>; 40945ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr 4095fe6060f1SDimitry Andric (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 1), 4096fe6060f1SDimitry Andric (STXSIBX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>; 40975ffd83dbSDimitry Andric 40985ffd83dbSDimitry Andric// Round & Convert QP -> DP/SP 40995ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpround f128:$src)), (f64 (XSCVQPDP $src))>; 41005ffd83dbSDimitry Andricdef : Pat<(f32 (any_fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>; 41015ffd83dbSDimitry Andric 41025ffd83dbSDimitry Andric// Convert SP -> QP 41035ffd83dbSDimitry Andricdef : Pat<(f128 (any_fpextend f32:$src)), 41045ffd83dbSDimitry Andric (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>; 41055ffd83dbSDimitry Andric 41065ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)), 41075ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC), 41085ffd83dbSDimitry Andric (COPY_TO_REGCLASS $XB, VSSRC)), 41095ffd83dbSDimitry Andric VSSRC))>; 41105ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)), 41115ffd83dbSDimitry Andric (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC), 41125ffd83dbSDimitry Andric (COPY_TO_REGCLASS $XB, VSSRC)), 41135ffd83dbSDimitry Andric VSSRC))>; 41145ffd83dbSDimitry Andric 41150b57cec5SDimitry Andric// Endianness-neutral patterns for const splats with ISA 3.0 instructions. 4116fe6060f1SDimitry Andricdefm : ScalToVecWPermute<v4i32, (i32 i32:$A), (MTVSRWS $A), 4117fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>; 41180b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)), 41190b57cec5SDimitry Andric (v4i32 (MTVSRWS $A))>; 41208bcb0991SDimitry Andricdef : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41218bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41228bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41238bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41248bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41258bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41268bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A, 41278bcb0991SDimitry Andric immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)), 41280b57cec5SDimitry Andric (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>; 4129fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 4130fe6060f1SDimitry Andric v4i32, FltToIntLoad.A, 4131fe6060f1SDimitry Andric (XVCVSPSXWS (LXVWSX ForceXForm:$A)), 4132fe6060f1SDimitry Andric (XVCVSPSXWS (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64))>; 4133fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 4134fe6060f1SDimitry Andric v4i32, FltToUIntLoad.A, 4135fe6060f1SDimitry Andric (XVCVSPUXWS (LXVWSX ForceXForm:$A)), 4136fe6060f1SDimitry Andric (XVCVSPUXWS (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64))>; 41375ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 41385ffd83dbSDimitry Andric v4i32, DblToIntLoadP9.A, 4139fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 DSForm:$A)), sub_64), 1), 4140fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 DSForm:$A)), sub_64)>; 41415ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 41425ffd83dbSDimitry Andric v4i32, DblToUIntLoadP9.A, 4143fe6060f1SDimitry Andric (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 DSForm:$A)), sub_64), 1), 4144fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 DSForm:$A)), sub_64)>; 41455ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 41465ffd83dbSDimitry Andric v2i64, FltToLongLoadP9.A, 4147fe6060f1SDimitry Andric (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), 0), 41485ffd83dbSDimitry Andric (SUBREG_TO_REG 41495ffd83dbSDimitry Andric (i64 1), 4150fe6060f1SDimitry Andric (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), sub_64)>; 41515ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 41525ffd83dbSDimitry Andric v2i64, FltToULongLoadP9.A, 4153fe6060f1SDimitry Andric (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), 0), 41545ffd83dbSDimitry Andric (SUBREG_TO_REG 41555ffd83dbSDimitry Andric (i64 1), 4156fe6060f1SDimitry Andric (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), sub_64)>; 4157fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldsplat ForceXForm:$A)), 4158fe6060f1SDimitry Andric (v4f32 (LXVWSX ForceXForm:$A))>; 4159fe6060f1SDimitry Andricdef : Pat<(v4i32 (PPCldsplat ForceXForm:$A)), 4160fe6060f1SDimitry Andric (v4i32 (LXVWSX ForceXForm:$A))>; 4161349cc55cSDimitry Andricdef : Pat<(v8i16 (PPCldsplat ForceXForm:$A)), 4162349cc55cSDimitry Andric (v8i16 (VSPLTHs 3, (LXSIHZX ForceXForm:$A)))>; 4163349cc55cSDimitry Andricdef : Pat<(v16i8 (PPCldsplat ForceXForm:$A)), 4164349cc55cSDimitry Andric (v16i8 (VSPLTBs 7, (LXSIBZX ForceXForm:$A)))>; 4165*bdd1243dSDimitry Andricdef : Pat<(v2f64 (PPCxxperm v2f64:$XT, v2f64:$XB, v4i32:$C)), 4166*bdd1243dSDimitry Andric (XXPERM v2f64:$XT, v2f64:$XB, v4i32:$C)>; 41675ffd83dbSDimitry Andric} // HasVSX, HasP9Vector 41685ffd83dbSDimitry Andric 4169fe6060f1SDimitry Andric// Any Power9 VSX subtarget with equivalent length but better Power10 VSX 4170fe6060f1SDimitry Andric// patterns. 4171fe6060f1SDimitry Andric// Two identical blocks are required due to the slightly different predicates: 4172fe6060f1SDimitry Andric// One without P10 instructions, the other is BigEndian only with P10 instructions. 4173fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, NoP10Vector] in { 4174fe6060f1SDimitry Andric// Little endian Power10 subtargets produce a shorter pattern but require a 4175fe6060f1SDimitry Andric// COPY_TO_REGCLASS. The COPY_TO_REGCLASS makes it appear to need two instructions 4176fe6060f1SDimitry Andric// to perform the operation, when only one instruction is produced in practice. 4177fe6060f1SDimitry Andric// The NoP10Vector predicate excludes these patterns from Power10 VSX subtargets. 4178fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 4179fe6060f1SDimitry Andric v16i8, ScalarLoads.Li8, 4180fe6060f1SDimitry Andric (VSPLTBs 7, (LXSIBZX ForceXForm:$src)), 4181fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>; 4182fe6060f1SDimitry Andric// Build vectors from i16 loads 4183fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 4184fe6060f1SDimitry Andric v8i16, ScalarLoads.Li16, 4185fe6060f1SDimitry Andric (VSPLTHs 3, (LXSIHZX ForceXForm:$src)), 4186fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>; 4187fe6060f1SDimitry Andric} // HasVSX, HasP9Vector, NoP10Vector 4188fe6060f1SDimitry Andric 4189fe6060f1SDimitry Andric// Any big endian Power9 VSX subtarget 4190fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian] in { 4191fe6060f1SDimitry Andric// Power10 VSX subtargets produce a shorter pattern for little endian targets 4192fe6060f1SDimitry Andric// but this is still the best pattern for Power9 and Power10 VSX big endian 4193fe6060f1SDimitry Andric// Build vectors from i8 loads 4194fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 4195fe6060f1SDimitry Andric v16i8, ScalarLoads.Li8, 4196fe6060f1SDimitry Andric (VSPLTBs 7, (LXSIBZX ForceXForm:$src)), 4197fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>; 4198fe6060f1SDimitry Andric// Build vectors from i16 loads 4199fe6060f1SDimitry Andricdefm : ScalToVecWPermute< 4200fe6060f1SDimitry Andric v8i16, ScalarLoads.Li16, 4201fe6060f1SDimitry Andric (VSPLTHs 3, (LXSIHZX ForceXForm:$src)), 4202fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>; 4203fe6060f1SDimitry Andric 42045ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 42055ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>; 42065ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 42075ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>; 42085ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 42095ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>; 42105ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 42115ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>; 42125ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 42135ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>; 42145ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 42155ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>; 42165ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 42175ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>; 42185ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 42195ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>; 42205ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)), 42215ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>; 4222349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 0)), 4223349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4224349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4225349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4226349cc55cSDimitry Andric 0))>; 4227349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 0)), 4228349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4229349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4230349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4231349cc55cSDimitry Andric 0))>; 42325ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)), 42335ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>; 4234349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 1)), 4235349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4236349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4237349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4238349cc55cSDimitry Andric 4))>; 4239349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 1)), 4240349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4241349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4242349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4243349cc55cSDimitry Andric 4))>; 42445ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)), 42455ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>; 4246349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 2)), 4247349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4248349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4249349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4250349cc55cSDimitry Andric 8))>; 4251349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 2)), 4252349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4253349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4254349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4255349cc55cSDimitry Andric 8))>; 42565ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)), 42575ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>; 4258349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 3)), 4259349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4260349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4261349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4262349cc55cSDimitry Andric 12))>; 4263349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 3)), 4264349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4265349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4266349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4267349cc55cSDimitry Andric 12))>; 42685ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)), 42695ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>; 42705ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)), 42715ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>; 42725ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)), 42735ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>; 42745ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)), 42755ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>; 42765ffd83dbSDimitry Andric 4277fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 0)), 4278fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4279fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 0))>; 4280fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 1)), 4281fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4282fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 4))>; 4283fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 2)), 4284fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4285fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 8))>; 4286fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 3)), 4287fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4288fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 12))>; 4289fe6060f1SDimitry Andric 42905ffd83dbSDimitry Andric// Scalar stores of i8 4291fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), ForceXForm:$dst), 4292fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), ForceXForm:$dst)>; 4293fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), ForceXForm:$dst), 4294fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>; 4295fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), ForceXForm:$dst), 4296fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), ForceXForm:$dst)>; 4297fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), ForceXForm:$dst), 4298fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>; 4299fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), ForceXForm:$dst), 4300fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), ForceXForm:$dst)>; 4301fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), ForceXForm:$dst), 4302fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>; 4303fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), ForceXForm:$dst), 4304fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), ForceXForm:$dst)>; 4305fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), ForceXForm:$dst), 4306fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>; 4307fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), ForceXForm:$dst), 4308fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), ForceXForm:$dst)>; 4309fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), ForceXForm:$dst), 4310fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>; 4311fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), ForceXForm:$dst), 4312fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), ForceXForm:$dst)>; 4313fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), ForceXForm:$dst), 4314fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>; 4315fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), ForceXForm:$dst), 4316fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), ForceXForm:$dst)>; 4317fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), ForceXForm:$dst), 4318fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>; 4319fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), ForceXForm:$dst), 4320fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), ForceXForm:$dst)>; 4321fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), ForceXForm:$dst), 4322fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>; 43235ffd83dbSDimitry Andric 43245ffd83dbSDimitry Andric// Scalar stores of i16 4325fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), ForceXForm:$dst), 4326fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>; 4327fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), ForceXForm:$dst), 4328fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>; 4329fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), ForceXForm:$dst), 4330fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>; 4331fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), ForceXForm:$dst), 4332fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>; 4333fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), ForceXForm:$dst), 4334fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>; 4335fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), ForceXForm:$dst), 4336fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>; 4337fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), ForceXForm:$dst), 4338fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>; 4339fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), ForceXForm:$dst), 4340fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>; 4341fe6060f1SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian 43425ffd83dbSDimitry Andric 4343fe6060f1SDimitry Andric// Big endian 64Bit Power9 subtarget. 4344fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] in { 4345fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load DSForm:$src)))), 4346fe6060f1SDimitry Andric (v2i64 (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64))>; 4347fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load XForm:$src)))), 4348fe6060f1SDimitry Andric (v2i64 (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64))>; 43495ffd83dbSDimitry Andric 4350fe6060f1SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load DSForm:$src)))), 4351fe6060f1SDimitry Andric (v2f64 (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64))>; 4352fe6060f1SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load XForm:$src)))), 4353fe6060f1SDimitry Andric (v2f64 (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64))>; 4354fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), XForm:$src), 43555ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4356fe6060f1SDimitry Andric sub_64), XForm:$src)>; 4357fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), XForm:$src), 43585ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4359fe6060f1SDimitry Andric sub_64), XForm:$src)>; 4360fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), XForm:$src), 4361fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>; 4362fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), XForm:$src), 4363fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>; 4364fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), DSForm:$src), 43655ffd83dbSDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4366fe6060f1SDimitry Andric sub_64), DSForm:$src)>; 4367fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), DSForm:$src), 43685ffd83dbSDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4369fe6060f1SDimitry Andric sub_64), DSForm:$src)>; 4370fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), DSForm:$src), 4371fe6060f1SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>; 4372fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), DSForm:$src), 4373fe6060f1SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>; 43745ffd83dbSDimitry Andric 43755ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP 43765ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), 43775ffd83dbSDimitry Andric (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 43785ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), 43795ffd83dbSDimitry Andric (f128 (XSCVSDQP 43805ffd83dbSDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 43815ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), 43825ffd83dbSDimitry Andric (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 43835ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), 43845ffd83dbSDimitry Andric (f128 (XSCVUDQP 43855ffd83dbSDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 43865ffd83dbSDimitry Andric 43875ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP 43885ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))), 43895ffd83dbSDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>; 43905ffd83dbSDimitry Andricforeach Idx = [0,2,3] in { 43915ffd83dbSDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))), 43925ffd83dbSDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 43935ffd83dbSDimitry Andric (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>; 43945ffd83dbSDimitry Andric} 43955ffd83dbSDimitry Andricforeach Idx = 0-3 in { 43965ffd83dbSDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))), 43975ffd83dbSDimitry Andric (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>; 43980b57cec5SDimitry Andric} 43990b57cec5SDimitry Andric 4400fe6060f1SDimitry Andric// (Un)Signed HWord vector extract -> QP/DP/SP 44015ffd83dbSDimitry Andricforeach Idx = 0-7 in { 44025ffd83dbSDimitry Andric def : Pat<(f128 (sint_to_fp 44035ffd83dbSDimitry Andric (i32 (sext_inreg 44045ffd83dbSDimitry Andric (vector_extract v8i16:$src, Idx), i16)))), 44055ffd83dbSDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 44065ffd83dbSDimitry Andric (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)), 44075ffd83dbSDimitry Andric sub_64)))>; 44085ffd83dbSDimitry Andric // The SDAG adds the `and` since an `i16` is being extracted as an `i32`. 44095ffd83dbSDimitry Andric def : Pat<(f128 (uint_to_fp 44105ffd83dbSDimitry Andric (and (i32 (vector_extract v8i16:$src, Idx)), 65535))), 44115ffd83dbSDimitry Andric (f128 (XSCVUDQP (EXTRACT_SUBREG 44125ffd83dbSDimitry Andric (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>; 4413fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfidus 4414fe6060f1SDimitry Andric (f64 (PPCmtvsrz (and (i32 (vector_extract v8i16:$src, Idx)), 4415fe6060f1SDimitry Andric 65535))))), 4416fe6060f1SDimitry Andric (f32 (XSCVUXDSP (EXTRACT_SUBREG 4417fe6060f1SDimitry Andric (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>; 4418fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfids 4419fe6060f1SDimitry Andric (f64 (PPCmtvsra 4420fe6060f1SDimitry Andric (i32 (sext_inreg (vector_extract v8i16:$src, Idx), 4421fe6060f1SDimitry Andric i16)))))), 4422fe6060f1SDimitry Andric (f32 (XSCVSXDSP (EXTRACT_SUBREG 4423fe6060f1SDimitry Andric (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)), 4424fe6060f1SDimitry Andric sub_64)))>; 4425fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfidu 4426fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4427fe6060f1SDimitry Andric (and (i32 (vector_extract v8i16:$src, Idx)), 4428fe6060f1SDimitry Andric 65535))))), 4429fe6060f1SDimitry Andric (f64 (XSCVUXDDP (EXTRACT_SUBREG 4430fe6060f1SDimitry Andric (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>; 4431fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfid 4432fe6060f1SDimitry Andric (f64 (PPCmtvsra 4433fe6060f1SDimitry Andric (i32 (sext_inreg (vector_extract v8i16:$src, Idx), 4434fe6060f1SDimitry Andric i16)))))), 4435fe6060f1SDimitry Andric (f64 (XSCVSXDDP (EXTRACT_SUBREG 4436fe6060f1SDimitry Andric (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)), 4437fe6060f1SDimitry Andric sub_64)))>; 44380b57cec5SDimitry Andric} 44390b57cec5SDimitry Andric 44405ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP 44415ffd83dbSDimitry Andricforeach Idx = 0-15 in { 44425ffd83dbSDimitry Andric def : Pat<(f128 (sint_to_fp 44435ffd83dbSDimitry Andric (i32 (sext_inreg (vector_extract v16i8:$src, Idx), 44445ffd83dbSDimitry Andric i8)))), 44455ffd83dbSDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 44465ffd83dbSDimitry Andric (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>; 44475ffd83dbSDimitry Andric def : Pat<(f128 (uint_to_fp 44485ffd83dbSDimitry Andric (and (i32 (vector_extract v16i8:$src, Idx)), 255))), 44495ffd83dbSDimitry Andric (f128 (XSCVUDQP 44505ffd83dbSDimitry Andric (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>; 4451fe6060f1SDimitry Andric 4452fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfidus 4453fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4454fe6060f1SDimitry Andric (and (i32 (vector_extract v16i8:$src, Idx)), 4455fe6060f1SDimitry Andric 255))))), 4456fe6060f1SDimitry Andric (f32 (XSCVUXDSP (EXTRACT_SUBREG 4457fe6060f1SDimitry Andric (VEXTRACTUB !add(Idx, Idx), $src), sub_64)))>; 4458fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfids 4459fe6060f1SDimitry Andric (f64 (PPCmtvsra 4460fe6060f1SDimitry Andric (i32 (sext_inreg (vector_extract v16i8:$src, Idx), 4461fe6060f1SDimitry Andric i8)))))), 4462fe6060f1SDimitry Andric (f32 (XSCVSXDSP (EXTRACT_SUBREG 4463fe6060f1SDimitry Andric (VEXTSH2D (VEXTRACTUB !add(Idx, Idx), $src)), 4464fe6060f1SDimitry Andric sub_64)))>; 4465fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfidu 4466fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4467fe6060f1SDimitry Andric (and (i32 (vector_extract v16i8:$src, Idx)), 4468fe6060f1SDimitry Andric 255))))), 4469fe6060f1SDimitry Andric (f64 (XSCVUXDDP (EXTRACT_SUBREG 4470fe6060f1SDimitry Andric (VEXTRACTUB !add(Idx, Idx), $src), sub_64)))>; 4471fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfid 4472fe6060f1SDimitry Andric (f64 (PPCmtvsra 4473fe6060f1SDimitry Andric (i32 (sext_inreg (vector_extract v16i8:$src, Idx), 4474fe6060f1SDimitry Andric i8)))))), 4475fe6060f1SDimitry Andric (f64 (XSCVSXDDP (EXTRACT_SUBREG 4476fe6060f1SDimitry Andric (VEXTSH2D (VEXTRACTUB !add(Idx, Idx), $src)), 4477fe6060f1SDimitry Andric sub_64)))>; 44780b57cec5SDimitry Andric} 44790b57cec5SDimitry Andric 44805ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP 44815ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), 44825ffd83dbSDimitry Andric (f128 (XSCVUDQP 44835ffd83dbSDimitry Andric (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>; 4484e8d8bef9SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian, IsPPC64 44855ffd83dbSDimitry Andric 44865ffd83dbSDimitry Andric// Little endian Power9 subtarget. 44875ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in { 44885ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 44895ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>; 44905ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 44915ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>; 44925ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 44935ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>; 44945ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 44955ffd83dbSDimitry Andric (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>; 44965ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))), 44975ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>; 44985ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))), 44995ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>; 45005ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))), 45015ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>; 45025ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))), 45035ffd83dbSDimitry Andric (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>; 45045ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)), 45055ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>; 4506349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 0)), 4507349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4508349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4509349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4510349cc55cSDimitry Andric 12))>; 4511349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 0)), 4512349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4513349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4514349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4515349cc55cSDimitry Andric 12))>; 45165ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)), 45175ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>; 4518349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 1)), 4519349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4520349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4521349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4522349cc55cSDimitry Andric 8))>; 4523349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 1)), 4524349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4525349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4526349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4527349cc55cSDimitry Andric 8))>; 45285ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)), 45295ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>; 4530349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 2)), 4531349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4532349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4533349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4534349cc55cSDimitry Andric 4))>; 4535349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 2)), 4536349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4537349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4538349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4539349cc55cSDimitry Andric 4))>; 45405ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)), 45415ffd83dbSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>; 4542349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 3)), 4543349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4544349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4545349cc55cSDimitry Andric (XSCVDPSXWS f64:$B), sub_64), 4546349cc55cSDimitry Andric 0))>; 4547349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 3)), 4548349cc55cSDimitry Andric (v4i32 (XXINSERTW v4i32:$A, 4549349cc55cSDimitry Andric (SUBREG_TO_REG (i64 1), 4550349cc55cSDimitry Andric (XSCVDPUXWS f64:$B), sub_64), 4551349cc55cSDimitry Andric 0))>; 45525ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)), 45535ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>; 45545ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)), 45555ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>; 45565ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)), 45575ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>; 45585ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)), 45595ffd83dbSDimitry Andric (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>; 45605ffd83dbSDimitry Andric 4561fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 0)), 4562fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4563fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 12))>; 4564fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 1)), 4565fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4566fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 8))>; 4567fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 2)), 4568fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4569fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 4))>; 4570fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 3)), 4571fe6060f1SDimitry Andric (v4f32 (XXINSERTW v4f32:$A, 4572fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 0))>; 45735ffd83dbSDimitry Andric 4574fe6060f1SDimitry Andricdef : Pat<(v8i16 (PPCld_vec_be ForceXForm:$src)), 4575fe6060f1SDimitry Andric (COPY_TO_REGCLASS (LXVH8X ForceXForm:$src), VRRC)>; 4576fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v8i16:$rS, ForceXForm:$dst), 4577fe6060f1SDimitry Andric (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), ForceXForm:$dst)>; 4578fe6060f1SDimitry Andric 4579fe6060f1SDimitry Andricdef : Pat<(v16i8 (PPCld_vec_be ForceXForm:$src)), 4580fe6060f1SDimitry Andric (COPY_TO_REGCLASS (LXVB16X ForceXForm:$src), VRRC)>; 4581fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v16i8:$rS, ForceXForm:$dst), 4582fe6060f1SDimitry Andric (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), ForceXForm:$dst)>; 45835ffd83dbSDimitry Andric 45845ffd83dbSDimitry Andric// Scalar stores of i8 4585fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), ForceXForm:$dst), 4586fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>; 4587fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), ForceXForm:$dst), 4588fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), ForceXForm:$dst)>; 4589fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), ForceXForm:$dst), 4590fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>; 4591fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), ForceXForm:$dst), 4592fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), ForceXForm:$dst)>; 4593fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), ForceXForm:$dst), 4594fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>; 4595fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), ForceXForm:$dst), 4596fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), ForceXForm:$dst)>; 4597fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), ForceXForm:$dst), 4598fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>; 4599fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), ForceXForm:$dst), 4600fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), ForceXForm:$dst)>; 4601fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), ForceXForm:$dst), 4602fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>; 4603fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), ForceXForm:$dst), 4604fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), ForceXForm:$dst)>; 4605fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), ForceXForm:$dst), 4606fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>; 4607fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), ForceXForm:$dst), 4608fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), ForceXForm:$dst)>; 4609fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), ForceXForm:$dst), 4610fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>; 4611fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), ForceXForm:$dst), 4612fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), ForceXForm:$dst)>; 4613fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), ForceXForm:$dst), 4614fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>; 4615fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), ForceXForm:$dst), 4616fe6060f1SDimitry Andric (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), ForceXForm:$dst)>; 46175ffd83dbSDimitry Andric 46185ffd83dbSDimitry Andric// Scalar stores of i16 4619fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), ForceXForm:$dst), 4620fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>; 4621fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), ForceXForm:$dst), 4622fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>; 4623fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), ForceXForm:$dst), 4624fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>; 4625fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), ForceXForm:$dst), 4626fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>; 4627fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), ForceXForm:$dst), 4628fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>; 4629fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), ForceXForm:$dst), 4630fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>; 4631fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), ForceXForm:$dst), 4632fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>; 4633fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), ForceXForm:$dst), 4634fe6060f1SDimitry Andric (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>; 46355ffd83dbSDimitry Andric 46365ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 4637fe6060f1SDimitry Andric v2i64, (i64 (load DSForm:$src)), 4638fe6060f1SDimitry Andric (XXPERMDIs (DFLOADf64 DSForm:$src), 2), 4639fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>; 46405ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 4641fe6060f1SDimitry Andric v2i64, (i64 (load XForm:$src)), 4642fe6060f1SDimitry Andric (XXPERMDIs (XFLOADf64 XForm:$src), 2), 4643fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>; 46445ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 4645fe6060f1SDimitry Andric v2f64, (f64 (load DSForm:$src)), 4646fe6060f1SDimitry Andric (XXPERMDIs (DFLOADf64 DSForm:$src), 2), 4647fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>; 46485ffd83dbSDimitry Andricdefm : ScalToVecWPermute< 4649fe6060f1SDimitry Andric v2f64, (f64 (load XForm:$src)), 4650fe6060f1SDimitry Andric (XXPERMDIs (XFLOADf64 XForm:$src), 2), 4651fe6060f1SDimitry Andric (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>; 46525ffd83dbSDimitry Andric 4653fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), XForm:$src), 46545ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4655fe6060f1SDimitry Andric sub_64), XForm:$src)>; 4656fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), XForm:$src), 46575ffd83dbSDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4658fe6060f1SDimitry Andric sub_64), XForm:$src)>; 4659fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), XForm:$src), 4660fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>; 4661fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), XForm:$src), 4662fe6060f1SDimitry Andric (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>; 4663fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), DSForm:$src), 46645ffd83dbSDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), 4665fe6060f1SDimitry Andric sub_64), DSForm:$src)>; 4666fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), DSForm:$src), 46675ffd83dbSDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64), 4668fe6060f1SDimitry Andric DSForm:$src)>; 4669fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), DSForm:$src), 4670fe6060f1SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>; 4671fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), DSForm:$src), 4672fe6060f1SDimitry Andric (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>; 46735ffd83dbSDimitry Andric 46745ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP 46755ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))), 46765ffd83dbSDimitry Andric (f128 (XSCVSDQP 46775ffd83dbSDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 46785ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))), 46795ffd83dbSDimitry Andric (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; 46805ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))), 46815ffd83dbSDimitry Andric (f128 (XSCVUDQP 46825ffd83dbSDimitry Andric (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>; 46835ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))), 46845ffd83dbSDimitry Andric (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; 46855ffd83dbSDimitry Andric 46865ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP 46875ffd83dbSDimitry Andricforeach Idx = [[0,3],[1,2],[3,0]] in { 46885ffd83dbSDimitry Andric def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))), 46895ffd83dbSDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG 46905ffd83dbSDimitry Andric (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)), 46915ffd83dbSDimitry Andric sub_64)))>; 46925ffd83dbSDimitry Andric} 46935ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))), 46945ffd83dbSDimitry Andric (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>; 46955ffd83dbSDimitry Andric 46965ffd83dbSDimitry Andricforeach Idx = [[0,12],[1,8],[2,4],[3,0]] in { 46975ffd83dbSDimitry Andric def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))), 46985ffd83dbSDimitry Andric (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>; 46990b57cec5SDimitry Andric} 47000b57cec5SDimitry Andric 4701fe6060f1SDimitry Andric// (Un)Signed HWord vector extract -> QP/DP/SP 47025ffd83dbSDimitry Andric// The Nested foreach lists identifies the vector element and corresponding 47035ffd83dbSDimitry Andric// register byte location. 47045ffd83dbSDimitry Andricforeach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in { 47055ffd83dbSDimitry Andric def : Pat<(f128 (sint_to_fp 47065ffd83dbSDimitry Andric (i32 (sext_inreg 47075ffd83dbSDimitry Andric (vector_extract v8i16:$src, !head(Idx)), i16)))), 47085ffd83dbSDimitry Andric (f128 (XSCVSDQP 47095ffd83dbSDimitry Andric (EXTRACT_SUBREG (VEXTSH2D 47105ffd83dbSDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src)), 47115ffd83dbSDimitry Andric sub_64)))>; 47125ffd83dbSDimitry Andric def : Pat<(f128 (uint_to_fp 47135ffd83dbSDimitry Andric (and (i32 (vector_extract v8i16:$src, !head(Idx))), 47145ffd83dbSDimitry Andric 65535))), 47155ffd83dbSDimitry Andric (f128 (XSCVUDQP (EXTRACT_SUBREG 47165ffd83dbSDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>; 4717fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfidus 4718fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4719fe6060f1SDimitry Andric (and (i32 (vector_extract v8i16:$src, !head(Idx))), 4720fe6060f1SDimitry Andric 65535))))), 4721fe6060f1SDimitry Andric (f32 (XSCVUXDSP (EXTRACT_SUBREG 4722fe6060f1SDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>; 4723fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfids 4724fe6060f1SDimitry Andric (f64 (PPCmtvsra 4725fe6060f1SDimitry Andric (i32 (sext_inreg (vector_extract v8i16:$src, 4726fe6060f1SDimitry Andric !head(Idx)), i16)))))), 4727fe6060f1SDimitry Andric (f32 (XSCVSXDSP 4728fe6060f1SDimitry Andric (EXTRACT_SUBREG 4729fe6060f1SDimitry Andric (VEXTSH2D (VEXTRACTUH !head(!tail(Idx)), $src)), 4730fe6060f1SDimitry Andric sub_64)))>; 4731fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfidu 4732fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4733fe6060f1SDimitry Andric (and (i32 (vector_extract v8i16:$src, !head(Idx))), 4734fe6060f1SDimitry Andric 65535))))), 4735fe6060f1SDimitry Andric (f64 (XSCVUXDDP (EXTRACT_SUBREG 4736fe6060f1SDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>; 4737fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfid 4738fe6060f1SDimitry Andric (f64 (PPCmtvsra 4739fe6060f1SDimitry Andric (i32 (sext_inreg 4740fe6060f1SDimitry Andric (vector_extract v8i16:$src, !head(Idx)), i16)))))), 4741fe6060f1SDimitry Andric (f64 (XSCVSXDDP 4742fe6060f1SDimitry Andric (EXTRACT_SUBREG (VEXTSH2D 4743fe6060f1SDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src)), 4744fe6060f1SDimitry Andric sub_64)))>; 47450b57cec5SDimitry Andric} 47460b57cec5SDimitry Andric 4747fe6060f1SDimitry Andric// (Un)Signed Byte vector extract -> QP/DP/SP 47485ffd83dbSDimitry Andricforeach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7], 47495ffd83dbSDimitry Andric [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in { 47505ffd83dbSDimitry Andric def : Pat<(f128 (sint_to_fp 47515ffd83dbSDimitry Andric (i32 (sext_inreg 47525ffd83dbSDimitry Andric (vector_extract v16i8:$src, !head(Idx)), i8)))), 47535ffd83dbSDimitry Andric (f128 (XSCVSDQP 47545ffd83dbSDimitry Andric (EXTRACT_SUBREG 47555ffd83dbSDimitry Andric (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)), 47565ffd83dbSDimitry Andric sub_64)))>; 47575ffd83dbSDimitry Andric def : Pat<(f128 (uint_to_fp 47585ffd83dbSDimitry Andric (and (i32 (vector_extract v16i8:$src, !head(Idx))), 47595ffd83dbSDimitry Andric 255))), 47605ffd83dbSDimitry Andric (f128 (XSCVUDQP 47615ffd83dbSDimitry Andric (EXTRACT_SUBREG 47625ffd83dbSDimitry Andric (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>; 4763fe6060f1SDimitry Andric 4764fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfidus 4765fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4766fe6060f1SDimitry Andric (and (i32 (vector_extract v16i8:$src, !head(Idx))), 4767fe6060f1SDimitry Andric 255))))), 4768fe6060f1SDimitry Andric (f32 (XSCVUXDSP (EXTRACT_SUBREG 4769fe6060f1SDimitry Andric (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>; 4770fe6060f1SDimitry Andric def : Pat<(f32 (PPCfcfids 4771fe6060f1SDimitry Andric (f64 (PPCmtvsra 4772fe6060f1SDimitry Andric (i32 (sext_inreg 4773fe6060f1SDimitry Andric (vector_extract v16i8:$src, !head(Idx)), i8)))))), 4774fe6060f1SDimitry Andric (f32 (XSCVSXDSP 4775fe6060f1SDimitry Andric (EXTRACT_SUBREG (VEXTSH2D 4776fe6060f1SDimitry Andric (VEXTRACTUB !head(!tail(Idx)), $src)), 4777fe6060f1SDimitry Andric sub_64)))>; 4778fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfidu 4779fe6060f1SDimitry Andric (f64 (PPCmtvsrz 4780fe6060f1SDimitry Andric (and (i32 4781fe6060f1SDimitry Andric (vector_extract v16i8:$src, !head(Idx))), 255))))), 4782fe6060f1SDimitry Andric (f64 (XSCVUXDDP (EXTRACT_SUBREG 4783fe6060f1SDimitry Andric (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>; 4784fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfidu 4785fe6060f1SDimitry Andric (f64 (PPCmtvsra 4786fe6060f1SDimitry Andric (i32 (sext_inreg 4787fe6060f1SDimitry Andric (vector_extract v16i8:$src, !head(Idx)), i8)))))), 4788fe6060f1SDimitry Andric (f64 (XSCVSXDDP 4789fe6060f1SDimitry Andric (EXTRACT_SUBREG (VEXTSH2D 4790fe6060f1SDimitry Andric (VEXTRACTUB !head(!tail(Idx)), $src)), 4791fe6060f1SDimitry Andric sub_64)))>; 4792fe6060f1SDimitry Andric 4793fe6060f1SDimitry Andric def : Pat<(f64 (PPCfcfid 4794fe6060f1SDimitry Andric (f64 (PPCmtvsra 4795fe6060f1SDimitry Andric (i32 (sext_inreg 4796fe6060f1SDimitry Andric (vector_extract v16i8:$src, !head(Idx)), i8)))))), 4797fe6060f1SDimitry Andric (f64 (XSCVSXDDP 4798fe6060f1SDimitry Andric (EXTRACT_SUBREG (VEXTSH2D 4799fe6060f1SDimitry Andric (VEXTRACTUH !head(!tail(Idx)), $src)), 4800fe6060f1SDimitry Andric sub_64)))>; 48015ffd83dbSDimitry Andric} 48025ffd83dbSDimitry Andric 48035ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP 48045ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), 48055ffd83dbSDimitry Andric (f128 (XSCVUDQP 48065ffd83dbSDimitry Andric (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>; 48075ffd83dbSDimitry Andric} // HasVSX, HasP9Vector, IsLittleEndian 48085ffd83dbSDimitry Andric 48095ffd83dbSDimitry Andric// Any Power9 VSX subtarget that supports Power9 Altivec. 48105ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec] in { 48110b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be 48120b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef. 48130b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))), 48140b57cec5SDimitry Andric (v4i32 (VABSDUW $A, $B))>; 48150b57cec5SDimitry Andric 48160b57cec5SDimitry Andricdef : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))), 48170b57cec5SDimitry Andric (v8i16 (VABSDUH $A, $B))>; 48180b57cec5SDimitry Andric 48190b57cec5SDimitry Andricdef : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))), 48200b57cec5SDimitry Andric (v16i8 (VABSDUB $A, $B))>; 48210b57cec5SDimitry Andric 48220b57cec5SDimitry Andric// As PPCVABSD description, the last operand indicates whether do the 48230b57cec5SDimitry Andric// sign bit flip. 48240b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))), 48250b57cec5SDimitry Andric (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>; 48265ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec 48275ffd83dbSDimitry Andric 4828e8d8bef9SDimitry Andric// Big endian Power9 64Bit VSX subtargets with P9 Altivec support. 4829e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] in { 48305ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))), 48315ffd83dbSDimitry Andric (VEXTUBLX $Idx, $S)>; 48325ffd83dbSDimitry Andric 48335ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))), 48345ffd83dbSDimitry Andric (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>; 48355ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))), 48365ffd83dbSDimitry Andric (VEXTUHLX (LI8 0), $S)>; 48375ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))), 48385ffd83dbSDimitry Andric (VEXTUHLX (LI8 2), $S)>; 48395ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))), 48405ffd83dbSDimitry Andric (VEXTUHLX (LI8 4), $S)>; 48415ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))), 48425ffd83dbSDimitry Andric (VEXTUHLX (LI8 6), $S)>; 48435ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))), 48445ffd83dbSDimitry Andric (VEXTUHLX (LI8 8), $S)>; 48455ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))), 48465ffd83dbSDimitry Andric (VEXTUHLX (LI8 10), $S)>; 48475ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))), 48485ffd83dbSDimitry Andric (VEXTUHLX (LI8 12), $S)>; 48495ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))), 48505ffd83dbSDimitry Andric (VEXTUHLX (LI8 14), $S)>; 48515ffd83dbSDimitry Andric 48525ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 48535ffd83dbSDimitry Andric (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>; 48545ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))), 48555ffd83dbSDimitry Andric (VEXTUWLX (LI8 0), $S)>; 48565ffd83dbSDimitry Andric 48575ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX 48585ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))), 48595ffd83dbSDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 48605ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32)>; 48615ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))), 48625ffd83dbSDimitry Andric (VEXTUWLX (LI8 8), $S)>; 48635ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))), 48645ffd83dbSDimitry Andric (VEXTUWLX (LI8 12), $S)>; 48655ffd83dbSDimitry Andric 48665ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 48675ffd83dbSDimitry Andric (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>; 48685ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))), 48695ffd83dbSDimitry Andric (EXTSW (VEXTUWLX (LI8 0), $S))>; 48705ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX 48715ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))), 48725ffd83dbSDimitry Andric (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 48735ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32))>; 48745ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))), 48755ffd83dbSDimitry Andric (EXTSW (VEXTUWLX (LI8 8), $S))>; 48765ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))), 48775ffd83dbSDimitry Andric (EXTSW (VEXTUWLX (LI8 12), $S))>; 48785ffd83dbSDimitry Andric 48795ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 48805ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>; 48815ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)), 48825ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>; 48835ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)), 48845ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>; 48855ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)), 48865ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>; 48875ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)), 48885ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>; 48895ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)), 48905ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>; 48915ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)), 48925ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>; 48935ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)), 48945ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>; 48955ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)), 48965ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>; 48975ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)), 48985ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>; 48995ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)), 49005ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>; 49015ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)), 49025ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>; 49035ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)), 49045ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>; 49055ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)), 49065ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>; 49075ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)), 49085ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>; 49095ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)), 49105ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>; 49115ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)), 49125ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>; 49135ffd83dbSDimitry Andric 49145ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 49155ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX 49165ffd83dbSDimitry Andric (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>; 49175ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)), 49185ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>; 49195ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)), 49205ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>; 49215ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)), 49225ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>; 49235ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)), 49245ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>; 49255ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)), 49265ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>; 49275ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)), 49285ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>; 49295ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)), 49305ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>; 49315ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)), 49325ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>; 49335ffd83dbSDimitry Andric 49345ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 49355ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX 49365ffd83dbSDimitry Andric (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>; 49375ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)), 49385ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>; 49395ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX 49405ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)), 49415ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 49425ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)), 49435ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>; 49445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)), 49455ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>; 49465ffd83dbSDimitry Andric 49475ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors. 49485ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete 49495ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file. 49505ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)), 49515ffd83dbSDimitry Andric (v2i64 (VEXTSW2D $A))>; 49525ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)), 49535ffd83dbSDimitry Andric (v2i64 (VEXTSH2D $A))>; 49545ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1, 49555ffd83dbSDimitry Andric HWordToWord.BE_A2, HWordToWord.BE_A3)), 49565ffd83dbSDimitry Andric (v4i32 (VEXTSH2W $A))>; 49575ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1, 49585ffd83dbSDimitry Andric ByteToWord.BE_A2, ByteToWord.BE_A3)), 49595ffd83dbSDimitry Andric (v4i32 (VEXTSB2W $A))>; 49605ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)), 49615ffd83dbSDimitry Andric (v2i64 (VEXTSB2D $A))>; 4962e8d8bef9SDimitry Andric} // HasVSX, HasP9Altivec, IsBigEndian, IsPPC64 49635ffd83dbSDimitry Andric 49645ffd83dbSDimitry Andric// Little endian Power9 VSX subtargets with P9 Altivec support. 49655ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in { 49665ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))), 49675ffd83dbSDimitry Andric (VEXTUBRX $Idx, $S)>; 49685ffd83dbSDimitry Andric 49695ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))), 49705ffd83dbSDimitry Andric (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>; 49715ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))), 49725ffd83dbSDimitry Andric (VEXTUHRX (LI8 0), $S)>; 49735ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))), 49745ffd83dbSDimitry Andric (VEXTUHRX (LI8 2), $S)>; 49755ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))), 49765ffd83dbSDimitry Andric (VEXTUHRX (LI8 4), $S)>; 49775ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))), 49785ffd83dbSDimitry Andric (VEXTUHRX (LI8 6), $S)>; 49795ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))), 49805ffd83dbSDimitry Andric (VEXTUHRX (LI8 8), $S)>; 49815ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))), 49825ffd83dbSDimitry Andric (VEXTUHRX (LI8 10), $S)>; 49835ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))), 49845ffd83dbSDimitry Andric (VEXTUHRX (LI8 12), $S)>; 49855ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))), 49865ffd83dbSDimitry Andric (VEXTUHRX (LI8 14), $S)>; 49875ffd83dbSDimitry Andric 49885ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 49895ffd83dbSDimitry Andric (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>; 49905ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))), 49915ffd83dbSDimitry Andric (VEXTUWRX (LI8 0), $S)>; 49925ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))), 49935ffd83dbSDimitry Andric (VEXTUWRX (LI8 4), $S)>; 49945ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX 49955ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))), 49965ffd83dbSDimitry Andric (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 49975ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32)>; 49985ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))), 49995ffd83dbSDimitry Andric (VEXTUWRX (LI8 12), $S)>; 50005ffd83dbSDimitry Andric 50015ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))), 50025ffd83dbSDimitry Andric (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>; 50035ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))), 50045ffd83dbSDimitry Andric (EXTSW (VEXTUWRX (LI8 0), $S))>; 50055ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))), 50065ffd83dbSDimitry Andric (EXTSW (VEXTUWRX (LI8 4), $S))>; 50075ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX 50085ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))), 50095ffd83dbSDimitry Andric (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 50105ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2), sub_32))>; 50115ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))), 50125ffd83dbSDimitry Andric (EXTSW (VEXTUWRX (LI8 12), $S))>; 50135ffd83dbSDimitry Andric 50145ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)), 50155ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>; 50165ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)), 50175ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>; 50185ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)), 50195ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>; 50205ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)), 50215ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>; 50225ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)), 50235ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>; 50245ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)), 50255ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>; 50265ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)), 50275ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>; 50285ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)), 50295ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>; 50305ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)), 50315ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>; 50325ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)), 50335ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>; 50345ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)), 50355ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>; 50365ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)), 50375ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>; 50385ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)), 50395ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>; 50405ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)), 50415ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>; 50425ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)), 50435ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>; 50445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)), 50455ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>; 50465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)), 50475ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>; 50485ffd83dbSDimitry Andric 50495ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)), 50505ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX 50515ffd83dbSDimitry Andric (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>; 50525ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)), 50535ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>; 50545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)), 50555ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>; 50565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)), 50575ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>; 50585ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)), 50595ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>; 50605ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)), 50615ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>; 50625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)), 50635ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>; 50645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)), 50655ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>; 50665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)), 50675ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>; 50685ffd83dbSDimitry Andric 50695ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)), 50705ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX 50715ffd83dbSDimitry Andric (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>; 50725ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)), 50735ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>; 50745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)), 50755ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>; 50765ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX 50775ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)), 50785ffd83dbSDimitry Andric (i32 VectorExtractions.LE_WORD_2)>; 50795ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)), 50805ffd83dbSDimitry Andric (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>; 50815ffd83dbSDimitry Andric 50825ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors. 50835ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete 50845ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file. 50855ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)), 50865ffd83dbSDimitry Andric (v2i64 (VEXTSW2D $A))>; 50875ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)), 50885ffd83dbSDimitry Andric (v2i64 (VEXTSH2D $A))>; 50895ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1, 50905ffd83dbSDimitry Andric HWordToWord.LE_A2, HWordToWord.LE_A3)), 50915ffd83dbSDimitry Andric (v4i32 (VEXTSH2W $A))>; 50925ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1, 50935ffd83dbSDimitry Andric ByteToWord.LE_A2, ByteToWord.LE_A3)), 50945ffd83dbSDimitry Andric (v4i32 (VEXTSB2W $A))>; 50955ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)), 50965ffd83dbSDimitry Andric (v2i64 (VEXTSB2D $A))>; 50975ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec, IsLittleEndian 50985ffd83dbSDimitry Andric 5099e8d8bef9SDimitry Andric// Big endian 64Bit VSX subtarget that supports additional direct moves from 5100e8d8bef9SDimitry Andric// ISA3.0. 5101e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] in { 51025ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 1)), 51035ffd83dbSDimitry Andric (i64 (MFVSRLD $A))>; 51045ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Big endian. 51055ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)), 51065ffd83dbSDimitry Andric (v2i64 (MTVSRDD $rB, $rA))>; 51075ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 51085ffd83dbSDimitry Andric (MTVSRDD 51095ffd83dbSDimitry Andric (RLDIMI AnyExts.B, AnyExts.A, 32, 0), 51105ffd83dbSDimitry Andric (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>; 51115ffd83dbSDimitry Andric 51125ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)), 51135ffd83dbSDimitry Andric (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>; 5114e8d8bef9SDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64 51155ffd83dbSDimitry Andric 51165ffd83dbSDimitry Andric// Little endian VSX subtarget that supports direct moves from ISA3.0. 51175ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in { 51185ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 0)), 51195ffd83dbSDimitry Andric (i64 (MFVSRLD $A))>; 51205ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Little endian. 51215ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)), 51225ffd83dbSDimitry Andric (v2i64 (MTVSRDD $rB, $rA))>; 51235ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)), 51245ffd83dbSDimitry Andric (MTVSRDD 51255ffd83dbSDimitry Andric (RLDIMI AnyExts.C, AnyExts.D, 32, 0), 51265ffd83dbSDimitry Andric (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>; 51275ffd83dbSDimitry Andric 51285ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)), 51295ffd83dbSDimitry Andric (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>; 51305ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian 51315ffd83dbSDimitry Andric} // AddedComplexity = 400 51325ffd83dbSDimitry Andric 51335ffd83dbSDimitry Andric//---------------------------- Instruction aliases ---------------------------// 51345ffd83dbSDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB", 51355ffd83dbSDimitry Andric (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 51365ffd83dbSDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB", 51375ffd83dbSDimitry Andric (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>; 51385ffd83dbSDimitry Andric 5139e8d8bef9SDimitry Andric// Certain versions of the AIX assembler may missassemble these mnemonics. 5140e8d8bef9SDimitry Andriclet Predicates = [ModernAs] in { 51415ffd83dbSDimitry Andric def : InstAlias<"xxspltd $XT, $XB, 0", 51425ffd83dbSDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>; 51435ffd83dbSDimitry Andric def : InstAlias<"xxspltd $XT, $XB, 1", 51445ffd83dbSDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>; 5145e8d8bef9SDimitry Andric def : InstAlias<"xxspltd $XT, $XB, 0", 5146e8d8bef9SDimitry Andric (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>; 5147e8d8bef9SDimitry Andric def : InstAlias<"xxspltd $XT, $XB, 1", 5148e8d8bef9SDimitry Andric (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>; 5149e8d8bef9SDimitry Andric} 5150e8d8bef9SDimitry Andric 51515ffd83dbSDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB", 51525ffd83dbSDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>; 51535ffd83dbSDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB", 51545ffd83dbSDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>; 51555ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB", 51565ffd83dbSDimitry Andric (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>; 51575ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB", 51585ffd83dbSDimitry Andric (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>; 51595ffd83dbSDimitry Andricdef : InstAlias<"mfvrd $rA, $XT", 51605ffd83dbSDimitry Andric (MFVRD g8rc:$rA, vrrc:$XT), 0>; 51615ffd83dbSDimitry Andricdef : InstAlias<"mffprd $rA, $src", 51625ffd83dbSDimitry Andric (MFVSRD g8rc:$rA, f8rc:$src)>; 51635ffd83dbSDimitry Andricdef : InstAlias<"mtvrd $XT, $rA", 51645ffd83dbSDimitry Andric (MTVRD vrrc:$XT, g8rc:$rA), 0>; 51655ffd83dbSDimitry Andricdef : InstAlias<"mtfprd $dst, $rA", 51665ffd83dbSDimitry Andric (MTVSRD f8rc:$dst, g8rc:$rA)>; 51675ffd83dbSDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT", 51685ffd83dbSDimitry Andric (MFVRWZ gprc:$rA, vrrc:$XT), 0>; 51695ffd83dbSDimitry Andricdef : InstAlias<"mffprwz $rA, $src", 51705ffd83dbSDimitry Andric (MFVSRWZ gprc:$rA, f8rc:$src)>; 51715ffd83dbSDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA", 51725ffd83dbSDimitry Andric (MTVRWA vrrc:$XT, gprc:$rA), 0>; 51735ffd83dbSDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA", 51745ffd83dbSDimitry Andric (MTVSRWA f8rc:$dst, gprc:$rA)>; 51755ffd83dbSDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA", 51765ffd83dbSDimitry Andric (MTVRWZ vrrc:$XT, gprc:$rA), 0>; 51775ffd83dbSDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA", 51785ffd83dbSDimitry Andric (MTVSRWZ f8rc:$dst, gprc:$rA)>; 5179