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]>;
798bcb0991SDimitry Andricdef SDT_PPCld_vec_be : SDTypeProfile<1, 1, [
808bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
818bcb0991SDimitry Andric]>;
828bcb0991SDimitry Andricdef SDT_PPCst_vec_be : SDTypeProfile<0, 2, [
838bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
848bcb0991SDimitry Andric]>;
850b57cec5SDimitry Andric
86bdd1243dSDimitry Andricdef SDT_PPCxxperm : SDTypeProfile<1, 3, [
87bdd1243dSDimitry Andric  SDTCisVT<0, v2f64>, SDTCisVT<1, v2f64>,
88bdd1243dSDimitry Andric  SDTCisVT<2, v2f64>, SDTCisVT<3, v4i32>]>;
895ffd83dbSDimitry Andric//--------------------------- Custom PPC nodes -------------------------------//
900b57cec5SDimitry Andricdef PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
910b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
920b57cec5SDimitry Andricdef PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
930b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayStore]>;
948bcb0991SDimitry Andricdef PPCld_vec_be  : SDNode<"PPCISD::LOAD_VEC_BE", SDT_PPCld_vec_be,
958bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
968bcb0991SDimitry Andricdef PPCst_vec_be : SDNode<"PPCISD::STORE_VEC_BE", SDT_PPCst_vec_be,
978bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayStore]>;
980b57cec5SDimitry Andricdef PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
990b57cec5SDimitry Andricdef PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
1000b57cec5SDimitry Andricdef PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
1010b57cec5SDimitry Andricdef PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
1020b57cec5SDimitry Andricdef PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
1030b57cec5SDimitry Andricdef PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
1040b57cec5SDimitry Andricdef PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
1050b57cec5SDimitry Andric
1068bcb0991SDimitry Andricdef PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>;
1070b57cec5SDimitry Andricdef PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
1080b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1098bcb0991SDimitry Andricdef PPCldsplat : SDNode<"PPCISD::LD_SPLAT", SDT_PPCldsplat,
1108bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
111349cc55cSDimitry Andricdef PPCzextldsplat : SDNode<"PPCISD::ZEXT_LD_SPLAT", SDT_PPCldsplat,
112349cc55cSDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
113349cc55cSDimitry Andricdef PPCsextldsplat : SDNode<"PPCISD::SEXT_LD_SPLAT", SDT_PPCldsplat,
114349cc55cSDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1155ffd83dbSDimitry Andricdef PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED",
1165ffd83dbSDimitry Andric                     SDTypeProfile<1, 1, []>, []>;
1170b57cec5SDimitry Andric
118bdd1243dSDimitry Andricdef PPCxxperm : SDNode<"PPCISD::XXPERM", SDT_PPCxxperm, []>;
1195ffd83dbSDimitry Andric//-------------------------- Predicate definitions ---------------------------//
1205ffd83dbSDimitry Andricdef HasVSX : Predicate<"Subtarget->hasVSX()">;
1215ffd83dbSDimitry Andricdef IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">;
1225ffd83dbSDimitry Andricdef IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">;
123e8d8bef9SDimitry Andricdef IsPPC64 : Predicate<"Subtarget->isPPC64()">;
1245ffd83dbSDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">;
1255ffd83dbSDimitry Andricdef HasP8Vector : Predicate<"Subtarget->hasP8Vector()">;
1265ffd83dbSDimitry Andricdef HasDirectMove : Predicate<"Subtarget->hasDirectMove()">;
1275ffd83dbSDimitry Andricdef NoP9Vector : Predicate<"!Subtarget->hasP9Vector()">;
1285ffd83dbSDimitry Andricdef HasP9Vector : Predicate<"Subtarget->hasP9Vector()">;
1295ffd83dbSDimitry Andricdef NoP9Altivec : Predicate<"!Subtarget->hasP9Altivec()">;
130fe6060f1SDimitry Andricdef NoP10Vector: Predicate<"!Subtarget->hasP10Vector()">;
1315ffd83dbSDimitry Andric
1320eae32dcSDimitry Andricdef PPCldsplatAlign16 : PatFrag<(ops node:$ptr), (PPCldsplat node:$ptr), [{
1330eae32dcSDimitry Andric  return cast<MemIntrinsicSDNode>(N)->getAlign() >= Align(16) &&
1340eae32dcSDimitry Andric         isOffsetMultipleOf(N, 16);
1350eae32dcSDimitry Andric}]>;
1360eae32dcSDimitry Andric
1375ffd83dbSDimitry Andric//--------------------- VSX-specific instruction formats ---------------------//
1385ffd83dbSDimitry Andric// By default, all VSX instructions are to be selected over their Altivec
1395ffd83dbSDimitry Andric// counter parts and they do not have unmodeled sideeffects.
1405ffd83dbSDimitry Andriclet AddedComplexity = 400, hasSideEffects = 0 in {
1410b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
1420b57cec5SDimitry Andric                    string asmstr, InstrItinClass itin, Intrinsic Int,
1430b57cec5SDimitry Andric                    ValueType OutTy, ValueType InTy> {
1440b57cec5SDimitry Andric  let BaseName = asmbase in {
1450b57cec5SDimitry Andric    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1460b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
1470b57cec5SDimitry Andric                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
1480b57cec5SDimitry Andric    let Defs = [CR6] in
149480093f4SDimitry Andric    def _rec    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1500b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1510b57cec5SDimitry Andric                       [(set InTy:$XT,
152e8d8bef9SDimitry Andric                                (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>,
153480093f4SDimitry Andric                       isRecordForm;
1540b57cec5SDimitry Andric  }
1550b57cec5SDimitry Andric}
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as
1580b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained
1590b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained
1600b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though
1610b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction
1620b57cec5SDimitry Andric// to use the same register for both inputs.
1630b57cec5SDimitry Andric// For example, an output DAG such as this:
1640b57cec5SDimitry Andric//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
1650b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs
1660b57cec5SDimitry Andric// to the XXPERMDI instruction.
1670b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
1680b57cec5SDimitry Andric                 InstrItinClass itin, list<dag> pattern>
1690b57cec5SDimitry Andric  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
1700b57cec5SDimitry Andric    let XB = XA;
1710b57cec5SDimitry Andric}
1720b57cec5SDimitry Andric
1735ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
1745ffd83dbSDimitry Andricclass X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1755ffd83dbSDimitry Andric                    list<dag> pattern>
1765ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
1775ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1780b57cec5SDimitry Andric
1795ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
1805ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1815ffd83dbSDimitry Andric                       list<dag> pattern>
1825ffd83dbSDimitry Andric  : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm;
1835ffd83dbSDimitry Andric
1845ffd83dbSDimitry Andric// [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
1855ffd83dbSDimitry Andric// So we use different operand class for VRB
1865ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1875ffd83dbSDimitry Andric                         RegisterOperand vbtype, list<dag> pattern>
1885ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
1895ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1905ffd83dbSDimitry Andric
1915ffd83dbSDimitry Andric// [PO VRT XO VRB XO /]
1925ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1935ffd83dbSDimitry Andric                    list<dag> pattern>
1945ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
1955ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1965ffd83dbSDimitry Andric
1975ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
1985ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1995ffd83dbSDimitry Andric                       list<dag> pattern>
2005ffd83dbSDimitry Andric  : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm;
2015ffd83dbSDimitry Andric
2025ffd83dbSDimitry Andric// [PO T XO B XO BX /]
2035ffd83dbSDimitry Andricclass XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2045ffd83dbSDimitry Andric                      list<dag> pattern>
2055ffd83dbSDimitry Andric  : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2065ffd83dbSDimitry Andric                    !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2075ffd83dbSDimitry Andric
2085ffd83dbSDimitry Andric// [PO T XO B XO BX TX]
2095ffd83dbSDimitry Andricclass XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2105ffd83dbSDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
2115ffd83dbSDimitry Andric  : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2125ffd83dbSDimitry Andric                    !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2135ffd83dbSDimitry Andric
2145ffd83dbSDimitry Andric// [PO T A B XO AX BX TX], src and dest register use different operand class
2155ffd83dbSDimitry Andricclass XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2165ffd83dbSDimitry Andric                RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2175ffd83dbSDimitry Andric                InstrItinClass itin, list<dag> pattern>
2185ffd83dbSDimitry Andric  : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2195ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2205ffd83dbSDimitry Andric
2215ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
2225ffd83dbSDimitry Andricclass X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2235ffd83dbSDimitry Andric                    list<dag> pattern>
2245ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2255ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2265ffd83dbSDimitry Andric
2275ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2285ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2295ffd83dbSDimitry Andric                       list<dag> pattern>
2305ffd83dbSDimitry Andric  : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm;
2315ffd83dbSDimitry Andric
2325ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
2335ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
2345ffd83dbSDimitry Andric                        list<dag> pattern>
2355ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
2365ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
2375ffd83dbSDimitry Andric            RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
2385ffd83dbSDimitry Andric
2395ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2405ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
2415ffd83dbSDimitry Andric                        list<dag> pattern>
2425ffd83dbSDimitry Andric  : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm;
2435ffd83dbSDimitry Andric
2445ffd83dbSDimitry Andricclass Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2455ffd83dbSDimitry Andric                              list<dag> pattern>
2465ffd83dbSDimitry Andric  : Z23Form_8<opcode, xo,
2475ffd83dbSDimitry Andric              (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2485ffd83dbSDimitry Andric              !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2495ffd83dbSDimitry Andric  let RC = ex;
2505ffd83dbSDimitry Andric}
2515ffd83dbSDimitry Andric
2525ffd83dbSDimitry Andric// [PO BF // VRA VRB XO /]
2535ffd83dbSDimitry Andricclass X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2545ffd83dbSDimitry Andric                    list<dag> pattern>
2555ffd83dbSDimitry Andric  : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2565ffd83dbSDimitry Andric             !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2575ffd83dbSDimitry Andric  let Pattern = pattern;
2585ffd83dbSDimitry Andric}
2595ffd83dbSDimitry Andric
2605ffd83dbSDimitry Andric// [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2615ffd83dbSDimitry Andric// "out" and "in" dag
2625ffd83dbSDimitry Andricclass X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2635ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
2645ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2655ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
2665ffd83dbSDimitry Andric
2675ffd83dbSDimitry Andric// [PO S RA RB XO SX]
2685ffd83dbSDimitry Andricclass X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2695ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
2705ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2715ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
2725ffd83dbSDimitry Andric} // Predicates = HasP9Vector
2735ffd83dbSDimitry Andric} // AddedComplexity = 400, hasSideEffects = 0
2745ffd83dbSDimitry Andric
2755ffd83dbSDimitry Andricmulticlass ScalToVecWPermute<ValueType Ty, dag In, dag NonPermOut, dag PermOut> {
2765ffd83dbSDimitry Andric  def : Pat<(Ty (scalar_to_vector In)), (Ty NonPermOut)>;
2775ffd83dbSDimitry Andric  def : Pat<(Ty (PPCSToV In)), (Ty PermOut)>;
2785ffd83dbSDimitry Andric}
2795ffd83dbSDimitry Andric
2805ffd83dbSDimitry Andric//-------------------------- Instruction definitions -------------------------//
2815ffd83dbSDimitry Andric// VSX instructions require the VSX feature, they are to be selected over
2825ffd83dbSDimitry Andric// equivalent Altivec patterns (as they address a larger register set) and
2835ffd83dbSDimitry Andric// they do not have unmodeled side effects.
2845ffd83dbSDimitry Andriclet Predicates = [HasVSX], AddedComplexity = 400 in {
2855ffd83dbSDimitry Andriclet hasSideEffects = 0 in {
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric  // Load indexed instructions
2880b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
2890b57cec5SDimitry Andric    let CodeSize = 3 in
2900b57cec5SDimitry Andric    def LXSDX : XX1Form_memOp<31, 588,
2910b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
2920b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
2930b57cec5SDimitry Andric                        []>;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
2960b57cec5SDimitry Andric    let CodeSize = 3 in
2970b57cec5SDimitry Andric      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
2980b57cec5SDimitry Andric                              "#XFLOADf64",
299fe6060f1SDimitry Andric                              [(set f64:$XT, (load XForm:$src))]>;
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3020b57cec5SDimitry Andric    def LXVD2X : XX1Form_memOp<31, 844,
3030b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3040b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
305fe6060f1SDimitry Andric                         []>;
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric    def LXVDSX : XX1Form_memOp<31, 332,
3080b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3090b57cec5SDimitry Andric                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3120b57cec5SDimitry Andric    def LXVW4X : XX1Form_memOp<31, 780,
3130b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3140b57cec5SDimitry Andric                         "lxvw4x $XT, $src", IIC_LdStLFD,
3150b57cec5SDimitry Andric                         []>;
3160b57cec5SDimitry Andric  } // mayLoad
3170b57cec5SDimitry Andric
3180b57cec5SDimitry Andric  // Store indexed instructions
3190b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
3200b57cec5SDimitry Andric    let CodeSize = 3 in
3210b57cec5SDimitry Andric    def STXSDX : XX1Form_memOp<31, 716,
3220b57cec5SDimitry Andric                        (outs), (ins vsfrc:$XT, memrr:$dst),
3230b57cec5SDimitry Andric                        "stxsdx $XT, $dst", IIC_LdStSTFD,
3240b57cec5SDimitry Andric                        []>;
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
3270b57cec5SDimitry Andric    let CodeSize = 3 in
3280b57cec5SDimitry Andric      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
3290b57cec5SDimitry Andric                              "#XFSTOREf64",
330fe6060f1SDimitry Andric                              [(store f64:$XT, XForm:$dst)]>;
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3330b57cec5SDimitry Andric    // The behaviour of this instruction is endianness-specific so we provide no
3340b57cec5SDimitry Andric    // pattern to match it without considering endianness.
3350b57cec5SDimitry Andric    def STXVD2X : XX1Form_memOp<31, 972,
3360b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3370b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
3380b57cec5SDimitry Andric                         []>;
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andric    def STXVW4X : XX1Form_memOp<31, 908,
3410b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3420b57cec5SDimitry Andric                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
3430b57cec5SDimitry Andric                         []>;
3440b57cec5SDimitry Andric    }
3450b57cec5SDimitry Andric  } // mayStore
3460b57cec5SDimitry Andric
347e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
348e8d8bef9SDimitry Andric  let Uses = [RM] in {
3490b57cec5SDimitry Andric  // Add/Mul Instructions
3500b57cec5SDimitry Andric  let isCommutable = 1 in {
3510b57cec5SDimitry Andric    def XSADDDP : XX3Form<60, 32,
3520b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3530b57cec5SDimitry Andric                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
3545ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>;
3550b57cec5SDimitry Andric    def XSMULDP : XX3Form<60, 48,
3560b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3570b57cec5SDimitry Andric                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
3585ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>;
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andric    def XVADDDP : XX3Form<60, 96,
3610b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3620b57cec5SDimitry Andric                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
3635ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>;
3640b57cec5SDimitry Andric
3650b57cec5SDimitry Andric    def XVADDSP : XX3Form<60, 64,
3660b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3670b57cec5SDimitry Andric                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
3685ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>;
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andric    def XVMULDP : XX3Form<60, 112,
3710b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3720b57cec5SDimitry Andric                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
3735ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>;
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andric    def XVMULSP : XX3Form<60, 80,
3760b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3770b57cec5SDimitry Andric                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
3785ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>;
3790b57cec5SDimitry Andric  }
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric  // Subtract Instructions
3820b57cec5SDimitry Andric  def XSSUBDP : XX3Form<60, 40,
3830b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3840b57cec5SDimitry Andric                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
3855ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>;
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric  def XVSUBDP : XX3Form<60, 104,
3880b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3890b57cec5SDimitry Andric                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
3905ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>;
3910b57cec5SDimitry Andric  def XVSUBSP : XX3Form<60, 72,
3920b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3930b57cec5SDimitry Andric                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
3945ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>;
3950b57cec5SDimitry Andric
3960b57cec5SDimitry Andric  // FMA Instructions
3970b57cec5SDimitry Andric  let BaseName = "XSMADDADP" in {
3980b57cec5SDimitry Andric  let isCommutable = 1 in
3990b57cec5SDimitry Andric  def XSMADDADP : XX3Form<60, 33,
4000b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4010b57cec5SDimitry Andric                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
4025ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, f64:$XTi))]>,
4030b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4040b57cec5SDimitry Andric                          AltVSXFMARel;
4050b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4060b57cec5SDimitry Andric  def XSMADDMDP : XX3Form<60, 41,
4070b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4080b57cec5SDimitry Andric                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4090b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4100b57cec5SDimitry Andric                          AltVSXFMARel;
4110b57cec5SDimitry Andric  }
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric  let BaseName = "XSMSUBADP" in {
4140b57cec5SDimitry Andric  let isCommutable = 1 in
4150b57cec5SDimitry Andric  def XSMSUBADP : XX3Form<60, 49,
4160b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4170b57cec5SDimitry Andric                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
4185ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
4190b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4200b57cec5SDimitry Andric                          AltVSXFMARel;
4210b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4220b57cec5SDimitry Andric  def XSMSUBMDP : XX3Form<60, 57,
4230b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4240b57cec5SDimitry Andric                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4250b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4260b57cec5SDimitry Andric                          AltVSXFMARel;
4270b57cec5SDimitry Andric  }
4280b57cec5SDimitry Andric
4290b57cec5SDimitry Andric  let BaseName = "XSNMADDADP" in {
4300b57cec5SDimitry Andric  let isCommutable = 1 in
4310b57cec5SDimitry Andric  def XSNMADDADP : XX3Form<60, 161,
4320b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4330b57cec5SDimitry Andric                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
4345ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, f64:$XTi)))]>,
4350b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4360b57cec5SDimitry Andric                          AltVSXFMARel;
4370b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4380b57cec5SDimitry Andric  def XSNMADDMDP : XX3Form<60, 169,
4390b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4400b57cec5SDimitry Andric                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4410b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4420b57cec5SDimitry Andric                          AltVSXFMARel;
4430b57cec5SDimitry Andric  }
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric  let BaseName = "XSNMSUBADP" in {
4460b57cec5SDimitry Andric  let isCommutable = 1 in
4470b57cec5SDimitry Andric  def XSNMSUBADP : XX3Form<60, 177,
4480b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4490b57cec5SDimitry Andric                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
4505ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
4510b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4520b57cec5SDimitry Andric                          AltVSXFMARel;
4530b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4540b57cec5SDimitry Andric  def XSNMSUBMDP : XX3Form<60, 185,
4550b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4560b57cec5SDimitry Andric                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4570b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4580b57cec5SDimitry Andric                          AltVSXFMARel;
4590b57cec5SDimitry Andric  }
4600b57cec5SDimitry Andric
4610b57cec5SDimitry Andric  let BaseName = "XVMADDADP" in {
4620b57cec5SDimitry Andric  let isCommutable = 1 in
4630b57cec5SDimitry Andric  def XVMADDADP : XX3Form<60, 97,
4640b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4650b57cec5SDimitry Andric                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
4665ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
4670b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4680b57cec5SDimitry Andric                          AltVSXFMARel;
4690b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4700b57cec5SDimitry Andric  def XVMADDMDP : XX3Form<60, 105,
4710b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4720b57cec5SDimitry Andric                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4730b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4740b57cec5SDimitry Andric                          AltVSXFMARel;
4750b57cec5SDimitry Andric  }
4760b57cec5SDimitry Andric
4770b57cec5SDimitry Andric  let BaseName = "XVMADDASP" in {
4780b57cec5SDimitry Andric  let isCommutable = 1 in
4790b57cec5SDimitry Andric  def XVMADDASP : XX3Form<60, 65,
4800b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4810b57cec5SDimitry Andric                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
4825ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
4830b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4840b57cec5SDimitry Andric                          AltVSXFMARel;
4850b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4860b57cec5SDimitry Andric  def XVMADDMSP : XX3Form<60, 73,
4870b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4880b57cec5SDimitry Andric                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
4890b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4900b57cec5SDimitry Andric                          AltVSXFMARel;
4910b57cec5SDimitry Andric  }
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric  let BaseName = "XVMSUBADP" in {
4940b57cec5SDimitry Andric  let isCommutable = 1 in
4950b57cec5SDimitry Andric  def XVMSUBADP : XX3Form<60, 113,
4960b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4970b57cec5SDimitry Andric                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
4985ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
4990b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5000b57cec5SDimitry Andric                          AltVSXFMARel;
5010b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5020b57cec5SDimitry Andric  def XVMSUBMDP : XX3Form<60, 121,
5030b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5040b57cec5SDimitry Andric                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5050b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5060b57cec5SDimitry Andric                          AltVSXFMARel;
5070b57cec5SDimitry Andric  }
5080b57cec5SDimitry Andric
5090b57cec5SDimitry Andric  let BaseName = "XVMSUBASP" in {
5100b57cec5SDimitry Andric  let isCommutable = 1 in
5110b57cec5SDimitry Andric  def XVMSUBASP : XX3Form<60, 81,
5120b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5130b57cec5SDimitry Andric                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
5145ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
5150b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5160b57cec5SDimitry Andric                          AltVSXFMARel;
5170b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5180b57cec5SDimitry Andric  def XVMSUBMSP : XX3Form<60, 89,
5190b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5200b57cec5SDimitry Andric                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
5210b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5220b57cec5SDimitry Andric                          AltVSXFMARel;
5230b57cec5SDimitry Andric  }
5240b57cec5SDimitry Andric
5250b57cec5SDimitry Andric  let BaseName = "XVNMADDADP" in {
5260b57cec5SDimitry Andric  let isCommutable = 1 in
5270b57cec5SDimitry Andric  def XVNMADDADP : XX3Form<60, 225,
5280b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5290b57cec5SDimitry Andric                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
5305ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
5310b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5320b57cec5SDimitry Andric                          AltVSXFMARel;
5330b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5340b57cec5SDimitry Andric  def XVNMADDMDP : XX3Form<60, 233,
5350b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5360b57cec5SDimitry Andric                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
5370b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5380b57cec5SDimitry Andric                          AltVSXFMARel;
5390b57cec5SDimitry Andric  }
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric  let BaseName = "XVNMADDASP" in {
5420b57cec5SDimitry Andric  let isCommutable = 1 in
5430b57cec5SDimitry Andric  def XVNMADDASP : XX3Form<60, 193,
5440b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5450b57cec5SDimitry Andric                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
5460b57cec5SDimitry Andric                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
5470b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5480b57cec5SDimitry Andric                          AltVSXFMARel;
5490b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5500b57cec5SDimitry Andric  def XVNMADDMSP : XX3Form<60, 201,
5510b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5520b57cec5SDimitry Andric                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5530b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5540b57cec5SDimitry Andric                          AltVSXFMARel;
5550b57cec5SDimitry Andric  }
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric  let BaseName = "XVNMSUBADP" in {
5580b57cec5SDimitry Andric  let isCommutable = 1 in
5590b57cec5SDimitry Andric  def XVNMSUBADP : XX3Form<60, 241,
5600b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5610b57cec5SDimitry Andric                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
5625ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
5630b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5640b57cec5SDimitry Andric                          AltVSXFMARel;
5650b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5660b57cec5SDimitry Andric  def XVNMSUBMDP : XX3Form<60, 249,
5670b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5680b57cec5SDimitry Andric                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5690b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5700b57cec5SDimitry Andric                          AltVSXFMARel;
5710b57cec5SDimitry Andric  }
5720b57cec5SDimitry Andric
5730b57cec5SDimitry Andric  let BaseName = "XVNMSUBASP" in {
5740b57cec5SDimitry Andric  let isCommutable = 1 in
5750b57cec5SDimitry Andric  def XVNMSUBASP : XX3Form<60, 209,
5760b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5770b57cec5SDimitry Andric                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
5785ffd83dbSDimitry Andric                          [(set v4f32:$XT, (fneg (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
5790b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5800b57cec5SDimitry Andric                          AltVSXFMARel;
5810b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5820b57cec5SDimitry Andric  def XVNMSUBMSP : XX3Form<60, 217,
5830b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5840b57cec5SDimitry Andric                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
5850b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5860b57cec5SDimitry Andric                          AltVSXFMARel;
5870b57cec5SDimitry Andric  }
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric  // Division Instructions
5900b57cec5SDimitry Andric  def XSDIVDP : XX3Form<60, 56,
5910b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
5920b57cec5SDimitry Andric                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
5935ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>;
5940b57cec5SDimitry Andric  def XSSQRTDP : XX2Form<60, 75,
5950b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
5960b57cec5SDimitry Andric                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
5975ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsqrt f64:$XB))]>;
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andric  def XSREDP : XX2Form<60, 90,
6000b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6010b57cec5SDimitry Andric                        "xsredp $XT, $XB", IIC_VecFP,
6020b57cec5SDimitry Andric                        [(set f64:$XT, (PPCfre f64:$XB))]>;
6030b57cec5SDimitry Andric  def XSRSQRTEDP : XX2Form<60, 74,
6040b57cec5SDimitry Andric                           (outs vsfrc:$XT), (ins vsfrc:$XB),
6050b57cec5SDimitry Andric                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
6060b57cec5SDimitry Andric                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
6070b57cec5SDimitry Andric
608e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
6090b57cec5SDimitry Andric  def XSTDIVDP : XX3Form_1<60, 61,
6100b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6110b57cec5SDimitry Andric                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
6120b57cec5SDimitry Andric  def XSTSQRTDP : XX2Form_1<60, 106,
6130b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsfrc:$XB),
614e8d8bef9SDimitry Andric                          "xstsqrtdp $crD, $XB", IIC_FPCompare,
615e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt f64:$XB))]>;
616e8d8bef9SDimitry Andric  def XVTDIVDP : XX3Form_1<60, 125,
617e8d8bef9SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
618e8d8bef9SDimitry Andric                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
619e8d8bef9SDimitry Andric  def XVTDIVSP : XX3Form_1<60, 93,
620e8d8bef9SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
621e8d8bef9SDimitry Andric                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
622e8d8bef9SDimitry Andric
623e8d8bef9SDimitry Andric  def XVTSQRTDP : XX2Form_1<60, 234,
624e8d8bef9SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
625e8d8bef9SDimitry Andric                          "xvtsqrtdp $crD, $XB", IIC_FPCompare,
626e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt v2f64:$XB))]>;
627e8d8bef9SDimitry Andric  def XVTSQRTSP : XX2Form_1<60, 170,
628e8d8bef9SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
629e8d8bef9SDimitry Andric                          "xvtsqrtsp $crD, $XB", IIC_FPCompare,
630e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt v4f32:$XB))]>;
631e8d8bef9SDimitry Andric  }
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andric  def XVDIVDP : XX3Form<60, 120,
6340b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6350b57cec5SDimitry Andric                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
6365ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>;
6370b57cec5SDimitry Andric  def XVDIVSP : XX3Form<60, 88,
6380b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6390b57cec5SDimitry Andric                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
6405ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>;
6410b57cec5SDimitry Andric
6420b57cec5SDimitry Andric  def XVSQRTDP : XX2Form<60, 203,
6430b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6440b57cec5SDimitry Andric                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
6455ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsqrt v2f64:$XB))]>;
6460b57cec5SDimitry Andric  def XVSQRTSP : XX2Form<60, 139,
6470b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6480b57cec5SDimitry Andric                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
6495ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsqrt v4f32:$XB))]>;
6500b57cec5SDimitry Andric
6510b57cec5SDimitry Andric  def XVREDP : XX2Form<60, 218,
6520b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6530b57cec5SDimitry Andric                        "xvredp $XT, $XB", IIC_VecFP,
6540b57cec5SDimitry Andric                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
6550b57cec5SDimitry Andric  def XVRESP : XX2Form<60, 154,
6560b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6570b57cec5SDimitry Andric                        "xvresp $XT, $XB", IIC_VecFP,
6580b57cec5SDimitry Andric                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andric  def XVRSQRTEDP : XX2Form<60, 202,
6610b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6620b57cec5SDimitry Andric                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
6630b57cec5SDimitry Andric                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
6640b57cec5SDimitry Andric  def XVRSQRTESP : XX2Form<60, 138,
6650b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6660b57cec5SDimitry Andric                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
6670b57cec5SDimitry Andric                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
6680b57cec5SDimitry Andric
6690b57cec5SDimitry Andric  // Compare Instructions
6700b57cec5SDimitry Andric  def XSCMPODP : XX3Form_1<60, 43,
6710b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6720b57cec5SDimitry Andric                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
6730b57cec5SDimitry Andric  def XSCMPUDP : XX3Form_1<60, 35,
6740b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6750b57cec5SDimitry Andric                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andric  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
6780b57cec5SDimitry Andric                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
6790b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
6800b57cec5SDimitry Andric  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
6810b57cec5SDimitry Andric                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
6820b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
6830b57cec5SDimitry Andric  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
6840b57cec5SDimitry Andric                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
6850b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
6860b57cec5SDimitry Andric  defm XVCMPGESP : XX3Form_Rcr<60, 83,
6870b57cec5SDimitry Andric                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
6880b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
6890b57cec5SDimitry Andric  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
6900b57cec5SDimitry Andric                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
6910b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
6920b57cec5SDimitry Andric  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
6930b57cec5SDimitry Andric                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
6940b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric  // Move Instructions
697e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
6980b57cec5SDimitry Andric  def XSABSDP : XX2Form<60, 345,
6990b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7000b57cec5SDimitry Andric                      "xsabsdp $XT, $XB", IIC_VecFP,
7010b57cec5SDimitry Andric                      [(set f64:$XT, (fabs f64:$XB))]>;
7020b57cec5SDimitry Andric  def XSNABSDP : XX2Form<60, 361,
7030b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7040b57cec5SDimitry Andric                      "xsnabsdp $XT, $XB", IIC_VecFP,
7050b57cec5SDimitry Andric                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
70681ad6265SDimitry Andric  let isCodeGenOnly = 1 in
70781ad6265SDimitry Andric  def XSNABSDPs : XX2Form<60, 361,
70881ad6265SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
70981ad6265SDimitry Andric                      "xsnabsdp $XT, $XB", IIC_VecFP,
71081ad6265SDimitry Andric                      [(set f32:$XT, (fneg (fabs f32:$XB)))]>;
7110b57cec5SDimitry Andric  def XSNEGDP : XX2Form<60, 377,
7120b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7130b57cec5SDimitry Andric                      "xsnegdp $XT, $XB", IIC_VecFP,
7140b57cec5SDimitry Andric                      [(set f64:$XT, (fneg f64:$XB))]>;
7150b57cec5SDimitry Andric  def XSCPSGNDP : XX3Form<60, 176,
7160b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
7170b57cec5SDimitry Andric                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
7180b57cec5SDimitry Andric                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
7190b57cec5SDimitry Andric
7200b57cec5SDimitry Andric  def XVABSDP : XX2Form<60, 473,
7210b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7220b57cec5SDimitry Andric                      "xvabsdp $XT, $XB", IIC_VecFP,
7230b57cec5SDimitry Andric                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
7240b57cec5SDimitry Andric
7250b57cec5SDimitry Andric  def XVABSSP : XX2Form<60, 409,
7260b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7270b57cec5SDimitry Andric                      "xvabssp $XT, $XB", IIC_VecFP,
7280b57cec5SDimitry Andric                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
7290b57cec5SDimitry Andric
7300b57cec5SDimitry Andric  def XVCPSGNDP : XX3Form<60, 240,
7310b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7320b57cec5SDimitry Andric                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
7330b57cec5SDimitry Andric                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
7340b57cec5SDimitry Andric  def XVCPSGNSP : XX3Form<60, 208,
7350b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7360b57cec5SDimitry Andric                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
7370b57cec5SDimitry Andric                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric  def XVNABSDP : XX2Form<60, 489,
7400b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7410b57cec5SDimitry Andric                      "xvnabsdp $XT, $XB", IIC_VecFP,
7420b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
7430b57cec5SDimitry Andric  def XVNABSSP : XX2Form<60, 425,
7440b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7450b57cec5SDimitry Andric                      "xvnabssp $XT, $XB", IIC_VecFP,
7460b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
7470b57cec5SDimitry Andric
7480b57cec5SDimitry Andric  def XVNEGDP : XX2Form<60, 505,
7490b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7500b57cec5SDimitry Andric                      "xvnegdp $XT, $XB", IIC_VecFP,
7510b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
7520b57cec5SDimitry Andric  def XVNEGSP : XX2Form<60, 441,
7530b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7540b57cec5SDimitry Andric                      "xvnegsp $XT, $XB", IIC_VecFP,
7550b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
756e8d8bef9SDimitry Andric  }
7570b57cec5SDimitry Andric
7580b57cec5SDimitry Andric  // Conversion Instructions
7590b57cec5SDimitry Andric  def XSCVDPSP : XX2Form<60, 265,
7600b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7610b57cec5SDimitry Andric                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
7620b57cec5SDimitry Andric  def XSCVDPSXDS : XX2Form<60, 344,
7630b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7640b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
765e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctidz f64:$XB))]>;
7660b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7670b57cec5SDimitry Andric  def XSCVDPSXDSs : XX2Form<60, 344,
7680b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7690b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
770e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctidz f32:$XB))]>;
7710b57cec5SDimitry Andric  def XSCVDPSXWS : XX2Form<60, 88,
7720b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7730b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
774e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>;
7750b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7760b57cec5SDimitry Andric  def XSCVDPSXWSs : XX2Form<60, 88,
7770b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7780b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
779e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>;
7800b57cec5SDimitry Andric  def XSCVDPUXDS : XX2Form<60, 328,
7810b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7820b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
783e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>;
7840b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7850b57cec5SDimitry Andric  def XSCVDPUXDSs : XX2Form<60, 328,
7860b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7870b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
788e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>;
7890b57cec5SDimitry Andric  def XSCVDPUXWS : XX2Form<60, 72,
7900b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7910b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
792e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>;
7930b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7940b57cec5SDimitry Andric  def XSCVDPUXWSs : XX2Form<60, 72,
7950b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7960b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
797e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>;
7980b57cec5SDimitry Andric  def XSCVSPDP : XX2Form<60, 329,
7990b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8000b57cec5SDimitry Andric                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
8010b57cec5SDimitry Andric  def XSCVSXDDP : XX2Form<60, 376,
8020b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8030b57cec5SDimitry Andric                      "xscvsxddp $XT, $XB", IIC_VecFP,
804e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fcfid f64:$XB))]>;
8050b57cec5SDimitry Andric  def XSCVUXDDP : XX2Form<60, 360,
8060b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8070b57cec5SDimitry Andric                      "xscvuxddp $XT, $XB", IIC_VecFP,
808e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>;
8090b57cec5SDimitry Andric
8100b57cec5SDimitry Andric  def XVCVDPSP : XX2Form<60, 393,
8110b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8120b57cec5SDimitry Andric                      "xvcvdpsp $XT, $XB", IIC_VecFP,
8130b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
8140b57cec5SDimitry Andric  def XVCVDPSXDS : XX2Form<60, 472,
8150b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8160b57cec5SDimitry Andric                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
817e8d8bef9SDimitry Andric                      [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>;
8180b57cec5SDimitry Andric  def XVCVDPSXWS : XX2Form<60, 216,
8190b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8200b57cec5SDimitry Andric                      "xvcvdpsxws $XT, $XB", IIC_VecFP,
8210b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
8220b57cec5SDimitry Andric  def XVCVDPUXDS : XX2Form<60, 456,
8230b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8240b57cec5SDimitry Andric                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
825e8d8bef9SDimitry Andric                      [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>;
8260b57cec5SDimitry Andric  def XVCVDPUXWS : XX2Form<60, 200,
8270b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8280b57cec5SDimitry Andric                      "xvcvdpuxws $XT, $XB", IIC_VecFP,
8290b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric  def XVCVSPDP : XX2Form<60, 457,
8320b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8330b57cec5SDimitry Andric                      "xvcvspdp $XT, $XB", IIC_VecFP,
8340b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
8350b57cec5SDimitry Andric  def XVCVSPSXDS : XX2Form<60, 408,
8360b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
837fe6060f1SDimitry Andric                      "xvcvspsxds $XT, $XB", IIC_VecFP,
838fe6060f1SDimitry Andric                      [(set v2i64:$XT, (int_ppc_vsx_xvcvspsxds v4f32:$XB))]>;
8390b57cec5SDimitry Andric  def XVCVSPSXWS : XX2Form<60, 152,
8400b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8410b57cec5SDimitry Andric                      "xvcvspsxws $XT, $XB", IIC_VecFP,
842e8d8bef9SDimitry Andric                      [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>;
8430b57cec5SDimitry Andric  def XVCVSPUXDS : XX2Form<60, 392,
8440b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
845fe6060f1SDimitry Andric                      "xvcvspuxds $XT, $XB", IIC_VecFP,
846fe6060f1SDimitry Andric                      [(set v2i64:$XT, (int_ppc_vsx_xvcvspuxds v4f32:$XB))]>;
8470b57cec5SDimitry Andric  def XVCVSPUXWS : XX2Form<60, 136,
8480b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8490b57cec5SDimitry Andric                      "xvcvspuxws $XT, $XB", IIC_VecFP,
850e8d8bef9SDimitry Andric                      [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>;
8510b57cec5SDimitry Andric  def XVCVSXDDP : XX2Form<60, 504,
8520b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8530b57cec5SDimitry Andric                      "xvcvsxddp $XT, $XB", IIC_VecFP,
854e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>;
8550b57cec5SDimitry Andric  def XVCVSXDSP : XX2Form<60, 440,
8560b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8570b57cec5SDimitry Andric                      "xvcvsxdsp $XT, $XB", IIC_VecFP,
8580b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
8590b57cec5SDimitry Andric  def XVCVSXWSP : XX2Form<60, 184,
8600b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8610b57cec5SDimitry Andric                      "xvcvsxwsp $XT, $XB", IIC_VecFP,
862e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>;
8630b57cec5SDimitry Andric  def XVCVUXDDP : XX2Form<60, 488,
8640b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8650b57cec5SDimitry Andric                      "xvcvuxddp $XT, $XB", IIC_VecFP,
866e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>;
8670b57cec5SDimitry Andric  def XVCVUXDSP : XX2Form<60, 424,
8680b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8690b57cec5SDimitry Andric                      "xvcvuxdsp $XT, $XB", IIC_VecFP,
8700b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
871e8d8bef9SDimitry Andric  def XVCVUXWSP : XX2Form<60, 168,
872e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
873e8d8bef9SDimitry Andric                      "xvcvuxwsp $XT, $XB", IIC_VecFP,
874e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>;
875e8d8bef9SDimitry Andric
876e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
877e8d8bef9SDimitry Andric  def XVCVSXWDP : XX2Form<60, 248,
878e8d8bef9SDimitry Andric                    (outs vsrc:$XT), (ins vsrc:$XB),
879e8d8bef9SDimitry Andric                    "xvcvsxwdp $XT, $XB", IIC_VecFP,
880e8d8bef9SDimitry Andric                    [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
8810b57cec5SDimitry Andric  def XVCVUXWDP : XX2Form<60, 232,
8820b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8830b57cec5SDimitry Andric                      "xvcvuxwdp $XT, $XB", IIC_VecFP,
8840b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
885e8d8bef9SDimitry Andric  }
8860b57cec5SDimitry Andric
887e8d8bef9SDimitry Andric  // Rounding Instructions respecting current rounding mode
8880b57cec5SDimitry Andric  def XSRDPIC : XX2Form<60, 107,
8890b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
890349cc55cSDimitry Andric                      "xsrdpic $XT, $XB", IIC_VecFP, []>;
8910b57cec5SDimitry Andric  def XVRDPIC : XX2Form<60, 235,
8920b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
893349cc55cSDimitry Andric                      "xvrdpic $XT, $XB", IIC_VecFP, []>;
8940b57cec5SDimitry Andric  def XVRSPIC : XX2Form<60, 171,
8950b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
896349cc55cSDimitry Andric                      "xvrspic $XT, $XB", IIC_VecFP, []>;
8970b57cec5SDimitry Andric  // Max/Min Instructions
8980b57cec5SDimitry Andric  let isCommutable = 1 in {
8990b57cec5SDimitry Andric  def XSMAXDP : XX3Form<60, 160,
9000b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9010b57cec5SDimitry Andric                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
9020b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9030b57cec5SDimitry Andric                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
9040b57cec5SDimitry Andric  def XSMINDP : XX3Form<60, 168,
9050b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9060b57cec5SDimitry Andric                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
9070b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9080b57cec5SDimitry Andric                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andric  def XVMAXDP : XX3Form<60, 224,
9110b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9120b57cec5SDimitry Andric                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
9130b57cec5SDimitry Andric                        [(set vsrc:$XT,
9140b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
9150b57cec5SDimitry Andric  def XVMINDP : XX3Form<60, 232,
9160b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9170b57cec5SDimitry Andric                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
9180b57cec5SDimitry Andric                        [(set vsrc:$XT,
9190b57cec5SDimitry Andric                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andric  def XVMAXSP : XX3Form<60, 192,
9220b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9230b57cec5SDimitry Andric                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
9240b57cec5SDimitry Andric                        [(set vsrc:$XT,
9250b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
9260b57cec5SDimitry Andric  def XVMINSP : XX3Form<60, 200,
9270b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9280b57cec5SDimitry Andric                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
9290b57cec5SDimitry Andric                        [(set vsrc:$XT,
9300b57cec5SDimitry Andric                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
9310b57cec5SDimitry Andric  } // isCommutable
932e8d8bef9SDimitry Andric  } // Uses = [RM]
933e8d8bef9SDimitry Andric
934e8d8bef9SDimitry Andric  // Rounding Instructions with static direction.
935e8d8bef9SDimitry Andric  def XSRDPI : XX2Form<60, 73,
936e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
937e8d8bef9SDimitry Andric                      "xsrdpi $XT, $XB", IIC_VecFP,
938e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_fround f64:$XB))]>;
939e8d8bef9SDimitry Andric  def XSRDPIM : XX2Form<60, 121,
940e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
941e8d8bef9SDimitry Andric                      "xsrdpim $XT, $XB", IIC_VecFP,
942e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_ffloor f64:$XB))]>;
943e8d8bef9SDimitry Andric  def XSRDPIP : XX2Form<60, 105,
944e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
945e8d8bef9SDimitry Andric                      "xsrdpip $XT, $XB", IIC_VecFP,
946e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_fceil f64:$XB))]>;
947e8d8bef9SDimitry Andric  def XSRDPIZ : XX2Form<60, 89,
948e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
949e8d8bef9SDimitry Andric                      "xsrdpiz $XT, $XB", IIC_VecFP,
950e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_ftrunc f64:$XB))]>;
951e8d8bef9SDimitry Andric
952e8d8bef9SDimitry Andric  def XVRDPI : XX2Form<60, 201,
953e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
954e8d8bef9SDimitry Andric                      "xvrdpi $XT, $XB", IIC_VecFP,
955e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_fround v2f64:$XB))]>;
956e8d8bef9SDimitry Andric  def XVRDPIM : XX2Form<60, 249,
957e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
958e8d8bef9SDimitry Andric                      "xvrdpim $XT, $XB", IIC_VecFP,
959e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
960e8d8bef9SDimitry Andric  def XVRDPIP : XX2Form<60, 233,
961e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
962e8d8bef9SDimitry Andric                      "xvrdpip $XT, $XB", IIC_VecFP,
963e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
964e8d8bef9SDimitry Andric  def XVRDPIZ : XX2Form<60, 217,
965e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
966e8d8bef9SDimitry Andric                      "xvrdpiz $XT, $XB", IIC_VecFP,
967e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
968e8d8bef9SDimitry Andric
969e8d8bef9SDimitry Andric  def XVRSPI : XX2Form<60, 137,
970e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
971e8d8bef9SDimitry Andric                      "xvrspi $XT, $XB", IIC_VecFP,
972e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_fround v4f32:$XB))]>;
973e8d8bef9SDimitry Andric  def XVRSPIM : XX2Form<60, 185,
974e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
975e8d8bef9SDimitry Andric                      "xvrspim $XT, $XB", IIC_VecFP,
976e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
977e8d8bef9SDimitry Andric  def XVRSPIP : XX2Form<60, 169,
978e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
979e8d8bef9SDimitry Andric                      "xvrspip $XT, $XB", IIC_VecFP,
980e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
981e8d8bef9SDimitry Andric  def XVRSPIZ : XX2Form<60, 153,
982e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
983e8d8bef9SDimitry Andric                      "xvrspiz $XT, $XB", IIC_VecFP,
984e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
985e8d8bef9SDimitry Andric  } // mayRaiseFPException
9860b57cec5SDimitry Andric
9870b57cec5SDimitry Andric  // Logical Instructions
9880b57cec5SDimitry Andric  let isCommutable = 1 in
9890b57cec5SDimitry Andric  def XXLAND : XX3Form<60, 130,
9900b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9910b57cec5SDimitry Andric                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
9920b57cec5SDimitry Andric                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
9930b57cec5SDimitry Andric  def XXLANDC : XX3Form<60, 138,
9940b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9950b57cec5SDimitry Andric                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
9960b57cec5SDimitry Andric                        [(set v4i32:$XT, (and v4i32:$XA,
997fe6060f1SDimitry Andric                                              (vnot v4i32:$XB)))]>;
9980b57cec5SDimitry Andric  let isCommutable = 1 in {
9990b57cec5SDimitry Andric  def XXLNOR : XX3Form<60, 162,
10000b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10010b57cec5SDimitry Andric                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
1002fe6060f1SDimitry Andric                       [(set v4i32:$XT, (vnot (or v4i32:$XA,
10030b57cec5SDimitry Andric                                               v4i32:$XB)))]>;
10040b57cec5SDimitry Andric  def XXLOR : XX3Form<60, 146,
10050b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10060b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
10070b57cec5SDimitry Andric                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
10080b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10090b57cec5SDimitry Andric  def XXLORf: XX3Form<60, 146,
10100b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
10110b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
10120b57cec5SDimitry Andric  def XXLXOR : XX3Form<60, 154,
10130b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10140b57cec5SDimitry Andric                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
10150b57cec5SDimitry Andric                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
10160b57cec5SDimitry Andric  } // isCommutable
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
10190b57cec5SDimitry Andric      isReMaterializable = 1 in {
10208bcb0991SDimitry Andric    def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
10210b57cec5SDimitry Andric                       "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10220b57cec5SDimitry Andric                       [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
10238bcb0991SDimitry Andric    def XXLXORdpz : XX3Form_SameOp<60, 154,
10240b57cec5SDimitry Andric                         (outs vsfrc:$XT), (ins),
10250b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10260b57cec5SDimitry Andric                         [(set f64:$XT, (fpimm0))]>;
10278bcb0991SDimitry Andric    def XXLXORspz : XX3Form_SameOp<60, 154,
10280b57cec5SDimitry Andric                         (outs vssrc:$XT), (ins),
10290b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10300b57cec5SDimitry Andric                         [(set f32:$XT, (fpimm0))]>;
10310b57cec5SDimitry Andric  }
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andric  // Permutation Instructions
10340b57cec5SDimitry Andric  def XXMRGHW : XX3Form<60, 18,
10350b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10360b57cec5SDimitry Andric                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
10370b57cec5SDimitry Andric  def XXMRGLW : XX3Form<60, 50,
10380b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10390b57cec5SDimitry Andric                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
10400b57cec5SDimitry Andric
10410b57cec5SDimitry Andric  def XXPERMDI : XX3Form_2<60, 10,
10420b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
10430b57cec5SDimitry Andric                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
10440b57cec5SDimitry Andric                       [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
10450b57cec5SDimitry Andric                         imm32SExt16:$DM))]>;
10460b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
1047349cc55cSDimitry Andric  // Note that the input register class for `$XA` of XXPERMDIs is `vsfrc` which
1048349cc55cSDimitry Andric  // is not the same with the input register class(`vsrc`) of XXPERMDI instruction.
1049349cc55cSDimitry Andric  // We did this on purpose because:
1050349cc55cSDimitry Andric  // 1: The input is primarily for loads that load a partial vector(LFIWZX,
1051349cc55cSDimitry Andric  //    etc.), no need for SUBREG_TO_REG.
1052349cc55cSDimitry Andric  // 2: With `vsfrc` register class, in the final assembly, float registers
1053349cc55cSDimitry Andric  //    like `f0` are used instead of vector scalar register like `vs0`. This
1054349cc55cSDimitry Andric  //    helps readability.
10550b57cec5SDimitry Andric  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
10560b57cec5SDimitry Andric                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
10570b57cec5SDimitry Andric  def XXSEL : XX4Form<60, 3,
10580b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
10590b57cec5SDimitry Andric                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andric  def XXSLDWI : XX3Form_2<60, 2,
10620b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
10630b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
10640b57cec5SDimitry Andric                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
10650b57cec5SDimitry Andric                                                  imm32SExt16:$SHW))]>;
10660b57cec5SDimitry Andric
10670b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10680b57cec5SDimitry Andric  def XXSLDWIs : XX3Form_2s<60, 2,
10690b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
10700b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
10710b57cec5SDimitry Andric
10720b57cec5SDimitry Andric  def XXSPLTW : XX2Form_2<60, 164,
10730b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
10740b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
10750b57cec5SDimitry Andric                       [(set v4i32:$XT,
10760b57cec5SDimitry Andric                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
10770b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10780b57cec5SDimitry Andric  def XXSPLTWs : XX2Form_2<60, 164,
10790b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
10800b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
10810b57cec5SDimitry Andric
10825ffd83dbSDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07
10835ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
10845ffd83dbSDimitry Andric  let isCommutable = 1 in {
10855ffd83dbSDimitry Andric    def XXLEQV : XX3Form<60, 186,
10865ffd83dbSDimitry Andric                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10875ffd83dbSDimitry Andric                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1088fe6060f1SDimitry Andric                         [(set v4i32:$XT, (vnot (xor v4i32:$XA, v4i32:$XB)))]>;
10895ffd83dbSDimitry Andric    def XXLNAND : XX3Form<60, 178,
10905ffd83dbSDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10915ffd83dbSDimitry Andric                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1092fe6060f1SDimitry Andric                          [(set v4i32:$XT, (vnot (and v4i32:$XA, v4i32:$XB)))]>;
10935ffd83dbSDimitry Andric  } // isCommutable
10940b57cec5SDimitry Andric
10955ffd83dbSDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
10965ffd83dbSDimitry Andric      isReMaterializable = 1 in {
10975ffd83dbSDimitry Andric    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
10985ffd83dbSDimitry Andric                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
10995ffd83dbSDimitry Andric                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
11005ffd83dbSDimitry Andric  }
11015ffd83dbSDimitry Andric
11025ffd83dbSDimitry Andric  def XXLORC : XX3Form<60, 170,
11035ffd83dbSDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
11045ffd83dbSDimitry Andric                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1105fe6060f1SDimitry Andric                       [(set v4i32:$XT, (or v4i32:$XA, (vnot v4i32:$XB)))]>;
11065ffd83dbSDimitry Andric
11075ffd83dbSDimitry Andric  // VSX scalar loads introduced in ISA 2.07
11085ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
11095ffd83dbSDimitry Andric    let CodeSize = 3 in
11105ffd83dbSDimitry Andric    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
11115ffd83dbSDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
11125ffd83dbSDimitry Andric    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
11135ffd83dbSDimitry Andric                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
11145ffd83dbSDimitry Andric    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
11155ffd83dbSDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
11165ffd83dbSDimitry Andric
11175ffd83dbSDimitry Andric    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
11185ffd83dbSDimitry Andric    let CodeSize = 3 in
11195ffd83dbSDimitry Andric    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
11205ffd83dbSDimitry Andric                            "#XFLOADf32",
1121fe6060f1SDimitry Andric                            [(set f32:$XT, (load XForm:$src))]>;
11225ffd83dbSDimitry Andric    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
11235ffd83dbSDimitry Andric    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
11245ffd83dbSDimitry Andric                       "#LIWAX",
1125fe6060f1SDimitry Andric                       [(set f64:$XT, (PPClfiwax ForceXForm:$src))]>;
11265ffd83dbSDimitry Andric    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
11275ffd83dbSDimitry Andric    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
11285ffd83dbSDimitry Andric                       "#LIWZX",
1129fe6060f1SDimitry Andric                       [(set f64:$XT, (PPClfiwzx ForceXForm:$src))]>;
11305ffd83dbSDimitry Andric  } // mayLoad
11315ffd83dbSDimitry Andric
11325ffd83dbSDimitry Andric  // VSX scalar stores introduced in ISA 2.07
11335ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
11345ffd83dbSDimitry Andric    let CodeSize = 3 in
11355ffd83dbSDimitry Andric    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
11365ffd83dbSDimitry Andric                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
11375ffd83dbSDimitry Andric    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
11385ffd83dbSDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
11395ffd83dbSDimitry Andric
11405ffd83dbSDimitry Andric    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
11415ffd83dbSDimitry Andric    let CodeSize = 3 in
11425ffd83dbSDimitry Andric    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
11435ffd83dbSDimitry Andric                            "#XFSTOREf32",
1144fe6060f1SDimitry Andric                            [(store f32:$XT, XForm:$dst)]>;
11455ffd83dbSDimitry Andric    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
11465ffd83dbSDimitry Andric    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
11475ffd83dbSDimitry Andric                       "#STIWX",
1148fe6060f1SDimitry Andric                      [(PPCstfiwx f64:$XT, ForceXForm:$dst)]>;
11495ffd83dbSDimitry Andric  } // mayStore
11505ffd83dbSDimitry Andric
11515ffd83dbSDimitry Andric  // VSX Elementary Scalar FP arithmetic (SP)
11525ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
11535ffd83dbSDimitry Andric  let isCommutable = 1 in {
11545ffd83dbSDimitry Andric    def XSADDSP : XX3Form<60, 0,
11555ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11565ffd83dbSDimitry Andric                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
11575ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>;
11585ffd83dbSDimitry Andric    def XSMULSP : XX3Form<60, 16,
11595ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11605ffd83dbSDimitry Andric                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
11615ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>;
11625ffd83dbSDimitry Andric  } // isCommutable
11635ffd83dbSDimitry Andric
11645ffd83dbSDimitry Andric  def XSSUBSP : XX3Form<60, 8,
11655ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11665ffd83dbSDimitry Andric                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
11675ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>;
11685ffd83dbSDimitry Andric  def XSDIVSP : XX3Form<60, 24,
11695ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11705ffd83dbSDimitry Andric                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
11715ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>;
11725ffd83dbSDimitry Andric
11735ffd83dbSDimitry Andric  def XSRESP : XX2Form<60, 26,
11745ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
11755ffd83dbSDimitry Andric                        "xsresp $XT, $XB", IIC_VecFP,
11765ffd83dbSDimitry Andric                        [(set f32:$XT, (PPCfre f32:$XB))]>;
11775ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1178e8d8bef9SDimitry Andric  let hasSideEffects = 1 in
11795ffd83dbSDimitry Andric  def XSRSP : XX2Form<60, 281,
11805ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vsfrc:$XB),
11815ffd83dbSDimitry Andric                        "xsrsp $XT, $XB", IIC_VecFP,
11825ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fpround f64:$XB))]>;
11835ffd83dbSDimitry Andric  def XSSQRTSP : XX2Form<60, 11,
11845ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
11855ffd83dbSDimitry Andric                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
11865ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsqrt f32:$XB))]>;
11875ffd83dbSDimitry Andric  def XSRSQRTESP : XX2Form<60, 10,
11885ffd83dbSDimitry Andric                           (outs vssrc:$XT), (ins vssrc:$XB),
11895ffd83dbSDimitry Andric                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
11905ffd83dbSDimitry Andric                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
11915ffd83dbSDimitry Andric
11925ffd83dbSDimitry Andric  // FMA Instructions
11935ffd83dbSDimitry Andric  let BaseName = "XSMADDASP" in {
11945ffd83dbSDimitry Andric  let isCommutable = 1 in
11955ffd83dbSDimitry Andric  def XSMADDASP : XX3Form<60, 1,
11965ffd83dbSDimitry Andric                          (outs vssrc:$XT),
11975ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
11985ffd83dbSDimitry Andric                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
11995ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB, f32:$XTi))]>,
12005ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12015ffd83dbSDimitry Andric                          AltVSXFMARel;
12025ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12035ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12045ffd83dbSDimitry Andric  def XSMADDMSP : XX3Form<60, 9,
12055ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12065ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12075ffd83dbSDimitry Andric                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
12085ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12095ffd83dbSDimitry Andric                          AltVSXFMARel;
12105ffd83dbSDimitry Andric  }
12115ffd83dbSDimitry Andric
12125ffd83dbSDimitry Andric  let BaseName = "XSMSUBASP" in {
12135ffd83dbSDimitry Andric  let isCommutable = 1 in
12145ffd83dbSDimitry Andric  def XSMSUBASP : XX3Form<60, 17,
12155ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12165ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12175ffd83dbSDimitry Andric                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
12185ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB,
12195ffd83dbSDimitry Andric                                              (fneg f32:$XTi)))]>,
12205ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12215ffd83dbSDimitry Andric                          AltVSXFMARel;
12225ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12235ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12245ffd83dbSDimitry Andric  def XSMSUBMSP : XX3Form<60, 25,
12255ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12265ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12275ffd83dbSDimitry Andric                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
12285ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12295ffd83dbSDimitry Andric                          AltVSXFMARel;
12305ffd83dbSDimitry Andric  }
12315ffd83dbSDimitry Andric
12325ffd83dbSDimitry Andric  let BaseName = "XSNMADDASP" in {
12335ffd83dbSDimitry Andric  let isCommutable = 1 in
12345ffd83dbSDimitry Andric  def XSNMADDASP : XX3Form<60, 129,
12355ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12365ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12375ffd83dbSDimitry Andric                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
12385ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
12395ffd83dbSDimitry Andric                                                    f32:$XTi)))]>,
12405ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12415ffd83dbSDimitry Andric                          AltVSXFMARel;
12425ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12435ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12445ffd83dbSDimitry Andric  def XSNMADDMSP : XX3Form<60, 137,
12455ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12465ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12475ffd83dbSDimitry Andric                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
12485ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12495ffd83dbSDimitry Andric                          AltVSXFMARel;
12505ffd83dbSDimitry Andric  }
12515ffd83dbSDimitry Andric
12525ffd83dbSDimitry Andric  let BaseName = "XSNMSUBASP" in {
12535ffd83dbSDimitry Andric  let isCommutable = 1 in
12545ffd83dbSDimitry Andric  def XSNMSUBASP : XX3Form<60, 145,
12555ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12565ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12575ffd83dbSDimitry Andric                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
12585ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
12595ffd83dbSDimitry Andric                                                    (fneg f32:$XTi))))]>,
12605ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12615ffd83dbSDimitry Andric                          AltVSXFMARel;
12625ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12635ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12645ffd83dbSDimitry Andric  def XSNMSUBMSP : XX3Form<60, 153,
12655ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12665ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12675ffd83dbSDimitry Andric                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
12685ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12695ffd83dbSDimitry Andric                          AltVSXFMARel;
12705ffd83dbSDimitry Andric  }
12715ffd83dbSDimitry Andric
12725ffd83dbSDimitry Andric  // Single Precision Conversions (FP <-> INT)
12735ffd83dbSDimitry Andric  def XSCVSXDSP : XX2Form<60, 312,
12745ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
12755ffd83dbSDimitry Andric                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1276e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fcfids f64:$XB))]>;
12775ffd83dbSDimitry Andric  def XSCVUXDSP : XX2Form<60, 296,
12785ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
12795ffd83dbSDimitry Andric                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1280e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>;
1281e8d8bef9SDimitry Andric  } // mayRaiseFPException
12825ffd83dbSDimitry Andric
12835ffd83dbSDimitry Andric  // Conversions between vector and scalar single precision
12845ffd83dbSDimitry Andric  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
12855ffd83dbSDimitry Andric                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
12865ffd83dbSDimitry Andric  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
12875ffd83dbSDimitry Andric                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
12885ffd83dbSDimitry Andric
12895ffd83dbSDimitry Andric  let Predicates = [HasVSX, HasDirectMove] in {
12905ffd83dbSDimitry Andric  // VSX direct move instructions
12915ffd83dbSDimitry Andric  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
12925ffd83dbSDimitry Andric                              "mfvsrd $rA, $XT", IIC_VecGeneral,
12935ffd83dbSDimitry Andric                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
12945ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
12955ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12965ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
12975ffd83dbSDimitry Andric  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
12985ffd83dbSDimitry Andric                             "mfvsrd $rA, $XT", IIC_VecGeneral,
12995ffd83dbSDimitry Andric                             []>,
13005ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13015ffd83dbSDimitry Andric  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
13025ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1303bdd1243dSDimitry Andric                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>, ZExt32To64;
13045ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13055ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13065ffd83dbSDimitry Andric  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
13075ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
13085ffd83dbSDimitry Andric                               []>;
13095ffd83dbSDimitry Andric  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
13105ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
13115ffd83dbSDimitry Andric                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
13125ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13135ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13145ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13155ffd83dbSDimitry Andric  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
13165ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
13175ffd83dbSDimitry Andric                              []>,
13185ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13195ffd83dbSDimitry Andric  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
13205ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
13215ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
13225ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13235ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13245ffd83dbSDimitry Andric  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
13255ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
13265ffd83dbSDimitry Andric                               []>;
13275ffd83dbSDimitry Andric  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
13285ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
13295ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
13305ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13315ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13325ffd83dbSDimitry Andric  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
13335ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
13345ffd83dbSDimitry Andric                               []>;
13355ffd83dbSDimitry Andric  } // HasDirectMove
13365ffd83dbSDimitry Andric
13375ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
13385ffd83dbSDimitry Andric
13395ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove] in {
13405ffd83dbSDimitry Andricdef MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
13415ffd83dbSDimitry Andric                            "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
13425ffd83dbSDimitry Andric
13435ffd83dbSDimitry Andricdef MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
13445ffd83dbSDimitry Andric                     "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
13455ffd83dbSDimitry Andric                     []>, Requires<[In64BitMode]>;
13465ffd83dbSDimitry Andric
13475ffd83dbSDimitry Andricdef MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
13485ffd83dbSDimitry Andric                            "mfvsrld $rA, $XT", IIC_VecGeneral,
13495ffd83dbSDimitry Andric                            []>, Requires<[In64BitMode]>;
13505ffd83dbSDimitry Andric
13515ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove
13525ffd83dbSDimitry Andric
13535ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
13545ffd83dbSDimitry Andric  // Quad-Precision Scalar Move Instructions:
13555ffd83dbSDimitry Andric  // Copy Sign
13565ffd83dbSDimitry Andric  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
13575ffd83dbSDimitry Andric                                [(set f128:$vT,
13585ffd83dbSDimitry Andric                                      (fcopysign f128:$vB, f128:$vA))]>;
13595ffd83dbSDimitry Andric
13605ffd83dbSDimitry Andric  // Absolute/Negative-Absolute/Negate
13615ffd83dbSDimitry Andric  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
13625ffd83dbSDimitry Andric                                [(set f128:$vT, (fabs f128:$vB))]>;
13635ffd83dbSDimitry Andric  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
13645ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
13655ffd83dbSDimitry Andric  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
13665ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg f128:$vB))]>;
13675ffd83dbSDimitry Andric
13685ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
13695ffd83dbSDimitry Andric  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
13705ffd83dbSDimitry Andric
13715ffd83dbSDimitry Andric  // Add/Divide/Multiply/Subtract
13725ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
13735ffd83dbSDimitry Andric  let isCommutable = 1 in {
13745ffd83dbSDimitry Andric  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
13755ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>;
13765ffd83dbSDimitry Andric  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
13775ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>;
13785ffd83dbSDimitry Andric  }
13795ffd83dbSDimitry Andric  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
13805ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>;
13815ffd83dbSDimitry Andric  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
13825ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>;
13835ffd83dbSDimitry Andric  // Square-Root
13845ffd83dbSDimitry Andric  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
13855ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsqrt f128:$vB))]>;
13865ffd83dbSDimitry Andric  // (Negative) Multiply-{Add/Subtract}
13875ffd83dbSDimitry Andric  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
13885ffd83dbSDimitry Andric                                    [(set f128:$vT,
13895ffd83dbSDimitry Andric                                          (any_fma f128:$vA, f128:$vB, f128:$vTi))]>;
13905ffd83dbSDimitry Andric  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
13915ffd83dbSDimitry Andric                                       [(set f128:$vT,
13925ffd83dbSDimitry Andric                                             (any_fma f128:$vA, f128:$vB,
13935ffd83dbSDimitry Andric                                                      (fneg f128:$vTi)))]>;
13945ffd83dbSDimitry Andric  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
13955ffd83dbSDimitry Andric                                     [(set f128:$vT,
13965ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
13975ffd83dbSDimitry Andric                                                          f128:$vTi)))]>;
13985ffd83dbSDimitry Andric  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
13995ffd83dbSDimitry Andric                                     [(set f128:$vT,
14005ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
14015ffd83dbSDimitry Andric                                                          (fneg f128:$vTi))))]>;
14025ffd83dbSDimitry Andric
14035ffd83dbSDimitry Andric  let isCommutable = 1 in {
14045ffd83dbSDimitry Andric  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
14055ffd83dbSDimitry Andric                                  [(set f128:$vT,
14065ffd83dbSDimitry Andric                                  (int_ppc_addf128_round_to_odd
14075ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14085ffd83dbSDimitry Andric  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
14095ffd83dbSDimitry Andric                                  [(set f128:$vT,
14105ffd83dbSDimitry Andric                                  (int_ppc_mulf128_round_to_odd
14115ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14125ffd83dbSDimitry Andric  }
14135ffd83dbSDimitry Andric  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
14145ffd83dbSDimitry Andric                                  [(set f128:$vT,
14155ffd83dbSDimitry Andric                                  (int_ppc_subf128_round_to_odd
14165ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14175ffd83dbSDimitry Andric  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
14185ffd83dbSDimitry Andric                                  [(set f128:$vT,
14195ffd83dbSDimitry Andric                                  (int_ppc_divf128_round_to_odd
14205ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14215ffd83dbSDimitry Andric  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
14225ffd83dbSDimitry Andric                                  [(set f128:$vT,
14235ffd83dbSDimitry Andric                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
14245ffd83dbSDimitry Andric
14255ffd83dbSDimitry Andric
14265ffd83dbSDimitry Andric  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
14275ffd83dbSDimitry Andric                                      [(set f128:$vT,
14285ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
14295ffd83dbSDimitry Andric                                      f128:$vA,f128:$vB,f128:$vTi))]>;
14305ffd83dbSDimitry Andric
14315ffd83dbSDimitry Andric  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
14325ffd83dbSDimitry Andric                                      [(set f128:$vT,
14335ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
14345ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
14355ffd83dbSDimitry Andric  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
14365ffd83dbSDimitry Andric                                      [(set f128:$vT,
14375ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
14385ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
14395ffd83dbSDimitry Andric  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
14405ffd83dbSDimitry Andric                                      [(set f128:$vT,
14415ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
14425ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
14435ffd83dbSDimitry Andric  } // mayRaiseFPException
14445ffd83dbSDimitry Andric
14455ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
14465ffd83dbSDimitry Andric  // QP Compare Ordered/Unordered
14475ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
14485ffd83dbSDimitry Andric    // DP/QP Compare Exponents
14495ffd83dbSDimitry Andric    def XSCMPEXPDP : XX3Form_1<60, 59,
14505ffd83dbSDimitry Andric                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
14515ffd83dbSDimitry Andric                               "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
14525ffd83dbSDimitry Andric    def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
14535ffd83dbSDimitry Andric
1454e8d8bef9SDimitry Andric    let mayRaiseFPException = 1 in {
1455e8d8bef9SDimitry Andric    def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1456e8d8bef9SDimitry Andric    def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1457e8d8bef9SDimitry Andric
14585ffd83dbSDimitry Andric    // DP Compare ==, >=, >, !=
14595ffd83dbSDimitry Andric    // Use vsrc for XT, because the entire register of XT is set.
14605ffd83dbSDimitry Andric    // XT.dword[1] = 0x0000_0000_0000_0000
14615ffd83dbSDimitry Andric    def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
14625ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14635ffd83dbSDimitry Andric    def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
14645ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14655ffd83dbSDimitry Andric    def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
14665ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14675ffd83dbSDimitry Andric    }
1468e8d8bef9SDimitry Andric  }
14695ffd83dbSDimitry Andric
14705ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
14715ffd83dbSDimitry Andric  // Quad-Precision Floating-Point Conversion Instructions:
14725ffd83dbSDimitry Andric
14735ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
14745ffd83dbSDimitry Andric    // Convert DP -> QP
14755ffd83dbSDimitry Andric    def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
14765ffd83dbSDimitry Andric                                       [(set f128:$vT, (any_fpextend f64:$vB))]>;
14775ffd83dbSDimitry Andric
14785ffd83dbSDimitry Andric    // Round & Convert QP -> DP (dword[1] is set to zero)
14795ffd83dbSDimitry Andric    def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
14805ffd83dbSDimitry Andric    def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
14815ffd83dbSDimitry Andric                                          [(set f64:$vT,
14825ffd83dbSDimitry Andric                                          (int_ppc_truncf128_round_to_odd
14835ffd83dbSDimitry Andric                                          f128:$vB))]>;
14845ffd83dbSDimitry Andric  }
14855ffd83dbSDimitry Andric
14865ffd83dbSDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
1487e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
14885ffd83dbSDimitry Andric    def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
14895ffd83dbSDimitry Andric    def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
14905ffd83dbSDimitry Andric    def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
14915ffd83dbSDimitry Andric    def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
14925ffd83dbSDimitry Andric  }
14935ffd83dbSDimitry Andric
14945ffd83dbSDimitry Andric  // Convert (Un)Signed DWord -> QP.
14955ffd83dbSDimitry Andric  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
14965ffd83dbSDimitry Andric  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
14975ffd83dbSDimitry Andric
14985ffd83dbSDimitry Andric  // (Round &) Convert DP <-> HP
14995ffd83dbSDimitry Andric  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
15005ffd83dbSDimitry Andric  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
15015ffd83dbSDimitry Andric  // but we still use vsfrc for it.
15025ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1503e8d8bef9SDimitry Andric  let hasSideEffects = 1, mayRaiseFPException = 1 in {
15045ffd83dbSDimitry Andric    def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
15055ffd83dbSDimitry Andric    def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
15065ffd83dbSDimitry Andric  }
15075ffd83dbSDimitry Andric
1508e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
15095ffd83dbSDimitry Andric  // Vector HP -> SP
15105ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15115ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15125ffd83dbSDimitry Andric  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
15135ffd83dbSDimitry Andric  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
15145ffd83dbSDimitry Andric                                 [(set v4f32:$XT,
15155ffd83dbSDimitry Andric                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
15165ffd83dbSDimitry Andric
15175ffd83dbSDimitry Andric  // Round to Quad-Precision Integer [with Inexact]
15185ffd83dbSDimitry Andric  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
15195ffd83dbSDimitry Andric  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
15205ffd83dbSDimitry Andric
15215ffd83dbSDimitry Andric  // Round Quad-Precision to Double-Extended Precision (fp80)
15225ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15235ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15245ffd83dbSDimitry Andric  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
1525e8d8bef9SDimitry Andric  }
15265ffd83dbSDimitry Andric
15275ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
15285ffd83dbSDimitry Andric  // Insert/Extract Instructions
15295ffd83dbSDimitry Andric
15305ffd83dbSDimitry Andric  // Insert Exponent DP/QP
15315ffd83dbSDimitry Andric  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
15325ffd83dbSDimitry Andric  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
15335ffd83dbSDimitry Andric                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
1534fe6060f1SDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1535fe6060f1SDimitry Andric  let hasSideEffects = 1 in {
15365ffd83dbSDimitry Andric    // vB NOTE: only vB.dword[0] is used, that's why we don't use
15375ffd83dbSDimitry Andric    //          X_VT5_VA5_VB5 form
15385ffd83dbSDimitry Andric    def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
15395ffd83dbSDimitry Andric                            "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
15405ffd83dbSDimitry Andric  }
15415ffd83dbSDimitry Andric
15425ffd83dbSDimitry Andric  // Extract Exponent/Significand DP/QP
15435ffd83dbSDimitry Andric  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
15445ffd83dbSDimitry Andric  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
15455ffd83dbSDimitry Andric
1546fe6060f1SDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1547fe6060f1SDimitry Andric  let hasSideEffects = 1 in {
15485ffd83dbSDimitry Andric    def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
15495ffd83dbSDimitry Andric    def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
15505ffd83dbSDimitry Andric  }
15515ffd83dbSDimitry Andric
15525ffd83dbSDimitry Andric  // Vector Insert Word
15535ffd83dbSDimitry Andric  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
15545ffd83dbSDimitry Andric  def XXINSERTW   :
15555ffd83dbSDimitry Andric    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
15565ffd83dbSDimitry Andric                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
15575ffd83dbSDimitry Andric                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
15585ffd83dbSDimitry Andric                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
15595ffd83dbSDimitry Andric                                                   imm32SExt16:$UIM))]>,
15605ffd83dbSDimitry Andric                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
15615ffd83dbSDimitry Andric
15625ffd83dbSDimitry Andric  // Vector Extract Unsigned Word
15635ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15645ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15655ffd83dbSDimitry Andric  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
15665ffd83dbSDimitry Andric                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
15675ffd83dbSDimitry Andric                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
15685ffd83dbSDimitry Andric
15695ffd83dbSDimitry Andric  // Vector Insert Exponent DP/SP
15705ffd83dbSDimitry Andric  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
15715ffd83dbSDimitry Andric    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
15725ffd83dbSDimitry Andric  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
15735ffd83dbSDimitry Andric    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
15745ffd83dbSDimitry Andric
15755ffd83dbSDimitry Andric  // Vector Extract Exponent/Significand DP/SP
15765ffd83dbSDimitry Andric  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
15775ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
15785ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
15795ffd83dbSDimitry Andric  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
15805ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
15815ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
15825ffd83dbSDimitry Andric  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
15835ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
15845ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
15855ffd83dbSDimitry Andric  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
15865ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
15875ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
15885ffd83dbSDimitry Andric
15895ffd83dbSDimitry Andric  // Test Data Class SP/DP/QP
15905ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15915ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
15925ffd83dbSDimitry Andric    def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
15935ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
15945ffd83dbSDimitry Andric                                "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
15955ffd83dbSDimitry Andric    def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
15965ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
15975ffd83dbSDimitry Andric                                "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
15985ffd83dbSDimitry Andric    def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
15995ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
16005ffd83dbSDimitry Andric                                "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
16015ffd83dbSDimitry Andric  }
16025ffd83dbSDimitry Andric
16035ffd83dbSDimitry Andric  // Vector Test Data Class SP/DP
16045ffd83dbSDimitry Andric  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
16055ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
16065ffd83dbSDimitry Andric                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
16075ffd83dbSDimitry Andric                              [(set v4i32: $XT,
16085ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
16095ffd83dbSDimitry Andric  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
16105ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
16115ffd83dbSDimitry Andric                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
16125ffd83dbSDimitry Andric                              [(set v2i64: $XT,
16135ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
16145ffd83dbSDimitry Andric
16155ffd83dbSDimitry Andric  // Maximum/Minimum Type-C/Type-J DP
1616e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
16175ffd83dbSDimitry Andric  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
16185ffd83dbSDimitry Andric                                 IIC_VecFP,
16195ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
16205ffd83dbSDimitry Andric  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc,
16215ffd83dbSDimitry Andric                                 IIC_VecFP,
16225ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>;
16235ffd83dbSDimitry Andric
16245ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16255ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16265ffd83dbSDimitry Andric    def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
16275ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
16285ffd83dbSDimitry Andric    def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
16295ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
16305ffd83dbSDimitry Andric  }
1631e8d8bef9SDimitry Andric  }
16325ffd83dbSDimitry Andric
16335ffd83dbSDimitry Andric  // Vector Byte-Reverse H/W/D/Q Word
16345ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16355ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16365ffd83dbSDimitry Andric  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
16375ffd83dbSDimitry Andric  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc,
16385ffd83dbSDimitry Andric    [(set v4i32:$XT, (bswap v4i32:$XB))]>;
16395ffd83dbSDimitry Andric  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc,
16405ffd83dbSDimitry Andric    [(set v2i64:$XT, (bswap v2i64:$XB))]>;
16415ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16425ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16435ffd83dbSDimitry Andric  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
16445ffd83dbSDimitry Andric
16455ffd83dbSDimitry Andric  // Vector Permute
1646bdd1243dSDimitry Andric  def XXPERM  : XX3Form<60, 26, (outs vsrc:$XT),
1647bdd1243dSDimitry Andric                                (ins vsrc:$XA, vsrc:$XTi, vsrc:$XB),
1648bdd1243dSDimitry Andric                        "xxperm $XT, $XA, $XB", IIC_VecPerm, []>,
1649bdd1243dSDimitry Andric                        RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
1650bdd1243dSDimitry Andric  def XXPERMR : XX3Form<60, 58, (outs vsrc:$XT),
1651bdd1243dSDimitry Andric                                (ins vsrc:$XA, vsrc:$XTi, vsrc:$XB),
1652bdd1243dSDimitry Andric                        "xxpermr $XT, $XA, $XB", IIC_VecPerm, []>,
1653bdd1243dSDimitry Andric                        RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
16545ffd83dbSDimitry Andric
16555ffd83dbSDimitry Andric  // Vector Splat Immediate Byte
16565ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16575ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16585ffd83dbSDimitry Andric  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
16595ffd83dbSDimitry Andric                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
16605ffd83dbSDimitry Andric
16615ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
16625ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
16635ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
16645ffd83dbSDimitry Andric  // Load Vector
16655ffd83dbSDimitry Andric  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
16665ffd83dbSDimitry Andric                            "lxv $XT, $src", IIC_LdStLFD, []>;
16675ffd83dbSDimitry Andric  // Load DWord
16685ffd83dbSDimitry Andric  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
16695ffd83dbSDimitry Andric                       "lxsd $vD, $src", IIC_LdStLFD, []>;
16705ffd83dbSDimitry Andric  // Load SP from src, convert it to DP, and place in dword[0]
16715ffd83dbSDimitry Andric  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
16725ffd83dbSDimitry Andric                       "lxssp $vD, $src", IIC_LdStLFD, []>;
16735ffd83dbSDimitry Andric
16745ffd83dbSDimitry Andric  // Load as Integer Byte/Halfword & Zero Indexed
16755ffd83dbSDimitry Andric  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
1676fe6060f1SDimitry Andric                              [(set f64:$XT, (PPClxsizx ForceXForm:$src, 1))]>;
16775ffd83dbSDimitry Andric  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
1678fe6060f1SDimitry Andric                              [(set f64:$XT, (PPClxsizx ForceXForm:$src, 2))]>;
16795ffd83dbSDimitry Andric
16805ffd83dbSDimitry Andric  // Load Vector Halfword*8/Byte*16 Indexed
16815ffd83dbSDimitry Andric  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
16825ffd83dbSDimitry Andric  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
16835ffd83dbSDimitry Andric
16845ffd83dbSDimitry Andric  // Load Vector Indexed
16855ffd83dbSDimitry Andric  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
1686fe6060f1SDimitry Andric                [(set v2f64:$XT, (load XForm:$src))]>;
16875ffd83dbSDimitry Andric  // Load Vector (Left-justified) with Length
16885ffd83dbSDimitry Andric  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
16895ffd83dbSDimitry Andric                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
16905ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
16915ffd83dbSDimitry Andric  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
16925ffd83dbSDimitry Andric                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
16935ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
16945ffd83dbSDimitry Andric
16955ffd83dbSDimitry Andric  // Load Vector Word & Splat Indexed
16965ffd83dbSDimitry Andric  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
16975ffd83dbSDimitry Andric  } // mayLoad
16985ffd83dbSDimitry Andric
16995ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
17005ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
17015ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
17025ffd83dbSDimitry Andric  // Store Vector
17035ffd83dbSDimitry Andric  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
17045ffd83dbSDimitry Andric                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
17055ffd83dbSDimitry Andric  // Store DWord
17065ffd83dbSDimitry Andric  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
17075ffd83dbSDimitry Andric                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
17085ffd83dbSDimitry Andric  // Convert DP of dword[0] to SP, and Store to dst
17095ffd83dbSDimitry Andric  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
17105ffd83dbSDimitry Andric                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
17115ffd83dbSDimitry Andric
17125ffd83dbSDimitry Andric  // Store as Integer Byte/Halfword Indexed
17135ffd83dbSDimitry Andric  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
1714fe6060f1SDimitry Andric                               [(PPCstxsix f64:$XT, ForceXForm:$dst, 1)]>;
17155ffd83dbSDimitry Andric  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
1716fe6060f1SDimitry Andric                               [(PPCstxsix f64:$XT, ForceXForm:$dst, 2)]>;
17175ffd83dbSDimitry Andric  let isCodeGenOnly = 1 in {
17185ffd83dbSDimitry Andric    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
17195ffd83dbSDimitry Andric    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
17205ffd83dbSDimitry Andric  }
17215ffd83dbSDimitry Andric
17225ffd83dbSDimitry Andric  // Store Vector Halfword*8/Byte*16 Indexed
17235ffd83dbSDimitry Andric  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
17245ffd83dbSDimitry Andric  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
17255ffd83dbSDimitry Andric
17265ffd83dbSDimitry Andric  // Store Vector Indexed
17275ffd83dbSDimitry Andric  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
1728fe6060f1SDimitry Andric                 [(store v2f64:$XT, XForm:$dst)]>;
17295ffd83dbSDimitry Andric
17305ffd83dbSDimitry Andric  // Store Vector (Left-justified) with Length
17315ffd83dbSDimitry Andric  def STXVL : XX1Form_memOp<31, 397, (outs),
17325ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
17335ffd83dbSDimitry Andric                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
17345ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
17355ffd83dbSDimitry Andric                              i64:$rB)]>;
17365ffd83dbSDimitry Andric  def STXVLL : XX1Form_memOp<31, 429, (outs),
17375ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
17385ffd83dbSDimitry Andric                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
17395ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
17405ffd83dbSDimitry Andric                              i64:$rB)]>;
17415ffd83dbSDimitry Andric  } // mayStore
17425ffd83dbSDimitry Andric
17435ffd83dbSDimitry Andric  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
17445ffd83dbSDimitry Andric                          "#DFLOADf32",
1745fe6060f1SDimitry Andric                          [(set f32:$XT, (load DSForm:$src))]>;
17465ffd83dbSDimitry Andric  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
17475ffd83dbSDimitry Andric                          "#DFLOADf64",
1748fe6060f1SDimitry Andric                          [(set f64:$XT, (load DSForm:$src))]>;
17495ffd83dbSDimitry Andric  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
17505ffd83dbSDimitry Andric                          "#DFSTOREf32",
1751fe6060f1SDimitry Andric                          [(store f32:$XT, DSForm:$dst)]>;
17525ffd83dbSDimitry Andric  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
17535ffd83dbSDimitry Andric                          "#DFSTOREf64",
1754fe6060f1SDimitry Andric                          [(store f64:$XT, DSForm:$dst)]>;
17555ffd83dbSDimitry Andric
17565ffd83dbSDimitry Andric  let mayStore = 1 in {
17575ffd83dbSDimitry Andric    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
17585ffd83dbSDimitry Andric                                          (ins spilltovsrrc:$XT, memrr:$dst),
17595ffd83dbSDimitry Andric                                          "#SPILLTOVSR_STX", []>;
17605ffd83dbSDimitry Andric    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
17615ffd83dbSDimitry Andric                              "#SPILLTOVSR_ST", []>;
17625ffd83dbSDimitry Andric  }
17635ffd83dbSDimitry Andric  let mayLoad = 1 in {
17645ffd83dbSDimitry Andric    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
17655ffd83dbSDimitry Andric                                          (ins memrr:$src),
17665ffd83dbSDimitry Andric                                          "#SPILLTOVSR_LDX", []>;
17675ffd83dbSDimitry Andric    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
17685ffd83dbSDimitry Andric                              "#SPILLTOVSR_LD", []>;
17695ffd83dbSDimitry Andric
17705ffd83dbSDimitry Andric  }
17715ffd83dbSDimitry Andric  } // HasP9Vector
17725ffd83dbSDimitry Andric} // hasSideEffects = 0
17735ffd83dbSDimitry Andric
17745ffd83dbSDimitry Andriclet PPC970_Single = 1, AddedComplexity = 400 in {
17750b57cec5SDimitry Andric
17760b57cec5SDimitry Andric  def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17770b57cec5SDimitry Andric                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
17780b57cec5SDimitry Andric                             "#SELECT_CC_VSRC",
17790b57cec5SDimitry Andric                             []>;
17800b57cec5SDimitry Andric  def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17810b57cec5SDimitry Andric                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
17820b57cec5SDimitry Andric                          "#SELECT_VSRC",
17830b57cec5SDimitry Andric                          [(set v2f64:$dst,
17840b57cec5SDimitry Andric                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
17850b57cec5SDimitry Andric  def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
17860b57cec5SDimitry Andric                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
17870b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
17880b57cec5SDimitry Andric                              []>;
17890b57cec5SDimitry Andric  def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
17900b57cec5SDimitry Andric                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
17910b57cec5SDimitry Andric                           "#SELECT_VSFRC",
17920b57cec5SDimitry Andric                           [(set f64:$dst,
17930b57cec5SDimitry Andric                                 (select i1:$cond, f64:$T, f64:$F))]>;
17940b57cec5SDimitry Andric  def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
17950b57cec5SDimitry Andric                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
17960b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
17970b57cec5SDimitry Andric                              []>;
17980b57cec5SDimitry Andric  def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
17990b57cec5SDimitry Andric                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
18000b57cec5SDimitry Andric                           "#SELECT_VSSRC",
18010b57cec5SDimitry Andric                           [(set f32:$dst,
18020b57cec5SDimitry Andric                                 (select i1:$cond, f32:$T, f32:$F))]>;
18030b57cec5SDimitry Andric}
18040b57cec5SDimitry Andric}
18050b57cec5SDimitry Andric
18065ffd83dbSDimitry Andric//----------------------------- DAG Definitions ------------------------------//
1807fe6060f1SDimitry Andric
1808fe6060f1SDimitry Andric// Output dag used to bitcast f32 to i32 and f64 to i64
1809fe6060f1SDimitry Andricdef Bitcast {
1810fe6060f1SDimitry Andric  dag FltToInt = (i32 (MFVSRWZ (EXTRACT_SUBREG (XSCVDPSPN $A), sub_64)));
1811fe6060f1SDimitry Andric  dag DblToLong = (i64 (MFVSRD $A));
1812fe6060f1SDimitry Andric}
1813fe6060f1SDimitry Andric
1814480093f4SDimitry Andricdef FpMinMax {
1815480093f4SDimitry Andric  dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC),
1816480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1817480093f4SDimitry Andric                                 VSSRC);
1818480093f4SDimitry Andric  dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC),
1819480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1820480093f4SDimitry Andric                                 VSSRC);
1821480093f4SDimitry Andric}
1822480093f4SDimitry Andric
18230b57cec5SDimitry Andricdef ScalarLoads {
1824fe6060f1SDimitry Andric  dag Li8 =       (i32 (extloadi8 ForceXForm:$src));
1825fe6060f1SDimitry Andric  dag ZELi8 =     (i32 (zextloadi8 ForceXForm:$src));
1826fe6060f1SDimitry Andric  dag ZELi8i64 =  (i64 (zextloadi8 ForceXForm:$src));
1827fe6060f1SDimitry Andric  dag SELi8 =     (i32 (sext_inreg (extloadi8 ForceXForm:$src), i8));
1828fe6060f1SDimitry Andric  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 ForceXForm:$src), i8));
18290b57cec5SDimitry Andric
1830fe6060f1SDimitry Andric  dag Li16 =      (i32 (extloadi16 ForceXForm:$src));
1831fe6060f1SDimitry Andric  dag ZELi16 =    (i32 (zextloadi16 ForceXForm:$src));
1832fe6060f1SDimitry Andric  dag ZELi16i64 = (i64 (zextloadi16 ForceXForm:$src));
1833fe6060f1SDimitry Andric  dag SELi16 =    (i32 (sextloadi16 ForceXForm:$src));
1834fe6060f1SDimitry Andric  dag SELi16i64 = (i64 (sextloadi16 ForceXForm:$src));
18350b57cec5SDimitry Andric
1836fe6060f1SDimitry Andric  dag Li32 = (i32 (load ForceXForm:$src));
18370b57cec5SDimitry Andric}
18380b57cec5SDimitry Andric
18390b57cec5SDimitry Andricdef DWToSPExtractConv {
18400b57cec5SDimitry Andric  dag El0US1 = (f32 (PPCfcfidus
18410b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18420b57cec5SDimitry Andric  dag El1US1 = (f32 (PPCfcfidus
18430b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18440b57cec5SDimitry Andric  dag El0US2 = (f32 (PPCfcfidus
18450b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18460b57cec5SDimitry Andric  dag El1US2 = (f32 (PPCfcfidus
18470b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18480b57cec5SDimitry Andric  dag El0SS1 = (f32 (PPCfcfids
18490b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18500b57cec5SDimitry Andric  dag El1SS1 = (f32 (PPCfcfids
18510b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18520b57cec5SDimitry Andric  dag El0SS2 = (f32 (PPCfcfids
18530b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18540b57cec5SDimitry Andric  dag El1SS2 = (f32 (PPCfcfids
18550b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18560b57cec5SDimitry Andric  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
18570b57cec5SDimitry Andric  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
18580b57cec5SDimitry Andric}
18590b57cec5SDimitry Andric
18605ffd83dbSDimitry Andricdef WToDPExtractConv {
18615ffd83dbSDimitry Andric  dag El0S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 0))));
18625ffd83dbSDimitry Andric  dag El1S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 1))));
18635ffd83dbSDimitry Andric  dag El2S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 2))));
18645ffd83dbSDimitry Andric  dag El3S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 3))));
18655ffd83dbSDimitry Andric  dag El0U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 0))));
18665ffd83dbSDimitry Andric  dag El1U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 1))));
18675ffd83dbSDimitry Andric  dag El2U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 2))));
18685ffd83dbSDimitry Andric  dag El3U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 3))));
18695ffd83dbSDimitry Andric  dag BV02S = (v2f64 (build_vector El0S, El2S));
18705ffd83dbSDimitry Andric  dag BV13S = (v2f64 (build_vector El1S, El3S));
18715ffd83dbSDimitry Andric  dag BV02U = (v2f64 (build_vector El0U, El2U));
18725ffd83dbSDimitry Andric  dag BV13U = (v2f64 (build_vector El1U, El3U));
18738bcb0991SDimitry Andric}
18748bcb0991SDimitry Andric
18750b57cec5SDimitry Andric/*  Direct moves of various widths from GPR's into VSR's. Each move lines
18760b57cec5SDimitry Andric    the value up into element 0 (both BE and LE). Namely, entities smaller than
18770b57cec5SDimitry Andric    a doubleword are shifted left and moved for BE. For LE, they're moved, then
18780b57cec5SDimitry Andric    swapped to go into the least significant element of the VSR.
18790b57cec5SDimitry Andric*/
18800b57cec5SDimitry Andricdef MovesToVSR {
18810b57cec5SDimitry Andric  dag BE_BYTE_0 =
18820b57cec5SDimitry Andric    (MTVSRD
18830b57cec5SDimitry Andric      (RLDICR
18840b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
18850b57cec5SDimitry Andric  dag BE_HALF_0 =
18860b57cec5SDimitry Andric    (MTVSRD
18870b57cec5SDimitry Andric      (RLDICR
18880b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
18890b57cec5SDimitry Andric  dag BE_WORD_0 =
18900b57cec5SDimitry Andric    (MTVSRD
18910b57cec5SDimitry Andric      (RLDICR
18920b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
18930b57cec5SDimitry Andric  dag BE_DWORD_0 = (MTVSRD $A);
18940b57cec5SDimitry Andric
18950b57cec5SDimitry Andric  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
18960b57cec5SDimitry Andric  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
18970b57cec5SDimitry Andric                                        LE_MTVSRW, sub_64));
18980b57cec5SDimitry Andric  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
18990b57cec5SDimitry Andric  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
19000b57cec5SDimitry Andric                                         BE_DWORD_0, sub_64));
19010b57cec5SDimitry Andric  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
19020b57cec5SDimitry Andric}
19030b57cec5SDimitry Andric
19040b57cec5SDimitry Andric/*  Patterns for extracting elements out of vectors. Integer elements are
19050b57cec5SDimitry Andric    extracted using direct move operations. Patterns for extracting elements
19060b57cec5SDimitry Andric    whose indices are not available at compile time are also provided with
19070b57cec5SDimitry Andric    various _VARIABLE_ patterns.
19080b57cec5SDimitry Andric    The numbering for the DAG's is for LE, but when used on BE, the correct
19090b57cec5SDimitry Andric    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
19100b57cec5SDimitry Andric*/
19110b57cec5SDimitry Andricdef VectorExtractions {
19120b57cec5SDimitry Andric  // Doubleword extraction
19130b57cec5SDimitry Andric  dag LE_DWORD_0 =
19140b57cec5SDimitry Andric    (MFVSRD
19150b57cec5SDimitry Andric      (EXTRACT_SUBREG
19160b57cec5SDimitry Andric        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
19170b57cec5SDimitry Andric                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
19180b57cec5SDimitry Andric  dag LE_DWORD_1 = (MFVSRD
19190b57cec5SDimitry Andric                     (EXTRACT_SUBREG
19200b57cec5SDimitry Andric                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19210b57cec5SDimitry Andric
19220b57cec5SDimitry Andric  // Word extraction
19230b57cec5SDimitry Andric  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
19240b57cec5SDimitry Andric  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
19250b57cec5SDimitry Andric  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
19260b57cec5SDimitry Andric                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19270b57cec5SDimitry Andric  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
19280b57cec5SDimitry Andric
19290b57cec5SDimitry Andric  // Halfword extraction
19300b57cec5SDimitry Andric  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
19310b57cec5SDimitry Andric  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
19320b57cec5SDimitry Andric  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
19330b57cec5SDimitry Andric  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
19340b57cec5SDimitry Andric  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
19350b57cec5SDimitry Andric  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
19360b57cec5SDimitry Andric  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
19370b57cec5SDimitry Andric  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andric  // Byte extraction
19400b57cec5SDimitry Andric  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
19410b57cec5SDimitry Andric  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
19420b57cec5SDimitry Andric  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
19430b57cec5SDimitry Andric  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
19440b57cec5SDimitry Andric  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
19450b57cec5SDimitry Andric  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
19460b57cec5SDimitry Andric  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
19470b57cec5SDimitry Andric  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
19480b57cec5SDimitry Andric  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
19490b57cec5SDimitry Andric  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
19500b57cec5SDimitry Andric  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
19510b57cec5SDimitry Andric  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
19520b57cec5SDimitry Andric  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
19530b57cec5SDimitry Andric  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
19540b57cec5SDimitry Andric  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
19550b57cec5SDimitry Andric  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric  /* Variable element number (BE and LE patterns must be specified separately)
19580b57cec5SDimitry Andric     This is a rather involved process.
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric     Conceptually, this is how the move is accomplished:
19610b57cec5SDimitry Andric     1. Identify which doubleword contains the element
19620b57cec5SDimitry Andric     2. Shift in the VMX register so that the correct doubleword is correctly
19630b57cec5SDimitry Andric        lined up for the MFVSRD
19640b57cec5SDimitry Andric     3. Perform the move so that the element (along with some extra stuff)
19650b57cec5SDimitry Andric        is in the GPR
19660b57cec5SDimitry Andric     4. Right shift within the GPR so that the element is right-justified
19670b57cec5SDimitry Andric
19680b57cec5SDimitry Andric     Of course, the index is an element number which has a different meaning
19690b57cec5SDimitry Andric     on LE/BE so the patterns have to be specified separately.
19700b57cec5SDimitry Andric
19710b57cec5SDimitry Andric     Note: The final result will be the element right-justified with high
19720b57cec5SDimitry Andric           order bits being arbitrarily defined (namely, whatever was in the
19730b57cec5SDimitry Andric           vector register to the left of the value originally).
19740b57cec5SDimitry Andric  */
19750b57cec5SDimitry Andric
19760b57cec5SDimitry Andric  /*  LE variable byte
19770b57cec5SDimitry Andric      Number 1. above:
19780b57cec5SDimitry Andric      - For elements 0-7, we shift left by 8 bytes since they're on the right
19790b57cec5SDimitry Andric      - For elements 8-15, we need not shift (shift left by zero bytes)
19800b57cec5SDimitry Andric      This is accomplished by inverting the bits of the index and AND-ing
19810b57cec5SDimitry Andric      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
19820b57cec5SDimitry Andric  */
19830b57cec5SDimitry Andric  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
19840b57cec5SDimitry Andric
19850b57cec5SDimitry Andric  //  Number 2. above:
19860b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
19870b57cec5SDimitry Andric  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
19880b57cec5SDimitry Andric
19890b57cec5SDimitry Andric  //  Number 3. above:
19900b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
19910b57cec5SDimitry Andric  dag LE_MV_VBYTE = (MFVSRD
19920b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19930b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
19940b57cec5SDimitry Andric                        sub_64));
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andric  /*  Number 4. above:
19970b57cec5SDimitry Andric      - Truncate the element number to the range 0-7 (8-15 are symmetrical
19980b57cec5SDimitry Andric        and out of range values are truncated accordingly)
19990b57cec5SDimitry Andric      - Multiply by 8 as we need to shift right by the number of bits, not bytes
20000b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20010b57cec5SDimitry Andric  */
20020b57cec5SDimitry Andric  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
20030b57cec5SDimitry Andric                                       sub_32);
20040b57cec5SDimitry Andric  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
20050b57cec5SDimitry Andric                                         sub_32);
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andric  /*  LE variable halfword
20080b57cec5SDimitry Andric      Number 1. above:
20090b57cec5SDimitry Andric      - For elements 0-3, we shift left by 8 since they're on the right
20100b57cec5SDimitry Andric      - For elements 4-7, we need not shift (shift left by zero bytes)
20110b57cec5SDimitry Andric      Similarly to the byte pattern, we invert the bits of the index, but we
20120b57cec5SDimitry Andric      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
20130b57cec5SDimitry Andric      Of course, the shift is still by 8 bytes, so we must multiply by 2.
20140b57cec5SDimitry Andric  */
20150b57cec5SDimitry Andric  dag LE_VHALF_PERM_VEC =
20160b57cec5SDimitry Andric    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andric  //  Number 2. above:
20190b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20200b57cec5SDimitry Andric  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
20210b57cec5SDimitry Andric
20220b57cec5SDimitry Andric  //  Number 3. above:
20230b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20240b57cec5SDimitry Andric  dag LE_MV_VHALF = (MFVSRD
20250b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20260b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
20270b57cec5SDimitry Andric                        sub_64));
20280b57cec5SDimitry Andric
20290b57cec5SDimitry Andric  /*  Number 4. above:
20300b57cec5SDimitry Andric      - Truncate the element number to the range 0-3 (4-7 are symmetrical
20310b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20320b57cec5SDimitry Andric      - Multiply by 16 as we need to shift right by the number of bits
20330b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20340b57cec5SDimitry Andric  */
20350b57cec5SDimitry Andric  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
20360b57cec5SDimitry Andric                                       sub_32);
20370b57cec5SDimitry Andric  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
20380b57cec5SDimitry Andric                                         sub_32);
20390b57cec5SDimitry Andric
20400b57cec5SDimitry Andric  /*  LE variable word
20410b57cec5SDimitry Andric      Number 1. above:
20420b57cec5SDimitry Andric      - For elements 0-1, we shift left by 8 since they're on the right
20430b57cec5SDimitry Andric      - For elements 2-3, we need not shift
20440b57cec5SDimitry Andric  */
20450b57cec5SDimitry Andric  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20460b57cec5SDimitry Andric                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
20470b57cec5SDimitry Andric
20480b57cec5SDimitry Andric  //  Number 2. above:
20490b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20500b57cec5SDimitry Andric  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
20510b57cec5SDimitry Andric
20520b57cec5SDimitry Andric  //  Number 3. above:
20530b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20540b57cec5SDimitry Andric  dag LE_MV_VWORD = (MFVSRD
20550b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20560b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
20570b57cec5SDimitry Andric                        sub_64));
20580b57cec5SDimitry Andric
20590b57cec5SDimitry Andric  /*  Number 4. above:
20600b57cec5SDimitry Andric      - Truncate the element number to the range 0-1 (2-3 are symmetrical
20610b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20620b57cec5SDimitry Andric      - Multiply by 32 as we need to shift right by the number of bits
20630b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20640b57cec5SDimitry Andric  */
20650b57cec5SDimitry Andric  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
20660b57cec5SDimitry Andric                                       sub_32);
20670b57cec5SDimitry Andric  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
20680b57cec5SDimitry Andric                                         sub_32);
20690b57cec5SDimitry Andric
20700b57cec5SDimitry Andric  /*  LE variable doubleword
20710b57cec5SDimitry Andric      Number 1. above:
20720b57cec5SDimitry Andric      - For element 0, we shift left by 8 since it's on the right
20730b57cec5SDimitry Andric      - For element 1, we need not shift
20740b57cec5SDimitry Andric  */
20750b57cec5SDimitry Andric  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20760b57cec5SDimitry Andric                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
20770b57cec5SDimitry Andric
20780b57cec5SDimitry Andric  //  Number 2. above:
20790b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20800b57cec5SDimitry Andric  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
20810b57cec5SDimitry Andric
20820b57cec5SDimitry Andric  // Number 3. above:
20830b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20840b57cec5SDimitry Andric  //  - Number 4. is not needed for the doubleword as the value is 64-bits
20850b57cec5SDimitry Andric  dag LE_VARIABLE_DWORD =
20860b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
20870b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
20880b57cec5SDimitry Andric                  sub_64));
20890b57cec5SDimitry Andric
20900b57cec5SDimitry Andric  /*  LE variable float
20910b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
20920b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
20930b57cec5SDimitry Andric  */
20940b57cec5SDimitry Andric  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
20950b57cec5SDimitry Andric                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
20960b57cec5SDimitry Andric  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
20970b57cec5SDimitry Andric  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
20980b57cec5SDimitry Andric
20990b57cec5SDimitry Andric  /*  LE variable double
21000b57cec5SDimitry Andric      Same as the LE doubleword except there is no move.
21010b57cec5SDimitry Andric  */
21020b57cec5SDimitry Andric  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21030b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21040b57cec5SDimitry Andric                                         LE_VDWORD_PERM_VEC));
21050b57cec5SDimitry Andric  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
21060b57cec5SDimitry Andric
21070b57cec5SDimitry Andric  /*  BE variable byte
21080b57cec5SDimitry Andric      The algorithm here is the same as the LE variable byte except:
21090b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
21100b57cec5SDimitry Andric        we simply AND the element number with 0x8
21110b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21120b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-7
21130b57cec5SDimitry Andric  */
2114480093f4SDimitry Andric  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8)));
21150b57cec5SDimitry Andric  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
21160b57cec5SDimitry Andric  dag BE_MV_VBYTE = (MFVSRD
21170b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21180b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
21190b57cec5SDimitry Andric                        sub_64));
21200b57cec5SDimitry Andric  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
21210b57cec5SDimitry Andric                                       sub_32);
21220b57cec5SDimitry Andric  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
21230b57cec5SDimitry Andric                                         sub_32);
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andric  /*  BE variable halfword
21260b57cec5SDimitry Andric      The algorithm here is the same as the LE variable halfword except:
21270b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
21280b57cec5SDimitry Andric        we simply AND the element number with 0x4 and multiply by 2
21290b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21300b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-3
21310b57cec5SDimitry Andric  */
21320b57cec5SDimitry Andric  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
2133480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 4), 1, 62)));
21340b57cec5SDimitry Andric  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
21350b57cec5SDimitry Andric  dag BE_MV_VHALF = (MFVSRD
21360b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21370b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
21380b57cec5SDimitry Andric                        sub_64));
21390b57cec5SDimitry Andric  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
21400b57cec5SDimitry Andric                                       sub_32);
21410b57cec5SDimitry Andric  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
21420b57cec5SDimitry Andric                                         sub_32);
21430b57cec5SDimitry Andric
21440b57cec5SDimitry Andric  /*  BE variable word
21450b57cec5SDimitry Andric      The algorithm is the same as the LE variable word except:
21460b57cec5SDimitry Andric      - The shift in the VMX register happens for opposite element numbers
21470b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21480b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-1
21490b57cec5SDimitry Andric  */
21500b57cec5SDimitry Andric  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2151480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 2), 2, 61)));
21520b57cec5SDimitry Andric  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
21530b57cec5SDimitry Andric  dag BE_MV_VWORD = (MFVSRD
21540b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21550b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
21560b57cec5SDimitry Andric                        sub_64));
21570b57cec5SDimitry Andric  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
21580b57cec5SDimitry Andric                                       sub_32);
21590b57cec5SDimitry Andric  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
21600b57cec5SDimitry Andric                                         sub_32);
21610b57cec5SDimitry Andric
21620b57cec5SDimitry Andric  /*  BE variable doubleword
21630b57cec5SDimitry Andric      Same as the LE doubleword except we shift in the VMX register for opposite
21640b57cec5SDimitry Andric      element indices.
21650b57cec5SDimitry Andric  */
21660b57cec5SDimitry Andric  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2167480093f4SDimitry Andric                                        (RLDICR (ANDI8_rec $Idx, 1), 3, 60)));
21680b57cec5SDimitry Andric  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
21690b57cec5SDimitry Andric  dag BE_VARIABLE_DWORD =
21700b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
21710b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
21720b57cec5SDimitry Andric                  sub_64));
21730b57cec5SDimitry Andric
21740b57cec5SDimitry Andric  /*  BE variable float
21750b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
21760b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
21770b57cec5SDimitry Andric  */
21780b57cec5SDimitry Andric  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
21790b57cec5SDimitry Andric  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
21800b57cec5SDimitry Andric  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
21810b57cec5SDimitry Andric
2182fe6060f1SDimitry Andric  //  BE variable float 32-bit version
2183fe6060f1SDimitry Andric  dag BE_32B_VFLOAT_PERM_VEC = (v16i8 (LVSL (i32 ZERO), (RLWINM $Idx, 2, 0, 29)));
2184fe6060f1SDimitry Andric  dag BE_32B_VFLOAT_PERMUTE = (VPERM $S, $S, BE_32B_VFLOAT_PERM_VEC);
2185fe6060f1SDimitry Andric  dag BE_32B_VARIABLE_FLOAT = (XSCVSPDPN BE_32B_VFLOAT_PERMUTE);
2186fe6060f1SDimitry Andric
21870b57cec5SDimitry Andric  /* BE variable double
21880b57cec5SDimitry Andric      Same as the BE doubleword except there is no move.
21890b57cec5SDimitry Andric  */
21900b57cec5SDimitry Andric  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21910b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21920b57cec5SDimitry Andric                                         BE_VDWORD_PERM_VEC));
21930b57cec5SDimitry Andric  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
2194fe6060f1SDimitry Andric
2195fe6060f1SDimitry Andric  //  BE variable double 32-bit version
2196fe6060f1SDimitry Andric  dag BE_32B_VDWORD_PERM_VEC = (v16i8 (LVSL (i32 ZERO),
2197fe6060f1SDimitry Andric                                        (RLWINM (ANDI_rec $Idx, 1), 3, 0, 28)));
2198fe6060f1SDimitry Andric  dag BE_32B_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2199fe6060f1SDimitry Andric                                      (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2200fe6060f1SDimitry Andric                                      BE_32B_VDWORD_PERM_VEC));
2201fe6060f1SDimitry Andric  dag BE_32B_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_32B_VDOUBLE_PERMUTE, VSRC);
22020b57cec5SDimitry Andric}
22030b57cec5SDimitry Andric
22040b57cec5SDimitry Andricdef AlignValues {
2205fe6060f1SDimitry Andric  dag F32_TO_BE_WORD1 = (v4f32 (XSCVDPSPN $B));
2206fe6060f1SDimitry Andric  dag I32_TO_BE_WORD1 = (SUBREG_TO_REG (i64 1), (MTVSRWZ $B), sub_64);
22070b57cec5SDimitry Andric}
22080b57cec5SDimitry Andric
22090b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64
22100b57cec5SDimitry Andricdef AnyExts {
22110b57cec5SDimitry Andric  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
22120b57cec5SDimitry Andric  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
22130b57cec5SDimitry Andric  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
22140b57cec5SDimitry Andric  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
22150b57cec5SDimitry Andric}
22160b57cec5SDimitry Andric
22170b57cec5SDimitry Andricdef DblToFlt {
22185ffd83dbSDimitry Andric  dag A0 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 0))));
22195ffd83dbSDimitry Andric  dag A1 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 1))));
22205ffd83dbSDimitry Andric  dag B0 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 0))));
22215ffd83dbSDimitry Andric  dag B1 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 1))));
22220b57cec5SDimitry Andric}
22230b57cec5SDimitry Andric
22240b57cec5SDimitry Andricdef ExtDbl {
22250b57cec5SDimitry Andric  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
22260b57cec5SDimitry Andric  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
22270b57cec5SDimitry Andric  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
22280b57cec5SDimitry Andric  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
22290b57cec5SDimitry Andric  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
22300b57cec5SDimitry Andric  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
22310b57cec5SDimitry Andric  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
22320b57cec5SDimitry Andric  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
22330b57cec5SDimitry Andric}
22340b57cec5SDimitry Andric
22350b57cec5SDimitry Andricdef ByteToWord {
22360b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
22370b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
22380b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
22390b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
22400b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
22410b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
22420b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
22430b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
22440b57cec5SDimitry Andric}
22450b57cec5SDimitry Andric
22460b57cec5SDimitry Andricdef ByteToDWord {
22470b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22480b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
22490b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22500b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
22510b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22520b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
22530b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22540b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
22550b57cec5SDimitry Andric}
22560b57cec5SDimitry Andric
22570b57cec5SDimitry Andricdef HWordToWord {
22580b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
22590b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
22600b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
22610b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
22620b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
22630b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
22640b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
22650b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
22660b57cec5SDimitry Andric}
22670b57cec5SDimitry Andric
22680b57cec5SDimitry Andricdef HWordToDWord {
22690b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22700b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
22710b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22720b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
22730b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22740b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
22750b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22760b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
22770b57cec5SDimitry Andric}
22780b57cec5SDimitry Andric
22790b57cec5SDimitry Andricdef WordToDWord {
22800b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
22810b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
22820b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
22830b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
22840b57cec5SDimitry Andric}
22850b57cec5SDimitry Andric
22860b57cec5SDimitry Andricdef FltToIntLoad {
2287fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 ForceXForm:$A)))));
22880b57cec5SDimitry Andric}
22890b57cec5SDimitry Andricdef FltToUIntLoad {
2290fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 ForceXForm:$A)))));
22910b57cec5SDimitry Andric}
22920b57cec5SDimitry Andricdef FltToLongLoad {
2293fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ForceXForm:$A)))));
22940b57cec5SDimitry Andric}
22950b57cec5SDimitry Andricdef FltToLongLoadP9 {
2296fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 DSForm:$A)))));
22970b57cec5SDimitry Andric}
22980b57cec5SDimitry Andricdef FltToULongLoad {
2299fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ForceXForm:$A)))));
23000b57cec5SDimitry Andric}
23010b57cec5SDimitry Andricdef FltToULongLoadP9 {
2302fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 DSForm:$A)))));
23030b57cec5SDimitry Andric}
23040b57cec5SDimitry Andricdef FltToLong {
23050b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
23060b57cec5SDimitry Andric}
23070b57cec5SDimitry Andricdef FltToULong {
23080b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
23090b57cec5SDimitry Andric}
23100b57cec5SDimitry Andricdef DblToInt {
23110b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
23120b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
23130b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
23140b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
23150b57cec5SDimitry Andric}
23160b57cec5SDimitry Andricdef DblToUInt {
23170b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
23180b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
23190b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
23200b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
23210b57cec5SDimitry Andric}
23220b57cec5SDimitry Andricdef DblToLong {
23230b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
23240b57cec5SDimitry Andric}
23250b57cec5SDimitry Andricdef DblToULong {
23260b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
23270b57cec5SDimitry Andric}
23280b57cec5SDimitry Andricdef DblToIntLoad {
2329fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ForceXForm:$A)))));
23300b57cec5SDimitry Andric}
23310b57cec5SDimitry Andricdef DblToIntLoadP9 {
2332fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load DSForm:$A)))));
23330b57cec5SDimitry Andric}
23340b57cec5SDimitry Andricdef DblToUIntLoad {
2335fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ForceXForm:$A)))));
23360b57cec5SDimitry Andric}
23370b57cec5SDimitry Andricdef DblToUIntLoadP9 {
2338fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load DSForm:$A)))));
23390b57cec5SDimitry Andric}
23400b57cec5SDimitry Andricdef DblToLongLoad {
2341fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load ForceXForm:$A)))));
23420b57cec5SDimitry Andric}
23430b57cec5SDimitry Andricdef DblToULongLoad {
2344fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load ForceXForm:$A)))));
23450b57cec5SDimitry Andric}
23460b57cec5SDimitry Andric
2347480093f4SDimitry Andric// FP load dags (for f32 -> v4f32)
2348480093f4SDimitry Andricdef LoadFP {
2349fe6060f1SDimitry Andric  dag A = (f32 (load ForceXForm:$A));
2350fe6060f1SDimitry Andric  dag B = (f32 (load ForceXForm:$B));
2351fe6060f1SDimitry Andric  dag C = (f32 (load ForceXForm:$C));
2352fe6060f1SDimitry Andric  dag D = (f32 (load ForceXForm:$D));
2353480093f4SDimitry Andric}
2354480093f4SDimitry Andric
23550b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32)
23560b57cec5SDimitry Andricdef MrgFP {
2357fe6060f1SDimitry Andric  dag LD32A = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64);
2358fe6060f1SDimitry Andric  dag LD32B = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$B), sub_64);
2359fe6060f1SDimitry Andric  dag LD32C = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$C), sub_64);
2360fe6060f1SDimitry Andric  dag LD32D = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$D), sub_64);
2361fe6060f1SDimitry Andric  dag AC = (XVCVDPSP (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
2362fe6060f1SDimitry Andric                               (SUBREG_TO_REG (i64 1), $C, sub_64), 0));
2363fe6060f1SDimitry Andric  dag BD = (XVCVDPSP (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64),
2364fe6060f1SDimitry Andric                               (SUBREG_TO_REG (i64 1), $D, sub_64), 0));
23650b57cec5SDimitry Andric  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
23660b57cec5SDimitry Andric  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
23670b57cec5SDimitry Andric  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
23680b57cec5SDimitry Andric  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
23690b57cec5SDimitry Andric}
23700b57cec5SDimitry Andric
23710b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors.
23720b57cec5SDimitry Andricdef MrgWords {
23730b57cec5SDimitry Andric  // For big endian, we merge low and hi doublewords (A, B).
23740b57cec5SDimitry Andric  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
23750b57cec5SDimitry Andric  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
23760b57cec5SDimitry Andric  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
23770b57cec5SDimitry Andric  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
23780b57cec5SDimitry Andric  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
23790b57cec5SDimitry Andric  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
23800b57cec5SDimitry Andric
23810b57cec5SDimitry Andric  // For little endian, we merge low and hi doublewords (B, A).
23820b57cec5SDimitry Andric  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
23830b57cec5SDimitry Andric  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
23840b57cec5SDimitry Andric  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
23850b57cec5SDimitry Andric  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
23860b57cec5SDimitry Andric  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
23870b57cec5SDimitry Andric  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
23880b57cec5SDimitry Andric
23890b57cec5SDimitry Andric  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
23900b57cec5SDimitry Andric  // then merge.
2391fe6060f1SDimitry Andric  dag AC = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$A, sub_64),
2392fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$C, sub_64), 0));
2393fe6060f1SDimitry Andric  dag BD = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$B, sub_64),
2394fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$D, sub_64), 0));
23950b57cec5SDimitry Andric  dag CVACS = (v4i32 (XVCVDPSXWS AC));
23960b57cec5SDimitry Andric  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
23970b57cec5SDimitry Andric  dag CVACU = (v4i32 (XVCVDPUXWS AC));
23980b57cec5SDimitry Andric  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
23990b57cec5SDimitry Andric
24000b57cec5SDimitry Andric  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
24010b57cec5SDimitry Andric  // then merge.
2402fe6060f1SDimitry Andric  dag DB = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$D, sub_64),
2403fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$B, sub_64), 0));
2404fe6060f1SDimitry Andric  dag CA = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$C, sub_64),
2405fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$A, sub_64), 0));
24060b57cec5SDimitry Andric  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
24070b57cec5SDimitry Andric  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
24080b57cec5SDimitry Andric  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
24090b57cec5SDimitry Andric  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
24100b57cec5SDimitry Andric}
24110b57cec5SDimitry Andric
2412fe6060f1SDimitry Andricdef DblwdCmp {
2413fe6060f1SDimitry Andric  dag SGTW = (v2i64 (v2i64 (VCMPGTSW v2i64:$vA, v2i64:$vB)));
2414fe6060f1SDimitry Andric  dag UGTW = (v2i64 (v2i64 (VCMPGTUW v2i64:$vA, v2i64:$vB)));
2415fe6060f1SDimitry Andric  dag EQW = (v2i64 (v2i64 (VCMPEQUW v2i64:$vA, v2i64:$vB)));
2416fe6060f1SDimitry Andric  dag UGTWSHAND = (v2i64 (XXLAND (v2i64 (XXSLDWI UGTW, UGTW, 1)), EQW));
2417fe6060f1SDimitry Andric  dag EQWSHAND = (v2i64 (XXLAND (v2i64 (XXSLDWI EQW, EQW, 1)), EQW));
2418fe6060f1SDimitry Andric  dag SGTWOR = (v2i64 (XXLOR SGTW, UGTWSHAND));
2419fe6060f1SDimitry Andric  dag UGTWOR = (v2i64 (XXLOR UGTW, UGTWSHAND));
2420fe6060f1SDimitry Andric  dag MRGSGT = (v2i64 (XXPERMDI (v2i64 (XXSPLTW SGTWOR, 0)),
2421fe6060f1SDimitry Andric                                (v2i64 (XXSPLTW SGTWOR, 2)), 0));
2422fe6060f1SDimitry Andric  dag MRGUGT = (v2i64 (XXPERMDI (v2i64 (XXSPLTW UGTWOR, 0)),
2423fe6060f1SDimitry Andric                                (v2i64 (XXSPLTW UGTWOR, 2)), 0));
2424fe6060f1SDimitry Andric  dag MRGEQ = (v2i64 (XXPERMDI (v2i64 (XXSPLTW EQWSHAND, 0)),
2425fe6060f1SDimitry Andric                               (v2i64 (XXSPLTW EQWSHAND, 2)), 0));
2426fe6060f1SDimitry Andric}
2427fe6060f1SDimitry Andric
24285ffd83dbSDimitry Andric//---------------------------- Anonymous Patterns ----------------------------//
24295ffd83dbSDimitry Andric// Predicate combinations are kept in roughly chronological order in terms of
24305ffd83dbSDimitry Andric// instruction availability in the architecture. For example, VSX came in with
24315ffd83dbSDimitry Andric// ISA 2.06 (Power7). There have since been additions in ISA 2.07 (Power8) and
24325ffd83dbSDimitry Andric// ISA 3.0 (Power9). However, the granularity of features on later subtargets
24335ffd83dbSDimitry Andric// is finer for various reasons. For example, we have Power8Vector,
24345ffd83dbSDimitry Andric// Power8Altivec, DirectMove that all came in with ISA 2.07. The situation is
24355ffd83dbSDimitry Andric// similar with ISA 3.0 with Power9Vector, Power9Altivec, IsISA3_0. Then there
24365ffd83dbSDimitry Andric// are orthogonal predicates such as endianness for which the order was
24375ffd83dbSDimitry Andric// arbitrarily chosen to be Big, Little.
24385ffd83dbSDimitry Andric//
24395ffd83dbSDimitry Andric// Predicate combinations available:
2440e8d8bef9SDimitry Andric// [HasVSX, IsLittleEndian, HasP8Altivec] Altivec patterns using VSX instr.
2441e8d8bef9SDimitry Andric// [HasVSX, IsBigEndian, HasP8Altivec] Altivec patterns using VSX instr.
24425ffd83dbSDimitry Andric// [HasVSX]
24435ffd83dbSDimitry Andric// [HasVSX, IsBigEndian]
24445ffd83dbSDimitry Andric// [HasVSX, IsLittleEndian]
24455ffd83dbSDimitry Andric// [HasVSX, NoP9Vector]
2446e8d8bef9SDimitry Andric// [HasVSX, NoP9Vector, IsLittleEndian]
2447fe6060f1SDimitry Andric// [HasVSX, NoP9Vector, IsBigEndian]
24485ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps]
24495ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps, IsBigEndian]
24505ffd83dbSDimitry Andric// [HasVSX, HasP8Vector]
2451fe6060f1SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian]
2452e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian, IsPPC64]
24535ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, IsLittleEndian]
2454e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64]
24555ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian]
24564824e7fdSDimitry Andric// [HasVSX, HasP8Altivec]
24575ffd83dbSDimitry Andric// [HasVSX, HasDirectMove]
24585ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsBigEndian]
24595ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsLittleEndian]
2460e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian, IsPPC64]
2461e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64]
24625ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian]
24635ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian]
24645ffd83dbSDimitry Andric// [HasVSX, HasP9Vector]
2465fe6060f1SDimitry Andric// [HasVSX, HasP9Vector, NoP10Vector]
2466fe6060f1SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian]
2467e8d8bef9SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian, IsPPC64]
24685ffd83dbSDimitry Andric// [HasVSX, HasP9Vector, IsLittleEndian]
24695ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec]
2470e8d8bef9SDimitry Andric// [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64]
24715ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec, IsLittleEndian]
2472e8d8bef9SDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64]
24735ffd83dbSDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian]
24740b57cec5SDimitry Andric
2475e8d8bef9SDimitry Andric// These Altivec patterns are here because we need a VSX instruction to match
2476e8d8bef9SDimitry Andric// the intrinsic (but only for little endian system).
2477e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsLittleEndian, HasP8Altivec] in
2478e8d8bef9SDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
2479e8d8bef9SDimitry Andric                                                    v16i8:$b, v16i8:$c)),
2480e8d8bef9SDimitry Andric            (v16i8 (VPERMXOR $a, $b, (XXLNOR (COPY_TO_REGCLASS $c, VSRC),
2481e8d8bef9SDimitry Andric                                             (COPY_TO_REGCLASS $c, VSRC))))>;
2482e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsBigEndian, HasP8Altivec] in
2483e8d8bef9SDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
2484e8d8bef9SDimitry Andric                                                    v16i8:$b, v16i8:$c)),
2485e8d8bef9SDimitry Andric            (v16i8 (VPERMXOR $a, $b, $c))>;
24864824e7fdSDimitry Andriclet Predicates = [HasVSX, HasP8Altivec] in
24874824e7fdSDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor_be v16i8:$a,
24884824e7fdSDimitry Andric                                                       v16i8:$b, v16i8:$c)),
24894824e7fdSDimitry Andric            (v16i8 (VPERMXOR $a, $b, $c))>;
2490e8d8bef9SDimitry Andric
24915ffd83dbSDimitry Andriclet AddedComplexity = 400 in {
24925ffd83dbSDimitry Andric// Valid for any VSX subtarget, regardless of endianness.
24930b57cec5SDimitry Andriclet Predicates = [HasVSX] in {
2494fe6060f1SDimitry Andricdef : Pat<(v4i32 (vnot v4i32:$A)),
24955ffd83dbSDimitry Andric          (v4i32 (XXLNOR $A, $A))>;
2496fe6060f1SDimitry Andricdef : Pat<(v4i32 (or (and (vnot v4i32:$C), v4i32:$A),
24975ffd83dbSDimitry Andric                     (and v4i32:$B, v4i32:$C))),
24985ffd83dbSDimitry Andric          (v4i32 (XXSEL $A, $B, $C))>;
24995ffd83dbSDimitry Andric
2500bdd1243dSDimitry Andricdef : Pat<(f64 (fpimm0neg)),
2501bdd1243dSDimitry Andric          (f64 (XSNEGDP (XXLXORdpz)))>;
2502bdd1243dSDimitry Andric
2503bdd1243dSDimitry Andricdef : Pat<(f32 (fpimm0neg)),
2504bdd1243dSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNEGDP (XXLXORdpz)), VSSRC))>;
2505bdd1243dSDimitry Andric
2506bdd1243dSDimitry Andricdef : Pat<(f64 (nzFPImmExactInti5:$A)),
2507bdd1243dSDimitry Andric          (COPY_TO_REGCLASS (XVCVSXWDP (COPY_TO_REGCLASS
2508bdd1243dSDimitry Andric                     (VSPLTISW (getFPAs5BitExactInt fpimm:$A)), VSRC)), VSFRC)>;
2509bdd1243dSDimitry Andric
2510bdd1243dSDimitry Andricdef : Pat<(f32 (nzFPImmExactInti5:$A)),
2511bdd1243dSDimitry Andric          (COPY_TO_REGCLASS (XVCVSXWDP (COPY_TO_REGCLASS
2512bdd1243dSDimitry Andric                     (VSPLTISW (getFPAs5BitExactInt fpimm:$A)), VSRC)), VSSRC)>;
2513bdd1243dSDimitry Andric
25145ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
25155ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
25165ffd83dbSDimitry Andric          (XSNMSUBADP $C, $A, $B)>;
25175ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
25185ffd83dbSDimitry Andric          (XSMSUBADP $C, $A, $B)>;
25195ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
25205ffd83dbSDimitry Andric          (XSNMADDADP $C, $A, $B)>;
25215ffd83dbSDimitry Andric
25225ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C),
25235ffd83dbSDimitry Andric          (XVNMSUBADP $C, $A, $B)>;
25245ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)),
25255ffd83dbSDimitry Andric          (XVMSUBADP $C, $A, $B)>;
25265ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)),
25275ffd83dbSDimitry Andric          (XVNMADDADP $C, $A, $B)>;
25285ffd83dbSDimitry Andric
25295ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C),
25305ffd83dbSDimitry Andric          (XVNMSUBASP $C, $A, $B)>;
25315ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
25325ffd83dbSDimitry Andric          (XVMSUBASP $C, $A, $B)>;
25335ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
25345ffd83dbSDimitry Andric          (XVNMADDASP $C, $A, $B)>;
25355ffd83dbSDimitry Andric
2536e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt f64:$frA), (XSSQRTDP $frA)>;
2537e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v2f64:$frA), (XVSQRTDP $frA)>;
2538e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v4f32:$frA), (XVSQRTSP $frA)>;
2539e8d8bef9SDimitry Andric
25405ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)),
25415ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25425ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)),
25435ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25445ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)),
25455ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25465ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)),
25475ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25485ffd83dbSDimitry Andric
25495ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)),
25505ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25515ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)),
25525ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25535ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)),
25545ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25555ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)),
25565ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25575ffd83dbSDimitry Andric
25585ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)),
25595ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25605ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)),
25615ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25625ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)),
25635ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25645ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)),
25655ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25665ffd83dbSDimitry Andric
25675ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)),
25685ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25695ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)),
25705ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25715ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)),
25725ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25735ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)),
25745ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25755ffd83dbSDimitry Andric
25765ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)),
25775ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25785ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)),
25795ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25805ffd83dbSDimitry Andric
25815ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)),
25825ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25835ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)),
25845ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25855ffd83dbSDimitry Andric
25865ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)),
25875ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25885ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)),
25895ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25905ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)),
25915ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25925ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)),
25935ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25945ffd83dbSDimitry Andric
25955ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
25965ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
25975ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
25985ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
25995ffd83dbSDimitry Andric
26005ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
26015ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
26025ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
26035ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
26045ffd83dbSDimitry Andric
26055ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
26065ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
26075ffd83dbSDimitry Andric
26085ffd83dbSDimitry Andric// Permutes.
26095ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
26105ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
26115ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
26125ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
26135ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
26145ffd83dbSDimitry Andric
26155ffd83dbSDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
26165ffd83dbSDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
26175ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)),
26185ffd83dbSDimitry Andric          (XXPERMDI $src, $src, 2)>;
26195ffd83dbSDimitry Andric
26205ffd83dbSDimitry Andric// Selects.
26215ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
26225ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26235ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
26245ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26255ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
26265ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26275ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
26285ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26295ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
26305ffd83dbSDimitry Andric          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
26315ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
26325ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26335ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
26345ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26355ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
26365ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26375ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
26385ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26395ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
26405ffd83dbSDimitry Andric          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
26415ffd83dbSDimitry Andric
26425ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
26435ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26445ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
26455ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26465ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
26475ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26485ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
26495ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26505ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
26515ffd83dbSDimitry Andric          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
26525ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
26535ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26545ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
26555ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26565ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
26575ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26585ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
26595ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26605ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
26615ffd83dbSDimitry Andric          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
26625ffd83dbSDimitry Andric
26635ffd83dbSDimitry Andric// Divides.
26645ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
26655ffd83dbSDimitry Andric          (XVDIVSP $A, $B)>;
26665ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
26675ffd83dbSDimitry Andric          (XVDIVDP $A, $B)>;
26685ffd83dbSDimitry Andric
2669e8d8bef9SDimitry Andric// Vector test for software divide and sqrt.
2670e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)),
2671e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>;
2672e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)),
2673e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>;
2674e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)),
2675e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>;
2676e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)),
2677e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>;
2678e8d8bef9SDimitry Andric
26795ffd83dbSDimitry Andric// Reciprocal estimate
26805ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A),
26815ffd83dbSDimitry Andric          (XVRESP $A)>;
26825ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A),
26835ffd83dbSDimitry Andric          (XVREDP $A)>;
26845ffd83dbSDimitry Andric
26855ffd83dbSDimitry Andric// Recip. square root estimate
26865ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
26875ffd83dbSDimitry Andric          (XVRSQRTESP $A)>;
26885ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
26895ffd83dbSDimitry Andric          (XVRSQRTEDP $A)>;
26905ffd83dbSDimitry Andric
26915ffd83dbSDimitry Andric// Vector selection
26925ffd83dbSDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
26935ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
26945ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
26955ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
26965ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
26975ffd83dbSDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
26985ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
26995ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
27005ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
27015ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
27025ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
27035ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
27045ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
27055ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
27065ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
27075ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
27085ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
27095ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
2710fe6060f1SDimitry Andricdef : Pat<(v1i128 (vselect v1i128:$vA, v1i128:$vB, v1i128:$vC)),
2711fe6060f1SDimitry Andric          (COPY_TO_REGCLASS
2712fe6060f1SDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
2713fe6060f1SDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
2714fe6060f1SDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
27155ffd83dbSDimitry Andric
27165ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fmaxnum v4f32:$src1, v4f32:$src2)),
27175ffd83dbSDimitry Andric          (v4f32 (XVMAXSP $src1, $src2))>;
27185ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fminnum v4f32:$src1, v4f32:$src2)),
27195ffd83dbSDimitry Andric          (v4f32 (XVMINSP $src1, $src2))>;
27205ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fmaxnum v2f64:$src1, v2f64:$src2)),
27215ffd83dbSDimitry Andric          (v2f64 (XVMAXDP $src1, $src2))>;
27225ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fminnum v2f64:$src1, v2f64:$src2)),
27235ffd83dbSDimitry Andric          (v2f64 (XVMINDP $src1, $src2))>;
27245ffd83dbSDimitry Andric
27255ffd83dbSDimitry Andric// f32 abs
27265ffd83dbSDimitry Andricdef : Pat<(f32 (fabs f32:$S)),
27275ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSABSDP
27285ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27295ffd83dbSDimitry Andric
27305ffd83dbSDimitry Andric// f32 nabs
27315ffd83dbSDimitry Andricdef : Pat<(f32 (fneg (fabs f32:$S))),
27325ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNABSDP
27335ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27345ffd83dbSDimitry Andric
27355ffd83dbSDimitry Andric// f32 Min.
27365ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)),
27375ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27385ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)),
27395ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27405ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))),
27415ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27425ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
27435ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27445ffd83dbSDimitry Andric// F32 Max.
27455ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)),
27465ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27475ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)),
27485ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27495ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))),
27505ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27515ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
27525ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27535ffd83dbSDimitry Andric
27545ffd83dbSDimitry Andric// f64 Min.
27555ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)),
27565ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27575ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)),
27585ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27595ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))),
27605ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27615ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
27625ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27635ffd83dbSDimitry Andric// f64 Max.
27645ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)),
27655ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27665ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)),
27675ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27685ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))),
27695ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27705ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
27715ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27725ffd83dbSDimitry Andric
2773fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, ForceXForm:$dst),
2774fe6060f1SDimitry Andric            (STXVD2X $rS, ForceXForm:$dst)>;
2775fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, ForceXForm:$dst),
2776fe6060f1SDimitry Andric            (STXVW4X $rS, ForceXForm:$dst)>;
2777fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
2778fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
27795ffd83dbSDimitry Andric
27805ffd83dbSDimitry Andric// Rounding for single precision.
27815ffd83dbSDimitry Andricdef : Pat<(f32 (any_fround f32:$S)),
27825ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPI
27835ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27845ffd83dbSDimitry Andricdef : Pat<(f32 (any_ffloor f32:$S)),
27855ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIM
27865ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27875ffd83dbSDimitry Andricdef : Pat<(f32 (any_fceil f32:$S)),
27885ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIP
27895ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27905ffd83dbSDimitry Andricdef : Pat<(f32 (any_ftrunc f32:$S)),
27915ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIZ
27925ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27935ffd83dbSDimitry Andricdef : Pat<(f32 (any_frint f32:$S)),
27945ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
27955ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2796e8d8bef9SDimitry Andricdef : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
27975ffd83dbSDimitry Andric
27985ffd83dbSDimitry Andric// Rounding for double precision.
2799e8d8bef9SDimitry Andricdef : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>;
2800e8d8bef9SDimitry Andricdef : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
28015ffd83dbSDimitry Andric
2802349cc55cSDimitry Andric// Rounding without exceptions (nearbyint). Due to strange tblgen behaviour,
2803349cc55cSDimitry Andric// these need to be defined after the any_frint versions so ISEL will correctly
2804349cc55cSDimitry Andric// add the chain to the strict versions.
2805349cc55cSDimitry Andricdef : Pat<(f32 (fnearbyint f32:$S)),
2806349cc55cSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
2807349cc55cSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2808349cc55cSDimitry Andricdef : Pat<(f64 (fnearbyint f64:$S)),
2809349cc55cSDimitry Andric          (f64 (XSRDPIC $S))>;
2810349cc55cSDimitry Andricdef : Pat<(v2f64 (fnearbyint v2f64:$S)),
2811349cc55cSDimitry Andric          (v2f64 (XVRDPIC $S))>;
2812349cc55cSDimitry Andricdef : Pat<(v4f32 (fnearbyint v4f32:$S)),
2813349cc55cSDimitry Andric          (v4f32 (XVRSPIC $S))>;
2814349cc55cSDimitry Andric
28155ffd83dbSDimitry Andric// Materialize a zero-vector of long long
28165ffd83dbSDimitry Andricdef : Pat<(v2i64 immAllZerosV),
28175ffd83dbSDimitry Andric          (v2i64 (XXLXORz))>;
28185ffd83dbSDimitry Andric
28190b57cec5SDimitry Andric// Build vectors of floating point converted to i32.
28200b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
28210b57cec5SDimitry Andric                               DblToInt.A, DblToInt.A)),
2822fe6060f1SDimitry Andric          (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS $A), sub_64), 1))>;
28230b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
28240b57cec5SDimitry Andric                               DblToUInt.A, DblToUInt.A)),
2825fe6060f1SDimitry Andric          (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS $A), sub_64), 1))>;
28260b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
2827fe6060f1SDimitry Andric          (v2i64 (XXPERMDI (SUBREG_TO_REG (i64 1), (XSCVDPSXDS $A), sub_64),
2828fe6060f1SDimitry Andric                           (SUBREG_TO_REG (i64 1), (XSCVDPSXDS $A), sub_64), 0))>;
28290b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
2830fe6060f1SDimitry Andric          (v2i64 (XXPERMDI (SUBREG_TO_REG (i64 1), (XSCVDPUXDS $A), sub_64),
2831fe6060f1SDimitry Andric                           (SUBREG_TO_REG (i64 1), (XSCVDPUXDS $A), sub_64), 0))>;
2832349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCSToV DblToInt.A)),
2833349cc55cSDimitry Andric          (v4i32 (SUBREG_TO_REG (i64 1), (XSCVDPSXWS f64:$A), sub_64))>;
2834349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCSToV DblToUInt.A)),
2835349cc55cSDimitry Andric          (v4i32 (SUBREG_TO_REG (i64 1), (XSCVDPUXWS f64:$A), sub_64))>;
28365ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28375ffd83dbSDimitry Andric  v4i32, FltToIntLoad.A,
2838fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWSs (XFLOADf32 ForceXForm:$A)), sub_64), 1),
2839fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWSs (XFLOADf32 ForceXForm:$A)), sub_64)>;
28405ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28415ffd83dbSDimitry Andric  v4i32, FltToUIntLoad.A,
2842fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWSs (XFLOADf32 ForceXForm:$A)), sub_64), 1),
2843fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWSs (XFLOADf32 ForceXForm:$A)), sub_64)>;
2844fe6060f1SDimitry Andricdef : Pat<(v4f32 (build_vector (f32 (fpround f64:$A)), (f32 (fpround f64:$A)),
2845fe6060f1SDimitry Andric                               (f32 (fpround f64:$A)), (f32 (fpround f64:$A)))),
2846fe6060f1SDimitry Andric          (v4f32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$A), sub_64), 0))>;
2847fe6060f1SDimitry Andric
28480b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
28490b57cec5SDimitry Andric          (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
2850349cc55cSDimitry Andric
2851349cc55cSDimitry Andric// Splat loads.
2852fe6060f1SDimitry Andricdef : Pat<(v2f64 (PPCldsplat ForceXForm:$A)),
2853fe6060f1SDimitry Andric          (v2f64 (LXVDSX ForceXForm:$A))>;
2854349cc55cSDimitry Andricdef : Pat<(v4f32 (PPCldsplat ForceXForm:$A)),
2855349cc55cSDimitry Andric          (v4f32 (XXSPLTW (SUBREG_TO_REG (i64 1), (LFIWZX ForceXForm:$A), sub_64), 1))>;
2856fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCldsplat ForceXForm:$A)),
2857fe6060f1SDimitry Andric          (v2i64 (LXVDSX ForceXForm:$A))>;
2858349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCldsplat ForceXForm:$A)),
2859349cc55cSDimitry Andric          (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (LFIWZX ForceXForm:$A), sub_64), 1))>;
2860349cc55cSDimitry Andricdef : Pat<(v2i64 (PPCzextldsplat ForceXForm:$A)),
2861349cc55cSDimitry Andric          (v2i64 (XXPERMDIs (LFIWZX ForceXForm:$A), 0))>;
2862349cc55cSDimitry Andricdef : Pat<(v2i64 (PPCsextldsplat ForceXForm:$A)),
2863349cc55cSDimitry Andric          (v2i64 (XXPERMDIs (LFIWAX ForceXForm:$A), 0))>;
28640b57cec5SDimitry Andric
28650b57cec5SDimitry Andric// Build vectors of floating point converted to i64.
28660b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
28670b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
28680b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
28690b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
28700b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
28710b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
28725ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28735ffd83dbSDimitry Andric  v2i64, DblToLongLoad.A,
2874fe6060f1SDimitry Andric  (XVCVDPSXDS (LXVDSX ForceXForm:$A)), (XVCVDPSXDS (LXVDSX ForceXForm:$A))>;
28755ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28765ffd83dbSDimitry Andric  v2i64, DblToULongLoad.A,
2877fe6060f1SDimitry Andric  (XVCVDPUXDS (LXVDSX ForceXForm:$A)), (XVCVDPUXDS (LXVDSX ForceXForm:$A))>;
2878fe6060f1SDimitry Andric
2879fe6060f1SDimitry Andric// Doubleword vector predicate comparisons without Power8.
2880fe6060f1SDimitry Andriclet AddedComplexity = 0 in {
2881fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 967)),
2882fe6060f1SDimitry Andric          (VCMPGTUB_rec DblwdCmp.MRGSGT, (v2i64 (XXLXORz)))>;
2883fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 711)),
2884fe6060f1SDimitry Andric          (VCMPGTUB_rec DblwdCmp.MRGUGT, (v2i64 (XXLXORz)))>;
2885fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 199)),
2886fe6060f1SDimitry Andric          (VCMPGTUB_rec DblwdCmp.MRGEQ, (v2i64 (XXLXORz)))>;
2887fe6060f1SDimitry Andric} // AddedComplexity = 0
2888fe6060f1SDimitry Andric
2889fe6060f1SDimitry Andric// XL Compat builtins.
2890fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsub f64:$A, f64:$B, f64:$C), (XSMSUBMDP $A, $B, $C)>;
2891fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (XSNMADDMDP $A, $B, $C)>;
2892fe6060f1SDimitry Andricdef : Pat<(int_ppc_fre f64:$A), (XSREDP $A)>;
2893fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrte vsfrc:$XB), (XSRSQRTEDP $XB)>;
289481ad6265SDimitry Andricdef : Pat<(int_ppc_fnabs f64:$A), (XSNABSDP $A)>;
289581ad6265SDimitry Andricdef : Pat<(int_ppc_fnabss f32:$A), (XSNABSDPs $A)>;
289681ad6265SDimitry Andric
289781ad6265SDimitry Andric// XXMRG[LH]W is a direct replacement for VMRG[LH]W respectively.
289881ad6265SDimitry Andric// Prefer the VSX form for greater register range.
289981ad6265SDimitry Andricdef:Pat<(vmrglw_unary_shuffle v16i8:$vA, undef),
290081ad6265SDimitry Andric        (COPY_TO_REGCLASS (XXMRGLW (COPY_TO_REGCLASS $vA, VSRC),
290181ad6265SDimitry Andric                                   (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
290281ad6265SDimitry Andricdef:Pat<(vmrghw_unary_shuffle v16i8:$vA, undef),
290381ad6265SDimitry Andric        (COPY_TO_REGCLASS (XXMRGHW (COPY_TO_REGCLASS $vA, VSRC),
290481ad6265SDimitry Andric                                   (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
290581ad6265SDimitry Andricdef:Pat<(vmrglw_shuffle v16i8:$vA, v16i8:$vB),
290681ad6265SDimitry Andric        (COPY_TO_REGCLASS (XXMRGLW (COPY_TO_REGCLASS $vA, VSRC),
290781ad6265SDimitry Andric                                   (COPY_TO_REGCLASS $vB, VSRC)), VRRC)>;
290881ad6265SDimitry Andricdef:Pat<(vmrghw_shuffle v16i8:$vA, v16i8:$vB),
290981ad6265SDimitry Andric        (COPY_TO_REGCLASS (XXMRGHW (COPY_TO_REGCLASS $vA, VSRC),
291081ad6265SDimitry Andric                                   (COPY_TO_REGCLASS $vB, VSRC)), VRRC)>;
291181ad6265SDimitry Andricdef:Pat<(vmrglw_swapped_shuffle v16i8:$vA, v16i8:$vB),
291281ad6265SDimitry Andric        (COPY_TO_REGCLASS (XXMRGLW (COPY_TO_REGCLASS $vB, VSRC),
291381ad6265SDimitry Andric                                   (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
291481ad6265SDimitry Andricdef:Pat<(vmrghw_swapped_shuffle v16i8:$vA, v16i8:$vB),
291581ad6265SDimitry Andric        (COPY_TO_REGCLASS (XXMRGHW (COPY_TO_REGCLASS $vB, VSRC),
291681ad6265SDimitry Andric                                   (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
29175ffd83dbSDimitry Andric} // HasVSX
29180b57cec5SDimitry Andric
29195ffd83dbSDimitry Andric// Any big endian VSX subtarget.
29205ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsBigEndian] in {
29215ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)),
29225ffd83dbSDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
29230b57cec5SDimitry Andric
29245ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
29255ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
29265ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
29275ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
29285ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
29295ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
29305ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
29315ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
29325ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
29335ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
29345ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
29355ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
29360b57cec5SDimitry Andric
29375ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
29385ffd83dbSDimitry Andric          (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
29390b57cec5SDimitry Andric
29400b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
29410b57cec5SDimitry Andric          (v2f64 (XXPERMDI
2942fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $A, sub_64),
2943fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>;
2944480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
2945480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
2946480093f4SDimitry Andric// XXPERMDI for 2 reasons:
2947480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
2948480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
2949480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
2950480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
2951480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2952480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
2953480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2954480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B),
2955480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>;
29560b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
29570b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
29580b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
29590b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
29600b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
29610b57cec5SDimitry Andric
29620b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
29630b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
29640b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
29650b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
29660b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
29670b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
29680b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
29690b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
29700b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
29710b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
29720b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
29730b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
29740b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
29755ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29765ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
29775ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
29785ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
29795ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
29805ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
29815ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
29825ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29835ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
29845ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
29855ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
29865ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
29875ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>;
29885ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
29895ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
29905ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
29915ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
29925ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
29935ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
29945ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
29955ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29965ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
29975ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>;
29985ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
29995ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
30005ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3),
30015ffd83dbSDimitry Andric                                    (XXPERMDI $A, $B, 3), 1)))>;
3002fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
3003fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
3004fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
3005fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS $A))>;
3006fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
3007fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
3008fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
3009fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS $A))>;
3010fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
3011fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
3012fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
3013fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS (XXSLDWI $A, $A, 1)))>;
3014fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
3015fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
3016fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
3017fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS (XXSLDWI $A, $A, 1)))>;
30185ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
30195ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
30205ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
3021349cc55cSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
30225ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
30235ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
30245ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
3025349cc55cSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
3026fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 0)),
3027fe6060f1SDimitry Andric          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), $A, 1))>;
3028fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 1)),
3029fe6060f1SDimitry Andric          (v2f64 (XXPERMDI $A, (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>;
30305ffd83dbSDimitry Andric} // HasVSX, IsBigEndian
30310b57cec5SDimitry Andric
30325ffd83dbSDimitry Andric// Any little endian VSX subtarget.
30335ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsLittleEndian] in {
30345ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2f64, (f64 f64:$A),
30355ffd83dbSDimitry Andric                         (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
30365ffd83dbSDimitry Andric                                   (SUBREG_TO_REG (i64 1), $A, sub_64), 0),
30375ffd83dbSDimitry Andric                         (SUBREG_TO_REG (i64 1), $A, sub_64)>;
30380b57cec5SDimitry Andric
30395ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
30405ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
30415ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
30425ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
30430b57cec5SDimitry Andric
3044fe6060f1SDimitry Andricdef : Pat<(v2f64 (PPCld_vec_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3045fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3046fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCld_vec_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3047fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v4f32:$rS, ForceXForm:$dst), (STXVW4X $rS, ForceXForm:$dst)>;
3048fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCld_vec_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3049fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v2i64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3050fe6060f1SDimitry Andricdef : Pat<(v4i32 (PPCld_vec_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3051fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v4i32:$rS, ForceXForm:$dst), (STXVW4X $rS, ForceXForm:$dst)>;
30525ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
30535ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
30545ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
30555ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
30565ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
30575ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
30585ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
30595ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
30600b57cec5SDimitry Andric
30615ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
30625ffd83dbSDimitry Andric          (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
30635ffd83dbSDimitry Andric
30640b57cec5SDimitry Andric// Little endian, available on all targets with VSX
30650b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
30660b57cec5SDimitry Andric          (v2f64 (XXPERMDI
3067fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $B, sub_64),
3068fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
3069480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
3070480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
3071480093f4SDimitry Andric// XXPERMDI for 2 reasons:
3072480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
3073480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
3074480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
3075480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
3076480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
3077480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
3078480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
3079480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C),
3080480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>;
30810b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
30820b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
30830b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
30840b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
30850b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
30860b57cec5SDimitry Andric
30870b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
30880b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
30890b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
30900b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
30910b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
30920b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
30930b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
30940b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
30950b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
30960b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
30970b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
30980b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
30990b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
31005ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
31015ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
31025ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
31035ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
31045ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
31055ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
31065ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
31075ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
31085ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
31095ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>;
31105ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
31115ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
31125ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
31135ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
31145ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
31155ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
31165ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
31175ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
31185ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
31195ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
31205ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
31215ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
31225ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3),
31235ffd83dbSDimitry Andric                                    (XXPERMDI $B, $A, 3), 1)))>;
31245ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
31255ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
31265ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>;
3127fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
3128fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
3129fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
3130fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS $A))>;
3131fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
3132fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
3133fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
3134fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS $A))>;
3135fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
3136fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
3137fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
3138fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS (XXSLDWI $A, $A, 1)))>;
3139fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
3140fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
3141fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
3142fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS (XXSLDWI $A, $A, 1)))>;
31435ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
31445ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
31455ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
31465ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
31475ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
31485ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
31495ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
31505ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
3151fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 0)),
3152fe6060f1SDimitry Andric          (v2f64 (XXPERMDI $A, (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>;
3153fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 1)),
3154fe6060f1SDimitry Andric          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), $A, 1))>;
31555ffd83dbSDimitry Andric} // HasVSX, IsLittleEndian
31560b57cec5SDimitry Andric
31575ffd83dbSDimitry Andric// Any pre-Power9 VSX subtarget.
31585ffd83dbSDimitry Andriclet Predicates = [HasVSX, NoP9Vector] in {
31595ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3160fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 8),
3161fe6060f1SDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), ForceXForm:$dst)>;
31625ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3163fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 8),
3164fe6060f1SDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), ForceXForm:$dst)>;
31655ffd83dbSDimitry Andric
31665ffd83dbSDimitry Andric// Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
31675ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31685ffd83dbSDimitry Andric  v4i32, DblToIntLoad.A,
3169fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (XFLOADf64 ForceXForm:$A)), sub_64), 1),
3170fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (XFLOADf64 ForceXForm:$A)), sub_64)>;
31715ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31725ffd83dbSDimitry Andric  v4i32, DblToUIntLoad.A,
3173fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (XFLOADf64 ForceXForm:$A)), sub_64), 1),
3174fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (XFLOADf64 ForceXForm:$A)), sub_64)>;
31755ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31765ffd83dbSDimitry Andric  v2i64, FltToLongLoad.A,
3177fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), VSFRC)), 0),
3178fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A),
31795ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
31805ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31815ffd83dbSDimitry Andric  v2i64, FltToULongLoad.A,
3182fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), VSFRC)), 0),
3183fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A),
31845ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
31855ffd83dbSDimitry Andric} // HasVSX, NoP9Vector
31865ffd83dbSDimitry Andric
3187e8d8bef9SDimitry Andric// Any little endian pre-Power9 VSX subtarget.
3188e8d8bef9SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsLittleEndian] in {
3189e8d8bef9SDimitry Andric// Load-and-splat using only X-Form VSX loads.
3190e8d8bef9SDimitry Andricdefm : ScalToVecWPermute<
3191fe6060f1SDimitry Andric  v2i64, (i64 (load ForceXForm:$src)),
3192fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 ForceXForm:$src), 2),
3193fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>;
3194e8d8bef9SDimitry Andricdefm : ScalToVecWPermute<
3195fe6060f1SDimitry Andric  v2f64, (f64 (load ForceXForm:$src)),
3196fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 ForceXForm:$src), 2),
3197fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>;
31980eae32dcSDimitry Andric
31990eae32dcSDimitry Andric// Splat loads.
32000eae32dcSDimitry Andricdef : Pat<(v8i16 (PPCldsplatAlign16 ForceXForm:$A)),
32010eae32dcSDimitry Andric          (v8i16 (VSPLTH 7, (LVX ForceXForm:$A)))>;
32020eae32dcSDimitry Andricdef : Pat<(v16i8 (PPCldsplatAlign16 ForceXForm:$A)),
32030eae32dcSDimitry Andric          (v16i8 (VSPLTB 15, (LVX ForceXForm:$A)))>;
3204e8d8bef9SDimitry Andric} // HasVSX, NoP9Vector, IsLittleEndian
3205e8d8bef9SDimitry Andric
3206fe6060f1SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsBigEndian] in {
3207fe6060f1SDimitry Andric  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x ForceXForm:$src)),
3208fe6060f1SDimitry Andric            (LXVD2X ForceXForm:$src)>;
3209fe6060f1SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, ForceXForm:$dst),
3210fe6060f1SDimitry Andric            (STXVD2X $rS, ForceXForm:$dst)>;
32110eae32dcSDimitry Andric
32120eae32dcSDimitry Andric  // Splat loads.
32130eae32dcSDimitry Andric  def : Pat<(v8i16 (PPCldsplatAlign16 ForceXForm:$A)),
32140eae32dcSDimitry Andric            (v8i16 (VSPLTH 0, (LVX ForceXForm:$A)))>;
32150eae32dcSDimitry Andric  def : Pat<(v16i8 (PPCldsplatAlign16 ForceXForm:$A)),
32160eae32dcSDimitry Andric            (v16i8 (VSPLTB 0, (LVX ForceXForm:$A)))>;
3217fe6060f1SDimitry Andric} // HasVSX, NoP9Vector, IsBigEndian
3218fe6060f1SDimitry Andric
32195ffd83dbSDimitry Andric// Any VSX subtarget that only has loads and stores that load in big endian
32205ffd83dbSDimitry Andric// order regardless of endianness. This is really pre-Power9 subtargets.
32215ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3222fe6060f1SDimitry Andric  def : Pat<(v2f64 (PPClxvd2x ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
32235ffd83dbSDimitry Andric
32245ffd83dbSDimitry Andric  // Stores.
3225fe6060f1SDimitry Andric  def : Pat<(PPCstxvd2x v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
32265ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps
32275ffd83dbSDimitry Andric
3228e8d8bef9SDimitry Andric// Big endian VSX subtarget that only has loads and stores that always
3229e8d8bef9SDimitry Andric// load in big endian order. Really big endian pre-Power9 subtargets.
32305ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in {
3231fe6060f1SDimitry Andric  def : Pat<(v2f64 (load ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3232fe6060f1SDimitry Andric  def : Pat<(v2i64 (load ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3233fe6060f1SDimitry Andric  def : Pat<(v4i32 (load ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3234fe6060f1SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3235fe6060f1SDimitry Andric  def : Pat<(store v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3236fe6060f1SDimitry Andric  def : Pat<(store v2i64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3237fe6060f1SDimitry Andric  def : Pat<(store v4i32:$XT, ForceXForm:$dst), (STXVW4X $XT, ForceXForm:$dst)>;
3238fe6060f1SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, ForceXForm:$dst),
3239fe6060f1SDimitry Andric            (STXVW4X $rS, ForceXForm:$dst)>;
3240fe6060f1SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector (i64 (load ForceXForm:$src)))),
3241fe6060f1SDimitry Andric           (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>;
32425ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps, IsBigEndian
32435ffd83dbSDimitry Andric
32445ffd83dbSDimitry Andric// Any Power8 VSX subtarget.
32455ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
32465ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
32475ffd83dbSDimitry Andric          (XXLEQV $A, $B)>;
3248fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 XForm:$src)),
3249fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (XFLOADf32 XForm:$src), VSFRC)>;
3250fe6060f1SDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 ForceXForm:$src)))),
3251fe6060f1SDimitry Andric          (f32 (XFLOADf32 ForceXForm:$src))>;
32525ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpextend f32:$src)),
32535ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $src, VSFRC)>;
32545ffd83dbSDimitry Andric
32555ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
32565ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
32575ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
32585ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
32595ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
32605ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
32615ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
32625ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
32635ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
32645ffd83dbSDimitry Andric          (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
32655ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
32665ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
32675ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
32685ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
32695ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
32705ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
32715ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
32725ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
32735ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
32745ffd83dbSDimitry Andric          (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
32755ffd83dbSDimitry Andric
32765ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
32775ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
32785ffd83dbSDimitry Andric          (XSNMSUBASP $C, $A, $B)>;
32795ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
32805ffd83dbSDimitry Andric          (XSMSUBASP $C, $A, $B)>;
32815ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
32825ffd83dbSDimitry Andric          (XSNMADDASP $C, $A, $B)>;
32835ffd83dbSDimitry Andric
32845ffd83dbSDimitry Andric// f32 neg
32855ffd83dbSDimitry Andric// Although XSNEGDP is available in P7, we want to select it starting from P8,
32865ffd83dbSDimitry Andric// so that FNMSUBS can be selected for fneg-fmsub pattern on P7. (VSX version,
32875ffd83dbSDimitry Andric// XSNMSUBASP, is available since P8)
32885ffd83dbSDimitry Andricdef : Pat<(f32 (fneg f32:$S)),
32895ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNEGDP
32905ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
32915ffd83dbSDimitry Andric
32925ffd83dbSDimitry Andric// Instructions for converting float to i32 feeding a store.
32935ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3294fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 4),
3295fe6060f1SDimitry Andric          (STIWX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>;
32965ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3297fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 4),
3298fe6060f1SDimitry Andric          (STIWX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>;
32995ffd83dbSDimitry Andric
33005ffd83dbSDimitry Andricdef : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
33015ffd83dbSDimitry Andric          (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
33025ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
33035ffd83dbSDimitry Andricdef : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
33045ffd83dbSDimitry Andric          (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
33055ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
33065ffd83dbSDimitry Andricdef : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
33075ffd83dbSDimitry Andric          (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
33085ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
33095ffd83dbSDimitry Andricdef : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
33105ffd83dbSDimitry Andric          (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
33115ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
33125ffd83dbSDimitry Andric
33135ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
33145ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
33155ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
33165ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
33175ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
33185ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
33195ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
33205ffd83dbSDimitry Andric          (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3321fe6060f1SDimitry Andric
3322fe6060f1SDimitry Andric// XL Compat builtins.
3323fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsubs f32:$A, f32:$B, f32:$C), (XSMSUBMSP $A, $B, $C)>;
3324fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadds f32:$A, f32:$B, f32:$C), (XSNMADDMSP $A, $B, $C)>;
3325fe6060f1SDimitry Andricdef : Pat<(int_ppc_fres f32:$A), (XSRESP $A)>;
3326fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_extract_exp f64:$A)),
3327fe6060f1SDimitry Andric          (EXTRACT_SUBREG (XSXEXPDP (COPY_TO_REGCLASS $A, VSFRC)), sub_32)>;
3328fe6060f1SDimitry Andricdef : Pat<(int_ppc_extract_sig f64:$A),
3329fe6060f1SDimitry Andric          (XSXSIGDP (COPY_TO_REGCLASS $A, VSFRC))>;
3330fe6060f1SDimitry Andricdef : Pat<(f64 (int_ppc_insert_exp f64:$A, i64:$B)),
3331fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (XSIEXPDP (COPY_TO_REGCLASS $A, G8RC), $B), F8RC)>;
3332fe6060f1SDimitry Andric
3333fe6060f1SDimitry Andricdef : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT),
3334fe6060f1SDimitry Andric          (STXSIWX f64:$XT, ForceXForm:$dst)>;
3335fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrtes vssrc:$XB), (XSRSQRTESP $XB)>;
33365ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
33375ffd83dbSDimitry Andric
3338fe6060f1SDimitry Andric// Any big endian Power8 VSX subtarget.
3339fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian] in {
33405ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
33415ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
33425ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
33435ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
33445ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
33455ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
33465ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
33475ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
33485ffd83dbSDimitry Andric
33495ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (BE)
3350fe6060f1SDimitry Andricdefm : ScalToVecWPermute<v4f32, (f32 f32:$A), (XSCVDPSPN $A), (XSCVDPSPN $A)>;
33515ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
33525ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
33535ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
33545ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
33555ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
33565ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
33575ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
33585ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
33595ffd83dbSDimitry Andric
33605ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
33615ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
33625ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
33635ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
33645ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
33655ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
33665ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
33675ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
33685ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
33695ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
33705ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
33715ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
33725ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
33735ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
33745ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
33755ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
33765ffd83dbSDimitry Andric
3377fe6060f1SDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i32:$Idx)),
3378fe6060f1SDimitry Andric          (f32 VectorExtractions.BE_32B_VARIABLE_FLOAT)>;
3379fe6060f1SDimitry Andric
3380fe6060f1SDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i32:$Idx)),
3381fe6060f1SDimitry Andric          (f64 VectorExtractions.BE_32B_VARIABLE_DOUBLE)>;
338281ad6265SDimitry Andric
338381ad6265SDimitry Andricdefm : ScalToVecWPermute<
338481ad6265SDimitry Andric  v4i32, (i32 (load ForceXForm:$src)),
338581ad6265SDimitry Andric  (XXSLDWIs (LIWZX ForceXForm:$src), 1),
338681ad6265SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
338781ad6265SDimitry Andricdefm : ScalToVecWPermute<
338881ad6265SDimitry Andric  v4f32, (f32 (load ForceXForm:$src)),
338981ad6265SDimitry Andric  (XXSLDWIs (LIWZX ForceXForm:$src), 1),
339081ad6265SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
3391fe6060f1SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian
3392fe6060f1SDimitry Andric
3393fe6060f1SDimitry Andric// Big endian Power8 64Bit VSX subtarget.
3394fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] in {
3395fe6060f1SDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
3396fe6060f1SDimitry Andric          (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
3397fe6060f1SDimitry Andric
33985ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
33995ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
34005ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
3401fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 ForceXForm:$src)))),
3402fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (LIWAX ForceXForm:$src), sub_64))>;
3403fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 ForceXForm:$src)))),
3404fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64))>;
34055ffd83dbSDimitry Andric
34065ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
34075ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
34085ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
34095ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
34105ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
34115ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
3412fe6060f1SDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 1)), ForceXForm:$src),
3413fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3414fe6060f1SDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 1)), ForceXForm:$src),
3415fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
34165ffd83dbSDimitry Andric
34175ffd83dbSDimitry Andric// Elements in a register on a BE system are in order <0, 1, 2, 3>.
34185ffd83dbSDimitry Andric// The store instructions store the second word from the left.
34195ffd83dbSDimitry Andric// So to align element zero, we need to modulo-left-shift by 3 words.
34205ffd83dbSDimitry Andric// Similar logic applies for elements 2 and 3.
34215ffd83dbSDimitry Andricforeach Idx = [ [0,3], [2,1], [3,2] ] in {
3422fe6060f1SDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), ForceXForm:$src),
34235ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3424fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
3425fe6060f1SDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), ForceXForm:$src),
34265ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3427fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
34285ffd83dbSDimitry Andric}
3429e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian, IsPPC64
34305ffd83dbSDimitry Andric
34315ffd83dbSDimitry Andric// Little endian Power8 VSX subtarget.
34325ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in {
34335ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
34345ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
34355ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
34365ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS
34375ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
34385ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
34395ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
34405ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
34415ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS
34425ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
34435ffd83dbSDimitry Andric
34445ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (LE)
34455ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4f32, (f32 f32:$A),
34465ffd83dbSDimitry Andric                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1),
3447fe6060f1SDimitry Andric                           (XSCVDPSPN $A)>;
34485ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
34495ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
34505ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
34515ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
34525ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
34535ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
34545ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
34555ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
34565ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
34575ffd83dbSDimitry Andric          (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
34585ffd83dbSDimitry Andric
34595ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
34605ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
34615ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
34625ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
34635ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
34645ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
34655ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
34665ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
34675ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
34685ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
34695ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
34705ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
34715ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
34725ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
34735ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
34745ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
34755ffd83dbSDimitry Andric
34765ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
34775ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
34785ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
34795ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3480fe6060f1SDimitry Andric  v2i64, (i64 (sextloadi32 ForceXForm:$src)),
3481fe6060f1SDimitry Andric  (XXPERMDIs (LIWAX ForceXForm:$src), 2),
3482fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWAX ForceXForm:$src), sub_64)>;
34835ffd83dbSDimitry Andric
34845ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3485fe6060f1SDimitry Andric  v2i64, (i64 (zextloadi32 ForceXForm:$src)),
3486fe6060f1SDimitry Andric  (XXPERMDIs (LIWZX ForceXForm:$src), 2),
3487fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
34885ffd83dbSDimitry Andric
34895ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3490fe6060f1SDimitry Andric  v4i32, (i32 (load ForceXForm:$src)),
3491fe6060f1SDimitry Andric  (XXPERMDIs (LIWZX ForceXForm:$src), 2),
3492fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
34935ffd83dbSDimitry Andric
34945ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3495fe6060f1SDimitry Andric  v4f32, (f32 (load ForceXForm:$src)),
3496fe6060f1SDimitry Andric  (XXPERMDIs (LIWZX ForceXForm:$src), 2),
3497fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
34985ffd83dbSDimitry Andric
34995ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
35005ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
35015ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
35025ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
35035ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
35045ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
3505fe6060f1SDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 2)), ForceXForm:$src),
3506fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3507fe6060f1SDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 2)), ForceXForm:$src),
3508fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
35095ffd83dbSDimitry Andric
35105ffd83dbSDimitry Andric// Elements in a register on a LE system are in order <3, 2, 1, 0>.
35115ffd83dbSDimitry Andric// The store instructions store the second word from the left.
35125ffd83dbSDimitry Andric// So to align element 3, we need to modulo-left-shift by 3 words.
35135ffd83dbSDimitry Andric// Similar logic applies for elements 0 and 1.
35145ffd83dbSDimitry Andricforeach Idx = [ [0,2], [1,1], [3,3] ] in {
3515fe6060f1SDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), ForceXForm:$src),
35165ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3517fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
3518fe6060f1SDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), ForceXForm:$src),
35195ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3520fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
35215ffd83dbSDimitry Andric}
35225ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, IsLittleEndian
35235ffd83dbSDimitry Andric
35245ffd83dbSDimitry Andric// Big endian pre-Power9 VSX subtarget.
3525e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] in {
3526fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), ForceXForm:$src),
3527fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3528fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), ForceXForm:$src),
3529fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3530fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), ForceXForm:$src),
35315ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3532fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3533fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), ForceXForm:$src),
35345ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3535fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3536e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64
35375ffd83dbSDimitry Andric
35385ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget.
35395ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in {
3540fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), ForceXForm:$src),
35415ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3542fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3543fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), ForceXForm:$src),
35445ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3545fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3546fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), ForceXForm:$src),
3547fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3548fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), ForceXForm:$src),
3549fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
35505ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian
35515ffd83dbSDimitry Andric
35525ffd83dbSDimitry Andric// Any VSX target with direct moves.
35535ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove] in {
35545ffd83dbSDimitry Andric// bitconvert f32 -> i32
35555ffd83dbSDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR)
3556fe6060f1SDimitry Andricdef : Pat<(i32 (bitconvert f32:$A)), Bitcast.FltToInt>;
3557fe6060f1SDimitry Andric
35585ffd83dbSDimitry Andric// bitconvert i32 -> f32
35595ffd83dbSDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single)
35605ffd83dbSDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)),
35615ffd83dbSDimitry Andric          (f32 (XSCVSPDPN
35625ffd83dbSDimitry Andric                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
35635ffd83dbSDimitry Andric
35645ffd83dbSDimitry Andric// bitconvert f64 -> i64
35655ffd83dbSDimitry Andric// (move to GPR, nothing else needed)
3566fe6060f1SDimitry Andricdef : Pat<(i64 (bitconvert f64:$A)), Bitcast.DblToLong>;
35675ffd83dbSDimitry Andric
35685ffd83dbSDimitry Andric// bitconvert i64 -> f64
35695ffd83dbSDimitry Andric// (move to FPR, nothing else needed)
35705ffd83dbSDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)),
35715ffd83dbSDimitry Andric          (f64 (MTVSRD $S))>;
35725ffd83dbSDimitry Andric
35735ffd83dbSDimitry Andric// Rounding to integer.
35745ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f64:$S)),
35755ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
35765ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f32:$S)),
35775ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
35785ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f64:$S)),
35795ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
35805ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f32:$S)),
35815ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
35825ffd83dbSDimitry Andricdef : Pat<(i64 (lround f64:$S)),
35835ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
35845ffd83dbSDimitry Andricdef : Pat<(i64 (lround f32:$S)),
35855ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
35865ffd83dbSDimitry Andricdef : Pat<(i64 (llround f64:$S)),
35875ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
35885ffd83dbSDimitry Andricdef : Pat<(i64 (llround f32:$S)),
35895ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
35905ffd83dbSDimitry Andric
35915ffd83dbSDimitry Andric// Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
35925ffd83dbSDimitry Andric// of f64
35935ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCmtvsrz i32:$A)),
35945ffd83dbSDimitry Andric          (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
35955ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCmtvsrz i32:$A)),
35965ffd83dbSDimitry Andric          (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
35975ffd83dbSDimitry Andric
35980b57cec5SDimitry Andric// Endianness-neutral constant splat on P8 and newer targets. The reason
35990b57cec5SDimitry Andric// for this pattern is that on targets with direct moves, we don't expand
36000b57cec5SDimitry Andric// BUILD_VECTOR nodes for v4i32.
36010b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
36020b57cec5SDimitry Andric                               immSExt5NonZero:$A, immSExt5NonZero:$A)),
36030b57cec5SDimitry Andric          (v4i32 (VSPLTISW imm:$A))>;
3604349cc55cSDimitry Andric
3605349cc55cSDimitry Andric// Splat loads.
3606349cc55cSDimitry Andricdef : Pat<(v8i16 (PPCldsplat ForceXForm:$A)),
3607349cc55cSDimitry Andric          (v8i16 (VSPLTHs 3, (MTVSRWZ (LHZX ForceXForm:$A))))>;
3608349cc55cSDimitry Andricdef : Pat<(v16i8 (PPCldsplat ForceXForm:$A)),
3609349cc55cSDimitry Andric          (v16i8 (VSPLTBs 7, (MTVSRWZ (LBZX ForceXForm:$A))))>;
36105ffd83dbSDimitry Andric} // HasVSX, HasDirectMove
36110b57cec5SDimitry Andric
36125ffd83dbSDimitry Andric// Big endian VSX subtarget with direct moves.
36135ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsBigEndian] in {
36145ffd83dbSDimitry Andric// v16i8 scalar <-> vector conversions (BE)
3615fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3616fe6060f1SDimitry Andric  v16i8, (i32 i32:$A),
3617fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64),
3618fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
3619fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3620fe6060f1SDimitry Andric  v8i16, (i32 i32:$A),
3621349cc55cSDimitry Andric  (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64),
3622fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
3623fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3624fe6060f1SDimitry Andric  v4i32, (i32 i32:$A),
3625fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64),
3626fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
36275ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector i64:$A)),
36285ffd83dbSDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
36295ffd83dbSDimitry Andric
36305ffd83dbSDimitry Andric// v2i64 scalar <-> vector conversions (BE)
36315ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 0)),
36325ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_1)>;
36335ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 1)),
36345ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_0)>;
36355ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
36365ffd83dbSDimitry Andric          (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
36375ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsBigEndian
36385ffd83dbSDimitry Andric
36395ffd83dbSDimitry Andric// Little endian VSX subtarget with direct moves.
36405ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsLittleEndian] in {
36415ffd83dbSDimitry Andric  // v16i8 scalar <-> vector conversions (LE)
36425ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v16i8, (i32 i32:$A),
36435ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
36445ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
36455ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v8i16, (i32 i32:$A),
36465ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
36475ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
36485ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4i32, (i32 i32:$A), MovesToVSR.LE_WORD_0,
36495ffd83dbSDimitry Andric                           (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
36505ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v2i64, (i64 i64:$A), MovesToVSR.LE_DWORD_0,
36515ffd83dbSDimitry Andric                           MovesToVSR.LE_DWORD_1>;
36525ffd83dbSDimitry Andric
36535ffd83dbSDimitry Andric  // v2i64 scalar <-> vector conversions (LE)
36545ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
36555ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
36565ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
36575ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
36585ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
36595ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
36605ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsLittleEndian
36615ffd83dbSDimitry Andric
36625ffd83dbSDimitry Andric// Big endian pre-P9 VSX subtarget with direct moves.
36635ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian] in {
36645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
36655ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
36665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
36675ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
36685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
36695ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
36705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
36715ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
36725ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
36735ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
36745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
36755ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
36765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
36775ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
36785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
36795ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
36805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
36815ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
36825ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
36835ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
36845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
36855ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
36865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
36875ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
36885ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
36895ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
36905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
36915ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
36925ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
36935ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
36945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
36955ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
36965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
36975ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
36985ffd83dbSDimitry Andric
36995ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (BE)
37005ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
37015ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
37025ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
37035ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
37045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
37055ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
37065ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
37075ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
37085ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
37095ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
37105ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
37115ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
37125ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
37135ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
37145ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
37155ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
37165ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
37175ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_HALF)>;
37185ffd83dbSDimitry Andric
37195ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (BE)
37205ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
37215ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
37225ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
37235ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
37245ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
37255ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
37265ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
37275ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
37285ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
37295ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_WORD)>;
37305ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian
37315ffd83dbSDimitry Andric
37325ffd83dbSDimitry Andric// Little endian pre-P9 VSX subtarget with direct moves.
37335ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] in {
37345ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
37355ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
37365ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
37375ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
37385ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
37395ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
37405ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
37415ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
37425ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
37435ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
37445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
37455ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
37465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
37475ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
37485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
37495ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
37505ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
37515ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
37525ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
37535ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
37545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
37555ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
37565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
37575ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
37585ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
37595ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
37605ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
37615ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
37625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
37635ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
37645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
37655ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
37665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
37675ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
37685ffd83dbSDimitry Andric
37695ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (LE)
37705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
37715ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
37725ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
37735ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
37745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
37755ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
37765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
37775ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
37785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
37795ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
37805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
37815ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
37825ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
37835ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
37845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
37855ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
37865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
37875ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_HALF)>;
37885ffd83dbSDimitry Andric
37895ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (LE)
37905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
37915ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
37925ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
37935ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
37945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
37955ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
37965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
37975ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
37985ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
37995ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_WORD)>;
38005ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian
38015ffd83dbSDimitry Andric
3802e8d8bef9SDimitry Andric// Big endian pre-Power9 64Bit VSX subtarget that has direct moves.
3803e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] in {
38040b57cec5SDimitry Andric// Big endian integer vectors using direct moves.
38050b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
38060b57cec5SDimitry Andric          (v2i64 (XXPERMDI
3807fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $A), sub_64),
3808fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $B), sub_64), 0))>;
38090b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
38100b57cec5SDimitry Andric          (XXPERMDI
3811fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3812fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), sub_64),
3813fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3814fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), sub_64), 0)>;
38150b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3816fe6060f1SDimitry Andric          (XXSPLTW (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64), 1)>;
3817e8d8bef9SDimitry Andric} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64
38180b57cec5SDimitry Andric
38195ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget that has direct moves.
38205ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in {
38210b57cec5SDimitry Andric// Little endian integer vectors using direct moves.
38220b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
38230b57cec5SDimitry Andric          (v2i64 (XXPERMDI
3824fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $B), sub_64),
3825fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $A), sub_64), 0))>;
38260b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
38270b57cec5SDimitry Andric          (XXPERMDI
3828fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3829fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), sub_64),
3830fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3831fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), sub_64), 0)>;
38320b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3833fe6060f1SDimitry Andric          (XXSPLTW (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64), 1)>;
38340b57cec5SDimitry Andric}
38350b57cec5SDimitry Andric
38365ffd83dbSDimitry Andric// Any Power9 VSX subtarget.
38375ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
38385ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
38395ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C),
38405ffd83dbSDimitry Andric          (XSNMSUBQP $C, $A, $B)>;
38415ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
38425ffd83dbSDimitry Andric          (XSMSUBQP $C, $A, $B)>;
38435ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
38445ffd83dbSDimitry Andric          (XSNMADDQP $C, $A, $B)>;
38458bcb0991SDimitry Andric
3846e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i64:$src)),
38475ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3848e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))),
38495ffd83dbSDimitry Andric          (f128 (XSCVSDQP $src))>;
3850e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))),
38515ffd83dbSDimitry Andric          (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
3852e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i64:$src)),
38535ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3854e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))),
38555ffd83dbSDimitry Andric          (f128 (XSCVUDQP $src))>;
38565ffd83dbSDimitry Andric
38575ffd83dbSDimitry Andric// Convert (Un)Signed Word -> QP.
3858e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i32:$src)),
38595ffd83dbSDimitry Andric          (f128 (XSCVSDQP (MTVSRWA $src)))>;
3860fe6060f1SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (load ForceXForm:$src)))),
3861fe6060f1SDimitry Andric          (f128 (XSCVSDQP (LIWAX ForceXForm:$src)))>;
3862e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i32:$src)),
38635ffd83dbSDimitry Andric          (f128 (XSCVUDQP (MTVSRWZ $src)))>;
3864fe6060f1SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i32 (load ForceXForm:$src)))),
3865fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LIWZX ForceXForm:$src)))>;
38665ffd83dbSDimitry Andric
38675ffd83dbSDimitry Andric// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
38685ffd83dbSDimitry Andric// separate pattern so that it can convert the input register class from
38695ffd83dbSDimitry Andric// VRRC(v8i16) to VSRC.
38705ffd83dbSDimitry Andricdef : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
38715ffd83dbSDimitry Andric          (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
38725ffd83dbSDimitry Andric
38735ffd83dbSDimitry Andric// Use current rounding mode
38745ffd83dbSDimitry Andricdef : Pat<(f128 (any_fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
38755ffd83dbSDimitry Andric// Round to nearest, ties away from zero
38765ffd83dbSDimitry Andricdef : Pat<(f128 (any_fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
38775ffd83dbSDimitry Andric// Round towards Zero
38785ffd83dbSDimitry Andricdef : Pat<(f128 (any_ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
38795ffd83dbSDimitry Andric// Round towards +Inf
38805ffd83dbSDimitry Andricdef : Pat<(f128 (any_fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
38815ffd83dbSDimitry Andric// Round towards -Inf
38825ffd83dbSDimitry Andricdef : Pat<(f128 (any_ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
38835ffd83dbSDimitry Andric// Use current rounding mode, [with Inexact]
38845ffd83dbSDimitry Andricdef : Pat<(f128 (any_frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
38855ffd83dbSDimitry Andric
38865ffd83dbSDimitry Andricdef : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
38875ffd83dbSDimitry Andric          (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
38885ffd83dbSDimitry Andric
38895ffd83dbSDimitry Andricdef : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
38905ffd83dbSDimitry Andric          (i64 (MFVSRD (EXTRACT_SUBREG
38915ffd83dbSDimitry Andric                          (v2i64 (XSXEXPQP $vA)), sub_64)))>;
38925ffd83dbSDimitry Andric
38935ffd83dbSDimitry Andric// Extra patterns expanding to vector Extract Word/Insert Word
38945ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
38955ffd83dbSDimitry Andric          (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
38965ffd83dbSDimitry Andricdef : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
38975ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
38985ffd83dbSDimitry Andric
38995ffd83dbSDimitry Andric// Vector Reverse
39005ffd83dbSDimitry Andricdef : Pat<(v8i16 (bswap v8i16 :$A)),
39015ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
39025ffd83dbSDimitry Andricdef : Pat<(v1i128 (bswap v1i128 :$A)),
39035ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
39045ffd83dbSDimitry Andric
39055ffd83dbSDimitry Andric// D-Form Load/Store
3906fe6060f1SDimitry Andricforeach Ty = [v4i32, v4f32, v2i64, v2f64] in {
3907fe6060f1SDimitry Andric  def : Pat<(Ty (load DQForm:$src)), (LXV memrix16:$src)>;
3908fe6060f1SDimitry Andric  def : Pat<(Ty (load XForm:$src)), (LXVX XForm:$src)>;
3909fe6060f1SDimitry Andric  def : Pat<(store Ty:$rS, DQForm:$dst), (STXV $rS, memrix16:$dst)>;
3910fe6060f1SDimitry Andric  def : Pat<(store Ty:$rS, XForm:$dst), (STXVX $rS, XForm:$dst)>;
3911fe6060f1SDimitry Andric}
3912fe6060f1SDimitry Andric
3913fe6060f1SDimitry Andricdef : Pat<(f128 (load DQForm:$src)),
39145ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3915fe6060f1SDimitry Andricdef : Pat<(f128 (load XForm:$src)),
3916fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LXVX XForm:$src), VRRC)>;
3917fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x DQForm:$src)), (LXV memrix16:$src)>;
3918fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x DQForm:$src)), (LXV memrix16:$src)>;
3919fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x XForm:$src)), (LXVX XForm:$src)>;
3920fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x XForm:$src)), (LXVX XForm:$src)>;
39215ffd83dbSDimitry Andric
3922fe6060f1SDimitry Andricdef : Pat<(store f128:$rS, DQForm:$dst),
39235ffd83dbSDimitry Andric          (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3924fe6060f1SDimitry Andricdef : Pat<(store f128:$rS, XForm:$dst),
3925fe6060f1SDimitry Andric          (STXVX (COPY_TO_REGCLASS $rS, VSRC), XForm:$dst)>;
3926fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, DQForm:$dst),
39275ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
3928fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, DQForm:$dst),
39295ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
3930fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, XForm:$dst),
3931fe6060f1SDimitry Andric          (STXVX $rS, XForm:$dst)>;
3932fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, XForm:$dst),
3933fe6060f1SDimitry Andric          (STXVX $rS, XForm:$dst)>;
39345ffd83dbSDimitry Andric
39355ffd83dbSDimitry Andric// Build vectors from i8 loads
39365ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.ZELi8,
3937fe6060f1SDimitry Andric                         (VSPLTHs 3, (LXSIBZX ForceXForm:$src)),
3938fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
39395ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi8,
3940fe6060f1SDimitry Andric                         (XXSPLTWs (LXSIBZX ForceXForm:$src), 1),
3941fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
39425ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi8i64,
3943fe6060f1SDimitry Andric                         (XXPERMDIs (LXSIBZX ForceXForm:$src), 0),
3944fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
3945fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3946fe6060f1SDimitry Andric  v4i32, ScalarLoads.SELi8,
3947fe6060f1SDimitry Andric  (XXSPLTWs (VEXTSB2Ws (LXSIBZX ForceXForm:$src)), 1),
3948fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSB2Ws (LXSIBZX ForceXForm:$src)), sub_64)>;
3949fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3950fe6060f1SDimitry Andric  v2i64, ScalarLoads.SELi8i64,
3951fe6060f1SDimitry Andric  (XXPERMDIs (VEXTSB2Ds (LXSIBZX ForceXForm:$src)), 0),
3952fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSB2Ds (LXSIBZX ForceXForm:$src)), sub_64)>;
39535ffd83dbSDimitry Andric
39545ffd83dbSDimitry Andric// Build vectors from i16 loads
3955fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3956fe6060f1SDimitry Andric  v4i32, ScalarLoads.ZELi16,
3957fe6060f1SDimitry Andric  (XXSPLTWs (LXSIHZX ForceXForm:$src), 1),
3958fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
3959fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3960fe6060f1SDimitry Andric  v2i64, ScalarLoads.ZELi16i64,
3961fe6060f1SDimitry Andric  (XXPERMDIs (LXSIHZX ForceXForm:$src), 0),
3962fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
3963fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3964fe6060f1SDimitry Andric  v4i32, ScalarLoads.SELi16,
3965fe6060f1SDimitry Andric  (XXSPLTWs (VEXTSH2Ws (LXSIHZX ForceXForm:$src)), 1),
3966fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSH2Ws (LXSIHZX ForceXForm:$src)), sub_64)>;
3967fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3968fe6060f1SDimitry Andric  v2i64, ScalarLoads.SELi16i64,
3969fe6060f1SDimitry Andric  (XXPERMDIs (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), 0),
3970fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), sub_64)>;
39715ffd83dbSDimitry Andric
39725ffd83dbSDimitry Andric// Load/convert and convert/store patterns for f16.
3973fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf16 ForceXForm:$src)),
3974fe6060f1SDimitry Andric          (f64 (XSCVHPDP (LXSIHZX ForceXForm:$src)))>;
3975fe6060f1SDimitry Andricdef : Pat<(truncstoref16 f64:$src, ForceXForm:$dst),
3976fe6060f1SDimitry Andric          (STXSIHX (XSCVDPHP $src), ForceXForm:$dst)>;
3977fe6060f1SDimitry Andricdef : Pat<(f32 (extloadf16 ForceXForm:$src)),
3978fe6060f1SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX ForceXForm:$src)), VSSRC))>;
3979fe6060f1SDimitry Andricdef : Pat<(truncstoref16 f32:$src, ForceXForm:$dst),
3980fe6060f1SDimitry Andric          (STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), ForceXForm:$dst)>;
39815ffd83dbSDimitry Andricdef : Pat<(f64 (f16_to_fp i32:$A)),
39825ffd83dbSDimitry Andric          (f64 (XSCVHPDP (MTVSRWZ $A)))>;
39835ffd83dbSDimitry Andricdef : Pat<(f32 (f16_to_fp i32:$A)),
39845ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (MTVSRWZ $A)), VSSRC))>;
39855ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f32:$A)),
39865ffd83dbSDimitry Andric          (i32 (MFVSRWZ (XSCVDPHP (COPY_TO_REGCLASS $A, VSFRC))))>;
39875ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f64:$A)), (i32 (MFVSRWZ (XSCVDPHP $A)))>;
39885ffd83dbSDimitry Andric
39895ffd83dbSDimitry Andric// Vector sign extensions
39905ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 1)),
39915ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
39925ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 2)),
39935ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
39945ffd83dbSDimitry Andric
3995fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 DSForm:$src)),
3996fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (DFLOADf32 DSForm:$src), VSFRC)>;
3997fe6060f1SDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 DSForm:$src)))),
3998fe6060f1SDimitry Andric          (f32 (DFLOADf32 DSForm:$src))>;
39995ffd83dbSDimitry Andric
4000fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh XForm:$src)),
4001fe6060f1SDimitry Andric          (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>;
4002fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh DSForm:$src)),
4003fe6060f1SDimitry Andric          (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>;
40045ffd83dbSDimitry Andric
40055ffd83dbSDimitry Andric// Convert (Un)Signed DWord in memory -> QP
4006fe6060f1SDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load XForm:$src)))),
4007fe6060f1SDimitry Andric          (f128 (XSCVSDQP (LXSDX XForm:$src)))>;
4008fe6060f1SDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load DSForm:$src)))),
4009fe6060f1SDimitry Andric          (f128 (XSCVSDQP (LXSD DSForm:$src)))>;
4010fe6060f1SDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load XForm:$src)))),
4011fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSDX XForm:$src)))>;
4012fe6060f1SDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load DSForm:$src)))),
4013fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSD DSForm:$src)))>;
40145ffd83dbSDimitry Andric
40155ffd83dbSDimitry Andric// Convert Unsigned HWord in memory -> QP
40165ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
4017fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSIHZX XForm:$src)))>;
40185ffd83dbSDimitry Andric
40195ffd83dbSDimitry Andric// Convert Unsigned Byte in memory -> QP
40205ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
4021fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSIBZX ForceXForm:$src)))>;
40225ffd83dbSDimitry Andric
40235ffd83dbSDimitry Andric// Truncate & Convert QP -> (Un)Signed (D)Word.
4024e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
4025e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
4026e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_sint f128:$src)),
40275ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
4028e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_uint f128:$src)),
40295ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
40305ffd83dbSDimitry Andric
40315ffd83dbSDimitry Andric// Instructions for store(fptosi).
40325ffd83dbSDimitry Andric// The 8-byte version is repeated here due to availability of D-Form STXSD.
40335ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4034fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), XForm:$dst, 8),
40355ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
4036fe6060f1SDimitry Andric                  XForm:$dst)>;
40375ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4038fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), DSForm:$dst, 8),
40395ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
4040fe6060f1SDimitry Andric                 DSForm:$dst)>;
40415ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4042fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 4),
4043fe6060f1SDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>;
40445ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4045fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 2),
4046fe6060f1SDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>;
40475ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4048fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 1),
4049fe6060f1SDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>;
40505ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4051fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), XForm:$dst, 8),
4052fe6060f1SDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), XForm:$dst)>;
40535ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4054fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), DSForm:$dst, 8),
4055fe6060f1SDimitry Andric          (STXSD (XSCVDPSXDS f64:$src), DSForm:$dst)>;
40565ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4057fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 2),
4058fe6060f1SDimitry Andric          (STXSIHX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>;
40595ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4060fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 1),
4061fe6060f1SDimitry Andric          (STXSIBX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>;
40625ffd83dbSDimitry Andric
40635ffd83dbSDimitry Andric// Instructions for store(fptoui).
40645ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4065fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), XForm:$dst, 8),
40665ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
4067fe6060f1SDimitry Andric                  XForm:$dst)>;
40685ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4069fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), DSForm:$dst, 8),
40705ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
4071fe6060f1SDimitry Andric                 DSForm:$dst)>;
40725ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4073fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 4),
4074fe6060f1SDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>;
40755ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4076fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 2),
4077fe6060f1SDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>;
40785ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4079fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 1),
4080fe6060f1SDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>;
40815ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4082fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), XForm:$dst, 8),
4083fe6060f1SDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), XForm:$dst)>;
40845ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4085fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), DSForm:$dst, 8),
4086fe6060f1SDimitry Andric          (STXSD (XSCVDPUXDS f64:$src), DSForm:$dst)>;
40875ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4088fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 2),
4089fe6060f1SDimitry Andric          (STXSIHX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>;
40905ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4091fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 1),
4092fe6060f1SDimitry Andric          (STXSIBX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>;
40935ffd83dbSDimitry Andric
40945ffd83dbSDimitry Andric// Round & Convert QP -> DP/SP
40955ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpround f128:$src)), (f64 (XSCVQPDP $src))>;
40965ffd83dbSDimitry Andricdef : Pat<(f32 (any_fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
40975ffd83dbSDimitry Andric
40985ffd83dbSDimitry Andric// Convert SP -> QP
40995ffd83dbSDimitry Andricdef : Pat<(f128 (any_fpextend f32:$src)),
41005ffd83dbSDimitry Andric          (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
41015ffd83dbSDimitry Andric
41025ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)),
41035ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC),
41045ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
41055ffd83dbSDimitry Andric                                 VSSRC))>;
41065ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)),
41075ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC),
41085ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
41095ffd83dbSDimitry Andric                                 VSSRC))>;
41105ffd83dbSDimitry Andric
41110b57cec5SDimitry Andric// Endianness-neutral patterns for const splats with ISA 3.0 instructions.
4112fe6060f1SDimitry Andricdefm : ScalToVecWPermute<v4i32, (i32 i32:$A), (MTVSRWS $A),
4113fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
41140b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
41150b57cec5SDimitry Andric          (v4i32 (MTVSRWS $A))>;
41168bcb0991SDimitry Andricdef : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41178bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41188bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41198bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41208bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41218bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41228bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41238bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
41240b57cec5SDimitry Andric          (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
4125fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4126fe6060f1SDimitry Andric  v4i32, FltToIntLoad.A,
4127fe6060f1SDimitry Andric  (XVCVSPSXWS (LXVWSX ForceXForm:$A)),
4128fe6060f1SDimitry Andric  (XVCVSPSXWS (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64))>;
4129fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4130fe6060f1SDimitry Andric  v4i32, FltToUIntLoad.A,
4131fe6060f1SDimitry Andric  (XVCVSPUXWS (LXVWSX ForceXForm:$A)),
4132fe6060f1SDimitry Andric  (XVCVSPUXWS (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64))>;
41335ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41345ffd83dbSDimitry Andric  v4i32, DblToIntLoadP9.A,
4135fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 DSForm:$A)), sub_64), 1),
4136fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 DSForm:$A)), sub_64)>;
41375ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41385ffd83dbSDimitry Andric  v4i32, DblToUIntLoadP9.A,
4139fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 DSForm:$A)), sub_64), 1),
4140fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 DSForm:$A)), sub_64)>;
41415ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41425ffd83dbSDimitry Andric  v2i64, FltToLongLoadP9.A,
4143fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), 0),
41445ffd83dbSDimitry Andric  (SUBREG_TO_REG
41455ffd83dbSDimitry Andric     (i64 1),
4146fe6060f1SDimitry Andric     (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), sub_64)>;
41475ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41485ffd83dbSDimitry Andric  v2i64, FltToULongLoadP9.A,
4149fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), 0),
41505ffd83dbSDimitry Andric  (SUBREG_TO_REG
41515ffd83dbSDimitry Andric     (i64 1),
4152fe6060f1SDimitry Andric     (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), sub_64)>;
4153fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldsplat ForceXForm:$A)),
4154fe6060f1SDimitry Andric          (v4f32 (LXVWSX ForceXForm:$A))>;
4155fe6060f1SDimitry Andricdef : Pat<(v4i32 (PPCldsplat ForceXForm:$A)),
4156fe6060f1SDimitry Andric          (v4i32 (LXVWSX ForceXForm:$A))>;
4157349cc55cSDimitry Andricdef : Pat<(v8i16 (PPCldsplat ForceXForm:$A)),
4158349cc55cSDimitry Andric          (v8i16 (VSPLTHs 3, (LXSIHZX ForceXForm:$A)))>;
4159349cc55cSDimitry Andricdef : Pat<(v16i8 (PPCldsplat ForceXForm:$A)),
4160349cc55cSDimitry Andric          (v16i8 (VSPLTBs 7, (LXSIBZX ForceXForm:$A)))>;
4161bdd1243dSDimitry Andricdef : Pat<(v2f64 (PPCxxperm v2f64:$XT, v2f64:$XB, v4i32:$C)),
4162bdd1243dSDimitry Andric          (XXPERM v2f64:$XT, v2f64:$XB, v4i32:$C)>;
41635ffd83dbSDimitry Andric} // HasVSX, HasP9Vector
41645ffd83dbSDimitry Andric
4165fe6060f1SDimitry Andric// Any Power9 VSX subtarget with equivalent length but better Power10 VSX
4166fe6060f1SDimitry Andric// patterns.
4167fe6060f1SDimitry Andric// Two identical blocks are required due to the slightly different predicates:
4168fe6060f1SDimitry Andric// One without P10 instructions, the other is BigEndian only with P10 instructions.
4169fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, NoP10Vector] in {
4170fe6060f1SDimitry Andric// Little endian Power10 subtargets produce a shorter pattern but require a
4171fe6060f1SDimitry Andric// COPY_TO_REGCLASS. The COPY_TO_REGCLASS makes it appear to need two instructions
4172fe6060f1SDimitry Andric// to perform the operation, when only one instruction is produced in practice.
4173fe6060f1SDimitry Andric// The NoP10Vector predicate excludes these patterns from Power10 VSX subtargets.
4174fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4175fe6060f1SDimitry Andric  v16i8, ScalarLoads.Li8,
4176fe6060f1SDimitry Andric  (VSPLTBs 7, (LXSIBZX ForceXForm:$src)),
4177fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
4178fe6060f1SDimitry Andric// Build vectors from i16 loads
4179fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4180fe6060f1SDimitry Andric  v8i16, ScalarLoads.Li16,
4181fe6060f1SDimitry Andric  (VSPLTHs 3, (LXSIHZX ForceXForm:$src)),
4182fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
4183fe6060f1SDimitry Andric} // HasVSX, HasP9Vector, NoP10Vector
4184fe6060f1SDimitry Andric
4185fe6060f1SDimitry Andric// Any big endian Power9 VSX subtarget
4186fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian] in {
4187fe6060f1SDimitry Andric// Power10 VSX subtargets produce a shorter pattern for little endian targets
4188fe6060f1SDimitry Andric// but this is still the best pattern for Power9 and Power10 VSX big endian
4189fe6060f1SDimitry Andric// Build vectors from i8 loads
4190fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4191fe6060f1SDimitry Andric  v16i8, ScalarLoads.Li8,
4192fe6060f1SDimitry Andric  (VSPLTBs 7, (LXSIBZX ForceXForm:$src)),
4193fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
4194fe6060f1SDimitry Andric// Build vectors from i16 loads
4195fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4196fe6060f1SDimitry Andric  v8i16, ScalarLoads.Li16,
4197fe6060f1SDimitry Andric  (VSPLTHs 3, (LXSIHZX ForceXForm:$src)),
4198fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
4199fe6060f1SDimitry Andric
42005ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
42015ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
42025ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
42035ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
42045ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
42055ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
42065ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
42075ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
42085ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
42095ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
42105ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
42115ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
42125ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
42135ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
42145ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
42155ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
42165ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
42175ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
4218349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 0)),
4219349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4220349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4221349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4222349cc55cSDimitry Andric                            0))>;
4223349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 0)),
4224349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4225349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4226349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4227349cc55cSDimitry Andric                            0))>;
42285ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
42295ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
4230349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 1)),
4231349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4232349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4233349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4234349cc55cSDimitry Andric                            4))>;
4235349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 1)),
4236349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4237349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4238349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4239349cc55cSDimitry Andric                            4))>;
42405ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
42415ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
4242349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 2)),
4243349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4244349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4245349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4246349cc55cSDimitry Andric                            8))>;
4247349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 2)),
4248349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4249349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4250349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4251349cc55cSDimitry Andric                            8))>;
42525ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
42535ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
4254349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 3)),
4255349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4256349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4257349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4258349cc55cSDimitry Andric                            12))>;
4259349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 3)),
4260349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4261349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4262349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4263349cc55cSDimitry Andric                            12))>;
42645ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
42655ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
42665ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
42675ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
42685ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
42695ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
42705ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
42715ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
42725ffd83dbSDimitry Andric
4273fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 0)),
4274fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4275fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 0))>;
4276fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 1)),
4277fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4278fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 4))>;
4279fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 2)),
4280fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4281fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 8))>;
4282fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 3)),
4283fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4284fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 12))>;
4285fe6060f1SDimitry Andric
42865ffd83dbSDimitry Andric// Scalar stores of i8
4287fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), ForceXForm:$dst),
4288fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), ForceXForm:$dst)>;
4289fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), ForceXForm:$dst),
4290fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
4291fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), ForceXForm:$dst),
4292fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), ForceXForm:$dst)>;
4293fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), ForceXForm:$dst),
4294fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4295fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), ForceXForm:$dst),
4296fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), ForceXForm:$dst)>;
4297fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), ForceXForm:$dst),
4298fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4299fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), ForceXForm:$dst),
4300fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), ForceXForm:$dst)>;
4301fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), ForceXForm:$dst),
4302fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4303fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), ForceXForm:$dst),
4304fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), ForceXForm:$dst)>;
4305fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), ForceXForm:$dst),
4306fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4307fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), ForceXForm:$dst),
4308fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), ForceXForm:$dst)>;
4309fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), ForceXForm:$dst),
4310fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4311fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), ForceXForm:$dst),
4312fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), ForceXForm:$dst)>;
4313fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), ForceXForm:$dst),
4314fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4315fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), ForceXForm:$dst),
4316fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), ForceXForm:$dst)>;
4317fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), ForceXForm:$dst),
4318fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
43195ffd83dbSDimitry Andric
43205ffd83dbSDimitry Andric// Scalar stores of i16
4321fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), ForceXForm:$dst),
4322fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
4323fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), ForceXForm:$dst),
4324fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4325fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), ForceXForm:$dst),
4326fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4327fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), ForceXForm:$dst),
4328fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4329fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), ForceXForm:$dst),
4330fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4331fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), ForceXForm:$dst),
4332fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4333fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), ForceXForm:$dst),
4334fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4335fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), ForceXForm:$dst),
4336fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
4337fe6060f1SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian
43385ffd83dbSDimitry Andric
4339fe6060f1SDimitry Andric// Big endian 64Bit Power9 subtarget.
4340fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] in {
4341fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load DSForm:$src)))),
4342fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64))>;
4343fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load XForm:$src)))),
4344fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64))>;
43455ffd83dbSDimitry Andric
4346fe6060f1SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load DSForm:$src)))),
4347fe6060f1SDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64))>;
4348fe6060f1SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load XForm:$src)))),
4349fe6060f1SDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64))>;
4350fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), XForm:$src),
43515ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4352fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4353fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), XForm:$src),
43545ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4355fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4356fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), XForm:$src),
4357fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4358fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), XForm:$src),
4359fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4360fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), DSForm:$src),
43615ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4362fe6060f1SDimitry Andric                       sub_64), DSForm:$src)>;
4363fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), DSForm:$src),
43645ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4365fe6060f1SDimitry Andric                       sub_64), DSForm:$src)>;
4366fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), DSForm:$src),
4367fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
4368fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), DSForm:$src),
4369fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
43705ffd83dbSDimitry Andric
43715ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
43725ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
43735ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
43745ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
43755ffd83dbSDimitry Andric          (f128 (XSCVSDQP
43765ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
43775ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
43785ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
43795ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
43805ffd83dbSDimitry Andric          (f128 (XSCVUDQP
43815ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
43825ffd83dbSDimitry Andric
43835ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
43845ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
43855ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
43865ffd83dbSDimitry Andricforeach Idx = [0,2,3] in {
43875ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
43885ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
43895ffd83dbSDimitry Andric                            (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
43905ffd83dbSDimitry Andric}
43915ffd83dbSDimitry Andricforeach Idx = 0-3 in {
43925ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
43935ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
43940b57cec5SDimitry Andric}
43950b57cec5SDimitry Andric
4396fe6060f1SDimitry Andric// (Un)Signed HWord vector extract -> QP/DP/SP
43975ffd83dbSDimitry Andricforeach Idx = 0-7 in {
43985ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
43995ffd83dbSDimitry Andric                    (i32 (sext_inreg
44005ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, Idx), i16)))),
44015ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG
44025ffd83dbSDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
44035ffd83dbSDimitry Andric                            sub_64)))>;
44045ffd83dbSDimitry Andric  // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
44055ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
44065ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
44075ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
44085ffd83dbSDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4409fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4410fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz (and (i32 (vector_extract v8i16:$src, Idx)),
4411fe6060f1SDimitry Andric                                        65535))))),
4412fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4413fe6060f1SDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4414fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4415fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4416fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v8i16:$src, Idx),
4417fe6060f1SDimitry Andric                               i16)))))),
4418fe6060f1SDimitry Andric          (f32 (XSCVSXDSP (EXTRACT_SUBREG
4419fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
4420fe6060f1SDimitry Andric                            sub_64)))>;
4421fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4422fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4423fe6060f1SDimitry Andric                          (and (i32 (vector_extract v8i16:$src, Idx)),
4424fe6060f1SDimitry Andric                               65535))))),
4425fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4426fe6060f1SDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4427fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4428fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4429fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v8i16:$src, Idx),
4430fe6060f1SDimitry Andric                               i16)))))),
4431fe6060f1SDimitry Andric          (f64 (XSCVSXDDP (EXTRACT_SUBREG
4432fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
4433fe6060f1SDimitry Andric                            sub_64)))>;
44340b57cec5SDimitry Andric}
44350b57cec5SDimitry Andric
44365ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP
44375ffd83dbSDimitry Andricforeach Idx = 0-15 in {
44385ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
44395ffd83dbSDimitry Andric                    (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
44405ffd83dbSDimitry Andric                                     i8)))),
44415ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
44425ffd83dbSDimitry Andric                              (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
44435ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
44445ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
44455ffd83dbSDimitry Andric            (f128 (XSCVUDQP
44465ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
4447fe6060f1SDimitry Andric
4448fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4449fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4450fe6060f1SDimitry Andric                          (and (i32 (vector_extract v16i8:$src, Idx)),
4451fe6060f1SDimitry Andric                               255))))),
4452fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4453fe6060f1SDimitry Andric                              (VEXTRACTUB !add(Idx, Idx), $src), sub_64)))>;
4454fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4455fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4456fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
4457fe6060f1SDimitry Andric                               i8)))))),
4458fe6060f1SDimitry Andric          (f32 (XSCVSXDSP (EXTRACT_SUBREG
4459fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUB !add(Idx, Idx), $src)),
4460fe6060f1SDimitry Andric                            sub_64)))>;
4461fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4462fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4463fe6060f1SDimitry Andric                          (and (i32 (vector_extract v16i8:$src, Idx)),
4464fe6060f1SDimitry Andric                          255))))),
4465fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4466fe6060f1SDimitry Andric                              (VEXTRACTUB !add(Idx, Idx), $src), sub_64)))>;
4467fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4468fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4469fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
4470fe6060f1SDimitry Andric                               i8)))))),
4471fe6060f1SDimitry Andric          (f64 (XSCVSXDDP (EXTRACT_SUBREG
4472fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUB !add(Idx, Idx), $src)),
4473fe6060f1SDimitry Andric                            sub_64)))>;
44740b57cec5SDimitry Andric}
44750b57cec5SDimitry Andric
44765ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
44775ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
44785ffd83dbSDimitry Andric          (f128 (XSCVUDQP
44795ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
4480e8d8bef9SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian, IsPPC64
44815ffd83dbSDimitry Andric
44825ffd83dbSDimitry Andric// Little endian Power9 subtarget.
44835ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in {
44845ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
44855ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
44865ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
44875ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
44885ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
44895ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
44905ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
44915ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
44925ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
44935ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
44945ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
44955ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
44965ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
44975ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
44985ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
44995ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
45005ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
45015ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
4502349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 0)),
4503349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4504349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4505349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4506349cc55cSDimitry Andric                            12))>;
4507349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 0)),
4508349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4509349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4510349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4511349cc55cSDimitry Andric                            12))>;
45125ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
45135ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
4514349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 1)),
4515349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4516349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4517349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4518349cc55cSDimitry Andric                            8))>;
4519349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 1)),
4520349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4521349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4522349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4523349cc55cSDimitry Andric                            8))>;
45245ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
45255ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
4526349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 2)),
4527349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4528349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4529349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4530349cc55cSDimitry Andric                            4))>;
4531349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 2)),
4532349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4533349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4534349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4535349cc55cSDimitry Andric                            4))>;
45365ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
45375ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
4538349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 3)),
4539349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4540349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4541349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4542349cc55cSDimitry Andric                            0))>;
4543349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 3)),
4544349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4545349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4546349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4547349cc55cSDimitry Andric                            0))>;
45485ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
45495ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
45505ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
45515ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
45525ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
45535ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
45545ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
45555ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
45565ffd83dbSDimitry Andric
4557fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 0)),
4558fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4559fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 12))>;
4560fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 1)),
4561fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4562fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 8))>;
4563fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 2)),
4564fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4565fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 4))>;
4566fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 3)),
4567fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4568fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 0))>;
45695ffd83dbSDimitry Andric
4570fe6060f1SDimitry Andricdef : Pat<(v8i16 (PPCld_vec_be ForceXForm:$src)),
4571fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LXVH8X ForceXForm:$src), VRRC)>;
4572fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v8i16:$rS, ForceXForm:$dst),
4573fe6060f1SDimitry Andric          (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), ForceXForm:$dst)>;
4574fe6060f1SDimitry Andric
4575fe6060f1SDimitry Andricdef : Pat<(v16i8 (PPCld_vec_be ForceXForm:$src)),
4576fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LXVB16X ForceXForm:$src), VRRC)>;
4577fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v16i8:$rS, ForceXForm:$dst),
4578fe6060f1SDimitry Andric          (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), ForceXForm:$dst)>;
45795ffd83dbSDimitry Andric
45805ffd83dbSDimitry Andric// Scalar stores of i8
4581fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), ForceXForm:$dst),
4582fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
4583fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), ForceXForm:$dst),
4584fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), ForceXForm:$dst)>;
4585fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), ForceXForm:$dst),
4586fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4587fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), ForceXForm:$dst),
4588fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), ForceXForm:$dst)>;
4589fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), ForceXForm:$dst),
4590fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4591fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), ForceXForm:$dst),
4592fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), ForceXForm:$dst)>;
4593fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), ForceXForm:$dst),
4594fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4595fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), ForceXForm:$dst),
4596fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), ForceXForm:$dst)>;
4597fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), ForceXForm:$dst),
4598fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4599fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), ForceXForm:$dst),
4600fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), ForceXForm:$dst)>;
4601fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), ForceXForm:$dst),
4602fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4603fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), ForceXForm:$dst),
4604fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), ForceXForm:$dst)>;
4605fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), ForceXForm:$dst),
4606fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4607fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), ForceXForm:$dst),
4608fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), ForceXForm:$dst)>;
4609fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), ForceXForm:$dst),
4610fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
4611fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), ForceXForm:$dst),
4612fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), ForceXForm:$dst)>;
46135ffd83dbSDimitry Andric
46145ffd83dbSDimitry Andric// Scalar stores of i16
4615fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), ForceXForm:$dst),
4616fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
4617fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), ForceXForm:$dst),
4618fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4619fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), ForceXForm:$dst),
4620fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4621fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), ForceXForm:$dst),
4622fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4623fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), ForceXForm:$dst),
4624fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4625fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), ForceXForm:$dst),
4626fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4627fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), ForceXForm:$dst),
4628fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4629fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), ForceXForm:$dst),
4630fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
46315ffd83dbSDimitry Andric
46325ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4633fe6060f1SDimitry Andric  v2i64, (i64 (load DSForm:$src)),
4634fe6060f1SDimitry Andric  (XXPERMDIs (DFLOADf64 DSForm:$src), 2),
4635fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>;
46365ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4637fe6060f1SDimitry Andric  v2i64, (i64 (load XForm:$src)),
4638fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 XForm:$src), 2),
4639fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>;
46405ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4641fe6060f1SDimitry Andric  v2f64, (f64 (load DSForm:$src)),
4642fe6060f1SDimitry Andric  (XXPERMDIs (DFLOADf64 DSForm:$src), 2),
4643fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>;
46445ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4645fe6060f1SDimitry Andric  v2f64, (f64 (load XForm:$src)),
4646fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 XForm:$src), 2),
4647fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>;
46485ffd83dbSDimitry Andric
4649fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), XForm:$src),
46505ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4651fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4652fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), XForm:$src),
46535ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4654fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4655fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), XForm:$src),
4656fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4657fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), XForm:$src),
4658fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4659fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), DSForm:$src),
46605ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4661fe6060f1SDimitry Andric                       sub_64), DSForm:$src)>;
4662fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), DSForm:$src),
46635ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4664fe6060f1SDimitry Andric                      DSForm:$src)>;
4665fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), DSForm:$src),
4666fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
4667fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), DSForm:$src),
4668fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
46695ffd83dbSDimitry Andric
46705ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
46715ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
46725ffd83dbSDimitry Andric          (f128 (XSCVSDQP
46735ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
46745ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
46755ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
46765ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
46775ffd83dbSDimitry Andric          (f128 (XSCVUDQP
46785ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
46795ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
46805ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
46815ffd83dbSDimitry Andric
46825ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
46835ffd83dbSDimitry Andricforeach Idx = [[0,3],[1,2],[3,0]] in {
46845ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
46855ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
46865ffd83dbSDimitry Andric                              (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
46875ffd83dbSDimitry Andric                              sub_64)))>;
46885ffd83dbSDimitry Andric}
46895ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
46905ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
46915ffd83dbSDimitry Andric
46925ffd83dbSDimitry Andricforeach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
46935ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
46945ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
46950b57cec5SDimitry Andric}
46960b57cec5SDimitry Andric
4697fe6060f1SDimitry Andric// (Un)Signed HWord vector extract -> QP/DP/SP
46985ffd83dbSDimitry Andric// The Nested foreach lists identifies the vector element and corresponding
46995ffd83dbSDimitry Andric// register byte location.
47005ffd83dbSDimitry Andricforeach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
47015ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
47025ffd83dbSDimitry Andric                    (i32 (sext_inreg
47035ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, !head(Idx)), i16)))),
47045ffd83dbSDimitry Andric            (f128 (XSCVSDQP
47055ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
47065ffd83dbSDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
47075ffd83dbSDimitry Andric                                    sub_64)))>;
47085ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
47095ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, !head(Idx))),
47105ffd83dbSDimitry Andric                         65535))),
47115ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
47125ffd83dbSDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4713fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4714fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4715fe6060f1SDimitry Andric                          (and (i32 (vector_extract v8i16:$src, !head(Idx))),
4716fe6060f1SDimitry Andric                          65535))))),
4717fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4718fe6060f1SDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4719fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4720fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4721fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v8i16:$src,
4722fe6060f1SDimitry Andric                                           !head(Idx)), i16)))))),
4723fe6060f1SDimitry Andric            (f32 (XSCVSXDSP
4724fe6060f1SDimitry Andric                    (EXTRACT_SUBREG
4725fe6060f1SDimitry Andric                     (VEXTSH2D (VEXTRACTUH !head(!tail(Idx)), $src)),
4726fe6060f1SDimitry Andric                     sub_64)))>;
4727fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4728fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4729fe6060f1SDimitry Andric                          (and (i32 (vector_extract v8i16:$src, !head(Idx))),
4730fe6060f1SDimitry Andric                          65535))))),
4731fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4732fe6060f1SDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4733fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4734fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4735fe6060f1SDimitry Andric                        (i32 (sext_inreg
4736fe6060f1SDimitry Andric                            (vector_extract v8i16:$src, !head(Idx)), i16)))))),
4737fe6060f1SDimitry Andric            (f64 (XSCVSXDDP
4738fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4739fe6060f1SDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
4740fe6060f1SDimitry Andric                                    sub_64)))>;
47410b57cec5SDimitry Andric}
47420b57cec5SDimitry Andric
4743fe6060f1SDimitry Andric// (Un)Signed Byte vector extract -> QP/DP/SP
47445ffd83dbSDimitry Andricforeach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
47455ffd83dbSDimitry Andric               [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
47465ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
47475ffd83dbSDimitry Andric                    (i32 (sext_inreg
47485ffd83dbSDimitry Andric                           (vector_extract v16i8:$src, !head(Idx)), i8)))),
47495ffd83dbSDimitry Andric            (f128 (XSCVSDQP
47505ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
47515ffd83dbSDimitry Andric                      (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
47525ffd83dbSDimitry Andric                      sub_64)))>;
47535ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
47545ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, !head(Idx))),
47555ffd83dbSDimitry Andric                         255))),
47565ffd83dbSDimitry Andric            (f128 (XSCVUDQP
47575ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
47585ffd83dbSDimitry Andric                      (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4759fe6060f1SDimitry Andric
4760fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4761fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4762fe6060f1SDimitry Andric                          (and (i32 (vector_extract v16i8:$src, !head(Idx))),
4763fe6060f1SDimitry Andric                          255))))),
4764fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4765fe6060f1SDimitry Andric                              (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4766fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4767fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4768fe6060f1SDimitry Andric                          (i32 (sext_inreg
4769fe6060f1SDimitry Andric                            (vector_extract v16i8:$src, !head(Idx)), i8)))))),
4770fe6060f1SDimitry Andric            (f32 (XSCVSXDSP
4771fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4772fe6060f1SDimitry Andric                                      (VEXTRACTUB !head(!tail(Idx)), $src)),
4773fe6060f1SDimitry Andric                                    sub_64)))>;
4774fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4775fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4776fe6060f1SDimitry Andric                          (and (i32
4777fe6060f1SDimitry Andric                            (vector_extract v16i8:$src, !head(Idx))), 255))))),
4778fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4779fe6060f1SDimitry Andric                              (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4780fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4781fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4782fe6060f1SDimitry Andric                        (i32 (sext_inreg
4783fe6060f1SDimitry Andric                            (vector_extract v16i8:$src, !head(Idx)), i8)))))),
4784fe6060f1SDimitry Andric            (f64 (XSCVSXDDP
4785fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4786fe6060f1SDimitry Andric                                      (VEXTRACTUB !head(!tail(Idx)), $src)),
4787fe6060f1SDimitry Andric                                    sub_64)))>;
4788fe6060f1SDimitry Andric
4789fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4790fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4791fe6060f1SDimitry Andric                        (i32 (sext_inreg
4792fe6060f1SDimitry Andric                          (vector_extract v16i8:$src, !head(Idx)), i8)))))),
4793fe6060f1SDimitry Andric            (f64 (XSCVSXDDP
4794fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4795fe6060f1SDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
4796fe6060f1SDimitry Andric                                    sub_64)))>;
47975ffd83dbSDimitry Andric}
47985ffd83dbSDimitry Andric
47995ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
48005ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
48015ffd83dbSDimitry Andric          (f128 (XSCVUDQP
48025ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
48035ffd83dbSDimitry Andric} // HasVSX, HasP9Vector, IsLittleEndian
48045ffd83dbSDimitry Andric
48055ffd83dbSDimitry Andric// Any Power9 VSX subtarget that supports Power9 Altivec.
48065ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec] in {
4807881fc203SDimitry Andric// Unsigned absolute-difference.
4808881fc203SDimitry Andricdef : Pat<(v4i32 (abdu v4i32:$A, v4i32:$B)),
48090b57cec5SDimitry Andric          (v4i32 (VABSDUW $A, $B))>;
48100b57cec5SDimitry Andric
4811881fc203SDimitry Andricdef : Pat<(v8i16 (abdu v8i16:$A, v8i16:$B)),
48120b57cec5SDimitry Andric          (v8i16 (VABSDUH $A, $B))>;
48130b57cec5SDimitry Andric
4814881fc203SDimitry Andricdef : Pat<(v16i8 (abdu v16i8:$A, v16i8:$B)),
48150b57cec5SDimitry Andric          (v16i8 (VABSDUB $A, $B))>;
48160b57cec5SDimitry Andric
4817881fc203SDimitry Andric// Signed absolute-difference.
4818881fc203SDimitry Andric// Power9 VABSD* instructions are designed to support unsigned integer
4819881fc203SDimitry Andric// vectors (byte/halfword/word), if we want to make use of them for signed
4820881fc203SDimitry Andric// integer vectors, we have to flip their sign bits first. To flip sign bit
4821881fc203SDimitry Andric// for byte/halfword integer vector would become inefficient, but for word
4822881fc203SDimitry Andric// integer vector, we can leverage XVNEGSP to make it efficiently.
4823881fc203SDimitry Andricdef : Pat<(v4i32 (abds v4i32:$A, v4i32:$B)),
48240b57cec5SDimitry Andric          (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
48255ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec
48265ffd83dbSDimitry Andric
4827e8d8bef9SDimitry Andric// Big endian Power9 64Bit VSX subtargets with P9 Altivec support.
4828e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] in {
48295ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
48305ffd83dbSDimitry Andric          (VEXTUBLX $Idx, $S)>;
48315ffd83dbSDimitry Andric
48325ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
48335ffd83dbSDimitry Andric          (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
48345ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
48355ffd83dbSDimitry Andric          (VEXTUHLX (LI8 0), $S)>;
48365ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
48375ffd83dbSDimitry Andric          (VEXTUHLX (LI8 2), $S)>;
48385ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
48395ffd83dbSDimitry Andric          (VEXTUHLX (LI8 4), $S)>;
48405ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
48415ffd83dbSDimitry Andric          (VEXTUHLX (LI8 6), $S)>;
48425ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
48435ffd83dbSDimitry Andric          (VEXTUHLX (LI8 8), $S)>;
48445ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
48455ffd83dbSDimitry Andric          (VEXTUHLX (LI8 10), $S)>;
48465ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
48475ffd83dbSDimitry Andric          (VEXTUHLX (LI8 12), $S)>;
48485ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
48495ffd83dbSDimitry Andric          (VEXTUHLX (LI8 14), $S)>;
48505ffd83dbSDimitry Andric
48515ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
48525ffd83dbSDimitry Andric          (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
48535ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
48545ffd83dbSDimitry Andric          (VEXTUWLX (LI8 0), $S)>;
48555ffd83dbSDimitry Andric
48565ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
48575ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
48585ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
48595ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
48605ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
48615ffd83dbSDimitry Andric          (VEXTUWLX (LI8 8), $S)>;
48625ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
48635ffd83dbSDimitry Andric          (VEXTUWLX (LI8 12), $S)>;
48645ffd83dbSDimitry Andric
48655ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
48665ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
48675ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
48685ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 0), $S))>;
48695ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
48705ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
48715ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
48725ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
48735ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
48745ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 8), $S))>;
48755ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
48765ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 12), $S))>;
48775ffd83dbSDimitry Andric
48785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
48795ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
48805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
48815ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
48825ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
48835ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
48845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
48855ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
48865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
48875ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
48885ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
48895ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
48905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
48915ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
48925ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
48935ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
48945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
48955ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
48965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
48975ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
48985ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
48995ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
49005ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
49015ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
49025ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
49035ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
49045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
49055ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
49065ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
49075ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
49085ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
49095ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
49105ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
49115ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
49125ffd83dbSDimitry Andric
49135ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
49145ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX
49155ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
49165ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
49175ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
49185ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
49195ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
49205ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
49215ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
49225ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
49235ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
49245ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
49255ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
49265ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
49275ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
49285ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
49295ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
49305ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
49315ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
49325ffd83dbSDimitry Andric
49335ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
49345ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX
49355ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
49365ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
49375ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
49385ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
49395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
49405ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
49415ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
49425ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
49435ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
49445ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
49455ffd83dbSDimitry Andric
49465ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
49475ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
49485ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
49495ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
49505ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
49515ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
49525ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
49535ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
49545ffd83dbSDimitry Andric                  HWordToWord.BE_A2, HWordToWord.BE_A3)),
49555ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
49565ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
49575ffd83dbSDimitry Andric                  ByteToWord.BE_A2, ByteToWord.BE_A3)),
49585ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
49595ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
49605ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
4961e8d8bef9SDimitry Andric} // HasVSX, HasP9Altivec, IsBigEndian, IsPPC64
49625ffd83dbSDimitry Andric
49635ffd83dbSDimitry Andric// Little endian Power9 VSX subtargets with P9 Altivec support.
49645ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in {
49655ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
49665ffd83dbSDimitry Andric          (VEXTUBRX $Idx, $S)>;
49675ffd83dbSDimitry Andric
49685ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
49695ffd83dbSDimitry Andric          (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
49705ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
49715ffd83dbSDimitry Andric          (VEXTUHRX (LI8 0), $S)>;
49725ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
49735ffd83dbSDimitry Andric          (VEXTUHRX (LI8 2), $S)>;
49745ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
49755ffd83dbSDimitry Andric          (VEXTUHRX (LI8 4), $S)>;
49765ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
49775ffd83dbSDimitry Andric          (VEXTUHRX (LI8 6), $S)>;
49785ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
49795ffd83dbSDimitry Andric          (VEXTUHRX (LI8 8), $S)>;
49805ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
49815ffd83dbSDimitry Andric          (VEXTUHRX (LI8 10), $S)>;
49825ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
49835ffd83dbSDimitry Andric          (VEXTUHRX (LI8 12), $S)>;
49845ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
49855ffd83dbSDimitry Andric          (VEXTUHRX (LI8 14), $S)>;
49865ffd83dbSDimitry Andric
49875ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
49885ffd83dbSDimitry Andric          (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
49895ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
49905ffd83dbSDimitry Andric          (VEXTUWRX (LI8 0), $S)>;
49915ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
49925ffd83dbSDimitry Andric          (VEXTUWRX (LI8 4), $S)>;
49935ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
49945ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
49955ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
49965ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
49975ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
49985ffd83dbSDimitry Andric          (VEXTUWRX (LI8 12), $S)>;
49995ffd83dbSDimitry Andric
50005ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
50015ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
50025ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
50035ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 0), $S))>;
50045ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
50055ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 4), $S))>;
50065ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
50075ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
50085ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
50095ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
50105ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
50115ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 12), $S))>;
50125ffd83dbSDimitry Andric
50135ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
50145ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
50155ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
50165ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
50175ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
50185ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
50195ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
50205ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
50215ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
50225ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
50235ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
50245ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
50255ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
50265ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
50275ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
50285ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
50295ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
50305ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
50315ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
50325ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
50335ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
50345ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
50355ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
50365ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
50375ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
50385ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
50395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
50405ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
50415ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
50425ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
50435ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
50445ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
50455ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
50465ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
50475ffd83dbSDimitry Andric
50485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
50495ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX
50505ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
50515ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
50525ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
50535ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
50545ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
50555ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
50565ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
50575ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
50585ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
50595ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
50605ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
50615ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
50625ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
50635ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
50645ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
50655ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
50665ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
50675ffd83dbSDimitry Andric
50685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
50695ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX
50705ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
50715ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
50725ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
50735ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
50745ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
50755ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
50765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
50775ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
50785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
50795ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
50805ffd83dbSDimitry Andric
50815ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
50825ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
50835ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
50845ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
50855ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
50865ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
50875ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
50885ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
50895ffd83dbSDimitry Andric                  HWordToWord.LE_A2, HWordToWord.LE_A3)),
50905ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
50915ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
50925ffd83dbSDimitry Andric                  ByteToWord.LE_A2, ByteToWord.LE_A3)),
50935ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
50945ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
50955ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
50965ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec, IsLittleEndian
50975ffd83dbSDimitry Andric
5098e8d8bef9SDimitry Andric// Big endian 64Bit VSX subtarget that supports additional direct moves from
5099e8d8bef9SDimitry Andric// ISA3.0.
5100e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] in {
51015ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 1)),
51025ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
51035ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Big endian.
51045ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
51055ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
51065ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
51075ffd83dbSDimitry Andric          (MTVSRDD
51085ffd83dbSDimitry Andric            (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
51095ffd83dbSDimitry Andric            (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
51105ffd83dbSDimitry Andric
51115ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
51125ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
5113e8d8bef9SDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64
51145ffd83dbSDimitry Andric
51155ffd83dbSDimitry Andric// Little endian VSX subtarget that supports direct moves from ISA3.0.
51165ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in {
51175ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 0)),
51185ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
51195ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Little endian.
51205ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
51215ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
51225ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
51235ffd83dbSDimitry Andric          (MTVSRDD
51245ffd83dbSDimitry Andric            (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
51255ffd83dbSDimitry Andric            (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
51265ffd83dbSDimitry Andric
51275ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
51285ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
51295ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian
51305ffd83dbSDimitry Andric} // AddedComplexity = 400
51315ffd83dbSDimitry Andric
51325ffd83dbSDimitry Andric//---------------------------- Instruction aliases ---------------------------//
51335ffd83dbSDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB",
51345ffd83dbSDimitry Andric                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
51355ffd83dbSDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB",
51365ffd83dbSDimitry Andric                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
51375ffd83dbSDimitry Andric
5138e8d8bef9SDimitry Andric// Certain versions of the AIX assembler may missassemble these mnemonics.
5139e8d8bef9SDimitry Andriclet Predicates = [ModernAs] in {
51405ffd83dbSDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 0",
51415ffd83dbSDimitry Andric                  (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
51425ffd83dbSDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 1",
51435ffd83dbSDimitry Andric                  (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
5144e8d8bef9SDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 0",
5145e8d8bef9SDimitry Andric                  (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
5146e8d8bef9SDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 1",
5147e8d8bef9SDimitry Andric                  (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
5148e8d8bef9SDimitry Andric}
5149e8d8bef9SDimitry Andric
51505ffd83dbSDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB",
51515ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
51525ffd83dbSDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB",
51535ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
51545ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
51555ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
51565ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
51575ffd83dbSDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
51585ffd83dbSDimitry Andricdef : InstAlias<"mfvrd $rA, $XT",
51595ffd83dbSDimitry Andric                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
51605ffd83dbSDimitry Andricdef : InstAlias<"mffprd $rA, $src",
51615ffd83dbSDimitry Andric                (MFVSRD g8rc:$rA, f8rc:$src)>;
51625ffd83dbSDimitry Andricdef : InstAlias<"mtvrd $XT, $rA",
51635ffd83dbSDimitry Andric                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
51645ffd83dbSDimitry Andricdef : InstAlias<"mtfprd $dst, $rA",
51655ffd83dbSDimitry Andric                (MTVSRD f8rc:$dst, g8rc:$rA)>;
51665ffd83dbSDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT",
51675ffd83dbSDimitry Andric                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
51685ffd83dbSDimitry Andricdef : InstAlias<"mffprwz $rA, $src",
51695ffd83dbSDimitry Andric                (MFVSRWZ gprc:$rA, f8rc:$src)>;
51705ffd83dbSDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA",
51715ffd83dbSDimitry Andric                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
51725ffd83dbSDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA",
51735ffd83dbSDimitry Andric                (MTVSRWA f8rc:$dst, gprc:$rA)>;
51745ffd83dbSDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA",
51755ffd83dbSDimitry Andric                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
51765ffd83dbSDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA",
51775ffd83dbSDimitry Andric                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
5178