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 PPCRegVSRCAsmOperand : AsmOperandClass {
550b57cec5SDimitry Andric  let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
560b57cec5SDimitry Andric}
570b57cec5SDimitry Andricdef vsrc : RegisterOperand<VSRC> {
580b57cec5SDimitry Andric  let ParserMatchClass = PPCRegVSRCAsmOperand;
590b57cec5SDimitry Andric}
600b57cec5SDimitry Andric
610b57cec5SDimitry Andricdef PPCRegVSFRCAsmOperand : AsmOperandClass {
620b57cec5SDimitry Andric  let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
630b57cec5SDimitry Andric}
640b57cec5SDimitry Andricdef vsfrc : RegisterOperand<VSFRC> {
650b57cec5SDimitry Andric  let ParserMatchClass = PPCRegVSFRCAsmOperand;
660b57cec5SDimitry Andric}
670b57cec5SDimitry Andric
680b57cec5SDimitry Andricdef PPCRegVSSRCAsmOperand : AsmOperandClass {
690b57cec5SDimitry Andric  let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
700b57cec5SDimitry Andric}
710b57cec5SDimitry Andricdef vssrc : RegisterOperand<VSSRC> {
720b57cec5SDimitry Andric  let ParserMatchClass = PPCRegVSSRCAsmOperand;
730b57cec5SDimitry Andric}
740b57cec5SDimitry Andric
750b57cec5SDimitry Andricdef PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass {
760b57cec5SDimitry Andric  let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber";
770b57cec5SDimitry Andric}
780b57cec5SDimitry Andric
790b57cec5SDimitry Andricdef spilltovsrrc : RegisterOperand<SPILLTOVSRRC> {
800b57cec5SDimitry Andric  let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand;
810b57cec5SDimitry Andric}
820b57cec5SDimitry Andric
830b57cec5SDimitry Andricdef SDT_PPCldvsxlh : SDTypeProfile<1, 1, [
840b57cec5SDimitry Andric  SDTCisVT<0, v4f32>, SDTCisPtrTy<1>
850b57cec5SDimitry Andric]>;
860b57cec5SDimitry Andric
878bcb0991SDimitry Andricdef SDT_PPCfpexth : SDTypeProfile<1, 2, [
888bcb0991SDimitry Andric  SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>, SDTCisPtrTy<2>
898bcb0991SDimitry Andric]>;
908bcb0991SDimitry Andric
918bcb0991SDimitry Andricdef SDT_PPCldsplat : SDTypeProfile<1, 1, [
928bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
930b57cec5SDimitry Andric]>;
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric// Little-endian-specific nodes.
960b57cec5SDimitry Andricdef SDT_PPClxvd2x : SDTypeProfile<1, 1, [
970b57cec5SDimitry Andric  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
980b57cec5SDimitry Andric]>;
990b57cec5SDimitry Andricdef SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
1000b57cec5SDimitry Andric  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
1010b57cec5SDimitry Andric]>;
1020b57cec5SDimitry Andricdef SDT_PPCxxswapd : SDTypeProfile<1, 1, [
1030b57cec5SDimitry Andric  SDTCisSameAs<0, 1>
1040b57cec5SDimitry Andric]>;
1050b57cec5SDimitry Andricdef SDTVecConv : SDTypeProfile<1, 2, [
1060b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>
1070b57cec5SDimitry Andric]>;
1080b57cec5SDimitry Andricdef SDTVabsd : SDTypeProfile<1, 3, [
1090b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<3, i32>
1100b57cec5SDimitry Andric]>;
1118bcb0991SDimitry Andricdef SDT_PPCld_vec_be : SDTypeProfile<1, 1, [
1128bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
1138bcb0991SDimitry Andric]>;
1148bcb0991SDimitry Andricdef SDT_PPCst_vec_be : SDTypeProfile<0, 2, [
1158bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
1168bcb0991SDimitry Andric]>;
1170b57cec5SDimitry Andric
1185ffd83dbSDimitry Andric//--------------------------- Custom PPC nodes -------------------------------//
1190b57cec5SDimitry Andricdef PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
1200b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1210b57cec5SDimitry Andricdef PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
1220b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayStore]>;
1238bcb0991SDimitry Andricdef PPCld_vec_be  : SDNode<"PPCISD::LOAD_VEC_BE", SDT_PPCld_vec_be,
1248bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1258bcb0991SDimitry Andricdef PPCst_vec_be : SDNode<"PPCISD::STORE_VEC_BE", SDT_PPCst_vec_be,
1268bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayStore]>;
1270b57cec5SDimitry Andricdef PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
1280b57cec5SDimitry Andricdef PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
1290b57cec5SDimitry Andricdef PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
1300b57cec5SDimitry Andricdef PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
1310b57cec5SDimitry Andricdef PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
1320b57cec5SDimitry Andricdef PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
1330b57cec5SDimitry Andricdef PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
1340b57cec5SDimitry Andricdef PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>;
1350b57cec5SDimitry Andric
1368bcb0991SDimitry Andricdef PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>;
1370b57cec5SDimitry Andricdef PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
1380b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1398bcb0991SDimitry Andricdef PPCldsplat : SDNode<"PPCISD::LD_SPLAT", SDT_PPCldsplat,
1408bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
141349cc55cSDimitry Andricdef PPCzextldsplat : SDNode<"PPCISD::ZEXT_LD_SPLAT", SDT_PPCldsplat,
142349cc55cSDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
143349cc55cSDimitry Andricdef PPCsextldsplat : SDNode<"PPCISD::SEXT_LD_SPLAT", SDT_PPCldsplat,
144349cc55cSDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1455ffd83dbSDimitry Andricdef PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED",
1465ffd83dbSDimitry Andric                     SDTypeProfile<1, 1, []>, []>;
1470b57cec5SDimitry Andric
1485ffd83dbSDimitry Andric//-------------------------- Predicate definitions ---------------------------//
1495ffd83dbSDimitry Andricdef HasVSX : Predicate<"Subtarget->hasVSX()">;
1505ffd83dbSDimitry Andricdef IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">;
1515ffd83dbSDimitry Andricdef IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">;
152e8d8bef9SDimitry Andricdef IsPPC64 : Predicate<"Subtarget->isPPC64()">;
1535ffd83dbSDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">;
1545ffd83dbSDimitry Andricdef HasP8Vector : Predicate<"Subtarget->hasP8Vector()">;
1555ffd83dbSDimitry Andricdef HasDirectMove : Predicate<"Subtarget->hasDirectMove()">;
1565ffd83dbSDimitry Andricdef NoP9Vector : Predicate<"!Subtarget->hasP9Vector()">;
1575ffd83dbSDimitry Andricdef HasP9Vector : Predicate<"Subtarget->hasP9Vector()">;
1585ffd83dbSDimitry Andricdef NoP9Altivec : Predicate<"!Subtarget->hasP9Altivec()">;
159fe6060f1SDimitry Andricdef NoP10Vector: Predicate<"!Subtarget->hasP10Vector()">;
1605ffd83dbSDimitry Andric
1615ffd83dbSDimitry Andric//--------------------- VSX-specific instruction formats ---------------------//
1625ffd83dbSDimitry Andric// By default, all VSX instructions are to be selected over their Altivec
1635ffd83dbSDimitry Andric// counter parts and they do not have unmodeled sideeffects.
1645ffd83dbSDimitry Andriclet AddedComplexity = 400, hasSideEffects = 0 in {
1650b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
1660b57cec5SDimitry Andric                    string asmstr, InstrItinClass itin, Intrinsic Int,
1670b57cec5SDimitry Andric                    ValueType OutTy, ValueType InTy> {
1680b57cec5SDimitry Andric  let BaseName = asmbase in {
1690b57cec5SDimitry Andric    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1700b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
1710b57cec5SDimitry Andric                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
1720b57cec5SDimitry Andric    let Defs = [CR6] in
173480093f4SDimitry Andric    def _rec    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1740b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1750b57cec5SDimitry Andric                       [(set InTy:$XT,
176e8d8bef9SDimitry Andric                                (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>,
177480093f4SDimitry Andric                       isRecordForm;
1780b57cec5SDimitry Andric  }
1790b57cec5SDimitry Andric}
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as
1820b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained
1830b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained
1840b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though
1850b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction
1860b57cec5SDimitry Andric// to use the same register for both inputs.
1870b57cec5SDimitry Andric// For example, an output DAG such as this:
1880b57cec5SDimitry Andric//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
1890b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs
1900b57cec5SDimitry Andric// to the XXPERMDI instruction.
1910b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
1920b57cec5SDimitry Andric                 InstrItinClass itin, list<dag> pattern>
1930b57cec5SDimitry Andric  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
1940b57cec5SDimitry Andric    let XB = XA;
1950b57cec5SDimitry Andric}
1960b57cec5SDimitry Andric
1975ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
1985ffd83dbSDimitry Andricclass X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1995ffd83dbSDimitry Andric                    list<dag> pattern>
2005ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2015ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2020b57cec5SDimitry Andric
2035ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2045ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2055ffd83dbSDimitry Andric                       list<dag> pattern>
2065ffd83dbSDimitry Andric  : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm;
2075ffd83dbSDimitry Andric
2085ffd83dbSDimitry Andric// [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2095ffd83dbSDimitry Andric// So we use different operand class for VRB
2105ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2115ffd83dbSDimitry Andric                         RegisterOperand vbtype, list<dag> pattern>
2125ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2135ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2145ffd83dbSDimitry Andric
2155ffd83dbSDimitry Andric// [PO VRT XO VRB XO /]
2165ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2175ffd83dbSDimitry Andric                    list<dag> pattern>
2185ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
2195ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2205ffd83dbSDimitry Andric
2215ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2225ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2235ffd83dbSDimitry Andric                       list<dag> pattern>
2245ffd83dbSDimitry Andric  : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm;
2255ffd83dbSDimitry Andric
2265ffd83dbSDimitry Andric// [PO T XO B XO BX /]
2275ffd83dbSDimitry Andricclass XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2285ffd83dbSDimitry Andric                      list<dag> pattern>
2295ffd83dbSDimitry Andric  : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2305ffd83dbSDimitry Andric                    !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2315ffd83dbSDimitry Andric
2325ffd83dbSDimitry Andric// [PO T XO B XO BX TX]
2335ffd83dbSDimitry Andricclass XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2345ffd83dbSDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
2355ffd83dbSDimitry Andric  : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2365ffd83dbSDimitry Andric                    !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2375ffd83dbSDimitry Andric
2385ffd83dbSDimitry Andric// [PO T A B XO AX BX TX], src and dest register use different operand class
2395ffd83dbSDimitry Andricclass XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2405ffd83dbSDimitry Andric                RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2415ffd83dbSDimitry Andric                InstrItinClass itin, list<dag> pattern>
2425ffd83dbSDimitry Andric  : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2435ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2445ffd83dbSDimitry Andric
2455ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
2465ffd83dbSDimitry Andricclass X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2475ffd83dbSDimitry Andric                    list<dag> pattern>
2485ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2495ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2505ffd83dbSDimitry Andric
2515ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2525ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2535ffd83dbSDimitry Andric                       list<dag> pattern>
2545ffd83dbSDimitry Andric  : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm;
2555ffd83dbSDimitry Andric
2565ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
2575ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
2585ffd83dbSDimitry Andric                        list<dag> pattern>
2595ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
2605ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
2615ffd83dbSDimitry Andric            RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
2625ffd83dbSDimitry Andric
2635ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2645ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
2655ffd83dbSDimitry Andric                        list<dag> pattern>
2665ffd83dbSDimitry Andric  : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm;
2675ffd83dbSDimitry Andric
2685ffd83dbSDimitry Andricclass Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2695ffd83dbSDimitry Andric                              list<dag> pattern>
2705ffd83dbSDimitry Andric  : Z23Form_8<opcode, xo,
2715ffd83dbSDimitry Andric              (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2725ffd83dbSDimitry Andric              !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2735ffd83dbSDimitry Andric  let RC = ex;
2745ffd83dbSDimitry Andric}
2755ffd83dbSDimitry Andric
2765ffd83dbSDimitry Andric// [PO BF // VRA VRB XO /]
2775ffd83dbSDimitry Andricclass X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2785ffd83dbSDimitry Andric                    list<dag> pattern>
2795ffd83dbSDimitry Andric  : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2805ffd83dbSDimitry Andric             !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2815ffd83dbSDimitry Andric  let Pattern = pattern;
2825ffd83dbSDimitry Andric}
2835ffd83dbSDimitry Andric
2845ffd83dbSDimitry Andric// [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2855ffd83dbSDimitry Andric// "out" and "in" dag
2865ffd83dbSDimitry Andricclass X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2875ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
2885ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2895ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
2905ffd83dbSDimitry Andric
2915ffd83dbSDimitry Andric// [PO S RA RB XO SX]
2925ffd83dbSDimitry Andricclass X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2935ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
2945ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2955ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
2965ffd83dbSDimitry Andric} // Predicates = HasP9Vector
2975ffd83dbSDimitry Andric} // AddedComplexity = 400, hasSideEffects = 0
2985ffd83dbSDimitry Andric
2995ffd83dbSDimitry Andricmulticlass ScalToVecWPermute<ValueType Ty, dag In, dag NonPermOut, dag PermOut> {
3005ffd83dbSDimitry Andric  def : Pat<(Ty (scalar_to_vector In)), (Ty NonPermOut)>;
3015ffd83dbSDimitry Andric  def : Pat<(Ty (PPCSToV In)), (Ty PermOut)>;
3025ffd83dbSDimitry Andric}
3035ffd83dbSDimitry Andric
3045ffd83dbSDimitry Andric//-------------------------- Instruction definitions -------------------------//
3055ffd83dbSDimitry Andric// VSX instructions require the VSX feature, they are to be selected over
3065ffd83dbSDimitry Andric// equivalent Altivec patterns (as they address a larger register set) and
3075ffd83dbSDimitry Andric// they do not have unmodeled side effects.
3085ffd83dbSDimitry Andriclet Predicates = [HasVSX], AddedComplexity = 400 in {
3095ffd83dbSDimitry Andriclet hasSideEffects = 0 in {
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric  // Load indexed instructions
3120b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
3130b57cec5SDimitry Andric    let CodeSize = 3 in
3140b57cec5SDimitry Andric    def LXSDX : XX1Form_memOp<31, 588,
3150b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
3160b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
3170b57cec5SDimitry Andric                        []>;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
3200b57cec5SDimitry Andric    let CodeSize = 3 in
3210b57cec5SDimitry Andric      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
3220b57cec5SDimitry Andric                              "#XFLOADf64",
323fe6060f1SDimitry Andric                              [(set f64:$XT, (load XForm:$src))]>;
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3260b57cec5SDimitry Andric    def LXVD2X : XX1Form_memOp<31, 844,
3270b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3280b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
329fe6060f1SDimitry Andric                         []>;
3300b57cec5SDimitry Andric
3310b57cec5SDimitry Andric    def LXVDSX : XX1Form_memOp<31, 332,
3320b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3330b57cec5SDimitry Andric                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3360b57cec5SDimitry Andric    def LXVW4X : XX1Form_memOp<31, 780,
3370b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3380b57cec5SDimitry Andric                         "lxvw4x $XT, $src", IIC_LdStLFD,
3390b57cec5SDimitry Andric                         []>;
3400b57cec5SDimitry Andric  } // mayLoad
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andric  // Store indexed instructions
3430b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
3440b57cec5SDimitry Andric    let CodeSize = 3 in
3450b57cec5SDimitry Andric    def STXSDX : XX1Form_memOp<31, 716,
3460b57cec5SDimitry Andric                        (outs), (ins vsfrc:$XT, memrr:$dst),
3470b57cec5SDimitry Andric                        "stxsdx $XT, $dst", IIC_LdStSTFD,
3480b57cec5SDimitry Andric                        []>;
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
3510b57cec5SDimitry Andric    let CodeSize = 3 in
3520b57cec5SDimitry Andric      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
3530b57cec5SDimitry Andric                              "#XFSTOREf64",
354fe6060f1SDimitry Andric                              [(store f64:$XT, XForm:$dst)]>;
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3570b57cec5SDimitry Andric    // The behaviour of this instruction is endianness-specific so we provide no
3580b57cec5SDimitry Andric    // pattern to match it without considering endianness.
3590b57cec5SDimitry Andric    def STXVD2X : XX1Form_memOp<31, 972,
3600b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3610b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
3620b57cec5SDimitry Andric                         []>;
3630b57cec5SDimitry Andric
3640b57cec5SDimitry Andric    def STXVW4X : XX1Form_memOp<31, 908,
3650b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3660b57cec5SDimitry Andric                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
3670b57cec5SDimitry Andric                         []>;
3680b57cec5SDimitry Andric    }
3690b57cec5SDimitry Andric  } // mayStore
3700b57cec5SDimitry Andric
371e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
372e8d8bef9SDimitry Andric  let Uses = [RM] in {
3730b57cec5SDimitry Andric  // Add/Mul Instructions
3740b57cec5SDimitry Andric  let isCommutable = 1 in {
3750b57cec5SDimitry Andric    def XSADDDP : XX3Form<60, 32,
3760b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3770b57cec5SDimitry Andric                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
3785ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>;
3790b57cec5SDimitry Andric    def XSMULDP : XX3Form<60, 48,
3800b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3810b57cec5SDimitry Andric                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
3825ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>;
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric    def XVADDDP : XX3Form<60, 96,
3850b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3860b57cec5SDimitry Andric                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
3875ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric    def XVADDSP : XX3Form<60, 64,
3900b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3910b57cec5SDimitry Andric                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
3925ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>;
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andric    def XVMULDP : XX3Form<60, 112,
3950b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3960b57cec5SDimitry Andric                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
3975ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>;
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric    def XVMULSP : XX3Form<60, 80,
4000b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4010b57cec5SDimitry Andric                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
4025ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>;
4030b57cec5SDimitry Andric  }
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric  // Subtract Instructions
4060b57cec5SDimitry Andric  def XSSUBDP : XX3Form<60, 40,
4070b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
4080b57cec5SDimitry Andric                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
4095ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>;
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andric  def XVSUBDP : XX3Form<60, 104,
4120b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4130b57cec5SDimitry Andric                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
4145ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>;
4150b57cec5SDimitry Andric  def XVSUBSP : XX3Form<60, 72,
4160b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4170b57cec5SDimitry Andric                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
4185ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>;
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andric  // FMA Instructions
4210b57cec5SDimitry Andric  let BaseName = "XSMADDADP" in {
4220b57cec5SDimitry Andric  let isCommutable = 1 in
4230b57cec5SDimitry Andric  def XSMADDADP : XX3Form<60, 33,
4240b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4250b57cec5SDimitry Andric                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
4265ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, f64:$XTi))]>,
4270b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4280b57cec5SDimitry Andric                          AltVSXFMARel;
4290b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4300b57cec5SDimitry Andric  def XSMADDMDP : XX3Form<60, 41,
4310b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4320b57cec5SDimitry Andric                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4330b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4340b57cec5SDimitry Andric                          AltVSXFMARel;
4350b57cec5SDimitry Andric  }
4360b57cec5SDimitry Andric
4370b57cec5SDimitry Andric  let BaseName = "XSMSUBADP" in {
4380b57cec5SDimitry Andric  let isCommutable = 1 in
4390b57cec5SDimitry Andric  def XSMSUBADP : XX3Form<60, 49,
4400b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4410b57cec5SDimitry Andric                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
4425ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
4430b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4440b57cec5SDimitry Andric                          AltVSXFMARel;
4450b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4460b57cec5SDimitry Andric  def XSMSUBMDP : XX3Form<60, 57,
4470b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4480b57cec5SDimitry Andric                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4490b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4500b57cec5SDimitry Andric                          AltVSXFMARel;
4510b57cec5SDimitry Andric  }
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andric  let BaseName = "XSNMADDADP" in {
4540b57cec5SDimitry Andric  let isCommutable = 1 in
4550b57cec5SDimitry Andric  def XSNMADDADP : XX3Form<60, 161,
4560b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4570b57cec5SDimitry Andric                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
4585ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, f64:$XTi)))]>,
4590b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4600b57cec5SDimitry Andric                          AltVSXFMARel;
4610b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4620b57cec5SDimitry Andric  def XSNMADDMDP : XX3Form<60, 169,
4630b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4640b57cec5SDimitry Andric                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4650b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4660b57cec5SDimitry Andric                          AltVSXFMARel;
4670b57cec5SDimitry Andric  }
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andric  let BaseName = "XSNMSUBADP" in {
4700b57cec5SDimitry Andric  let isCommutable = 1 in
4710b57cec5SDimitry Andric  def XSNMSUBADP : XX3Form<60, 177,
4720b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4730b57cec5SDimitry Andric                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
4745ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
4750b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4760b57cec5SDimitry Andric                          AltVSXFMARel;
4770b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4780b57cec5SDimitry Andric  def XSNMSUBMDP : XX3Form<60, 185,
4790b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4800b57cec5SDimitry Andric                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4810b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4820b57cec5SDimitry Andric                          AltVSXFMARel;
4830b57cec5SDimitry Andric  }
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andric  let BaseName = "XVMADDADP" in {
4860b57cec5SDimitry Andric  let isCommutable = 1 in
4870b57cec5SDimitry Andric  def XVMADDADP : XX3Form<60, 97,
4880b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4890b57cec5SDimitry Andric                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
4905ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
4910b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4920b57cec5SDimitry Andric                          AltVSXFMARel;
4930b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4940b57cec5SDimitry Andric  def XVMADDMDP : XX3Form<60, 105,
4950b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4960b57cec5SDimitry Andric                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4970b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4980b57cec5SDimitry Andric                          AltVSXFMARel;
4990b57cec5SDimitry Andric  }
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andric  let BaseName = "XVMADDASP" in {
5020b57cec5SDimitry Andric  let isCommutable = 1 in
5030b57cec5SDimitry Andric  def XVMADDASP : XX3Form<60, 65,
5040b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5050b57cec5SDimitry Andric                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
5065ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
5070b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5080b57cec5SDimitry Andric                          AltVSXFMARel;
5090b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5100b57cec5SDimitry Andric  def XVMADDMSP : XX3Form<60, 73,
5110b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5120b57cec5SDimitry Andric                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5130b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5140b57cec5SDimitry Andric                          AltVSXFMARel;
5150b57cec5SDimitry Andric  }
5160b57cec5SDimitry Andric
5170b57cec5SDimitry Andric  let BaseName = "XVMSUBADP" in {
5180b57cec5SDimitry Andric  let isCommutable = 1 in
5190b57cec5SDimitry Andric  def XVMSUBADP : XX3Form<60, 113,
5200b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5210b57cec5SDimitry Andric                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
5225ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
5230b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5240b57cec5SDimitry Andric                          AltVSXFMARel;
5250b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5260b57cec5SDimitry Andric  def XVMSUBMDP : XX3Form<60, 121,
5270b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5280b57cec5SDimitry Andric                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5290b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5300b57cec5SDimitry Andric                          AltVSXFMARel;
5310b57cec5SDimitry Andric  }
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric  let BaseName = "XVMSUBASP" in {
5340b57cec5SDimitry Andric  let isCommutable = 1 in
5350b57cec5SDimitry Andric  def XVMSUBASP : XX3Form<60, 81,
5360b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5370b57cec5SDimitry Andric                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
5385ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
5390b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5400b57cec5SDimitry Andric                          AltVSXFMARel;
5410b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5420b57cec5SDimitry Andric  def XVMSUBMSP : XX3Form<60, 89,
5430b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5440b57cec5SDimitry Andric                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
5450b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5460b57cec5SDimitry Andric                          AltVSXFMARel;
5470b57cec5SDimitry Andric  }
5480b57cec5SDimitry Andric
5490b57cec5SDimitry Andric  let BaseName = "XVNMADDADP" in {
5500b57cec5SDimitry Andric  let isCommutable = 1 in
5510b57cec5SDimitry Andric  def XVNMADDADP : XX3Form<60, 225,
5520b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5530b57cec5SDimitry Andric                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
5545ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
5550b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5560b57cec5SDimitry Andric                          AltVSXFMARel;
5570b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5580b57cec5SDimitry Andric  def XVNMADDMDP : XX3Form<60, 233,
5590b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5600b57cec5SDimitry Andric                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
5610b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5620b57cec5SDimitry Andric                          AltVSXFMARel;
5630b57cec5SDimitry Andric  }
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andric  let BaseName = "XVNMADDASP" in {
5660b57cec5SDimitry Andric  let isCommutable = 1 in
5670b57cec5SDimitry Andric  def XVNMADDASP : XX3Form<60, 193,
5680b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5690b57cec5SDimitry Andric                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
5700b57cec5SDimitry Andric                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
5710b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5720b57cec5SDimitry Andric                          AltVSXFMARel;
5730b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5740b57cec5SDimitry Andric  def XVNMADDMSP : XX3Form<60, 201,
5750b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5760b57cec5SDimitry Andric                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5770b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5780b57cec5SDimitry Andric                          AltVSXFMARel;
5790b57cec5SDimitry Andric  }
5800b57cec5SDimitry Andric
5810b57cec5SDimitry Andric  let BaseName = "XVNMSUBADP" in {
5820b57cec5SDimitry Andric  let isCommutable = 1 in
5830b57cec5SDimitry Andric  def XVNMSUBADP : XX3Form<60, 241,
5840b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5850b57cec5SDimitry Andric                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
5865ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
5870b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5880b57cec5SDimitry Andric                          AltVSXFMARel;
5890b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5900b57cec5SDimitry Andric  def XVNMSUBMDP : XX3Form<60, 249,
5910b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5920b57cec5SDimitry Andric                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5930b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5940b57cec5SDimitry Andric                          AltVSXFMARel;
5950b57cec5SDimitry Andric  }
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric  let BaseName = "XVNMSUBASP" in {
5980b57cec5SDimitry Andric  let isCommutable = 1 in
5990b57cec5SDimitry Andric  def XVNMSUBASP : XX3Form<60, 209,
6000b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
6010b57cec5SDimitry Andric                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
6025ffd83dbSDimitry Andric                          [(set v4f32:$XT, (fneg (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
6030b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
6040b57cec5SDimitry Andric                          AltVSXFMARel;
6050b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
6060b57cec5SDimitry Andric  def XVNMSUBMSP : XX3Form<60, 217,
6070b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
6080b57cec5SDimitry Andric                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
6090b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
6100b57cec5SDimitry Andric                          AltVSXFMARel;
6110b57cec5SDimitry Andric  }
6120b57cec5SDimitry Andric
6130b57cec5SDimitry Andric  // Division Instructions
6140b57cec5SDimitry Andric  def XSDIVDP : XX3Form<60, 56,
6150b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
6160b57cec5SDimitry Andric                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
6175ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>;
6180b57cec5SDimitry Andric  def XSSQRTDP : XX2Form<60, 75,
6190b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6200b57cec5SDimitry Andric                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
6215ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsqrt f64:$XB))]>;
6220b57cec5SDimitry Andric
6230b57cec5SDimitry Andric  def XSREDP : XX2Form<60, 90,
6240b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6250b57cec5SDimitry Andric                        "xsredp $XT, $XB", IIC_VecFP,
6260b57cec5SDimitry Andric                        [(set f64:$XT, (PPCfre f64:$XB))]>;
6270b57cec5SDimitry Andric  def XSRSQRTEDP : XX2Form<60, 74,
6280b57cec5SDimitry Andric                           (outs vsfrc:$XT), (ins vsfrc:$XB),
6290b57cec5SDimitry Andric                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
6300b57cec5SDimitry Andric                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
6310b57cec5SDimitry Andric
632e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
6330b57cec5SDimitry Andric  def XSTDIVDP : XX3Form_1<60, 61,
6340b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6350b57cec5SDimitry Andric                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
6360b57cec5SDimitry Andric  def XSTSQRTDP : XX2Form_1<60, 106,
6370b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsfrc:$XB),
638e8d8bef9SDimitry Andric                          "xstsqrtdp $crD, $XB", IIC_FPCompare,
639e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt f64:$XB))]>;
640e8d8bef9SDimitry Andric  def XVTDIVDP : XX3Form_1<60, 125,
641e8d8bef9SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
642e8d8bef9SDimitry Andric                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
643e8d8bef9SDimitry Andric  def XVTDIVSP : XX3Form_1<60, 93,
644e8d8bef9SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
645e8d8bef9SDimitry Andric                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
646e8d8bef9SDimitry Andric
647e8d8bef9SDimitry Andric  def XVTSQRTDP : XX2Form_1<60, 234,
648e8d8bef9SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
649e8d8bef9SDimitry Andric                          "xvtsqrtdp $crD, $XB", IIC_FPCompare,
650e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt v2f64:$XB))]>;
651e8d8bef9SDimitry Andric  def XVTSQRTSP : XX2Form_1<60, 170,
652e8d8bef9SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
653e8d8bef9SDimitry Andric                          "xvtsqrtsp $crD, $XB", IIC_FPCompare,
654e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt v4f32:$XB))]>;
655e8d8bef9SDimitry Andric  }
6560b57cec5SDimitry Andric
6570b57cec5SDimitry Andric  def XVDIVDP : XX3Form<60, 120,
6580b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6590b57cec5SDimitry Andric                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
6605ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>;
6610b57cec5SDimitry Andric  def XVDIVSP : XX3Form<60, 88,
6620b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6630b57cec5SDimitry Andric                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
6645ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>;
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andric  def XVSQRTDP : XX2Form<60, 203,
6670b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6680b57cec5SDimitry Andric                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
6695ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsqrt v2f64:$XB))]>;
6700b57cec5SDimitry Andric  def XVSQRTSP : XX2Form<60, 139,
6710b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6720b57cec5SDimitry Andric                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
6735ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsqrt v4f32:$XB))]>;
6740b57cec5SDimitry Andric
6750b57cec5SDimitry Andric  def XVREDP : XX2Form<60, 218,
6760b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6770b57cec5SDimitry Andric                        "xvredp $XT, $XB", IIC_VecFP,
6780b57cec5SDimitry Andric                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
6790b57cec5SDimitry Andric  def XVRESP : XX2Form<60, 154,
6800b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6810b57cec5SDimitry Andric                        "xvresp $XT, $XB", IIC_VecFP,
6820b57cec5SDimitry Andric                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
6830b57cec5SDimitry Andric
6840b57cec5SDimitry Andric  def XVRSQRTEDP : XX2Form<60, 202,
6850b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6860b57cec5SDimitry Andric                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
6870b57cec5SDimitry Andric                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
6880b57cec5SDimitry Andric  def XVRSQRTESP : XX2Form<60, 138,
6890b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6900b57cec5SDimitry Andric                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
6910b57cec5SDimitry Andric                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
6920b57cec5SDimitry Andric
6930b57cec5SDimitry Andric  // Compare Instructions
6940b57cec5SDimitry Andric  def XSCMPODP : XX3Form_1<60, 43,
6950b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6960b57cec5SDimitry Andric                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
6970b57cec5SDimitry Andric  def XSCMPUDP : XX3Form_1<60, 35,
6980b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6990b57cec5SDimitry Andric                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andric  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
7020b57cec5SDimitry Andric                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
7030b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
7040b57cec5SDimitry Andric  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
7050b57cec5SDimitry Andric                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
7060b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
7070b57cec5SDimitry Andric  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
7080b57cec5SDimitry Andric                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
7090b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
7100b57cec5SDimitry Andric  defm XVCMPGESP : XX3Form_Rcr<60, 83,
7110b57cec5SDimitry Andric                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
7120b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
7130b57cec5SDimitry Andric  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
7140b57cec5SDimitry Andric                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
7150b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
7160b57cec5SDimitry Andric  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
7170b57cec5SDimitry Andric                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
7180b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
7190b57cec5SDimitry Andric
7200b57cec5SDimitry Andric  // Move Instructions
721e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
7220b57cec5SDimitry Andric  def XSABSDP : XX2Form<60, 345,
7230b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7240b57cec5SDimitry Andric                      "xsabsdp $XT, $XB", IIC_VecFP,
7250b57cec5SDimitry Andric                      [(set f64:$XT, (fabs f64:$XB))]>;
7260b57cec5SDimitry Andric  def XSNABSDP : XX2Form<60, 361,
7270b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7280b57cec5SDimitry Andric                      "xsnabsdp $XT, $XB", IIC_VecFP,
7290b57cec5SDimitry Andric                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
7300b57cec5SDimitry Andric  def XSNEGDP : XX2Form<60, 377,
7310b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7320b57cec5SDimitry Andric                      "xsnegdp $XT, $XB", IIC_VecFP,
7330b57cec5SDimitry Andric                      [(set f64:$XT, (fneg f64:$XB))]>;
7340b57cec5SDimitry Andric  def XSCPSGNDP : XX3Form<60, 176,
7350b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
7360b57cec5SDimitry Andric                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
7370b57cec5SDimitry Andric                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric  def XVABSDP : XX2Form<60, 473,
7400b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7410b57cec5SDimitry Andric                      "xvabsdp $XT, $XB", IIC_VecFP,
7420b57cec5SDimitry Andric                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andric  def XVABSSP : XX2Form<60, 409,
7450b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7460b57cec5SDimitry Andric                      "xvabssp $XT, $XB", IIC_VecFP,
7470b57cec5SDimitry Andric                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric  def XVCPSGNDP : XX3Form<60, 240,
7500b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7510b57cec5SDimitry Andric                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
7520b57cec5SDimitry Andric                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
7530b57cec5SDimitry Andric  def XVCPSGNSP : XX3Form<60, 208,
7540b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7550b57cec5SDimitry Andric                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
7560b57cec5SDimitry Andric                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
7570b57cec5SDimitry Andric
7580b57cec5SDimitry Andric  def XVNABSDP : XX2Form<60, 489,
7590b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7600b57cec5SDimitry Andric                      "xvnabsdp $XT, $XB", IIC_VecFP,
7610b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
7620b57cec5SDimitry Andric  def XVNABSSP : XX2Form<60, 425,
7630b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7640b57cec5SDimitry Andric                      "xvnabssp $XT, $XB", IIC_VecFP,
7650b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
7660b57cec5SDimitry Andric
7670b57cec5SDimitry Andric  def XVNEGDP : XX2Form<60, 505,
7680b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7690b57cec5SDimitry Andric                      "xvnegdp $XT, $XB", IIC_VecFP,
7700b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
7710b57cec5SDimitry Andric  def XVNEGSP : XX2Form<60, 441,
7720b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7730b57cec5SDimitry Andric                      "xvnegsp $XT, $XB", IIC_VecFP,
7740b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
775e8d8bef9SDimitry Andric  }
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andric  // Conversion Instructions
7780b57cec5SDimitry Andric  def XSCVDPSP : XX2Form<60, 265,
7790b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7800b57cec5SDimitry Andric                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
7810b57cec5SDimitry Andric  def XSCVDPSXDS : XX2Form<60, 344,
7820b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7830b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
784e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctidz f64:$XB))]>;
7850b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7860b57cec5SDimitry Andric  def XSCVDPSXDSs : XX2Form<60, 344,
7870b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7880b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
789e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctidz f32:$XB))]>;
7900b57cec5SDimitry Andric  def XSCVDPSXWS : XX2Form<60, 88,
7910b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7920b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
793e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>;
7940b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7950b57cec5SDimitry Andric  def XSCVDPSXWSs : XX2Form<60, 88,
7960b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7970b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
798e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>;
7990b57cec5SDimitry Andric  def XSCVDPUXDS : XX2Form<60, 328,
8000b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8010b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
802e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>;
8030b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
8040b57cec5SDimitry Andric  def XSCVDPUXDSs : XX2Form<60, 328,
8050b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
8060b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
807e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>;
8080b57cec5SDimitry Andric  def XSCVDPUXWS : XX2Form<60, 72,
8090b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8100b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
811e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>;
8120b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
8130b57cec5SDimitry Andric  def XSCVDPUXWSs : XX2Form<60, 72,
8140b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
8150b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
816e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>;
8170b57cec5SDimitry Andric  def XSCVSPDP : XX2Form<60, 329,
8180b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8190b57cec5SDimitry Andric                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
8200b57cec5SDimitry Andric  def XSCVSXDDP : XX2Form<60, 376,
8210b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8220b57cec5SDimitry Andric                      "xscvsxddp $XT, $XB", IIC_VecFP,
823e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fcfid f64:$XB))]>;
8240b57cec5SDimitry Andric  def XSCVUXDDP : XX2Form<60, 360,
8250b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8260b57cec5SDimitry Andric                      "xscvuxddp $XT, $XB", IIC_VecFP,
827e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>;
8280b57cec5SDimitry Andric
8290b57cec5SDimitry Andric  def XVCVDPSP : XX2Form<60, 393,
8300b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8310b57cec5SDimitry Andric                      "xvcvdpsp $XT, $XB", IIC_VecFP,
8320b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
8330b57cec5SDimitry Andric  def XVCVDPSXDS : XX2Form<60, 472,
8340b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8350b57cec5SDimitry Andric                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
836e8d8bef9SDimitry Andric                      [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>;
8370b57cec5SDimitry Andric  def XVCVDPSXWS : XX2Form<60, 216,
8380b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8390b57cec5SDimitry Andric                      "xvcvdpsxws $XT, $XB", IIC_VecFP,
8400b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
8410b57cec5SDimitry Andric  def XVCVDPUXDS : XX2Form<60, 456,
8420b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8430b57cec5SDimitry Andric                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
844e8d8bef9SDimitry Andric                      [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>;
8450b57cec5SDimitry Andric  def XVCVDPUXWS : XX2Form<60, 200,
8460b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8470b57cec5SDimitry Andric                      "xvcvdpuxws $XT, $XB", IIC_VecFP,
8480b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric  def XVCVSPDP : XX2Form<60, 457,
8510b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8520b57cec5SDimitry Andric                      "xvcvspdp $XT, $XB", IIC_VecFP,
8530b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
8540b57cec5SDimitry Andric  def XVCVSPSXDS : XX2Form<60, 408,
8550b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
856fe6060f1SDimitry Andric                      "xvcvspsxds $XT, $XB", IIC_VecFP,
857fe6060f1SDimitry Andric                      [(set v2i64:$XT, (int_ppc_vsx_xvcvspsxds v4f32:$XB))]>;
8580b57cec5SDimitry Andric  def XVCVSPSXWS : XX2Form<60, 152,
8590b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8600b57cec5SDimitry Andric                      "xvcvspsxws $XT, $XB", IIC_VecFP,
861e8d8bef9SDimitry Andric                      [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>;
8620b57cec5SDimitry Andric  def XVCVSPUXDS : XX2Form<60, 392,
8630b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
864fe6060f1SDimitry Andric                      "xvcvspuxds $XT, $XB", IIC_VecFP,
865fe6060f1SDimitry Andric                      [(set v2i64:$XT, (int_ppc_vsx_xvcvspuxds v4f32:$XB))]>;
8660b57cec5SDimitry Andric  def XVCVSPUXWS : XX2Form<60, 136,
8670b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8680b57cec5SDimitry Andric                      "xvcvspuxws $XT, $XB", IIC_VecFP,
869e8d8bef9SDimitry Andric                      [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>;
8700b57cec5SDimitry Andric  def XVCVSXDDP : XX2Form<60, 504,
8710b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8720b57cec5SDimitry Andric                      "xvcvsxddp $XT, $XB", IIC_VecFP,
873e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>;
8740b57cec5SDimitry Andric  def XVCVSXDSP : XX2Form<60, 440,
8750b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8760b57cec5SDimitry Andric                      "xvcvsxdsp $XT, $XB", IIC_VecFP,
8770b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
8780b57cec5SDimitry Andric  def XVCVSXWSP : XX2Form<60, 184,
8790b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8800b57cec5SDimitry Andric                      "xvcvsxwsp $XT, $XB", IIC_VecFP,
881e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>;
8820b57cec5SDimitry Andric  def XVCVUXDDP : XX2Form<60, 488,
8830b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8840b57cec5SDimitry Andric                      "xvcvuxddp $XT, $XB", IIC_VecFP,
885e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>;
8860b57cec5SDimitry Andric  def XVCVUXDSP : XX2Form<60, 424,
8870b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8880b57cec5SDimitry Andric                      "xvcvuxdsp $XT, $XB", IIC_VecFP,
8890b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
890e8d8bef9SDimitry Andric  def XVCVUXWSP : XX2Form<60, 168,
891e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
892e8d8bef9SDimitry Andric                      "xvcvuxwsp $XT, $XB", IIC_VecFP,
893e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>;
894e8d8bef9SDimitry Andric
895e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
896e8d8bef9SDimitry Andric  def XVCVSXWDP : XX2Form<60, 248,
897e8d8bef9SDimitry Andric                    (outs vsrc:$XT), (ins vsrc:$XB),
898e8d8bef9SDimitry Andric                    "xvcvsxwdp $XT, $XB", IIC_VecFP,
899e8d8bef9SDimitry Andric                    [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
9000b57cec5SDimitry Andric  def XVCVUXWDP : XX2Form<60, 232,
9010b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9020b57cec5SDimitry Andric                      "xvcvuxwdp $XT, $XB", IIC_VecFP,
9030b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
904e8d8bef9SDimitry Andric  }
9050b57cec5SDimitry Andric
906e8d8bef9SDimitry Andric  // Rounding Instructions respecting current rounding mode
9070b57cec5SDimitry Andric  def XSRDPIC : XX2Form<60, 107,
9080b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
909349cc55cSDimitry Andric                      "xsrdpic $XT, $XB", IIC_VecFP, []>;
9100b57cec5SDimitry Andric  def XVRDPIC : XX2Form<60, 235,
9110b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
912349cc55cSDimitry Andric                      "xvrdpic $XT, $XB", IIC_VecFP, []>;
9130b57cec5SDimitry Andric  def XVRSPIC : XX2Form<60, 171,
9140b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
915349cc55cSDimitry Andric                      "xvrspic $XT, $XB", IIC_VecFP, []>;
9160b57cec5SDimitry Andric  // Max/Min Instructions
9170b57cec5SDimitry Andric  let isCommutable = 1 in {
9180b57cec5SDimitry Andric  def XSMAXDP : XX3Form<60, 160,
9190b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9200b57cec5SDimitry Andric                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
9210b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9220b57cec5SDimitry Andric                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
9230b57cec5SDimitry Andric  def XSMINDP : XX3Form<60, 168,
9240b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9250b57cec5SDimitry Andric                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
9260b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9270b57cec5SDimitry Andric                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andric  def XVMAXDP : XX3Form<60, 224,
9300b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9310b57cec5SDimitry Andric                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
9320b57cec5SDimitry Andric                        [(set vsrc:$XT,
9330b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
9340b57cec5SDimitry Andric  def XVMINDP : XX3Form<60, 232,
9350b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9360b57cec5SDimitry Andric                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
9370b57cec5SDimitry Andric                        [(set vsrc:$XT,
9380b57cec5SDimitry Andric                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
9390b57cec5SDimitry Andric
9400b57cec5SDimitry Andric  def XVMAXSP : XX3Form<60, 192,
9410b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9420b57cec5SDimitry Andric                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
9430b57cec5SDimitry Andric                        [(set vsrc:$XT,
9440b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
9450b57cec5SDimitry Andric  def XVMINSP : XX3Form<60, 200,
9460b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9470b57cec5SDimitry Andric                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
9480b57cec5SDimitry Andric                        [(set vsrc:$XT,
9490b57cec5SDimitry Andric                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
9500b57cec5SDimitry Andric  } // isCommutable
951e8d8bef9SDimitry Andric  } // Uses = [RM]
952e8d8bef9SDimitry Andric
953e8d8bef9SDimitry Andric  // Rounding Instructions with static direction.
954e8d8bef9SDimitry Andric  def XSRDPI : XX2Form<60, 73,
955e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
956e8d8bef9SDimitry Andric                      "xsrdpi $XT, $XB", IIC_VecFP,
957e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_fround f64:$XB))]>;
958e8d8bef9SDimitry Andric  def XSRDPIM : XX2Form<60, 121,
959e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
960e8d8bef9SDimitry Andric                      "xsrdpim $XT, $XB", IIC_VecFP,
961e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_ffloor f64:$XB))]>;
962e8d8bef9SDimitry Andric  def XSRDPIP : XX2Form<60, 105,
963e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
964e8d8bef9SDimitry Andric                      "xsrdpip $XT, $XB", IIC_VecFP,
965e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_fceil f64:$XB))]>;
966e8d8bef9SDimitry Andric  def XSRDPIZ : XX2Form<60, 89,
967e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
968e8d8bef9SDimitry Andric                      "xsrdpiz $XT, $XB", IIC_VecFP,
969e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_ftrunc f64:$XB))]>;
970e8d8bef9SDimitry Andric
971e8d8bef9SDimitry Andric  def XVRDPI : XX2Form<60, 201,
972e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
973e8d8bef9SDimitry Andric                      "xvrdpi $XT, $XB", IIC_VecFP,
974e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_fround v2f64:$XB))]>;
975e8d8bef9SDimitry Andric  def XVRDPIM : XX2Form<60, 249,
976e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
977e8d8bef9SDimitry Andric                      "xvrdpim $XT, $XB", IIC_VecFP,
978e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
979e8d8bef9SDimitry Andric  def XVRDPIP : XX2Form<60, 233,
980e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
981e8d8bef9SDimitry Andric                      "xvrdpip $XT, $XB", IIC_VecFP,
982e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
983e8d8bef9SDimitry Andric  def XVRDPIZ : XX2Form<60, 217,
984e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
985e8d8bef9SDimitry Andric                      "xvrdpiz $XT, $XB", IIC_VecFP,
986e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
987e8d8bef9SDimitry Andric
988e8d8bef9SDimitry Andric  def XVRSPI : XX2Form<60, 137,
989e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
990e8d8bef9SDimitry Andric                      "xvrspi $XT, $XB", IIC_VecFP,
991e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_fround v4f32:$XB))]>;
992e8d8bef9SDimitry Andric  def XVRSPIM : XX2Form<60, 185,
993e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
994e8d8bef9SDimitry Andric                      "xvrspim $XT, $XB", IIC_VecFP,
995e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
996e8d8bef9SDimitry Andric  def XVRSPIP : XX2Form<60, 169,
997e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
998e8d8bef9SDimitry Andric                      "xvrspip $XT, $XB", IIC_VecFP,
999e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
1000e8d8bef9SDimitry Andric  def XVRSPIZ : XX2Form<60, 153,
1001e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
1002e8d8bef9SDimitry Andric                      "xvrspiz $XT, $XB", IIC_VecFP,
1003e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
1004e8d8bef9SDimitry Andric  } // mayRaiseFPException
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andric  // Logical Instructions
10070b57cec5SDimitry Andric  let isCommutable = 1 in
10080b57cec5SDimitry Andric  def XXLAND : XX3Form<60, 130,
10090b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10100b57cec5SDimitry Andric                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
10110b57cec5SDimitry Andric                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
10120b57cec5SDimitry Andric  def XXLANDC : XX3Form<60, 138,
10130b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10140b57cec5SDimitry Andric                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
10150b57cec5SDimitry Andric                        [(set v4i32:$XT, (and v4i32:$XA,
1016fe6060f1SDimitry Andric                                              (vnot v4i32:$XB)))]>;
10170b57cec5SDimitry Andric  let isCommutable = 1 in {
10180b57cec5SDimitry Andric  def XXLNOR : XX3Form<60, 162,
10190b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10200b57cec5SDimitry Andric                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
1021fe6060f1SDimitry Andric                       [(set v4i32:$XT, (vnot (or v4i32:$XA,
10220b57cec5SDimitry Andric                                               v4i32:$XB)))]>;
10230b57cec5SDimitry Andric  def XXLOR : XX3Form<60, 146,
10240b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10250b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
10260b57cec5SDimitry Andric                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
10270b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10280b57cec5SDimitry Andric  def XXLORf: XX3Form<60, 146,
10290b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
10300b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
10310b57cec5SDimitry Andric  def XXLXOR : XX3Form<60, 154,
10320b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10330b57cec5SDimitry Andric                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
10340b57cec5SDimitry Andric                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
10350b57cec5SDimitry Andric  } // isCommutable
10360b57cec5SDimitry Andric
10370b57cec5SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
10380b57cec5SDimitry Andric      isReMaterializable = 1 in {
10398bcb0991SDimitry Andric    def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
10400b57cec5SDimitry Andric                       "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10410b57cec5SDimitry Andric                       [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
10428bcb0991SDimitry Andric    def XXLXORdpz : XX3Form_SameOp<60, 154,
10430b57cec5SDimitry Andric                         (outs vsfrc:$XT), (ins),
10440b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10450b57cec5SDimitry Andric                         [(set f64:$XT, (fpimm0))]>;
10468bcb0991SDimitry Andric    def XXLXORspz : XX3Form_SameOp<60, 154,
10470b57cec5SDimitry Andric                         (outs vssrc:$XT), (ins),
10480b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10490b57cec5SDimitry Andric                         [(set f32:$XT, (fpimm0))]>;
10500b57cec5SDimitry Andric  }
10510b57cec5SDimitry Andric
10520b57cec5SDimitry Andric  // Permutation Instructions
10530b57cec5SDimitry Andric  def XXMRGHW : XX3Form<60, 18,
10540b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10550b57cec5SDimitry Andric                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
10560b57cec5SDimitry Andric  def XXMRGLW : XX3Form<60, 50,
10570b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10580b57cec5SDimitry Andric                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
10590b57cec5SDimitry Andric
10600b57cec5SDimitry Andric  def XXPERMDI : XX3Form_2<60, 10,
10610b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
10620b57cec5SDimitry Andric                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
10630b57cec5SDimitry Andric                       [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
10640b57cec5SDimitry Andric                         imm32SExt16:$DM))]>;
10650b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
1066349cc55cSDimitry Andric  // Note that the input register class for `$XA` of XXPERMDIs is `vsfrc` which
1067349cc55cSDimitry Andric  // is not the same with the input register class(`vsrc`) of XXPERMDI instruction.
1068349cc55cSDimitry Andric  // We did this on purpose because:
1069349cc55cSDimitry Andric  // 1: The input is primarily for loads that load a partial vector(LFIWZX,
1070349cc55cSDimitry Andric  //    etc.), no need for SUBREG_TO_REG.
1071349cc55cSDimitry Andric  // 2: With `vsfrc` register class, in the final assembly, float registers
1072349cc55cSDimitry Andric  //    like `f0` are used instead of vector scalar register like `vs0`. This
1073349cc55cSDimitry Andric  //    helps readability.
10740b57cec5SDimitry Andric  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
10750b57cec5SDimitry Andric                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
10760b57cec5SDimitry Andric  def XXSEL : XX4Form<60, 3,
10770b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
10780b57cec5SDimitry Andric                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
10790b57cec5SDimitry Andric
10800b57cec5SDimitry Andric  def XXSLDWI : XX3Form_2<60, 2,
10810b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
10820b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
10830b57cec5SDimitry Andric                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
10840b57cec5SDimitry Andric                                                  imm32SExt16:$SHW))]>;
10850b57cec5SDimitry Andric
10860b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10870b57cec5SDimitry Andric  def XXSLDWIs : XX3Form_2s<60, 2,
10880b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
10890b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
10900b57cec5SDimitry Andric
10910b57cec5SDimitry Andric  def XXSPLTW : XX2Form_2<60, 164,
10920b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
10930b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
10940b57cec5SDimitry Andric                       [(set v4i32:$XT,
10950b57cec5SDimitry Andric                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
10960b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10970b57cec5SDimitry Andric  def XXSPLTWs : XX2Form_2<60, 164,
10980b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
10990b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
11000b57cec5SDimitry Andric
11015ffd83dbSDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07
11025ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
11035ffd83dbSDimitry Andric  let isCommutable = 1 in {
11045ffd83dbSDimitry Andric    def XXLEQV : XX3Form<60, 186,
11055ffd83dbSDimitry Andric                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
11065ffd83dbSDimitry Andric                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1107fe6060f1SDimitry Andric                         [(set v4i32:$XT, (vnot (xor v4i32:$XA, v4i32:$XB)))]>;
11085ffd83dbSDimitry Andric    def XXLNAND : XX3Form<60, 178,
11095ffd83dbSDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
11105ffd83dbSDimitry Andric                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1111fe6060f1SDimitry Andric                          [(set v4i32:$XT, (vnot (and v4i32:$XA, v4i32:$XB)))]>;
11125ffd83dbSDimitry Andric  } // isCommutable
11130b57cec5SDimitry Andric
11145ffd83dbSDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
11155ffd83dbSDimitry Andric      isReMaterializable = 1 in {
11165ffd83dbSDimitry Andric    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
11175ffd83dbSDimitry Andric                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
11185ffd83dbSDimitry Andric                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
11195ffd83dbSDimitry Andric  }
11205ffd83dbSDimitry Andric
11215ffd83dbSDimitry Andric  def XXLORC : XX3Form<60, 170,
11225ffd83dbSDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
11235ffd83dbSDimitry Andric                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1124fe6060f1SDimitry Andric                       [(set v4i32:$XT, (or v4i32:$XA, (vnot v4i32:$XB)))]>;
11255ffd83dbSDimitry Andric
11265ffd83dbSDimitry Andric  // VSX scalar loads introduced in ISA 2.07
11275ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
11285ffd83dbSDimitry Andric    let CodeSize = 3 in
11295ffd83dbSDimitry Andric    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
11305ffd83dbSDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
11315ffd83dbSDimitry Andric    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
11325ffd83dbSDimitry Andric                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
11335ffd83dbSDimitry Andric    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
11345ffd83dbSDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
11355ffd83dbSDimitry Andric
11365ffd83dbSDimitry Andric    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
11375ffd83dbSDimitry Andric    let CodeSize = 3 in
11385ffd83dbSDimitry Andric    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
11395ffd83dbSDimitry Andric                            "#XFLOADf32",
1140fe6060f1SDimitry Andric                            [(set f32:$XT, (load XForm:$src))]>;
11415ffd83dbSDimitry Andric    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
11425ffd83dbSDimitry Andric    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
11435ffd83dbSDimitry Andric                       "#LIWAX",
1144fe6060f1SDimitry Andric                       [(set f64:$XT, (PPClfiwax ForceXForm:$src))]>;
11455ffd83dbSDimitry Andric    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
11465ffd83dbSDimitry Andric    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
11475ffd83dbSDimitry Andric                       "#LIWZX",
1148fe6060f1SDimitry Andric                       [(set f64:$XT, (PPClfiwzx ForceXForm:$src))]>;
11495ffd83dbSDimitry Andric  } // mayLoad
11505ffd83dbSDimitry Andric
11515ffd83dbSDimitry Andric  // VSX scalar stores introduced in ISA 2.07
11525ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
11535ffd83dbSDimitry Andric    let CodeSize = 3 in
11545ffd83dbSDimitry Andric    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
11555ffd83dbSDimitry Andric                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
11565ffd83dbSDimitry Andric    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
11575ffd83dbSDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
11585ffd83dbSDimitry Andric
11595ffd83dbSDimitry Andric    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
11605ffd83dbSDimitry Andric    let CodeSize = 3 in
11615ffd83dbSDimitry Andric    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
11625ffd83dbSDimitry Andric                            "#XFSTOREf32",
1163fe6060f1SDimitry Andric                            [(store f32:$XT, XForm:$dst)]>;
11645ffd83dbSDimitry Andric    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
11655ffd83dbSDimitry Andric    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
11665ffd83dbSDimitry Andric                       "#STIWX",
1167fe6060f1SDimitry Andric                      [(PPCstfiwx f64:$XT, ForceXForm:$dst)]>;
11685ffd83dbSDimitry Andric  } // mayStore
11695ffd83dbSDimitry Andric
11705ffd83dbSDimitry Andric  // VSX Elementary Scalar FP arithmetic (SP)
11715ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
11725ffd83dbSDimitry Andric  let isCommutable = 1 in {
11735ffd83dbSDimitry Andric    def XSADDSP : XX3Form<60, 0,
11745ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11755ffd83dbSDimitry Andric                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
11765ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>;
11775ffd83dbSDimitry Andric    def XSMULSP : XX3Form<60, 16,
11785ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11795ffd83dbSDimitry Andric                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
11805ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>;
11815ffd83dbSDimitry Andric  } // isCommutable
11825ffd83dbSDimitry Andric
11835ffd83dbSDimitry Andric  def XSSUBSP : XX3Form<60, 8,
11845ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11855ffd83dbSDimitry Andric                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
11865ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>;
11875ffd83dbSDimitry Andric  def XSDIVSP : XX3Form<60, 24,
11885ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11895ffd83dbSDimitry Andric                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
11905ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>;
11915ffd83dbSDimitry Andric
11925ffd83dbSDimitry Andric  def XSRESP : XX2Form<60, 26,
11935ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
11945ffd83dbSDimitry Andric                        "xsresp $XT, $XB", IIC_VecFP,
11955ffd83dbSDimitry Andric                        [(set f32:$XT, (PPCfre f32:$XB))]>;
11965ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1197e8d8bef9SDimitry Andric  let hasSideEffects = 1 in
11985ffd83dbSDimitry Andric  def XSRSP : XX2Form<60, 281,
11995ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vsfrc:$XB),
12005ffd83dbSDimitry Andric                        "xsrsp $XT, $XB", IIC_VecFP,
12015ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fpround f64:$XB))]>;
12025ffd83dbSDimitry Andric  def XSSQRTSP : XX2Form<60, 11,
12035ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
12045ffd83dbSDimitry Andric                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
12055ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsqrt f32:$XB))]>;
12065ffd83dbSDimitry Andric  def XSRSQRTESP : XX2Form<60, 10,
12075ffd83dbSDimitry Andric                           (outs vssrc:$XT), (ins vssrc:$XB),
12085ffd83dbSDimitry Andric                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
12095ffd83dbSDimitry Andric                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
12105ffd83dbSDimitry Andric
12115ffd83dbSDimitry Andric  // FMA Instructions
12125ffd83dbSDimitry Andric  let BaseName = "XSMADDASP" in {
12135ffd83dbSDimitry Andric  let isCommutable = 1 in
12145ffd83dbSDimitry Andric  def XSMADDASP : XX3Form<60, 1,
12155ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12165ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12175ffd83dbSDimitry Andric                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
12185ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB, f32:$XTi))]>,
12195ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12205ffd83dbSDimitry Andric                          AltVSXFMARel;
12215ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12225ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12235ffd83dbSDimitry Andric  def XSMADDMSP : XX3Form<60, 9,
12245ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12255ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12265ffd83dbSDimitry Andric                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
12275ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12285ffd83dbSDimitry Andric                          AltVSXFMARel;
12295ffd83dbSDimitry Andric  }
12305ffd83dbSDimitry Andric
12315ffd83dbSDimitry Andric  let BaseName = "XSMSUBASP" in {
12325ffd83dbSDimitry Andric  let isCommutable = 1 in
12335ffd83dbSDimitry Andric  def XSMSUBASP : XX3Form<60, 17,
12345ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12355ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12365ffd83dbSDimitry Andric                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
12375ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB,
12385ffd83dbSDimitry Andric                                              (fneg f32:$XTi)))]>,
12395ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12405ffd83dbSDimitry Andric                          AltVSXFMARel;
12415ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12425ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12435ffd83dbSDimitry Andric  def XSMSUBMSP : XX3Form<60, 25,
12445ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12455ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12465ffd83dbSDimitry Andric                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
12475ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12485ffd83dbSDimitry Andric                          AltVSXFMARel;
12495ffd83dbSDimitry Andric  }
12505ffd83dbSDimitry Andric
12515ffd83dbSDimitry Andric  let BaseName = "XSNMADDASP" in {
12525ffd83dbSDimitry Andric  let isCommutable = 1 in
12535ffd83dbSDimitry Andric  def XSNMADDASP : XX3Form<60, 129,
12545ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12555ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12565ffd83dbSDimitry Andric                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
12575ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
12585ffd83dbSDimitry Andric                                                    f32:$XTi)))]>,
12595ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12605ffd83dbSDimitry Andric                          AltVSXFMARel;
12615ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12625ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12635ffd83dbSDimitry Andric  def XSNMADDMSP : XX3Form<60, 137,
12645ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12655ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12665ffd83dbSDimitry Andric                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
12675ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12685ffd83dbSDimitry Andric                          AltVSXFMARel;
12695ffd83dbSDimitry Andric  }
12705ffd83dbSDimitry Andric
12715ffd83dbSDimitry Andric  let BaseName = "XSNMSUBASP" in {
12725ffd83dbSDimitry Andric  let isCommutable = 1 in
12735ffd83dbSDimitry Andric  def XSNMSUBASP : XX3Form<60, 145,
12745ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12755ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12765ffd83dbSDimitry Andric                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
12775ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
12785ffd83dbSDimitry Andric                                                    (fneg f32:$XTi))))]>,
12795ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12805ffd83dbSDimitry Andric                          AltVSXFMARel;
12815ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12825ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12835ffd83dbSDimitry Andric  def XSNMSUBMSP : XX3Form<60, 153,
12845ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12855ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12865ffd83dbSDimitry Andric                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
12875ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12885ffd83dbSDimitry Andric                          AltVSXFMARel;
12895ffd83dbSDimitry Andric  }
12905ffd83dbSDimitry Andric
12915ffd83dbSDimitry Andric  // Single Precision Conversions (FP <-> INT)
12925ffd83dbSDimitry Andric  def XSCVSXDSP : XX2Form<60, 312,
12935ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
12945ffd83dbSDimitry Andric                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1295e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fcfids f64:$XB))]>;
12965ffd83dbSDimitry Andric  def XSCVUXDSP : XX2Form<60, 296,
12975ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
12985ffd83dbSDimitry Andric                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1299e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>;
1300e8d8bef9SDimitry Andric  } // mayRaiseFPException
13015ffd83dbSDimitry Andric
13025ffd83dbSDimitry Andric  // Conversions between vector and scalar single precision
13035ffd83dbSDimitry Andric  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
13045ffd83dbSDimitry Andric                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
13055ffd83dbSDimitry Andric  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
13065ffd83dbSDimitry Andric                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
13075ffd83dbSDimitry Andric
13085ffd83dbSDimitry Andric  let Predicates = [HasVSX, HasDirectMove] in {
13095ffd83dbSDimitry Andric  // VSX direct move instructions
13105ffd83dbSDimitry Andric  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
13115ffd83dbSDimitry Andric                              "mfvsrd $rA, $XT", IIC_VecGeneral,
13125ffd83dbSDimitry Andric                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
13135ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13145ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13155ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13165ffd83dbSDimitry Andric  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
13175ffd83dbSDimitry Andric                             "mfvsrd $rA, $XT", IIC_VecGeneral,
13185ffd83dbSDimitry Andric                             []>,
13195ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13205ffd83dbSDimitry Andric  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
13215ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
13225ffd83dbSDimitry Andric                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
13235ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13245ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13255ffd83dbSDimitry Andric  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
13265ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
13275ffd83dbSDimitry Andric                               []>;
13285ffd83dbSDimitry Andric  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
13295ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
13305ffd83dbSDimitry Andric                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
13315ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13325ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13335ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13345ffd83dbSDimitry Andric  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
13355ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
13365ffd83dbSDimitry Andric                              []>,
13375ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13385ffd83dbSDimitry Andric  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
13395ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
13405ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
13415ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13425ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13435ffd83dbSDimitry Andric  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
13445ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
13455ffd83dbSDimitry Andric                               []>;
13465ffd83dbSDimitry Andric  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
13475ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
13485ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
13495ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13505ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13515ffd83dbSDimitry Andric  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
13525ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
13535ffd83dbSDimitry Andric                               []>;
13545ffd83dbSDimitry Andric  } // HasDirectMove
13555ffd83dbSDimitry Andric
13565ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
13575ffd83dbSDimitry Andric
13585ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove] in {
13595ffd83dbSDimitry Andricdef MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
13605ffd83dbSDimitry Andric                            "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
13615ffd83dbSDimitry Andric
13625ffd83dbSDimitry Andricdef MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
13635ffd83dbSDimitry Andric                     "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
13645ffd83dbSDimitry Andric                     []>, Requires<[In64BitMode]>;
13655ffd83dbSDimitry Andric
13665ffd83dbSDimitry Andricdef MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
13675ffd83dbSDimitry Andric                            "mfvsrld $rA, $XT", IIC_VecGeneral,
13685ffd83dbSDimitry Andric                            []>, Requires<[In64BitMode]>;
13695ffd83dbSDimitry Andric
13705ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove
13715ffd83dbSDimitry Andric
13725ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
13735ffd83dbSDimitry Andric  // Quad-Precision Scalar Move Instructions:
13745ffd83dbSDimitry Andric  // Copy Sign
13755ffd83dbSDimitry Andric  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
13765ffd83dbSDimitry Andric                                [(set f128:$vT,
13775ffd83dbSDimitry Andric                                      (fcopysign f128:$vB, f128:$vA))]>;
13785ffd83dbSDimitry Andric
13795ffd83dbSDimitry Andric  // Absolute/Negative-Absolute/Negate
13805ffd83dbSDimitry Andric  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
13815ffd83dbSDimitry Andric                                [(set f128:$vT, (fabs f128:$vB))]>;
13825ffd83dbSDimitry Andric  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
13835ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
13845ffd83dbSDimitry Andric  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
13855ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg f128:$vB))]>;
13865ffd83dbSDimitry Andric
13875ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
13885ffd83dbSDimitry Andric  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
13895ffd83dbSDimitry Andric
13905ffd83dbSDimitry Andric  // Add/Divide/Multiply/Subtract
13915ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
13925ffd83dbSDimitry Andric  let isCommutable = 1 in {
13935ffd83dbSDimitry Andric  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
13945ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>;
13955ffd83dbSDimitry Andric  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
13965ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>;
13975ffd83dbSDimitry Andric  }
13985ffd83dbSDimitry Andric  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
13995ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>;
14005ffd83dbSDimitry Andric  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
14015ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>;
14025ffd83dbSDimitry Andric  // Square-Root
14035ffd83dbSDimitry Andric  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
14045ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsqrt f128:$vB))]>;
14055ffd83dbSDimitry Andric  // (Negative) Multiply-{Add/Subtract}
14065ffd83dbSDimitry Andric  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
14075ffd83dbSDimitry Andric                                    [(set f128:$vT,
14085ffd83dbSDimitry Andric                                          (any_fma f128:$vA, f128:$vB, f128:$vTi))]>;
14095ffd83dbSDimitry Andric  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
14105ffd83dbSDimitry Andric                                       [(set f128:$vT,
14115ffd83dbSDimitry Andric                                             (any_fma f128:$vA, f128:$vB,
14125ffd83dbSDimitry Andric                                                      (fneg f128:$vTi)))]>;
14135ffd83dbSDimitry Andric  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
14145ffd83dbSDimitry Andric                                     [(set f128:$vT,
14155ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
14165ffd83dbSDimitry Andric                                                          f128:$vTi)))]>;
14175ffd83dbSDimitry Andric  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
14185ffd83dbSDimitry Andric                                     [(set f128:$vT,
14195ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
14205ffd83dbSDimitry Andric                                                          (fneg f128:$vTi))))]>;
14215ffd83dbSDimitry Andric
14225ffd83dbSDimitry Andric  let isCommutable = 1 in {
14235ffd83dbSDimitry Andric  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
14245ffd83dbSDimitry Andric                                  [(set f128:$vT,
14255ffd83dbSDimitry Andric                                  (int_ppc_addf128_round_to_odd
14265ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14275ffd83dbSDimitry Andric  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
14285ffd83dbSDimitry Andric                                  [(set f128:$vT,
14295ffd83dbSDimitry Andric                                  (int_ppc_mulf128_round_to_odd
14305ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14315ffd83dbSDimitry Andric  }
14325ffd83dbSDimitry Andric  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
14335ffd83dbSDimitry Andric                                  [(set f128:$vT,
14345ffd83dbSDimitry Andric                                  (int_ppc_subf128_round_to_odd
14355ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14365ffd83dbSDimitry Andric  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
14375ffd83dbSDimitry Andric                                  [(set f128:$vT,
14385ffd83dbSDimitry Andric                                  (int_ppc_divf128_round_to_odd
14395ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14405ffd83dbSDimitry Andric  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
14415ffd83dbSDimitry Andric                                  [(set f128:$vT,
14425ffd83dbSDimitry Andric                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
14435ffd83dbSDimitry Andric
14445ffd83dbSDimitry Andric
14455ffd83dbSDimitry Andric  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
14465ffd83dbSDimitry Andric                                      [(set f128:$vT,
14475ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
14485ffd83dbSDimitry Andric                                      f128:$vA,f128:$vB,f128:$vTi))]>;
14495ffd83dbSDimitry Andric
14505ffd83dbSDimitry Andric  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
14515ffd83dbSDimitry Andric                                      [(set f128:$vT,
14525ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
14535ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
14545ffd83dbSDimitry Andric  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
14555ffd83dbSDimitry Andric                                      [(set f128:$vT,
14565ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
14575ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
14585ffd83dbSDimitry Andric  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
14595ffd83dbSDimitry Andric                                      [(set f128:$vT,
14605ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
14615ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
14625ffd83dbSDimitry Andric  } // mayRaiseFPException
14635ffd83dbSDimitry Andric
14645ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
14655ffd83dbSDimitry Andric  // QP Compare Ordered/Unordered
14665ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
14675ffd83dbSDimitry Andric    // DP/QP Compare Exponents
14685ffd83dbSDimitry Andric    def XSCMPEXPDP : XX3Form_1<60, 59,
14695ffd83dbSDimitry Andric                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
14705ffd83dbSDimitry Andric                               "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
14715ffd83dbSDimitry Andric    def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
14725ffd83dbSDimitry Andric
1473e8d8bef9SDimitry Andric    let mayRaiseFPException = 1 in {
1474e8d8bef9SDimitry Andric    def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1475e8d8bef9SDimitry Andric    def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1476e8d8bef9SDimitry Andric
14775ffd83dbSDimitry Andric    // DP Compare ==, >=, >, !=
14785ffd83dbSDimitry Andric    // Use vsrc for XT, because the entire register of XT is set.
14795ffd83dbSDimitry Andric    // XT.dword[1] = 0x0000_0000_0000_0000
14805ffd83dbSDimitry Andric    def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
14815ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14825ffd83dbSDimitry Andric    def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
14835ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14845ffd83dbSDimitry Andric    def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
14855ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14865ffd83dbSDimitry Andric    }
1487e8d8bef9SDimitry Andric  }
14885ffd83dbSDimitry Andric
14895ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
14905ffd83dbSDimitry Andric  // Quad-Precision Floating-Point Conversion Instructions:
14915ffd83dbSDimitry Andric
14925ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
14935ffd83dbSDimitry Andric    // Convert DP -> QP
14945ffd83dbSDimitry Andric    def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
14955ffd83dbSDimitry Andric                                       [(set f128:$vT, (any_fpextend f64:$vB))]>;
14965ffd83dbSDimitry Andric
14975ffd83dbSDimitry Andric    // Round & Convert QP -> DP (dword[1] is set to zero)
14985ffd83dbSDimitry Andric    def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
14995ffd83dbSDimitry Andric    def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
15005ffd83dbSDimitry Andric                                          [(set f64:$vT,
15015ffd83dbSDimitry Andric                                          (int_ppc_truncf128_round_to_odd
15025ffd83dbSDimitry Andric                                          f128:$vB))]>;
15035ffd83dbSDimitry Andric  }
15045ffd83dbSDimitry Andric
15055ffd83dbSDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
1506e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
15075ffd83dbSDimitry Andric    def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
15085ffd83dbSDimitry Andric    def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
15095ffd83dbSDimitry Andric    def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
15105ffd83dbSDimitry Andric    def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
15115ffd83dbSDimitry Andric  }
15125ffd83dbSDimitry Andric
15135ffd83dbSDimitry Andric  // Convert (Un)Signed DWord -> QP.
15145ffd83dbSDimitry Andric  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
15155ffd83dbSDimitry Andric  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
15165ffd83dbSDimitry Andric
15175ffd83dbSDimitry Andric  // (Round &) Convert DP <-> HP
15185ffd83dbSDimitry Andric  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
15195ffd83dbSDimitry Andric  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
15205ffd83dbSDimitry Andric  // but we still use vsfrc for it.
15215ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1522e8d8bef9SDimitry Andric  let hasSideEffects = 1, mayRaiseFPException = 1 in {
15235ffd83dbSDimitry Andric    def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
15245ffd83dbSDimitry Andric    def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
15255ffd83dbSDimitry Andric  }
15265ffd83dbSDimitry Andric
1527e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
15285ffd83dbSDimitry Andric  // Vector HP -> SP
15295ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15305ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15315ffd83dbSDimitry Andric  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
15325ffd83dbSDimitry Andric  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
15335ffd83dbSDimitry Andric                                 [(set v4f32:$XT,
15345ffd83dbSDimitry Andric                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
15355ffd83dbSDimitry Andric
15365ffd83dbSDimitry Andric  // Round to Quad-Precision Integer [with Inexact]
15375ffd83dbSDimitry Andric  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
15385ffd83dbSDimitry Andric  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
15395ffd83dbSDimitry Andric
15405ffd83dbSDimitry Andric  // Round Quad-Precision to Double-Extended Precision (fp80)
15415ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15425ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15435ffd83dbSDimitry Andric  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
1544e8d8bef9SDimitry Andric  }
15455ffd83dbSDimitry Andric
15465ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
15475ffd83dbSDimitry Andric  // Insert/Extract Instructions
15485ffd83dbSDimitry Andric
15495ffd83dbSDimitry Andric  // Insert Exponent DP/QP
15505ffd83dbSDimitry Andric  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
15515ffd83dbSDimitry Andric  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
15525ffd83dbSDimitry Andric                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
1553fe6060f1SDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1554fe6060f1SDimitry Andric  let hasSideEffects = 1 in {
15555ffd83dbSDimitry Andric    // vB NOTE: only vB.dword[0] is used, that's why we don't use
15565ffd83dbSDimitry Andric    //          X_VT5_VA5_VB5 form
15575ffd83dbSDimitry Andric    def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
15585ffd83dbSDimitry Andric                            "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
15595ffd83dbSDimitry Andric  }
15605ffd83dbSDimitry Andric
15615ffd83dbSDimitry Andric  // Extract Exponent/Significand DP/QP
15625ffd83dbSDimitry Andric  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
15635ffd83dbSDimitry Andric  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
15645ffd83dbSDimitry Andric
1565fe6060f1SDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1566fe6060f1SDimitry Andric  let hasSideEffects = 1 in {
15675ffd83dbSDimitry Andric    def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
15685ffd83dbSDimitry Andric    def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
15695ffd83dbSDimitry Andric  }
15705ffd83dbSDimitry Andric
15715ffd83dbSDimitry Andric  // Vector Insert Word
15725ffd83dbSDimitry Andric  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
15735ffd83dbSDimitry Andric  def XXINSERTW   :
15745ffd83dbSDimitry Andric    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
15755ffd83dbSDimitry Andric                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
15765ffd83dbSDimitry Andric                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
15775ffd83dbSDimitry Andric                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
15785ffd83dbSDimitry Andric                                                   imm32SExt16:$UIM))]>,
15795ffd83dbSDimitry Andric                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
15805ffd83dbSDimitry Andric
15815ffd83dbSDimitry Andric  // Vector Extract Unsigned Word
15825ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15835ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15845ffd83dbSDimitry Andric  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
15855ffd83dbSDimitry Andric                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
15865ffd83dbSDimitry Andric                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
15875ffd83dbSDimitry Andric
15885ffd83dbSDimitry Andric  // Vector Insert Exponent DP/SP
15895ffd83dbSDimitry Andric  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
15905ffd83dbSDimitry Andric    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
15915ffd83dbSDimitry Andric  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
15925ffd83dbSDimitry Andric    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
15935ffd83dbSDimitry Andric
15945ffd83dbSDimitry Andric  // Vector Extract Exponent/Significand DP/SP
15955ffd83dbSDimitry Andric  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
15965ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
15975ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
15985ffd83dbSDimitry Andric  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
15995ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
16005ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
16015ffd83dbSDimitry Andric  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
16025ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
16035ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
16045ffd83dbSDimitry Andric  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
16055ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
16065ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
16075ffd83dbSDimitry Andric
16085ffd83dbSDimitry Andric  // Test Data Class SP/DP/QP
16095ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16105ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16115ffd83dbSDimitry Andric    def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
16125ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
16135ffd83dbSDimitry Andric                                "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
16145ffd83dbSDimitry Andric    def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
16155ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
16165ffd83dbSDimitry Andric                                "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
16175ffd83dbSDimitry Andric    def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
16185ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
16195ffd83dbSDimitry Andric                                "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
16205ffd83dbSDimitry Andric  }
16215ffd83dbSDimitry Andric
16225ffd83dbSDimitry Andric  // Vector Test Data Class SP/DP
16235ffd83dbSDimitry Andric  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
16245ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
16255ffd83dbSDimitry Andric                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
16265ffd83dbSDimitry Andric                              [(set v4i32: $XT,
16275ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
16285ffd83dbSDimitry Andric  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
16295ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
16305ffd83dbSDimitry Andric                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
16315ffd83dbSDimitry Andric                              [(set v2i64: $XT,
16325ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
16335ffd83dbSDimitry Andric
16345ffd83dbSDimitry Andric  // Maximum/Minimum Type-C/Type-J DP
1635e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
16365ffd83dbSDimitry Andric  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
16375ffd83dbSDimitry Andric                                 IIC_VecFP,
16385ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
16395ffd83dbSDimitry Andric  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc,
16405ffd83dbSDimitry Andric                                 IIC_VecFP,
16415ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>;
16425ffd83dbSDimitry Andric
16435ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16445ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16455ffd83dbSDimitry Andric    def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
16465ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
16475ffd83dbSDimitry Andric    def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
16485ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
16495ffd83dbSDimitry Andric  }
1650e8d8bef9SDimitry Andric  }
16515ffd83dbSDimitry Andric
16525ffd83dbSDimitry Andric  // Vector Byte-Reverse H/W/D/Q Word
16535ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16545ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16555ffd83dbSDimitry Andric  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
16565ffd83dbSDimitry Andric  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc,
16575ffd83dbSDimitry Andric    [(set v4i32:$XT, (bswap v4i32:$XB))]>;
16585ffd83dbSDimitry Andric  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc,
16595ffd83dbSDimitry Andric    [(set v2i64:$XT, (bswap v2i64:$XB))]>;
16605ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16615ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16625ffd83dbSDimitry Andric  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
16635ffd83dbSDimitry Andric
16645ffd83dbSDimitry Andric  // Vector Permute
16655ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16665ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16675ffd83dbSDimitry Andric    def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
16685ffd83dbSDimitry Andric                                  IIC_VecPerm, []>;
16695ffd83dbSDimitry Andric    def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
16705ffd83dbSDimitry Andric                                  IIC_VecPerm, []>;
16715ffd83dbSDimitry Andric  }
16725ffd83dbSDimitry Andric
16735ffd83dbSDimitry Andric  // Vector Splat Immediate Byte
16745ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16755ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16765ffd83dbSDimitry Andric  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
16775ffd83dbSDimitry Andric                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
16785ffd83dbSDimitry Andric
16795ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
16805ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
16815ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
16825ffd83dbSDimitry Andric  // Load Vector
16835ffd83dbSDimitry Andric  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
16845ffd83dbSDimitry Andric                            "lxv $XT, $src", IIC_LdStLFD, []>;
16855ffd83dbSDimitry Andric  // Load DWord
16865ffd83dbSDimitry Andric  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
16875ffd83dbSDimitry Andric                       "lxsd $vD, $src", IIC_LdStLFD, []>;
16885ffd83dbSDimitry Andric  // Load SP from src, convert it to DP, and place in dword[0]
16895ffd83dbSDimitry Andric  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
16905ffd83dbSDimitry Andric                       "lxssp $vD, $src", IIC_LdStLFD, []>;
16915ffd83dbSDimitry Andric
16925ffd83dbSDimitry Andric  // Load as Integer Byte/Halfword & Zero Indexed
16935ffd83dbSDimitry Andric  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
1694fe6060f1SDimitry Andric                              [(set f64:$XT, (PPClxsizx ForceXForm:$src, 1))]>;
16955ffd83dbSDimitry Andric  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
1696fe6060f1SDimitry Andric                              [(set f64:$XT, (PPClxsizx ForceXForm:$src, 2))]>;
16975ffd83dbSDimitry Andric
16985ffd83dbSDimitry Andric  // Load Vector Halfword*8/Byte*16 Indexed
16995ffd83dbSDimitry Andric  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
17005ffd83dbSDimitry Andric  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
17015ffd83dbSDimitry Andric
17025ffd83dbSDimitry Andric  // Load Vector Indexed
17035ffd83dbSDimitry Andric  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
1704fe6060f1SDimitry Andric                [(set v2f64:$XT, (load XForm:$src))]>;
17055ffd83dbSDimitry Andric  // Load Vector (Left-justified) with Length
17065ffd83dbSDimitry Andric  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
17075ffd83dbSDimitry Andric                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
17085ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
17095ffd83dbSDimitry Andric  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
17105ffd83dbSDimitry Andric                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
17115ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
17125ffd83dbSDimitry Andric
17135ffd83dbSDimitry Andric  // Load Vector Word & Splat Indexed
17145ffd83dbSDimitry Andric  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
17155ffd83dbSDimitry Andric  } // mayLoad
17165ffd83dbSDimitry Andric
17175ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
17185ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
17195ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
17205ffd83dbSDimitry Andric  // Store Vector
17215ffd83dbSDimitry Andric  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
17225ffd83dbSDimitry Andric                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
17235ffd83dbSDimitry Andric  // Store DWord
17245ffd83dbSDimitry Andric  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
17255ffd83dbSDimitry Andric                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
17265ffd83dbSDimitry Andric  // Convert DP of dword[0] to SP, and Store to dst
17275ffd83dbSDimitry Andric  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
17285ffd83dbSDimitry Andric                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
17295ffd83dbSDimitry Andric
17305ffd83dbSDimitry Andric  // Store as Integer Byte/Halfword Indexed
17315ffd83dbSDimitry Andric  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
1732fe6060f1SDimitry Andric                               [(PPCstxsix f64:$XT, ForceXForm:$dst, 1)]>;
17335ffd83dbSDimitry Andric  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
1734fe6060f1SDimitry Andric                               [(PPCstxsix f64:$XT, ForceXForm:$dst, 2)]>;
17355ffd83dbSDimitry Andric  let isCodeGenOnly = 1 in {
17365ffd83dbSDimitry Andric    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
17375ffd83dbSDimitry Andric    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
17385ffd83dbSDimitry Andric  }
17395ffd83dbSDimitry Andric
17405ffd83dbSDimitry Andric  // Store Vector Halfword*8/Byte*16 Indexed
17415ffd83dbSDimitry Andric  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
17425ffd83dbSDimitry Andric  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
17435ffd83dbSDimitry Andric
17445ffd83dbSDimitry Andric  // Store Vector Indexed
17455ffd83dbSDimitry Andric  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
1746fe6060f1SDimitry Andric                 [(store v2f64:$XT, XForm:$dst)]>;
17475ffd83dbSDimitry Andric
17485ffd83dbSDimitry Andric  // Store Vector (Left-justified) with Length
17495ffd83dbSDimitry Andric  def STXVL : XX1Form_memOp<31, 397, (outs),
17505ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
17515ffd83dbSDimitry Andric                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
17525ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
17535ffd83dbSDimitry Andric                              i64:$rB)]>;
17545ffd83dbSDimitry Andric  def STXVLL : XX1Form_memOp<31, 429, (outs),
17555ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
17565ffd83dbSDimitry Andric                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
17575ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
17585ffd83dbSDimitry Andric                              i64:$rB)]>;
17595ffd83dbSDimitry Andric  } // mayStore
17605ffd83dbSDimitry Andric
17615ffd83dbSDimitry Andric  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
17625ffd83dbSDimitry Andric                          "#DFLOADf32",
1763fe6060f1SDimitry Andric                          [(set f32:$XT, (load DSForm:$src))]>;
17645ffd83dbSDimitry Andric  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
17655ffd83dbSDimitry Andric                          "#DFLOADf64",
1766fe6060f1SDimitry Andric                          [(set f64:$XT, (load DSForm:$src))]>;
17675ffd83dbSDimitry Andric  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
17685ffd83dbSDimitry Andric                          "#DFSTOREf32",
1769fe6060f1SDimitry Andric                          [(store f32:$XT, DSForm:$dst)]>;
17705ffd83dbSDimitry Andric  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
17715ffd83dbSDimitry Andric                          "#DFSTOREf64",
1772fe6060f1SDimitry Andric                          [(store f64:$XT, DSForm:$dst)]>;
17735ffd83dbSDimitry Andric
17745ffd83dbSDimitry Andric  let mayStore = 1 in {
17755ffd83dbSDimitry Andric    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
17765ffd83dbSDimitry Andric                                          (ins spilltovsrrc:$XT, memrr:$dst),
17775ffd83dbSDimitry Andric                                          "#SPILLTOVSR_STX", []>;
17785ffd83dbSDimitry Andric    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
17795ffd83dbSDimitry Andric                              "#SPILLTOVSR_ST", []>;
17805ffd83dbSDimitry Andric  }
17815ffd83dbSDimitry Andric  let mayLoad = 1 in {
17825ffd83dbSDimitry Andric    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
17835ffd83dbSDimitry Andric                                          (ins memrr:$src),
17845ffd83dbSDimitry Andric                                          "#SPILLTOVSR_LDX", []>;
17855ffd83dbSDimitry Andric    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
17865ffd83dbSDimitry Andric                              "#SPILLTOVSR_LD", []>;
17875ffd83dbSDimitry Andric
17885ffd83dbSDimitry Andric  }
17895ffd83dbSDimitry Andric  } // HasP9Vector
17905ffd83dbSDimitry Andric} // hasSideEffects = 0
17915ffd83dbSDimitry Andric
17925ffd83dbSDimitry Andriclet PPC970_Single = 1, AddedComplexity = 400 in {
17930b57cec5SDimitry Andric
17940b57cec5SDimitry Andric  def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17950b57cec5SDimitry Andric                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
17960b57cec5SDimitry Andric                             "#SELECT_CC_VSRC",
17970b57cec5SDimitry Andric                             []>;
17980b57cec5SDimitry Andric  def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17990b57cec5SDimitry Andric                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
18000b57cec5SDimitry Andric                          "#SELECT_VSRC",
18010b57cec5SDimitry Andric                          [(set v2f64:$dst,
18020b57cec5SDimitry Andric                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
18030b57cec5SDimitry Andric  def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
18040b57cec5SDimitry Andric                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
18050b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
18060b57cec5SDimitry Andric                              []>;
18070b57cec5SDimitry Andric  def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
18080b57cec5SDimitry Andric                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
18090b57cec5SDimitry Andric                           "#SELECT_VSFRC",
18100b57cec5SDimitry Andric                           [(set f64:$dst,
18110b57cec5SDimitry Andric                                 (select i1:$cond, f64:$T, f64:$F))]>;
18120b57cec5SDimitry Andric  def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
18130b57cec5SDimitry Andric                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
18140b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
18150b57cec5SDimitry Andric                              []>;
18160b57cec5SDimitry Andric  def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
18170b57cec5SDimitry Andric                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
18180b57cec5SDimitry Andric                           "#SELECT_VSSRC",
18190b57cec5SDimitry Andric                           [(set f32:$dst,
18200b57cec5SDimitry Andric                                 (select i1:$cond, f32:$T, f32:$F))]>;
18210b57cec5SDimitry Andric}
18220b57cec5SDimitry Andric}
18230b57cec5SDimitry Andric
18245ffd83dbSDimitry Andric//----------------------------- DAG Definitions ------------------------------//
1825fe6060f1SDimitry Andric
1826fe6060f1SDimitry Andric// Output dag used to bitcast f32 to i32 and f64 to i64
1827fe6060f1SDimitry Andricdef Bitcast {
1828fe6060f1SDimitry Andric  dag FltToInt = (i32 (MFVSRWZ (EXTRACT_SUBREG (XSCVDPSPN $A), sub_64)));
1829fe6060f1SDimitry Andric  dag DblToLong = (i64 (MFVSRD $A));
1830fe6060f1SDimitry Andric}
1831fe6060f1SDimitry Andric
1832480093f4SDimitry Andricdef FpMinMax {
1833480093f4SDimitry Andric  dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC),
1834480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1835480093f4SDimitry Andric                                 VSSRC);
1836480093f4SDimitry Andric  dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC),
1837480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1838480093f4SDimitry Andric                                 VSSRC);
1839480093f4SDimitry Andric}
1840480093f4SDimitry Andric
18410b57cec5SDimitry Andricdef ScalarLoads {
1842fe6060f1SDimitry Andric  dag Li8 =       (i32 (extloadi8 ForceXForm:$src));
1843fe6060f1SDimitry Andric  dag ZELi8 =     (i32 (zextloadi8 ForceXForm:$src));
1844fe6060f1SDimitry Andric  dag ZELi8i64 =  (i64 (zextloadi8 ForceXForm:$src));
1845fe6060f1SDimitry Andric  dag SELi8 =     (i32 (sext_inreg (extloadi8 ForceXForm:$src), i8));
1846fe6060f1SDimitry Andric  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 ForceXForm:$src), i8));
18470b57cec5SDimitry Andric
1848fe6060f1SDimitry Andric  dag Li16 =      (i32 (extloadi16 ForceXForm:$src));
1849fe6060f1SDimitry Andric  dag ZELi16 =    (i32 (zextloadi16 ForceXForm:$src));
1850fe6060f1SDimitry Andric  dag ZELi16i64 = (i64 (zextloadi16 ForceXForm:$src));
1851fe6060f1SDimitry Andric  dag SELi16 =    (i32 (sextloadi16 ForceXForm:$src));
1852fe6060f1SDimitry Andric  dag SELi16i64 = (i64 (sextloadi16 ForceXForm:$src));
18530b57cec5SDimitry Andric
1854fe6060f1SDimitry Andric  dag Li32 = (i32 (load ForceXForm:$src));
18550b57cec5SDimitry Andric}
18560b57cec5SDimitry Andric
18570b57cec5SDimitry Andricdef DWToSPExtractConv {
18580b57cec5SDimitry Andric  dag El0US1 = (f32 (PPCfcfidus
18590b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18600b57cec5SDimitry Andric  dag El1US1 = (f32 (PPCfcfidus
18610b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18620b57cec5SDimitry Andric  dag El0US2 = (f32 (PPCfcfidus
18630b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18640b57cec5SDimitry Andric  dag El1US2 = (f32 (PPCfcfidus
18650b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18660b57cec5SDimitry Andric  dag El0SS1 = (f32 (PPCfcfids
18670b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18680b57cec5SDimitry Andric  dag El1SS1 = (f32 (PPCfcfids
18690b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18700b57cec5SDimitry Andric  dag El0SS2 = (f32 (PPCfcfids
18710b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18720b57cec5SDimitry Andric  dag El1SS2 = (f32 (PPCfcfids
18730b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18740b57cec5SDimitry Andric  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
18750b57cec5SDimitry Andric  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
18760b57cec5SDimitry Andric}
18770b57cec5SDimitry Andric
18785ffd83dbSDimitry Andricdef WToDPExtractConv {
18795ffd83dbSDimitry Andric  dag El0S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 0))));
18805ffd83dbSDimitry Andric  dag El1S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 1))));
18815ffd83dbSDimitry Andric  dag El2S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 2))));
18825ffd83dbSDimitry Andric  dag El3S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 3))));
18835ffd83dbSDimitry Andric  dag El0U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 0))));
18845ffd83dbSDimitry Andric  dag El1U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 1))));
18855ffd83dbSDimitry Andric  dag El2U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 2))));
18865ffd83dbSDimitry Andric  dag El3U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 3))));
18875ffd83dbSDimitry Andric  dag BV02S = (v2f64 (build_vector El0S, El2S));
18885ffd83dbSDimitry Andric  dag BV13S = (v2f64 (build_vector El1S, El3S));
18895ffd83dbSDimitry Andric  dag BV02U = (v2f64 (build_vector El0U, El2U));
18905ffd83dbSDimitry Andric  dag BV13U = (v2f64 (build_vector El1U, El3U));
18918bcb0991SDimitry Andric}
18928bcb0991SDimitry Andric
18930b57cec5SDimitry Andric/*  Direct moves of various widths from GPR's into VSR's. Each move lines
18940b57cec5SDimitry Andric    the value up into element 0 (both BE and LE). Namely, entities smaller than
18950b57cec5SDimitry Andric    a doubleword are shifted left and moved for BE. For LE, they're moved, then
18960b57cec5SDimitry Andric    swapped to go into the least significant element of the VSR.
18970b57cec5SDimitry Andric*/
18980b57cec5SDimitry Andricdef MovesToVSR {
18990b57cec5SDimitry Andric  dag BE_BYTE_0 =
19000b57cec5SDimitry Andric    (MTVSRD
19010b57cec5SDimitry Andric      (RLDICR
19020b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
19030b57cec5SDimitry Andric  dag BE_HALF_0 =
19040b57cec5SDimitry Andric    (MTVSRD
19050b57cec5SDimitry Andric      (RLDICR
19060b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
19070b57cec5SDimitry Andric  dag BE_WORD_0 =
19080b57cec5SDimitry Andric    (MTVSRD
19090b57cec5SDimitry Andric      (RLDICR
19100b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
19110b57cec5SDimitry Andric  dag BE_DWORD_0 = (MTVSRD $A);
19120b57cec5SDimitry Andric
19130b57cec5SDimitry Andric  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
19140b57cec5SDimitry Andric  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
19150b57cec5SDimitry Andric                                        LE_MTVSRW, sub_64));
19160b57cec5SDimitry Andric  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
19170b57cec5SDimitry Andric  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
19180b57cec5SDimitry Andric                                         BE_DWORD_0, sub_64));
19190b57cec5SDimitry Andric  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
19200b57cec5SDimitry Andric}
19210b57cec5SDimitry Andric
19220b57cec5SDimitry Andric/*  Patterns for extracting elements out of vectors. Integer elements are
19230b57cec5SDimitry Andric    extracted using direct move operations. Patterns for extracting elements
19240b57cec5SDimitry Andric    whose indices are not available at compile time are also provided with
19250b57cec5SDimitry Andric    various _VARIABLE_ patterns.
19260b57cec5SDimitry Andric    The numbering for the DAG's is for LE, but when used on BE, the correct
19270b57cec5SDimitry Andric    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
19280b57cec5SDimitry Andric*/
19290b57cec5SDimitry Andricdef VectorExtractions {
19300b57cec5SDimitry Andric  // Doubleword extraction
19310b57cec5SDimitry Andric  dag LE_DWORD_0 =
19320b57cec5SDimitry Andric    (MFVSRD
19330b57cec5SDimitry Andric      (EXTRACT_SUBREG
19340b57cec5SDimitry Andric        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
19350b57cec5SDimitry Andric                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
19360b57cec5SDimitry Andric  dag LE_DWORD_1 = (MFVSRD
19370b57cec5SDimitry Andric                     (EXTRACT_SUBREG
19380b57cec5SDimitry Andric                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric  // Word extraction
19410b57cec5SDimitry Andric  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
19420b57cec5SDimitry Andric  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
19430b57cec5SDimitry Andric  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
19440b57cec5SDimitry Andric                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19450b57cec5SDimitry Andric  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
19460b57cec5SDimitry Andric
19470b57cec5SDimitry Andric  // Halfword extraction
19480b57cec5SDimitry Andric  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
19490b57cec5SDimitry Andric  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
19500b57cec5SDimitry Andric  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
19510b57cec5SDimitry Andric  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
19520b57cec5SDimitry Andric  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
19530b57cec5SDimitry Andric  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
19540b57cec5SDimitry Andric  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
19550b57cec5SDimitry Andric  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric  // Byte extraction
19580b57cec5SDimitry Andric  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
19590b57cec5SDimitry Andric  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
19600b57cec5SDimitry Andric  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
19610b57cec5SDimitry Andric  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
19620b57cec5SDimitry Andric  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
19630b57cec5SDimitry Andric  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
19640b57cec5SDimitry Andric  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
19650b57cec5SDimitry Andric  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
19660b57cec5SDimitry Andric  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
19670b57cec5SDimitry Andric  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
19680b57cec5SDimitry Andric  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
19690b57cec5SDimitry Andric  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
19700b57cec5SDimitry Andric  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
19710b57cec5SDimitry Andric  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
19720b57cec5SDimitry Andric  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
19730b57cec5SDimitry Andric  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andric  /* Variable element number (BE and LE patterns must be specified separately)
19760b57cec5SDimitry Andric     This is a rather involved process.
19770b57cec5SDimitry Andric
19780b57cec5SDimitry Andric     Conceptually, this is how the move is accomplished:
19790b57cec5SDimitry Andric     1. Identify which doubleword contains the element
19800b57cec5SDimitry Andric     2. Shift in the VMX register so that the correct doubleword is correctly
19810b57cec5SDimitry Andric        lined up for the MFVSRD
19820b57cec5SDimitry Andric     3. Perform the move so that the element (along with some extra stuff)
19830b57cec5SDimitry Andric        is in the GPR
19840b57cec5SDimitry Andric     4. Right shift within the GPR so that the element is right-justified
19850b57cec5SDimitry Andric
19860b57cec5SDimitry Andric     Of course, the index is an element number which has a different meaning
19870b57cec5SDimitry Andric     on LE/BE so the patterns have to be specified separately.
19880b57cec5SDimitry Andric
19890b57cec5SDimitry Andric     Note: The final result will be the element right-justified with high
19900b57cec5SDimitry Andric           order bits being arbitrarily defined (namely, whatever was in the
19910b57cec5SDimitry Andric           vector register to the left of the value originally).
19920b57cec5SDimitry Andric  */
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andric  /*  LE variable byte
19950b57cec5SDimitry Andric      Number 1. above:
19960b57cec5SDimitry Andric      - For elements 0-7, we shift left by 8 bytes since they're on the right
19970b57cec5SDimitry Andric      - For elements 8-15, we need not shift (shift left by zero bytes)
19980b57cec5SDimitry Andric      This is accomplished by inverting the bits of the index and AND-ing
19990b57cec5SDimitry Andric      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
20000b57cec5SDimitry Andric  */
20010b57cec5SDimitry Andric  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andric  //  Number 2. above:
20040b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20050b57cec5SDimitry Andric  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andric  //  Number 3. above:
20080b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20090b57cec5SDimitry Andric  dag LE_MV_VBYTE = (MFVSRD
20100b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20110b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
20120b57cec5SDimitry Andric                        sub_64));
20130b57cec5SDimitry Andric
20140b57cec5SDimitry Andric  /*  Number 4. above:
20150b57cec5SDimitry Andric      - Truncate the element number to the range 0-7 (8-15 are symmetrical
20160b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20170b57cec5SDimitry Andric      - Multiply by 8 as we need to shift right by the number of bits, not bytes
20180b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20190b57cec5SDimitry Andric  */
20200b57cec5SDimitry Andric  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
20210b57cec5SDimitry Andric                                       sub_32);
20220b57cec5SDimitry Andric  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
20230b57cec5SDimitry Andric                                         sub_32);
20240b57cec5SDimitry Andric
20250b57cec5SDimitry Andric  /*  LE variable halfword
20260b57cec5SDimitry Andric      Number 1. above:
20270b57cec5SDimitry Andric      - For elements 0-3, we shift left by 8 since they're on the right
20280b57cec5SDimitry Andric      - For elements 4-7, we need not shift (shift left by zero bytes)
20290b57cec5SDimitry Andric      Similarly to the byte pattern, we invert the bits of the index, but we
20300b57cec5SDimitry Andric      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
20310b57cec5SDimitry Andric      Of course, the shift is still by 8 bytes, so we must multiply by 2.
20320b57cec5SDimitry Andric  */
20330b57cec5SDimitry Andric  dag LE_VHALF_PERM_VEC =
20340b57cec5SDimitry Andric    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
20350b57cec5SDimitry Andric
20360b57cec5SDimitry Andric  //  Number 2. above:
20370b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20380b57cec5SDimitry Andric  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
20390b57cec5SDimitry Andric
20400b57cec5SDimitry Andric  //  Number 3. above:
20410b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20420b57cec5SDimitry Andric  dag LE_MV_VHALF = (MFVSRD
20430b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20440b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
20450b57cec5SDimitry Andric                        sub_64));
20460b57cec5SDimitry Andric
20470b57cec5SDimitry Andric  /*  Number 4. above:
20480b57cec5SDimitry Andric      - Truncate the element number to the range 0-3 (4-7 are symmetrical
20490b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20500b57cec5SDimitry Andric      - Multiply by 16 as we need to shift right by the number of bits
20510b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20520b57cec5SDimitry Andric  */
20530b57cec5SDimitry Andric  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
20540b57cec5SDimitry Andric                                       sub_32);
20550b57cec5SDimitry Andric  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
20560b57cec5SDimitry Andric                                         sub_32);
20570b57cec5SDimitry Andric
20580b57cec5SDimitry Andric  /*  LE variable word
20590b57cec5SDimitry Andric      Number 1. above:
20600b57cec5SDimitry Andric      - For elements 0-1, we shift left by 8 since they're on the right
20610b57cec5SDimitry Andric      - For elements 2-3, we need not shift
20620b57cec5SDimitry Andric  */
20630b57cec5SDimitry Andric  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20640b57cec5SDimitry Andric                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
20650b57cec5SDimitry Andric
20660b57cec5SDimitry Andric  //  Number 2. above:
20670b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20680b57cec5SDimitry Andric  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
20690b57cec5SDimitry Andric
20700b57cec5SDimitry Andric  //  Number 3. above:
20710b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20720b57cec5SDimitry Andric  dag LE_MV_VWORD = (MFVSRD
20730b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20740b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
20750b57cec5SDimitry Andric                        sub_64));
20760b57cec5SDimitry Andric
20770b57cec5SDimitry Andric  /*  Number 4. above:
20780b57cec5SDimitry Andric      - Truncate the element number to the range 0-1 (2-3 are symmetrical
20790b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20800b57cec5SDimitry Andric      - Multiply by 32 as we need to shift right by the number of bits
20810b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20820b57cec5SDimitry Andric  */
20830b57cec5SDimitry Andric  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
20840b57cec5SDimitry Andric                                       sub_32);
20850b57cec5SDimitry Andric  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
20860b57cec5SDimitry Andric                                         sub_32);
20870b57cec5SDimitry Andric
20880b57cec5SDimitry Andric  /*  LE variable doubleword
20890b57cec5SDimitry Andric      Number 1. above:
20900b57cec5SDimitry Andric      - For element 0, we shift left by 8 since it's on the right
20910b57cec5SDimitry Andric      - For element 1, we need not shift
20920b57cec5SDimitry Andric  */
20930b57cec5SDimitry Andric  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20940b57cec5SDimitry Andric                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
20950b57cec5SDimitry Andric
20960b57cec5SDimitry Andric  //  Number 2. above:
20970b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20980b57cec5SDimitry Andric  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
20990b57cec5SDimitry Andric
21000b57cec5SDimitry Andric  // Number 3. above:
21010b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
21020b57cec5SDimitry Andric  //  - Number 4. is not needed for the doubleword as the value is 64-bits
21030b57cec5SDimitry Andric  dag LE_VARIABLE_DWORD =
21040b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
21050b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
21060b57cec5SDimitry Andric                  sub_64));
21070b57cec5SDimitry Andric
21080b57cec5SDimitry Andric  /*  LE variable float
21090b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
21100b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
21110b57cec5SDimitry Andric  */
21120b57cec5SDimitry Andric  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
21130b57cec5SDimitry Andric                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
21140b57cec5SDimitry Andric  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
21150b57cec5SDimitry Andric  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
21160b57cec5SDimitry Andric
21170b57cec5SDimitry Andric  /*  LE variable double
21180b57cec5SDimitry Andric      Same as the LE doubleword except there is no move.
21190b57cec5SDimitry Andric  */
21200b57cec5SDimitry Andric  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21210b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21220b57cec5SDimitry Andric                                         LE_VDWORD_PERM_VEC));
21230b57cec5SDimitry Andric  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andric  /*  BE variable byte
21260b57cec5SDimitry Andric      The algorithm here is the same as the LE variable byte 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 0x8
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-7
21310b57cec5SDimitry Andric  */
2132480093f4SDimitry Andric  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8)));
21330b57cec5SDimitry Andric  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
21340b57cec5SDimitry Andric  dag BE_MV_VBYTE = (MFVSRD
21350b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21360b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
21370b57cec5SDimitry Andric                        sub_64));
21380b57cec5SDimitry Andric  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
21390b57cec5SDimitry Andric                                       sub_32);
21400b57cec5SDimitry Andric  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
21410b57cec5SDimitry Andric                                         sub_32);
21420b57cec5SDimitry Andric
21430b57cec5SDimitry Andric  /*  BE variable halfword
21440b57cec5SDimitry Andric      The algorithm here is the same as the LE variable halfword except:
21450b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
21460b57cec5SDimitry Andric        we simply AND the element number with 0x4 and multiply by 2
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-3
21490b57cec5SDimitry Andric  */
21500b57cec5SDimitry Andric  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
2151480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 4), 1, 62)));
21520b57cec5SDimitry Andric  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
21530b57cec5SDimitry Andric  dag BE_MV_VHALF = (MFVSRD
21540b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21550b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
21560b57cec5SDimitry Andric                        sub_64));
21570b57cec5SDimitry Andric  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
21580b57cec5SDimitry Andric                                       sub_32);
21590b57cec5SDimitry Andric  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
21600b57cec5SDimitry Andric                                         sub_32);
21610b57cec5SDimitry Andric
21620b57cec5SDimitry Andric  /*  BE variable word
21630b57cec5SDimitry Andric      The algorithm is the same as the LE variable word except:
21640b57cec5SDimitry Andric      - The shift in the VMX register happens for opposite element numbers
21650b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21660b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-1
21670b57cec5SDimitry Andric  */
21680b57cec5SDimitry Andric  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2169480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 2), 2, 61)));
21700b57cec5SDimitry Andric  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
21710b57cec5SDimitry Andric  dag BE_MV_VWORD = (MFVSRD
21720b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21730b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
21740b57cec5SDimitry Andric                        sub_64));
21750b57cec5SDimitry Andric  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
21760b57cec5SDimitry Andric                                       sub_32);
21770b57cec5SDimitry Andric  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
21780b57cec5SDimitry Andric                                         sub_32);
21790b57cec5SDimitry Andric
21800b57cec5SDimitry Andric  /*  BE variable doubleword
21810b57cec5SDimitry Andric      Same as the LE doubleword except we shift in the VMX register for opposite
21820b57cec5SDimitry Andric      element indices.
21830b57cec5SDimitry Andric  */
21840b57cec5SDimitry Andric  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2185480093f4SDimitry Andric                                        (RLDICR (ANDI8_rec $Idx, 1), 3, 60)));
21860b57cec5SDimitry Andric  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
21870b57cec5SDimitry Andric  dag BE_VARIABLE_DWORD =
21880b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
21890b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
21900b57cec5SDimitry Andric                  sub_64));
21910b57cec5SDimitry Andric
21920b57cec5SDimitry Andric  /*  BE variable float
21930b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
21940b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
21950b57cec5SDimitry Andric  */
21960b57cec5SDimitry Andric  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
21970b57cec5SDimitry Andric  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
21980b57cec5SDimitry Andric  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
21990b57cec5SDimitry Andric
2200fe6060f1SDimitry Andric  //  BE variable float 32-bit version
2201fe6060f1SDimitry Andric  dag BE_32B_VFLOAT_PERM_VEC = (v16i8 (LVSL (i32 ZERO), (RLWINM $Idx, 2, 0, 29)));
2202fe6060f1SDimitry Andric  dag BE_32B_VFLOAT_PERMUTE = (VPERM $S, $S, BE_32B_VFLOAT_PERM_VEC);
2203fe6060f1SDimitry Andric  dag BE_32B_VARIABLE_FLOAT = (XSCVSPDPN BE_32B_VFLOAT_PERMUTE);
2204fe6060f1SDimitry Andric
22050b57cec5SDimitry Andric  /* BE variable double
22060b57cec5SDimitry Andric      Same as the BE doubleword except there is no move.
22070b57cec5SDimitry Andric  */
22080b57cec5SDimitry Andric  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
22090b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
22100b57cec5SDimitry Andric                                         BE_VDWORD_PERM_VEC));
22110b57cec5SDimitry Andric  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
2212fe6060f1SDimitry Andric
2213fe6060f1SDimitry Andric  //  BE variable double 32-bit version
2214fe6060f1SDimitry Andric  dag BE_32B_VDWORD_PERM_VEC = (v16i8 (LVSL (i32 ZERO),
2215fe6060f1SDimitry Andric                                        (RLWINM (ANDI_rec $Idx, 1), 3, 0, 28)));
2216fe6060f1SDimitry Andric  dag BE_32B_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2217fe6060f1SDimitry Andric                                      (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2218fe6060f1SDimitry Andric                                      BE_32B_VDWORD_PERM_VEC));
2219fe6060f1SDimitry Andric  dag BE_32B_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_32B_VDOUBLE_PERMUTE, VSRC);
22200b57cec5SDimitry Andric}
22210b57cec5SDimitry Andric
22220b57cec5SDimitry Andricdef AlignValues {
2223fe6060f1SDimitry Andric  dag F32_TO_BE_WORD1 = (v4f32 (XSCVDPSPN $B));
2224fe6060f1SDimitry Andric  dag I32_TO_BE_WORD1 = (SUBREG_TO_REG (i64 1), (MTVSRWZ $B), sub_64);
22250b57cec5SDimitry Andric}
22260b57cec5SDimitry Andric
22270b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64
22280b57cec5SDimitry Andricdef AnyExts {
22290b57cec5SDimitry Andric  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
22300b57cec5SDimitry Andric  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
22310b57cec5SDimitry Andric  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
22320b57cec5SDimitry Andric  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
22330b57cec5SDimitry Andric}
22340b57cec5SDimitry Andric
22350b57cec5SDimitry Andricdef DblToFlt {
22365ffd83dbSDimitry Andric  dag A0 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 0))));
22375ffd83dbSDimitry Andric  dag A1 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 1))));
22385ffd83dbSDimitry Andric  dag B0 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 0))));
22395ffd83dbSDimitry Andric  dag B1 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 1))));
22400b57cec5SDimitry Andric}
22410b57cec5SDimitry Andric
22420b57cec5SDimitry Andricdef ExtDbl {
22430b57cec5SDimitry Andric  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
22440b57cec5SDimitry Andric  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
22450b57cec5SDimitry Andric  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
22460b57cec5SDimitry Andric  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
22470b57cec5SDimitry Andric  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
22480b57cec5SDimitry Andric  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
22490b57cec5SDimitry Andric  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
22500b57cec5SDimitry Andric  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
22510b57cec5SDimitry Andric}
22520b57cec5SDimitry Andric
22530b57cec5SDimitry Andricdef ByteToWord {
22540b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
22550b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
22560b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
22570b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
22580b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
22590b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
22600b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
22610b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
22620b57cec5SDimitry Andric}
22630b57cec5SDimitry Andric
22640b57cec5SDimitry Andricdef ByteToDWord {
22650b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22660b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
22670b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22680b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
22690b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22700b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
22710b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22720b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
22730b57cec5SDimitry Andric}
22740b57cec5SDimitry Andric
22750b57cec5SDimitry Andricdef HWordToWord {
22760b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
22770b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
22780b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
22790b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
22800b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
22810b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
22820b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
22830b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
22840b57cec5SDimitry Andric}
22850b57cec5SDimitry Andric
22860b57cec5SDimitry Andricdef HWordToDWord {
22870b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22880b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
22890b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22900b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
22910b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22920b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
22930b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22940b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
22950b57cec5SDimitry Andric}
22960b57cec5SDimitry Andric
22970b57cec5SDimitry Andricdef WordToDWord {
22980b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
22990b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
23000b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
23010b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
23020b57cec5SDimitry Andric}
23030b57cec5SDimitry Andric
23040b57cec5SDimitry Andricdef FltToIntLoad {
2305fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 ForceXForm:$A)))));
23060b57cec5SDimitry Andric}
23070b57cec5SDimitry Andricdef FltToUIntLoad {
2308fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 ForceXForm:$A)))));
23090b57cec5SDimitry Andric}
23100b57cec5SDimitry Andricdef FltToLongLoad {
2311fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ForceXForm:$A)))));
23120b57cec5SDimitry Andric}
23130b57cec5SDimitry Andricdef FltToLongLoadP9 {
2314fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 DSForm:$A)))));
23150b57cec5SDimitry Andric}
23160b57cec5SDimitry Andricdef FltToULongLoad {
2317fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ForceXForm:$A)))));
23180b57cec5SDimitry Andric}
23190b57cec5SDimitry Andricdef FltToULongLoadP9 {
2320fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 DSForm:$A)))));
23210b57cec5SDimitry Andric}
23220b57cec5SDimitry Andricdef FltToLong {
23230b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
23240b57cec5SDimitry Andric}
23250b57cec5SDimitry Andricdef FltToULong {
23260b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
23270b57cec5SDimitry Andric}
23280b57cec5SDimitry Andricdef DblToInt {
23290b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
23300b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
23310b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
23320b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
23330b57cec5SDimitry Andric}
23340b57cec5SDimitry Andricdef DblToUInt {
23350b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
23360b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
23370b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
23380b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
23390b57cec5SDimitry Andric}
23400b57cec5SDimitry Andricdef DblToLong {
23410b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
23420b57cec5SDimitry Andric}
23430b57cec5SDimitry Andricdef DblToULong {
23440b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
23450b57cec5SDimitry Andric}
23460b57cec5SDimitry Andricdef DblToIntLoad {
2347fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ForceXForm:$A)))));
23480b57cec5SDimitry Andric}
23490b57cec5SDimitry Andricdef DblToIntLoadP9 {
2350fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load DSForm:$A)))));
23510b57cec5SDimitry Andric}
23520b57cec5SDimitry Andricdef DblToUIntLoad {
2353fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ForceXForm:$A)))));
23540b57cec5SDimitry Andric}
23550b57cec5SDimitry Andricdef DblToUIntLoadP9 {
2356fe6060f1SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load DSForm:$A)))));
23570b57cec5SDimitry Andric}
23580b57cec5SDimitry Andricdef DblToLongLoad {
2359fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load ForceXForm:$A)))));
23600b57cec5SDimitry Andric}
23610b57cec5SDimitry Andricdef DblToULongLoad {
2362fe6060f1SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load ForceXForm:$A)))));
23630b57cec5SDimitry Andric}
23640b57cec5SDimitry Andric
2365480093f4SDimitry Andric// FP load dags (for f32 -> v4f32)
2366480093f4SDimitry Andricdef LoadFP {
2367fe6060f1SDimitry Andric  dag A = (f32 (load ForceXForm:$A));
2368fe6060f1SDimitry Andric  dag B = (f32 (load ForceXForm:$B));
2369fe6060f1SDimitry Andric  dag C = (f32 (load ForceXForm:$C));
2370fe6060f1SDimitry Andric  dag D = (f32 (load ForceXForm:$D));
2371480093f4SDimitry Andric}
2372480093f4SDimitry Andric
23730b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32)
23740b57cec5SDimitry Andricdef MrgFP {
2375fe6060f1SDimitry Andric  dag LD32A = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64);
2376fe6060f1SDimitry Andric  dag LD32B = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$B), sub_64);
2377fe6060f1SDimitry Andric  dag LD32C = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$C), sub_64);
2378fe6060f1SDimitry Andric  dag LD32D = (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$D), sub_64);
2379fe6060f1SDimitry Andric  dag AC = (XVCVDPSP (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
2380fe6060f1SDimitry Andric                               (SUBREG_TO_REG (i64 1), $C, sub_64), 0));
2381fe6060f1SDimitry Andric  dag BD = (XVCVDPSP (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64),
2382fe6060f1SDimitry Andric                               (SUBREG_TO_REG (i64 1), $D, sub_64), 0));
23830b57cec5SDimitry Andric  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
23840b57cec5SDimitry Andric  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
23850b57cec5SDimitry Andric  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
23860b57cec5SDimitry Andric  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
23870b57cec5SDimitry Andric}
23880b57cec5SDimitry Andric
23890b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors.
23900b57cec5SDimitry Andricdef MrgWords {
23910b57cec5SDimitry Andric  // For big endian, we merge low and hi doublewords (A, B).
23920b57cec5SDimitry Andric  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
23930b57cec5SDimitry Andric  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
23940b57cec5SDimitry Andric  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
23950b57cec5SDimitry Andric  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
23960b57cec5SDimitry Andric  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
23970b57cec5SDimitry Andric  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
23980b57cec5SDimitry Andric
23990b57cec5SDimitry Andric  // For little endian, we merge low and hi doublewords (B, A).
24000b57cec5SDimitry Andric  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
24010b57cec5SDimitry Andric  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
24020b57cec5SDimitry Andric  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
24030b57cec5SDimitry Andric  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
24040b57cec5SDimitry Andric  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
24050b57cec5SDimitry Andric  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
24060b57cec5SDimitry Andric
24070b57cec5SDimitry Andric  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
24080b57cec5SDimitry Andric  // then merge.
2409fe6060f1SDimitry Andric  dag AC = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$A, sub_64),
2410fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$C, sub_64), 0));
2411fe6060f1SDimitry Andric  dag BD = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$B, sub_64),
2412fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$D, sub_64), 0));
24130b57cec5SDimitry Andric  dag CVACS = (v4i32 (XVCVDPSXWS AC));
24140b57cec5SDimitry Andric  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
24150b57cec5SDimitry Andric  dag CVACU = (v4i32 (XVCVDPUXWS AC));
24160b57cec5SDimitry Andric  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
24170b57cec5SDimitry Andric
24180b57cec5SDimitry Andric  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
24190b57cec5SDimitry Andric  // then merge.
2420fe6060f1SDimitry Andric  dag DB = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$D, sub_64),
2421fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$B, sub_64), 0));
2422fe6060f1SDimitry Andric  dag CA = (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), f64:$C, sub_64),
2423fe6060f1SDimitry Andric                            (SUBREG_TO_REG (i64 1), f64:$A, sub_64), 0));
24240b57cec5SDimitry Andric  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
24250b57cec5SDimitry Andric  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
24260b57cec5SDimitry Andric  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
24270b57cec5SDimitry Andric  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
24280b57cec5SDimitry Andric}
24290b57cec5SDimitry Andric
2430fe6060f1SDimitry Andricdef DblwdCmp {
2431fe6060f1SDimitry Andric  dag SGTW = (v2i64 (v2i64 (VCMPGTSW v2i64:$vA, v2i64:$vB)));
2432fe6060f1SDimitry Andric  dag UGTW = (v2i64 (v2i64 (VCMPGTUW v2i64:$vA, v2i64:$vB)));
2433fe6060f1SDimitry Andric  dag EQW = (v2i64 (v2i64 (VCMPEQUW v2i64:$vA, v2i64:$vB)));
2434fe6060f1SDimitry Andric  dag UGTWSHAND = (v2i64 (XXLAND (v2i64 (XXSLDWI UGTW, UGTW, 1)), EQW));
2435fe6060f1SDimitry Andric  dag EQWSHAND = (v2i64 (XXLAND (v2i64 (XXSLDWI EQW, EQW, 1)), EQW));
2436fe6060f1SDimitry Andric  dag SGTWOR = (v2i64 (XXLOR SGTW, UGTWSHAND));
2437fe6060f1SDimitry Andric  dag UGTWOR = (v2i64 (XXLOR UGTW, UGTWSHAND));
2438fe6060f1SDimitry Andric  dag MRGSGT = (v2i64 (XXPERMDI (v2i64 (XXSPLTW SGTWOR, 0)),
2439fe6060f1SDimitry Andric                                (v2i64 (XXSPLTW SGTWOR, 2)), 0));
2440fe6060f1SDimitry Andric  dag MRGUGT = (v2i64 (XXPERMDI (v2i64 (XXSPLTW UGTWOR, 0)),
2441fe6060f1SDimitry Andric                                (v2i64 (XXSPLTW UGTWOR, 2)), 0));
2442fe6060f1SDimitry Andric  dag MRGEQ = (v2i64 (XXPERMDI (v2i64 (XXSPLTW EQWSHAND, 0)),
2443fe6060f1SDimitry Andric                               (v2i64 (XXSPLTW EQWSHAND, 2)), 0));
2444fe6060f1SDimitry Andric}
2445fe6060f1SDimitry Andric
24465ffd83dbSDimitry Andric//---------------------------- Anonymous Patterns ----------------------------//
24475ffd83dbSDimitry Andric// Predicate combinations are kept in roughly chronological order in terms of
24485ffd83dbSDimitry Andric// instruction availability in the architecture. For example, VSX came in with
24495ffd83dbSDimitry Andric// ISA 2.06 (Power7). There have since been additions in ISA 2.07 (Power8) and
24505ffd83dbSDimitry Andric// ISA 3.0 (Power9). However, the granularity of features on later subtargets
24515ffd83dbSDimitry Andric// is finer for various reasons. For example, we have Power8Vector,
24525ffd83dbSDimitry Andric// Power8Altivec, DirectMove that all came in with ISA 2.07. The situation is
24535ffd83dbSDimitry Andric// similar with ISA 3.0 with Power9Vector, Power9Altivec, IsISA3_0. Then there
24545ffd83dbSDimitry Andric// are orthogonal predicates such as endianness for which the order was
24555ffd83dbSDimitry Andric// arbitrarily chosen to be Big, Little.
24565ffd83dbSDimitry Andric//
24575ffd83dbSDimitry Andric// Predicate combinations available:
2458e8d8bef9SDimitry Andric// [HasVSX, IsLittleEndian, HasP8Altivec] Altivec patterns using VSX instr.
2459e8d8bef9SDimitry Andric// [HasVSX, IsBigEndian, HasP8Altivec] Altivec patterns using VSX instr.
24605ffd83dbSDimitry Andric// [HasVSX]
24615ffd83dbSDimitry Andric// [HasVSX, IsBigEndian]
24625ffd83dbSDimitry Andric// [HasVSX, IsLittleEndian]
24635ffd83dbSDimitry Andric// [HasVSX, NoP9Vector]
2464e8d8bef9SDimitry Andric// [HasVSX, NoP9Vector, IsLittleEndian]
2465fe6060f1SDimitry Andric// [HasVSX, NoP9Vector, IsBigEndian]
24665ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps]
24675ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps, IsBigEndian]
24685ffd83dbSDimitry Andric// [HasVSX, HasP8Vector]
2469fe6060f1SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian]
2470e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian, IsPPC64]
24715ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, IsLittleEndian]
2472e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64]
24735ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian]
24744824e7fdSDimitry Andric// [HasVSX, HasP8Altivec]
24755ffd83dbSDimitry Andric// [HasVSX, HasDirectMove]
24765ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsBigEndian]
24775ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsLittleEndian]
2478e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian, IsPPC64]
2479e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64]
24805ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian]
24815ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian]
24825ffd83dbSDimitry Andric// [HasVSX, HasP9Vector]
2483fe6060f1SDimitry Andric// [HasVSX, HasP9Vector, NoP10Vector]
2484fe6060f1SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian]
2485e8d8bef9SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian, IsPPC64]
24865ffd83dbSDimitry Andric// [HasVSX, HasP9Vector, IsLittleEndian]
24875ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec]
2488e8d8bef9SDimitry Andric// [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64]
24895ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec, IsLittleEndian]
2490e8d8bef9SDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64]
24915ffd83dbSDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian]
24920b57cec5SDimitry Andric
2493e8d8bef9SDimitry Andric// These Altivec patterns are here because we need a VSX instruction to match
2494e8d8bef9SDimitry Andric// the intrinsic (but only for little endian system).
2495e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsLittleEndian, HasP8Altivec] in
2496e8d8bef9SDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
2497e8d8bef9SDimitry Andric                                                    v16i8:$b, v16i8:$c)),
2498e8d8bef9SDimitry Andric            (v16i8 (VPERMXOR $a, $b, (XXLNOR (COPY_TO_REGCLASS $c, VSRC),
2499e8d8bef9SDimitry Andric                                             (COPY_TO_REGCLASS $c, VSRC))))>;
2500e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsBigEndian, HasP8Altivec] in
2501e8d8bef9SDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
2502e8d8bef9SDimitry Andric                                                    v16i8:$b, v16i8:$c)),
2503e8d8bef9SDimitry Andric            (v16i8 (VPERMXOR $a, $b, $c))>;
25044824e7fdSDimitry Andriclet Predicates = [HasVSX, HasP8Altivec] in
25054824e7fdSDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor_be v16i8:$a,
25064824e7fdSDimitry Andric                                                       v16i8:$b, v16i8:$c)),
25074824e7fdSDimitry Andric            (v16i8 (VPERMXOR $a, $b, $c))>;
2508e8d8bef9SDimitry Andric
25095ffd83dbSDimitry Andriclet AddedComplexity = 400 in {
25105ffd83dbSDimitry Andric// Valid for any VSX subtarget, regardless of endianness.
25110b57cec5SDimitry Andriclet Predicates = [HasVSX] in {
2512fe6060f1SDimitry Andricdef : Pat<(v4i32 (vnot v4i32:$A)),
25135ffd83dbSDimitry Andric          (v4i32 (XXLNOR $A, $A))>;
2514fe6060f1SDimitry Andricdef : Pat<(v4i32 (or (and (vnot v4i32:$C), v4i32:$A),
25155ffd83dbSDimitry Andric                     (and v4i32:$B, v4i32:$C))),
25165ffd83dbSDimitry Andric          (v4i32 (XXSEL $A, $B, $C))>;
25175ffd83dbSDimitry Andric
25185ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
25195ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
25205ffd83dbSDimitry Andric          (XSNMSUBADP $C, $A, $B)>;
25215ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
25225ffd83dbSDimitry Andric          (XSMSUBADP $C, $A, $B)>;
25235ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
25245ffd83dbSDimitry Andric          (XSNMADDADP $C, $A, $B)>;
25255ffd83dbSDimitry Andric
25265ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C),
25275ffd83dbSDimitry Andric          (XVNMSUBADP $C, $A, $B)>;
25285ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)),
25295ffd83dbSDimitry Andric          (XVMSUBADP $C, $A, $B)>;
25305ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)),
25315ffd83dbSDimitry Andric          (XVNMADDADP $C, $A, $B)>;
25325ffd83dbSDimitry Andric
25335ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C),
25345ffd83dbSDimitry Andric          (XVNMSUBASP $C, $A, $B)>;
25355ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
25365ffd83dbSDimitry Andric          (XVMSUBASP $C, $A, $B)>;
25375ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
25385ffd83dbSDimitry Andric          (XVNMADDASP $C, $A, $B)>;
25395ffd83dbSDimitry Andric
2540e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt f64:$frA), (XSSQRTDP $frA)>;
2541e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v2f64:$frA), (XVSQRTDP $frA)>;
2542e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v4f32:$frA), (XVSQRTSP $frA)>;
2543e8d8bef9SDimitry Andric
25445ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)),
25455ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25465ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)),
25475ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25485ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)),
25495ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25505ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)),
25515ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25525ffd83dbSDimitry Andric
25535ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)),
25545ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25555ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)),
25565ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25575ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)),
25585ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25595ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)),
25605ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25615ffd83dbSDimitry Andric
25625ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)),
25635ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25645ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)),
25655ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25665ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)),
25675ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25685ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)),
25695ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25705ffd83dbSDimitry Andric
25715ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)),
25725ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25735ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)),
25745ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25755ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)),
25765ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25775ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)),
25785ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25795ffd83dbSDimitry Andric
25805ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)),
25815ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25825ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)),
25835ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25845ffd83dbSDimitry Andric
25855ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)),
25865ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25875ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)),
25885ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25895ffd83dbSDimitry Andric
25905ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)),
25915ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25925ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)),
25935ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25945ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)),
25955ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25965ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)),
25975ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25985ffd83dbSDimitry Andric
25995ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
26005ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
26015ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
26025ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
26035ffd83dbSDimitry Andric
26045ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
26055ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
26065ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
26075ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
26085ffd83dbSDimitry Andric
26095ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
26105ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
26115ffd83dbSDimitry Andric
26125ffd83dbSDimitry Andric// Permutes.
26135ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
26145ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
26155ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
26165ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
26175ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
26185ffd83dbSDimitry Andric
26195ffd83dbSDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
26205ffd83dbSDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
26215ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)),
26225ffd83dbSDimitry Andric          (XXPERMDI $src, $src, 2)>;
26235ffd83dbSDimitry Andric
26245ffd83dbSDimitry Andric// Selects.
26255ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
26265ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26275ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
26285ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26295ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
26305ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26315ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
26325ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26335ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
26345ffd83dbSDimitry Andric          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
26355ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
26365ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26375ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
26385ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26395ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
26405ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26415ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
26425ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26435ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
26445ffd83dbSDimitry Andric          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
26455ffd83dbSDimitry Andric
26465ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
26475ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26485ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
26495ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26505ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
26515ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26525ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
26535ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26545ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
26555ffd83dbSDimitry Andric          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
26565ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
26575ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26585ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
26595ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26605ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
26615ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26625ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
26635ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26645ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
26655ffd83dbSDimitry Andric          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
26665ffd83dbSDimitry Andric
26675ffd83dbSDimitry Andric// Divides.
26685ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
26695ffd83dbSDimitry Andric          (XVDIVSP $A, $B)>;
26705ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
26715ffd83dbSDimitry Andric          (XVDIVDP $A, $B)>;
26725ffd83dbSDimitry Andric
2673e8d8bef9SDimitry Andric// Vector test for software divide and sqrt.
2674e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)),
2675e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>;
2676e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)),
2677e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>;
2678e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)),
2679e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>;
2680e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)),
2681e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>;
2682e8d8bef9SDimitry Andric
26835ffd83dbSDimitry Andric// Reciprocal estimate
26845ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A),
26855ffd83dbSDimitry Andric          (XVRESP $A)>;
26865ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A),
26875ffd83dbSDimitry Andric          (XVREDP $A)>;
26885ffd83dbSDimitry Andric
26895ffd83dbSDimitry Andric// Recip. square root estimate
26905ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
26915ffd83dbSDimitry Andric          (XVRSQRTESP $A)>;
26925ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
26935ffd83dbSDimitry Andric          (XVRSQRTEDP $A)>;
26945ffd83dbSDimitry Andric
26955ffd83dbSDimitry Andric// Vector selection
26965ffd83dbSDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
26975ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
26985ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
26995ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
27005ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
27015ffd83dbSDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
27025ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
27035ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
27045ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
27055ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
27065ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
27075ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
27085ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
27095ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
27105ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
27115ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
27125ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
27135ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
2714fe6060f1SDimitry Andricdef : Pat<(v1i128 (vselect v1i128:$vA, v1i128:$vB, v1i128:$vC)),
2715fe6060f1SDimitry Andric          (COPY_TO_REGCLASS
2716fe6060f1SDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
2717fe6060f1SDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
2718fe6060f1SDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
27195ffd83dbSDimitry Andric
27205ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fmaxnum v4f32:$src1, v4f32:$src2)),
27215ffd83dbSDimitry Andric          (v4f32 (XVMAXSP $src1, $src2))>;
27225ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fminnum v4f32:$src1, v4f32:$src2)),
27235ffd83dbSDimitry Andric          (v4f32 (XVMINSP $src1, $src2))>;
27245ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fmaxnum v2f64:$src1, v2f64:$src2)),
27255ffd83dbSDimitry Andric          (v2f64 (XVMAXDP $src1, $src2))>;
27265ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fminnum v2f64:$src1, v2f64:$src2)),
27275ffd83dbSDimitry Andric          (v2f64 (XVMINDP $src1, $src2))>;
27285ffd83dbSDimitry Andric
27295ffd83dbSDimitry Andric// f32 abs
27305ffd83dbSDimitry Andricdef : Pat<(f32 (fabs f32:$S)),
27315ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSABSDP
27325ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27335ffd83dbSDimitry Andric
27345ffd83dbSDimitry Andric// f32 nabs
27355ffd83dbSDimitry Andricdef : Pat<(f32 (fneg (fabs f32:$S))),
27365ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNABSDP
27375ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27385ffd83dbSDimitry Andric
27395ffd83dbSDimitry Andric// f32 Min.
27405ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)),
27415ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27425ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)),
27435ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27445ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))),
27455ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27465ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
27475ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
27485ffd83dbSDimitry Andric// F32 Max.
27495ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)),
27505ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27515ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)),
27525ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27535ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))),
27545ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27555ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
27565ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
27575ffd83dbSDimitry Andric
27585ffd83dbSDimitry Andric// f64 Min.
27595ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)),
27605ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27615ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)),
27625ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27635ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))),
27645ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27655ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
27665ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27675ffd83dbSDimitry Andric// f64 Max.
27685ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)),
27695ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27705ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)),
27715ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27725ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))),
27735ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27745ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
27755ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27765ffd83dbSDimitry Andric
2777fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, ForceXForm:$dst),
2778fe6060f1SDimitry Andric            (STXVD2X $rS, ForceXForm:$dst)>;
2779fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, ForceXForm:$dst),
2780fe6060f1SDimitry Andric            (STXVW4X $rS, ForceXForm:$dst)>;
2781fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
2782fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
27835ffd83dbSDimitry Andric
27845ffd83dbSDimitry Andric// Rounding for single precision.
27855ffd83dbSDimitry Andricdef : Pat<(f32 (any_fround f32:$S)),
27865ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPI
27875ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27885ffd83dbSDimitry Andricdef : Pat<(f32 (any_ffloor f32:$S)),
27895ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIM
27905ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27915ffd83dbSDimitry Andricdef : Pat<(f32 (any_fceil f32:$S)),
27925ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIP
27935ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27945ffd83dbSDimitry Andricdef : Pat<(f32 (any_ftrunc f32:$S)),
27955ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIZ
27965ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27975ffd83dbSDimitry Andricdef : Pat<(f32 (any_frint f32:$S)),
27985ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
27995ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2800e8d8bef9SDimitry Andricdef : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
28015ffd83dbSDimitry Andric
28025ffd83dbSDimitry Andric// Rounding for double precision.
2803e8d8bef9SDimitry Andricdef : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>;
2804e8d8bef9SDimitry Andricdef : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
28055ffd83dbSDimitry Andric
2806349cc55cSDimitry Andric// Rounding without exceptions (nearbyint). Due to strange tblgen behaviour,
2807349cc55cSDimitry Andric// these need to be defined after the any_frint versions so ISEL will correctly
2808349cc55cSDimitry Andric// add the chain to the strict versions.
2809349cc55cSDimitry Andricdef : Pat<(f32 (fnearbyint f32:$S)),
2810349cc55cSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
2811349cc55cSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2812349cc55cSDimitry Andricdef : Pat<(f64 (fnearbyint f64:$S)),
2813349cc55cSDimitry Andric          (f64 (XSRDPIC $S))>;
2814349cc55cSDimitry Andricdef : Pat<(v2f64 (fnearbyint v2f64:$S)),
2815349cc55cSDimitry Andric          (v2f64 (XVRDPIC $S))>;
2816349cc55cSDimitry Andricdef : Pat<(v4f32 (fnearbyint v4f32:$S)),
2817349cc55cSDimitry Andric          (v4f32 (XVRSPIC $S))>;
2818349cc55cSDimitry Andric
28195ffd83dbSDimitry Andric// Materialize a zero-vector of long long
28205ffd83dbSDimitry Andricdef : Pat<(v2i64 immAllZerosV),
28215ffd83dbSDimitry Andric          (v2i64 (XXLXORz))>;
28225ffd83dbSDimitry Andric
28230b57cec5SDimitry Andric// Build vectors of floating point converted to i32.
28240b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
28250b57cec5SDimitry Andric                               DblToInt.A, DblToInt.A)),
2826fe6060f1SDimitry Andric          (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS $A), sub_64), 1))>;
28270b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
28280b57cec5SDimitry Andric                               DblToUInt.A, DblToUInt.A)),
2829fe6060f1SDimitry Andric          (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS $A), sub_64), 1))>;
28300b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
2831fe6060f1SDimitry Andric          (v2i64 (XXPERMDI (SUBREG_TO_REG (i64 1), (XSCVDPSXDS $A), sub_64),
2832fe6060f1SDimitry Andric                           (SUBREG_TO_REG (i64 1), (XSCVDPSXDS $A), sub_64), 0))>;
28330b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
2834fe6060f1SDimitry Andric          (v2i64 (XXPERMDI (SUBREG_TO_REG (i64 1), (XSCVDPUXDS $A), sub_64),
2835fe6060f1SDimitry Andric                           (SUBREG_TO_REG (i64 1), (XSCVDPUXDS $A), sub_64), 0))>;
2836349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCSToV DblToInt.A)),
2837349cc55cSDimitry Andric          (v4i32 (SUBREG_TO_REG (i64 1), (XSCVDPSXWS f64:$A), sub_64))>;
2838349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCSToV DblToUInt.A)),
2839349cc55cSDimitry Andric          (v4i32 (SUBREG_TO_REG (i64 1), (XSCVDPUXWS f64:$A), sub_64))>;
28405ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28415ffd83dbSDimitry Andric  v4i32, FltToIntLoad.A,
2842fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWSs (XFLOADf32 ForceXForm:$A)), sub_64), 1),
2843fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWSs (XFLOADf32 ForceXForm:$A)), sub_64)>;
28445ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28455ffd83dbSDimitry Andric  v4i32, FltToUIntLoad.A,
2846fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWSs (XFLOADf32 ForceXForm:$A)), sub_64), 1),
2847fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWSs (XFLOADf32 ForceXForm:$A)), sub_64)>;
2848fe6060f1SDimitry Andricdef : Pat<(v4f32 (build_vector (f32 (fpround f64:$A)), (f32 (fpround f64:$A)),
2849fe6060f1SDimitry Andric                               (f32 (fpround f64:$A)), (f32 (fpround f64:$A)))),
2850fe6060f1SDimitry Andric          (v4f32 (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$A), sub_64), 0))>;
2851fe6060f1SDimitry Andric
28520b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
28530b57cec5SDimitry Andric          (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
2854349cc55cSDimitry Andric
2855349cc55cSDimitry Andric// Splat loads.
2856fe6060f1SDimitry Andricdef : Pat<(v2f64 (PPCldsplat ForceXForm:$A)),
2857fe6060f1SDimitry Andric          (v2f64 (LXVDSX ForceXForm:$A))>;
2858349cc55cSDimitry Andricdef : Pat<(v4f32 (PPCldsplat ForceXForm:$A)),
2859349cc55cSDimitry Andric          (v4f32 (XXSPLTW (SUBREG_TO_REG (i64 1), (LFIWZX ForceXForm:$A), sub_64), 1))>;
2860fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCldsplat ForceXForm:$A)),
2861fe6060f1SDimitry Andric          (v2i64 (LXVDSX ForceXForm:$A))>;
2862349cc55cSDimitry Andricdef : Pat<(v4i32 (PPCldsplat ForceXForm:$A)),
2863349cc55cSDimitry Andric          (v4i32 (XXSPLTW (SUBREG_TO_REG (i64 1), (LFIWZX ForceXForm:$A), sub_64), 1))>;
2864349cc55cSDimitry Andricdef : Pat<(v2i64 (PPCzextldsplat ForceXForm:$A)),
2865349cc55cSDimitry Andric          (v2i64 (XXPERMDIs (LFIWZX ForceXForm:$A), 0))>;
2866349cc55cSDimitry Andricdef : Pat<(v2i64 (PPCsextldsplat ForceXForm:$A)),
2867349cc55cSDimitry Andric          (v2i64 (XXPERMDIs (LFIWAX ForceXForm:$A), 0))>;
28680b57cec5SDimitry Andric
28690b57cec5SDimitry Andric// Build vectors of floating point converted to i64.
28700b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
28710b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
28720b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
28730b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
28740b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
28750b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
28765ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28775ffd83dbSDimitry Andric  v2i64, DblToLongLoad.A,
2878fe6060f1SDimitry Andric  (XVCVDPSXDS (LXVDSX ForceXForm:$A)), (XVCVDPSXDS (LXVDSX ForceXForm:$A))>;
28795ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
28805ffd83dbSDimitry Andric  v2i64, DblToULongLoad.A,
2881fe6060f1SDimitry Andric  (XVCVDPUXDS (LXVDSX ForceXForm:$A)), (XVCVDPUXDS (LXVDSX ForceXForm:$A))>;
2882fe6060f1SDimitry Andric
2883fe6060f1SDimitry Andric// Doubleword vector predicate comparisons without Power8.
2884fe6060f1SDimitry Andriclet AddedComplexity = 0 in {
2885fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 967)),
2886fe6060f1SDimitry Andric          (VCMPGTUB_rec DblwdCmp.MRGSGT, (v2i64 (XXLXORz)))>;
2887fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 711)),
2888fe6060f1SDimitry Andric          (VCMPGTUB_rec DblwdCmp.MRGUGT, (v2i64 (XXLXORz)))>;
2889fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCvcmp_rec v2i64:$vA, v2i64:$vB, 199)),
2890fe6060f1SDimitry Andric          (VCMPGTUB_rec DblwdCmp.MRGEQ, (v2i64 (XXLXORz)))>;
2891fe6060f1SDimitry Andric} // AddedComplexity = 0
2892fe6060f1SDimitry Andric
2893fe6060f1SDimitry Andric// XL Compat builtins.
2894fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsub f64:$A, f64:$B, f64:$C), (XSMSUBMDP $A, $B, $C)>;
2895fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmsub f64:$A, f64:$B, f64:$C), (XSNMSUBMDP $A, $B, $C)>;
2896fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (XSNMADDMDP $A, $B, $C)>;
2897fe6060f1SDimitry Andricdef : Pat<(int_ppc_fre f64:$A), (XSREDP $A)>;
2898fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrte vsfrc:$XB), (XSRSQRTEDP $XB)>;
28995ffd83dbSDimitry Andric} // HasVSX
29000b57cec5SDimitry Andric
29015ffd83dbSDimitry Andric// Any big endian VSX subtarget.
29025ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsBigEndian] in {
29035ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)),
29045ffd83dbSDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
29050b57cec5SDimitry Andric
29065ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
29075ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
29085ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
29095ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
29105ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
29115ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
29125ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
29135ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
29145ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
29155ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
29165ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
29175ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
29180b57cec5SDimitry Andric
29195ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
29205ffd83dbSDimitry Andric          (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
29210b57cec5SDimitry Andric
29220b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
29230b57cec5SDimitry Andric          (v2f64 (XXPERMDI
2924fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $A, sub_64),
2925fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>;
2926480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
2927480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
2928480093f4SDimitry Andric// XXPERMDI for 2 reasons:
2929480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
2930480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
2931480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
2932480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
2933480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2934480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
2935480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2936480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B),
2937480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>;
29380b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
29390b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
29400b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
29410b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
29420b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
29430b57cec5SDimitry Andric
29440b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
29450b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
29460b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
29470b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
29480b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
29490b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
29500b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
29510b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
29520b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
29530b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
29540b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
29550b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
29560b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
29575ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29585ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
29595ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
29605ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
29615ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
29625ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
29635ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
29645ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29655ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
29665ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
29675ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
29685ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
29695ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>;
29705ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
29715ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
29725ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
29735ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
29745ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
29755ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
29765ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
29775ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29785ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
29795ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>;
29805ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
29815ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
29825ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3),
29835ffd83dbSDimitry Andric                                    (XXPERMDI $A, $B, 3), 1)))>;
2984fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
2985fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2986fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
2987fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS $A))>;
2988fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
2989fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2990fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
2991fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS $A))>;
2992fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
2993fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2994fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
2995fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS (XXSLDWI $A, $A, 1)))>;
2996fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
2997fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2998fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
2999fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS (XXSLDWI $A, $A, 1)))>;
30005ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
30015ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
30025ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
3003349cc55cSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
30045ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
30055ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
30065ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
3007349cc55cSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
3008fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 0)),
3009fe6060f1SDimitry Andric          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), $A, 1))>;
3010fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 1)),
3011fe6060f1SDimitry Andric          (v2f64 (XXPERMDI $A, (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>;
30125ffd83dbSDimitry Andric} // HasVSX, IsBigEndian
30130b57cec5SDimitry Andric
30145ffd83dbSDimitry Andric// Any little endian VSX subtarget.
30155ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsLittleEndian] in {
30165ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2f64, (f64 f64:$A),
30175ffd83dbSDimitry Andric                         (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
30185ffd83dbSDimitry Andric                                   (SUBREG_TO_REG (i64 1), $A, sub_64), 0),
30195ffd83dbSDimitry Andric                         (SUBREG_TO_REG (i64 1), $A, sub_64)>;
30200b57cec5SDimitry Andric
3021fe6060f1SDimitry Andricdef : Pat<(f64 (extractelt (v2f64 (bitconvert (v16i8
3022fe6060f1SDimitry Andric                 (PPCvperm v16i8:$A, v16i8:$B, v16i8:$C)))), 0)),
3023fe6060f1SDimitry Andric          (f64 (EXTRACT_SUBREG (VPERM $B, $A, $C), sub_64))>;
30245ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
30255ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
30265ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
30275ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
30280b57cec5SDimitry Andric
3029fe6060f1SDimitry Andricdef : Pat<(v2f64 (PPCld_vec_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3030fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3031fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCld_vec_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3032fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v4f32:$rS, ForceXForm:$dst), (STXVW4X $rS, ForceXForm:$dst)>;
3033fe6060f1SDimitry Andricdef : Pat<(v2i64 (PPCld_vec_be ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3034fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v2i64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3035fe6060f1SDimitry Andricdef : Pat<(v4i32 (PPCld_vec_be ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3036fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v4i32:$rS, ForceXForm:$dst), (STXVW4X $rS, ForceXForm:$dst)>;
30375ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
30385ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
30395ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
30405ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
30415ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
30425ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
30435ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
30445ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
30450b57cec5SDimitry Andric
30465ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
30475ffd83dbSDimitry Andric          (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
30485ffd83dbSDimitry Andric
30490b57cec5SDimitry Andric// Little endian, available on all targets with VSX
30500b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
30510b57cec5SDimitry Andric          (v2f64 (XXPERMDI
3052fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $B, sub_64),
3053fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
3054480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
3055480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
3056480093f4SDimitry Andric// XXPERMDI for 2 reasons:
3057480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
3058480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
3059480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
3060480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
3061480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
3062480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
3063480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
3064480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C),
3065480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>;
30660b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
30670b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
30680b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
30690b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
30700b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
30710b57cec5SDimitry Andric
30720b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
30730b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
30740b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
30750b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
30760b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
30770b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
30780b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
30790b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
30800b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
30810b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
30820b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
30830b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
30840b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
30855ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
30865ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
30875ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
30885ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
30895ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
30905ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
30915ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
30925ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
30935ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
30945ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>;
30955ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
30965ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
30975ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
30985ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
30995ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
31005ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
31015ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
31025ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
31035ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
31045ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
31055ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
31065ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
31075ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3),
31085ffd83dbSDimitry Andric                                    (XXPERMDI $B, $A, 3), 1)))>;
31095ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
31105ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
31115ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>;
3112fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
3113fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
3114fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
3115fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS $A))>;
3116fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
3117fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
3118fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 3)))))),
3119fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS $A))>;
3120fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_sint
3121fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
3122fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
3123fe6060f1SDimitry Andric          (v2i64 (XVCVSPSXDS (XXSLDWI $A, $A, 1)))>;
3124fe6060f1SDimitry Andricdef : Pat<(v2i64 (fp_to_uint
3125fe6060f1SDimitry Andric                   (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
3126fe6060f1SDimitry Andric                                 (f64 (fpextend (extractelt v4f32:$A, 2)))))),
3127fe6060f1SDimitry Andric          (v2i64 (XVCVSPUXDS (XXSLDWI $A, $A, 1)))>;
31285ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
31295ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
31305ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
31315ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
31325ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
31335ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
31345ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
31355ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
3136fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 0)),
3137fe6060f1SDimitry Andric          (v2f64 (XXPERMDI $A, (SUBREG_TO_REG (i64 1), $B, sub_64), 0))>;
3138fe6060f1SDimitry Andricdef : Pat<(v2f64 (insertelt v2f64:$A, f64:$B, 1)),
3139fe6060f1SDimitry Andric          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $B, sub_64), $A, 1))>;
31405ffd83dbSDimitry Andric} // HasVSX, IsLittleEndian
31410b57cec5SDimitry Andric
31425ffd83dbSDimitry Andric// Any pre-Power9 VSX subtarget.
31435ffd83dbSDimitry Andriclet Predicates = [HasVSX, NoP9Vector] in {
31445ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3145fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 8),
3146fe6060f1SDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), ForceXForm:$dst)>;
31475ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3148fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 8),
3149fe6060f1SDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), ForceXForm:$dst)>;
31505ffd83dbSDimitry Andric
31515ffd83dbSDimitry Andric// Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
31525ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31535ffd83dbSDimitry Andric  v4i32, DblToIntLoad.A,
3154fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (XFLOADf64 ForceXForm:$A)), sub_64), 1),
3155fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (XFLOADf64 ForceXForm:$A)), sub_64)>;
31565ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31575ffd83dbSDimitry Andric  v4i32, DblToUIntLoad.A,
3158fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (XFLOADf64 ForceXForm:$A)), sub_64), 1),
3159fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (XFLOADf64 ForceXForm:$A)), sub_64)>;
31605ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31615ffd83dbSDimitry Andric  v2i64, FltToLongLoad.A,
3162fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), VSFRC)), 0),
3163fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A),
31645ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
31655ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
31665ffd83dbSDimitry Andric  v2i64, FltToULongLoad.A,
3167fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A), VSFRC)), 0),
3168fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 ForceXForm:$A),
31695ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
31705ffd83dbSDimitry Andric} // HasVSX, NoP9Vector
31715ffd83dbSDimitry Andric
3172e8d8bef9SDimitry Andric// Any little endian pre-Power9 VSX subtarget.
3173e8d8bef9SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsLittleEndian] in {
3174e8d8bef9SDimitry Andric// Load-and-splat using only X-Form VSX loads.
3175e8d8bef9SDimitry Andricdefm : ScalToVecWPermute<
3176fe6060f1SDimitry Andric  v2i64, (i64 (load ForceXForm:$src)),
3177fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 ForceXForm:$src), 2),
3178fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>;
3179e8d8bef9SDimitry Andricdefm : ScalToVecWPermute<
3180fe6060f1SDimitry Andric  v2f64, (f64 (load ForceXForm:$src)),
3181fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 ForceXForm:$src), 2),
3182fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>;
3183e8d8bef9SDimitry Andric} // HasVSX, NoP9Vector, IsLittleEndian
3184e8d8bef9SDimitry Andric
3185fe6060f1SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsBigEndian] in {
3186fe6060f1SDimitry Andric  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x ForceXForm:$src)),
3187fe6060f1SDimitry Andric            (LXVD2X ForceXForm:$src)>;
3188fe6060f1SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, ForceXForm:$dst),
3189fe6060f1SDimitry Andric            (STXVD2X $rS, ForceXForm:$dst)>;
3190fe6060f1SDimitry Andric} // HasVSX, NoP9Vector, IsBigEndian
3191fe6060f1SDimitry Andric
31925ffd83dbSDimitry Andric// Any VSX subtarget that only has loads and stores that load in big endian
31935ffd83dbSDimitry Andric// order regardless of endianness. This is really pre-Power9 subtargets.
31945ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3195fe6060f1SDimitry Andric  def : Pat<(v2f64 (PPClxvd2x ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
31965ffd83dbSDimitry Andric
31975ffd83dbSDimitry Andric  // Stores.
3198fe6060f1SDimitry Andric  def : Pat<(PPCstxvd2x v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
31995ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps
32005ffd83dbSDimitry Andric
3201e8d8bef9SDimitry Andric// Big endian VSX subtarget that only has loads and stores that always
3202e8d8bef9SDimitry Andric// load in big endian order. Really big endian pre-Power9 subtargets.
32035ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in {
3204fe6060f1SDimitry Andric  def : Pat<(v2f64 (load ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3205fe6060f1SDimitry Andric  def : Pat<(v2i64 (load ForceXForm:$src)), (LXVD2X ForceXForm:$src)>;
3206fe6060f1SDimitry Andric  def : Pat<(v4i32 (load ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3207fe6060f1SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x ForceXForm:$src)), (LXVW4X ForceXForm:$src)>;
3208fe6060f1SDimitry Andric  def : Pat<(store v2f64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3209fe6060f1SDimitry Andric  def : Pat<(store v2i64:$rS, ForceXForm:$dst), (STXVD2X $rS, ForceXForm:$dst)>;
3210fe6060f1SDimitry Andric  def : Pat<(store v4i32:$XT, ForceXForm:$dst), (STXVW4X $XT, ForceXForm:$dst)>;
3211fe6060f1SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, ForceXForm:$dst),
3212fe6060f1SDimitry Andric            (STXVW4X $rS, ForceXForm:$dst)>;
3213fe6060f1SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector (i64 (load ForceXForm:$src)))),
3214fe6060f1SDimitry Andric           (SUBREG_TO_REG (i64 1), (XFLOADf64 ForceXForm:$src), sub_64)>;
32155ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps, IsBigEndian
32165ffd83dbSDimitry Andric
32175ffd83dbSDimitry Andric// Any Power8 VSX subtarget.
32185ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
32195ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
32205ffd83dbSDimitry Andric          (XXLEQV $A, $B)>;
3221fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 XForm:$src)),
3222fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (XFLOADf32 XForm:$src), VSFRC)>;
3223fe6060f1SDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 ForceXForm:$src)))),
3224fe6060f1SDimitry Andric          (f32 (XFLOADf32 ForceXForm:$src))>;
32255ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpextend f32:$src)),
32265ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $src, VSFRC)>;
32275ffd83dbSDimitry Andric
32285ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
32295ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
32305ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
32315ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
32325ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
32335ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
32345ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
32355ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
32365ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
32375ffd83dbSDimitry Andric          (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
32385ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
32395ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
32405ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
32415ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
32425ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
32435ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
32445ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
32455ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
32465ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
32475ffd83dbSDimitry Andric          (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
32485ffd83dbSDimitry Andric
32495ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
32505ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
32515ffd83dbSDimitry Andric          (XSNMSUBASP $C, $A, $B)>;
32525ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
32535ffd83dbSDimitry Andric          (XSMSUBASP $C, $A, $B)>;
32545ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
32555ffd83dbSDimitry Andric          (XSNMADDASP $C, $A, $B)>;
32565ffd83dbSDimitry Andric
32575ffd83dbSDimitry Andric// f32 neg
32585ffd83dbSDimitry Andric// Although XSNEGDP is available in P7, we want to select it starting from P8,
32595ffd83dbSDimitry Andric// so that FNMSUBS can be selected for fneg-fmsub pattern on P7. (VSX version,
32605ffd83dbSDimitry Andric// XSNMSUBASP, is available since P8)
32615ffd83dbSDimitry Andricdef : Pat<(f32 (fneg f32:$S)),
32625ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNEGDP
32635ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
32645ffd83dbSDimitry Andric
32655ffd83dbSDimitry Andric// Instructions for converting float to i32 feeding a store.
32665ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3267fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 4),
3268fe6060f1SDimitry Andric          (STIWX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>;
32695ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3270fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 4),
3271fe6060f1SDimitry Andric          (STIWX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>;
32725ffd83dbSDimitry Andric
32735ffd83dbSDimitry Andricdef : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
32745ffd83dbSDimitry Andric          (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
32755ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
32765ffd83dbSDimitry Andricdef : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
32775ffd83dbSDimitry Andric          (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
32785ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
32795ffd83dbSDimitry Andricdef : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
32805ffd83dbSDimitry Andric          (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
32815ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
32825ffd83dbSDimitry Andricdef : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
32835ffd83dbSDimitry Andric          (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
32845ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
32855ffd83dbSDimitry Andric
32865ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
32875ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
32885ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
32895ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
32905ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
32915ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
32925ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
32935ffd83dbSDimitry Andric          (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3294fe6060f1SDimitry Andric
3295fe6060f1SDimitry Andric// XL Compat builtins.
3296fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsubs f32:$A, f32:$B, f32:$C), (XSMSUBMSP $A, $B, $C)>;
3297fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmsubs f32:$A, f32:$B, f32:$C), (XSNMSUBMSP $A, $B, $C)>;
3298fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadds f32:$A, f32:$B, f32:$C), (XSNMADDMSP $A, $B, $C)>;
3299fe6060f1SDimitry Andricdef : Pat<(int_ppc_fres f32:$A), (XSRESP $A)>;
3300fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_extract_exp f64:$A)),
3301fe6060f1SDimitry Andric          (EXTRACT_SUBREG (XSXEXPDP (COPY_TO_REGCLASS $A, VSFRC)), sub_32)>;
3302fe6060f1SDimitry Andricdef : Pat<(int_ppc_extract_sig f64:$A),
3303fe6060f1SDimitry Andric          (XSXSIGDP (COPY_TO_REGCLASS $A, VSFRC))>;
3304fe6060f1SDimitry Andricdef : Pat<(f64 (int_ppc_insert_exp f64:$A, i64:$B)),
3305fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (XSIEXPDP (COPY_TO_REGCLASS $A, G8RC), $B), F8RC)>;
3306fe6060f1SDimitry Andric
3307fe6060f1SDimitry Andricdef : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT),
3308fe6060f1SDimitry Andric          (STXSIWX f64:$XT, ForceXForm:$dst)>;
3309fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrtes vssrc:$XB), (XSRSQRTESP $XB)>;
33105ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
33115ffd83dbSDimitry Andric
3312fe6060f1SDimitry Andric// Any big endian Power8 VSX subtarget.
3313fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian] in {
33145ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
33155ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
33165ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
33175ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
33185ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
33195ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
33205ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
33215ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
33225ffd83dbSDimitry Andric
33235ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (BE)
3324fe6060f1SDimitry Andricdefm : ScalToVecWPermute<v4f32, (f32 f32:$A), (XSCVDPSPN $A), (XSCVDPSPN $A)>;
33255ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
33265ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
33275ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
33285ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
33295ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
33305ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
33315ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
33325ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
33335ffd83dbSDimitry Andric
33345ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
33355ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
33365ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
33375ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
33385ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
33395ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
33405ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
33415ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
33425ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
33435ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
33445ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
33455ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
33465ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
33475ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
33485ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
33495ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
33505ffd83dbSDimitry Andric
3351fe6060f1SDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i32:$Idx)),
3352fe6060f1SDimitry Andric          (f32 VectorExtractions.BE_32B_VARIABLE_FLOAT)>;
3353fe6060f1SDimitry Andric
3354fe6060f1SDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i32:$Idx)),
3355fe6060f1SDimitry Andric          (f64 VectorExtractions.BE_32B_VARIABLE_DOUBLE)>;
3356fe6060f1SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian
3357fe6060f1SDimitry Andric
3358fe6060f1SDimitry Andric// Big endian Power8 64Bit VSX subtarget.
3359fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] in {
3360fe6060f1SDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
3361fe6060f1SDimitry Andric          (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
3362fe6060f1SDimitry Andric
33635ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
33645ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
33655ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
3366fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 ForceXForm:$src)))),
3367fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (LIWAX ForceXForm:$src), sub_64))>;
3368fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 ForceXForm:$src)))),
3369fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64))>;
3370fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3371fe6060f1SDimitry Andric  v4i32, (i32 (load ForceXForm:$src)),
3372fe6060f1SDimitry Andric  (XXSLDWIs (LIWZX ForceXForm:$src), 1),
3373fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
3374fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3375fe6060f1SDimitry Andric  v4f32, (f32 (load ForceXForm:$src)),
3376fe6060f1SDimitry Andric  (XXSLDWIs (LIWZX ForceXForm:$src), 1),
3377fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
33785ffd83dbSDimitry Andric
33795ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
33805ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
33815ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
33825ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
33835ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
33845ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
3385fe6060f1SDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 1)), ForceXForm:$src),
3386fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3387fe6060f1SDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 1)), ForceXForm:$src),
3388fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
33895ffd83dbSDimitry Andric
33905ffd83dbSDimitry Andric// Elements in a register on a BE system are in order <0, 1, 2, 3>.
33915ffd83dbSDimitry Andric// The store instructions store the second word from the left.
33925ffd83dbSDimitry Andric// So to align element zero, we need to modulo-left-shift by 3 words.
33935ffd83dbSDimitry Andric// Similar logic applies for elements 2 and 3.
33945ffd83dbSDimitry Andricforeach Idx = [ [0,3], [2,1], [3,2] ] in {
3395fe6060f1SDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), ForceXForm:$src),
33965ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3397fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
3398fe6060f1SDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), ForceXForm:$src),
33995ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3400fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
34015ffd83dbSDimitry Andric}
3402e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian, IsPPC64
34035ffd83dbSDimitry Andric
34045ffd83dbSDimitry Andric// Little endian Power8 VSX subtarget.
34055ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in {
34065ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
34075ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
34085ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
34095ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS
34105ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
34115ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
34125ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
34135ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
34145ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS
34155ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
34165ffd83dbSDimitry Andric
34175ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (LE)
34185ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4f32, (f32 f32:$A),
34195ffd83dbSDimitry Andric                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1),
3420fe6060f1SDimitry Andric                           (XSCVDPSPN $A)>;
34215ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
34225ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
34235ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
34245ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
34255ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
34265ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
34275ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
34285ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
34295ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
34305ffd83dbSDimitry Andric          (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
34315ffd83dbSDimitry Andric
34325ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
34335ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
34345ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
34355ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
34365ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
34375ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
34385ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
34395ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
34405ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
34415ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
34425ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
34435ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
34445ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
34455ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
34465ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
34475ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
34485ffd83dbSDimitry Andric
34495ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
34505ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
34515ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
34525ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3453fe6060f1SDimitry Andric  v2i64, (i64 (sextloadi32 ForceXForm:$src)),
3454fe6060f1SDimitry Andric  (XXPERMDIs (LIWAX ForceXForm:$src), 2),
3455fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWAX ForceXForm:$src), sub_64)>;
34565ffd83dbSDimitry Andric
34575ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3458fe6060f1SDimitry Andric  v2i64, (i64 (zextloadi32 ForceXForm:$src)),
3459fe6060f1SDimitry Andric  (XXPERMDIs (LIWZX ForceXForm:$src), 2),
3460fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
34615ffd83dbSDimitry Andric
34625ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3463fe6060f1SDimitry Andric  v4i32, (i32 (load ForceXForm:$src)),
3464fe6060f1SDimitry Andric  (XXPERMDIs (LIWZX ForceXForm:$src), 2),
3465fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
34665ffd83dbSDimitry Andric
34675ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3468fe6060f1SDimitry Andric  v4f32, (f32 (load ForceXForm:$src)),
3469fe6060f1SDimitry Andric  (XXPERMDIs (LIWZX ForceXForm:$src), 2),
3470fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$src), sub_64)>;
34715ffd83dbSDimitry Andric
34725ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
34735ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
34745ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
34755ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
34765ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
34775ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
3478fe6060f1SDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 2)), ForceXForm:$src),
3479fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3480fe6060f1SDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 2)), ForceXForm:$src),
3481fe6060f1SDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
34825ffd83dbSDimitry Andric
34835ffd83dbSDimitry Andric// Elements in a register on a LE system are in order <3, 2, 1, 0>.
34845ffd83dbSDimitry Andric// The store instructions store the second word from the left.
34855ffd83dbSDimitry Andric// So to align element 3, we need to modulo-left-shift by 3 words.
34865ffd83dbSDimitry Andric// Similar logic applies for elements 0 and 1.
34875ffd83dbSDimitry Andricforeach Idx = [ [0,2], [1,1], [3,3] ] in {
3488fe6060f1SDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), ForceXForm:$src),
34895ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3490fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
3491fe6060f1SDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), ForceXForm:$src),
34925ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3493fe6060f1SDimitry Andric                                   sub_64), ForceXForm:$src)>;
34945ffd83dbSDimitry Andric}
34955ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, IsLittleEndian
34965ffd83dbSDimitry Andric
34975ffd83dbSDimitry Andric// Big endian pre-Power9 VSX subtarget.
3498e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] in {
3499fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), ForceXForm:$src),
3500fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3501fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), ForceXForm:$src),
3502fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3503fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), ForceXForm:$src),
35045ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3505fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3506fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), ForceXForm:$src),
35075ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3508fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3509e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64
35105ffd83dbSDimitry Andric
35115ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget.
35125ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in {
3513fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), ForceXForm:$src),
35145ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3515fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3516fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), ForceXForm:$src),
35175ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3518fe6060f1SDimitry Andric                      ForceXForm:$src)>;
3519fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), ForceXForm:$src),
3520fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
3521fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), ForceXForm:$src),
3522fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), ForceXForm:$src)>;
35235ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian
35245ffd83dbSDimitry Andric
35255ffd83dbSDimitry Andric// Any VSX target with direct moves.
35265ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove] in {
35275ffd83dbSDimitry Andric// bitconvert f32 -> i32
35285ffd83dbSDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR)
3529fe6060f1SDimitry Andricdef : Pat<(i32 (bitconvert f32:$A)), Bitcast.FltToInt>;
3530fe6060f1SDimitry Andric
35315ffd83dbSDimitry Andric// bitconvert i32 -> f32
35325ffd83dbSDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single)
35335ffd83dbSDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)),
35345ffd83dbSDimitry Andric          (f32 (XSCVSPDPN
35355ffd83dbSDimitry Andric                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
35365ffd83dbSDimitry Andric
35375ffd83dbSDimitry Andric// bitconvert f64 -> i64
35385ffd83dbSDimitry Andric// (move to GPR, nothing else needed)
3539fe6060f1SDimitry Andricdef : Pat<(i64 (bitconvert f64:$A)), Bitcast.DblToLong>;
35405ffd83dbSDimitry Andric
35415ffd83dbSDimitry Andric// bitconvert i64 -> f64
35425ffd83dbSDimitry Andric// (move to FPR, nothing else needed)
35435ffd83dbSDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)),
35445ffd83dbSDimitry Andric          (f64 (MTVSRD $S))>;
35455ffd83dbSDimitry Andric
35465ffd83dbSDimitry Andric// Rounding to integer.
35475ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f64:$S)),
35485ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
35495ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f32:$S)),
35505ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
35515ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f64:$S)),
35525ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
35535ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f32:$S)),
35545ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
35555ffd83dbSDimitry Andricdef : Pat<(i64 (lround f64:$S)),
35565ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
35575ffd83dbSDimitry Andricdef : Pat<(i64 (lround f32:$S)),
35585ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
35595ffd83dbSDimitry Andricdef : Pat<(i64 (llround f64:$S)),
35605ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
35615ffd83dbSDimitry Andricdef : Pat<(i64 (llround f32:$S)),
35625ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
35635ffd83dbSDimitry Andric
35645ffd83dbSDimitry Andric// Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
35655ffd83dbSDimitry Andric// of f64
35665ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCmtvsrz i32:$A)),
35675ffd83dbSDimitry Andric          (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
35685ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCmtvsrz i32:$A)),
35695ffd83dbSDimitry Andric          (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
35705ffd83dbSDimitry Andric
35710b57cec5SDimitry Andric// Endianness-neutral constant splat on P8 and newer targets. The reason
35720b57cec5SDimitry Andric// for this pattern is that on targets with direct moves, we don't expand
35730b57cec5SDimitry Andric// BUILD_VECTOR nodes for v4i32.
35740b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
35750b57cec5SDimitry Andric                               immSExt5NonZero:$A, immSExt5NonZero:$A)),
35760b57cec5SDimitry Andric          (v4i32 (VSPLTISW imm:$A))>;
3577349cc55cSDimitry Andric
3578349cc55cSDimitry Andric// Splat loads.
3579349cc55cSDimitry Andricdef : Pat<(v8i16 (PPCldsplat ForceXForm:$A)),
3580349cc55cSDimitry Andric          (v8i16 (VSPLTHs 3, (MTVSRWZ (LHZX ForceXForm:$A))))>;
3581349cc55cSDimitry Andricdef : Pat<(v16i8 (PPCldsplat ForceXForm:$A)),
3582349cc55cSDimitry Andric          (v16i8 (VSPLTBs 7, (MTVSRWZ (LBZX ForceXForm:$A))))>;
35835ffd83dbSDimitry Andric} // HasVSX, HasDirectMove
35840b57cec5SDimitry Andric
35855ffd83dbSDimitry Andric// Big endian VSX subtarget with direct moves.
35865ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsBigEndian] in {
35875ffd83dbSDimitry Andric// v16i8 scalar <-> vector conversions (BE)
3588fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3589fe6060f1SDimitry Andric  v16i8, (i32 i32:$A),
3590fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64),
3591fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
3592fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3593fe6060f1SDimitry Andric  v8i16, (i32 i32:$A),
3594349cc55cSDimitry Andric  (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64),
3595fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
3596fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3597fe6060f1SDimitry Andric  v4i32, (i32 i32:$A),
3598fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64),
3599fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
36005ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector i64:$A)),
36015ffd83dbSDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
36025ffd83dbSDimitry Andric
36035ffd83dbSDimitry Andric// v2i64 scalar <-> vector conversions (BE)
36045ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 0)),
36055ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_1)>;
36065ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 1)),
36075ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_0)>;
36085ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
36095ffd83dbSDimitry Andric          (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
36105ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsBigEndian
36115ffd83dbSDimitry Andric
36125ffd83dbSDimitry Andric// Little endian VSX subtarget with direct moves.
36135ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsLittleEndian] in {
36145ffd83dbSDimitry Andric  // v16i8 scalar <-> vector conversions (LE)
36155ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v16i8, (i32 i32:$A),
36165ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
36175ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
36185ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v8i16, (i32 i32:$A),
36195ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
36205ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
36215ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4i32, (i32 i32:$A), MovesToVSR.LE_WORD_0,
36225ffd83dbSDimitry Andric                           (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
36235ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v2i64, (i64 i64:$A), MovesToVSR.LE_DWORD_0,
36245ffd83dbSDimitry Andric                           MovesToVSR.LE_DWORD_1>;
36255ffd83dbSDimitry Andric
36265ffd83dbSDimitry Andric  // v2i64 scalar <-> vector conversions (LE)
36275ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
36285ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
36295ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
36305ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
36315ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
36325ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
36335ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsLittleEndian
36345ffd83dbSDimitry Andric
36355ffd83dbSDimitry Andric// Big endian pre-P9 VSX subtarget with direct moves.
36365ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian] in {
36375ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
36385ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
36395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
36405ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
36415ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
36425ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
36435ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
36445ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
36455ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
36465ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
36475ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
36485ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
36495ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
36505ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
36515ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
36525ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
36535ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
36545ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
36555ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
36565ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
36575ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
36585ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
36595ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
36605ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
36615ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
36625ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
36635ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
36645ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
36655ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
36665ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
36675ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
36685ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
36695ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
36705ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
36715ffd83dbSDimitry Andric
36725ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (BE)
36735ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
36745ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
36755ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
36765ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
36775ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
36785ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
36795ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
36805ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
36815ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
36825ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
36835ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
36845ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
36855ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
36865ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
36875ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
36885ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
36895ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
36905ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_HALF)>;
36915ffd83dbSDimitry Andric
36925ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (BE)
36935ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
36945ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
36955ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
36965ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
36975ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
36985ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
36995ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
37005ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
37015ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
37025ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_WORD)>;
37035ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian
37045ffd83dbSDimitry Andric
37055ffd83dbSDimitry Andric// Little endian pre-P9 VSX subtarget with direct moves.
37065ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] in {
37075ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
37085ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
37095ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
37105ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
37115ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
37125ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
37135ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
37145ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
37155ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
37165ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
37175ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
37185ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
37195ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
37205ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
37215ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
37225ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
37235ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
37245ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
37255ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
37265ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
37275ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
37285ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
37295ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
37305ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
37315ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
37325ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
37335ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
37345ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
37355ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
37365ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
37375ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
37385ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
37395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
37405ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
37415ffd83dbSDimitry Andric
37425ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (LE)
37435ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
37445ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
37455ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
37465ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
37475ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
37485ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
37495ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
37505ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
37515ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
37525ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
37535ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
37545ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
37555ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
37565ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
37575ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
37585ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
37595ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
37605ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_HALF)>;
37615ffd83dbSDimitry Andric
37625ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (LE)
37635ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
37645ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
37655ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
37665ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
37675ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
37685ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
37695ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
37705ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
37715ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
37725ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_WORD)>;
37735ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian
37745ffd83dbSDimitry Andric
3775e8d8bef9SDimitry Andric// Big endian pre-Power9 64Bit VSX subtarget that has direct moves.
3776e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] in {
37770b57cec5SDimitry Andric// Big endian integer vectors using direct moves.
37780b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
37790b57cec5SDimitry Andric          (v2i64 (XXPERMDI
3780fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $A), sub_64),
3781fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $B), sub_64), 0))>;
37820b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
37830b57cec5SDimitry Andric          (XXPERMDI
3784fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3785fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), sub_64),
3786fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3787fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), sub_64), 0)>;
37880b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3789fe6060f1SDimitry Andric          (XXSPLTW (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64), 1)>;
3790e8d8bef9SDimitry Andric} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64
37910b57cec5SDimitry Andric
37925ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget that has direct moves.
37935ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in {
37940b57cec5SDimitry Andric// Little endian integer vectors using direct moves.
37950b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
37960b57cec5SDimitry Andric          (v2i64 (XXPERMDI
3797fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $B), sub_64),
3798fe6060f1SDimitry Andric                    (SUBREG_TO_REG (i64 1), (MTVSRD $A), sub_64), 0))>;
37990b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
38000b57cec5SDimitry Andric          (XXPERMDI
3801fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3802fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), sub_64),
3803fe6060f1SDimitry Andric            (SUBREG_TO_REG (i64 1),
3804fe6060f1SDimitry Andric              (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), sub_64), 0)>;
38050b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3806fe6060f1SDimitry Andric          (XXSPLTW (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64), 1)>;
38070b57cec5SDimitry Andric}
38080b57cec5SDimitry Andric
38095ffd83dbSDimitry Andric// Any Power9 VSX subtarget.
38105ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
38115ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
38125ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C),
38135ffd83dbSDimitry Andric          (XSNMSUBQP $C, $A, $B)>;
38145ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
38155ffd83dbSDimitry Andric          (XSMSUBQP $C, $A, $B)>;
38165ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
38175ffd83dbSDimitry Andric          (XSNMADDQP $C, $A, $B)>;
38188bcb0991SDimitry Andric
3819e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i64:$src)),
38205ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3821e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))),
38225ffd83dbSDimitry Andric          (f128 (XSCVSDQP $src))>;
3823e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))),
38245ffd83dbSDimitry Andric          (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
3825e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i64:$src)),
38265ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3827e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))),
38285ffd83dbSDimitry Andric          (f128 (XSCVUDQP $src))>;
38295ffd83dbSDimitry Andric
38305ffd83dbSDimitry Andric// Convert (Un)Signed Word -> QP.
3831e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i32:$src)),
38325ffd83dbSDimitry Andric          (f128 (XSCVSDQP (MTVSRWA $src)))>;
3833fe6060f1SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (load ForceXForm:$src)))),
3834fe6060f1SDimitry Andric          (f128 (XSCVSDQP (LIWAX ForceXForm:$src)))>;
3835e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i32:$src)),
38365ffd83dbSDimitry Andric          (f128 (XSCVUDQP (MTVSRWZ $src)))>;
3837fe6060f1SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i32 (load ForceXForm:$src)))),
3838fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LIWZX ForceXForm:$src)))>;
38395ffd83dbSDimitry Andric
38405ffd83dbSDimitry Andric// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
38415ffd83dbSDimitry Andric// separate pattern so that it can convert the input register class from
38425ffd83dbSDimitry Andric// VRRC(v8i16) to VSRC.
38435ffd83dbSDimitry Andricdef : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
38445ffd83dbSDimitry Andric          (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
38455ffd83dbSDimitry Andric
38465ffd83dbSDimitry Andric// Use current rounding mode
38475ffd83dbSDimitry Andricdef : Pat<(f128 (any_fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
38485ffd83dbSDimitry Andric// Round to nearest, ties away from zero
38495ffd83dbSDimitry Andricdef : Pat<(f128 (any_fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
38505ffd83dbSDimitry Andric// Round towards Zero
38515ffd83dbSDimitry Andricdef : Pat<(f128 (any_ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
38525ffd83dbSDimitry Andric// Round towards +Inf
38535ffd83dbSDimitry Andricdef : Pat<(f128 (any_fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
38545ffd83dbSDimitry Andric// Round towards -Inf
38555ffd83dbSDimitry Andricdef : Pat<(f128 (any_ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
38565ffd83dbSDimitry Andric// Use current rounding mode, [with Inexact]
38575ffd83dbSDimitry Andricdef : Pat<(f128 (any_frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
38585ffd83dbSDimitry Andric
38595ffd83dbSDimitry Andricdef : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
38605ffd83dbSDimitry Andric          (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
38615ffd83dbSDimitry Andric
38625ffd83dbSDimitry Andricdef : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
38635ffd83dbSDimitry Andric          (i64 (MFVSRD (EXTRACT_SUBREG
38645ffd83dbSDimitry Andric                          (v2i64 (XSXEXPQP $vA)), sub_64)))>;
38655ffd83dbSDimitry Andric
38665ffd83dbSDimitry Andric// Extra patterns expanding to vector Extract Word/Insert Word
38675ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
38685ffd83dbSDimitry Andric          (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
38695ffd83dbSDimitry Andricdef : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
38705ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
38715ffd83dbSDimitry Andric
38725ffd83dbSDimitry Andric// Vector Reverse
38735ffd83dbSDimitry Andricdef : Pat<(v8i16 (bswap v8i16 :$A)),
38745ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
38755ffd83dbSDimitry Andricdef : Pat<(v1i128 (bswap v1i128 :$A)),
38765ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
38775ffd83dbSDimitry Andric
38785ffd83dbSDimitry Andric// D-Form Load/Store
3879fe6060f1SDimitry Andricforeach Ty = [v4i32, v4f32, v2i64, v2f64] in {
3880fe6060f1SDimitry Andric  def : Pat<(Ty (load DQForm:$src)), (LXV memrix16:$src)>;
3881fe6060f1SDimitry Andric  def : Pat<(Ty (load XForm:$src)), (LXVX XForm:$src)>;
3882fe6060f1SDimitry Andric  def : Pat<(store Ty:$rS, DQForm:$dst), (STXV $rS, memrix16:$dst)>;
3883fe6060f1SDimitry Andric  def : Pat<(store Ty:$rS, XForm:$dst), (STXVX $rS, XForm:$dst)>;
3884fe6060f1SDimitry Andric}
3885fe6060f1SDimitry Andric
3886fe6060f1SDimitry Andricdef : Pat<(f128 (load DQForm:$src)),
38875ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3888fe6060f1SDimitry Andricdef : Pat<(f128 (load XForm:$src)),
3889fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LXVX XForm:$src), VRRC)>;
3890fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x DQForm:$src)), (LXV memrix16:$src)>;
3891fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x DQForm:$src)), (LXV memrix16:$src)>;
3892fe6060f1SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x XForm:$src)), (LXVX XForm:$src)>;
3893fe6060f1SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x XForm:$src)), (LXVX XForm:$src)>;
38945ffd83dbSDimitry Andric
3895fe6060f1SDimitry Andricdef : Pat<(store f128:$rS, DQForm:$dst),
38965ffd83dbSDimitry Andric          (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3897fe6060f1SDimitry Andricdef : Pat<(store f128:$rS, XForm:$dst),
3898fe6060f1SDimitry Andric          (STXVX (COPY_TO_REGCLASS $rS, VSRC), XForm:$dst)>;
3899fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, DQForm:$dst),
39005ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
3901fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, DQForm:$dst),
39025ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
3903fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, XForm:$dst),
3904fe6060f1SDimitry Andric          (STXVX $rS, XForm:$dst)>;
3905fe6060f1SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, XForm:$dst),
3906fe6060f1SDimitry Andric          (STXVX $rS, XForm:$dst)>;
39075ffd83dbSDimitry Andric
39085ffd83dbSDimitry Andric// Build vectors from i8 loads
39095ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.ZELi8,
3910fe6060f1SDimitry Andric                         (VSPLTHs 3, (LXSIBZX ForceXForm:$src)),
3911fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
39125ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi8,
3913fe6060f1SDimitry Andric                         (XXSPLTWs (LXSIBZX ForceXForm:$src), 1),
3914fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
39155ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi8i64,
3916fe6060f1SDimitry Andric                         (XXPERMDIs (LXSIBZX ForceXForm:$src), 0),
3917fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
3918fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3919fe6060f1SDimitry Andric  v4i32, ScalarLoads.SELi8,
3920fe6060f1SDimitry Andric  (XXSPLTWs (VEXTSB2Ws (LXSIBZX ForceXForm:$src)), 1),
3921fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSB2Ws (LXSIBZX ForceXForm:$src)), sub_64)>;
3922fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3923fe6060f1SDimitry Andric  v2i64, ScalarLoads.SELi8i64,
3924fe6060f1SDimitry Andric  (XXPERMDIs (VEXTSB2Ds (LXSIBZX ForceXForm:$src)), 0),
3925fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSB2Ds (LXSIBZX ForceXForm:$src)), sub_64)>;
39265ffd83dbSDimitry Andric
39275ffd83dbSDimitry Andric// Build vectors from i16 loads
3928fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3929fe6060f1SDimitry Andric  v4i32, ScalarLoads.ZELi16,
3930fe6060f1SDimitry Andric  (XXSPLTWs (LXSIHZX ForceXForm:$src), 1),
3931fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
3932fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3933fe6060f1SDimitry Andric  v2i64, ScalarLoads.ZELi16i64,
3934fe6060f1SDimitry Andric  (XXPERMDIs (LXSIHZX ForceXForm:$src), 0),
3935fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
3936fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3937fe6060f1SDimitry Andric  v4i32, ScalarLoads.SELi16,
3938fe6060f1SDimitry Andric  (XXSPLTWs (VEXTSH2Ws (LXSIHZX ForceXForm:$src)), 1),
3939fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSH2Ws (LXSIHZX ForceXForm:$src)), sub_64)>;
3940fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
3941fe6060f1SDimitry Andric  v2i64, ScalarLoads.SELi16i64,
3942fe6060f1SDimitry Andric  (XXPERMDIs (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), 0),
3943fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (VEXTSH2Ds (LXSIHZX ForceXForm:$src)), sub_64)>;
39445ffd83dbSDimitry Andric
39455ffd83dbSDimitry Andric// Load/convert and convert/store patterns for f16.
3946fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf16 ForceXForm:$src)),
3947fe6060f1SDimitry Andric          (f64 (XSCVHPDP (LXSIHZX ForceXForm:$src)))>;
3948fe6060f1SDimitry Andricdef : Pat<(truncstoref16 f64:$src, ForceXForm:$dst),
3949fe6060f1SDimitry Andric          (STXSIHX (XSCVDPHP $src), ForceXForm:$dst)>;
3950fe6060f1SDimitry Andricdef : Pat<(f32 (extloadf16 ForceXForm:$src)),
3951fe6060f1SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX ForceXForm:$src)), VSSRC))>;
3952fe6060f1SDimitry Andricdef : Pat<(truncstoref16 f32:$src, ForceXForm:$dst),
3953fe6060f1SDimitry Andric          (STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), ForceXForm:$dst)>;
39545ffd83dbSDimitry Andricdef : Pat<(f64 (f16_to_fp i32:$A)),
39555ffd83dbSDimitry Andric          (f64 (XSCVHPDP (MTVSRWZ $A)))>;
39565ffd83dbSDimitry Andricdef : Pat<(f32 (f16_to_fp i32:$A)),
39575ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (MTVSRWZ $A)), VSSRC))>;
39585ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f32:$A)),
39595ffd83dbSDimitry Andric          (i32 (MFVSRWZ (XSCVDPHP (COPY_TO_REGCLASS $A, VSFRC))))>;
39605ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f64:$A)), (i32 (MFVSRWZ (XSCVDPHP $A)))>;
39615ffd83dbSDimitry Andric
39625ffd83dbSDimitry Andric// Vector sign extensions
39635ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 1)),
39645ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
39655ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 2)),
39665ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
39675ffd83dbSDimitry Andric
3968fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 DSForm:$src)),
3969fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (DFLOADf32 DSForm:$src), VSFRC)>;
3970fe6060f1SDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 DSForm:$src)))),
3971fe6060f1SDimitry Andric          (f32 (DFLOADf32 DSForm:$src))>;
39725ffd83dbSDimitry Andric
3973fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh XForm:$src)),
3974fe6060f1SDimitry Andric          (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>;
3975fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh DSForm:$src)),
3976fe6060f1SDimitry Andric          (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>;
39775ffd83dbSDimitry Andric
39785ffd83dbSDimitry Andric// Convert (Un)Signed DWord in memory -> QP
3979fe6060f1SDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load XForm:$src)))),
3980fe6060f1SDimitry Andric          (f128 (XSCVSDQP (LXSDX XForm:$src)))>;
3981fe6060f1SDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load DSForm:$src)))),
3982fe6060f1SDimitry Andric          (f128 (XSCVSDQP (LXSD DSForm:$src)))>;
3983fe6060f1SDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load XForm:$src)))),
3984fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSDX XForm:$src)))>;
3985fe6060f1SDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load DSForm:$src)))),
3986fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSD DSForm:$src)))>;
39875ffd83dbSDimitry Andric
39885ffd83dbSDimitry Andric// Convert Unsigned HWord in memory -> QP
39895ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
3990fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSIHZX XForm:$src)))>;
39915ffd83dbSDimitry Andric
39925ffd83dbSDimitry Andric// Convert Unsigned Byte in memory -> QP
39935ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
3994fe6060f1SDimitry Andric          (f128 (XSCVUDQP (LXSIBZX ForceXForm:$src)))>;
39955ffd83dbSDimitry Andric
39965ffd83dbSDimitry Andric// Truncate & Convert QP -> (Un)Signed (D)Word.
3997e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3998e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3999e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_sint f128:$src)),
40005ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
4001e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_uint f128:$src)),
40025ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
40035ffd83dbSDimitry Andric
40045ffd83dbSDimitry Andric// Instructions for store(fptosi).
40055ffd83dbSDimitry Andric// The 8-byte version is repeated here due to availability of D-Form STXSD.
40065ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4007fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), XForm:$dst, 8),
40085ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
4009fe6060f1SDimitry Andric                  XForm:$dst)>;
40105ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4011fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), DSForm:$dst, 8),
40125ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
4013fe6060f1SDimitry Andric                 DSForm:$dst)>;
40145ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4015fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 4),
4016fe6060f1SDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>;
40175ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4018fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 2),
4019fe6060f1SDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>;
40205ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4021fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ForceXForm:$dst, 1),
4022fe6060f1SDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), ForceXForm:$dst)>;
40235ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4024fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), XForm:$dst, 8),
4025fe6060f1SDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), XForm:$dst)>;
40265ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4027fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), DSForm:$dst, 8),
4028fe6060f1SDimitry Andric          (STXSD (XSCVDPSXDS f64:$src), DSForm:$dst)>;
40295ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4030fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 2),
4031fe6060f1SDimitry Andric          (STXSIHX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>;
40325ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4033fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ForceXForm:$dst, 1),
4034fe6060f1SDimitry Andric          (STXSIBX (XSCVDPSXWS f64:$src), ForceXForm:$dst)>;
40355ffd83dbSDimitry Andric
40365ffd83dbSDimitry Andric// Instructions for store(fptoui).
40375ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4038fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), XForm:$dst, 8),
40395ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
4040fe6060f1SDimitry Andric                  XForm:$dst)>;
40415ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4042fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), DSForm:$dst, 8),
40435ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
4044fe6060f1SDimitry Andric                 DSForm:$dst)>;
40455ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4046fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 4),
4047fe6060f1SDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>;
40485ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4049fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 2),
4050fe6060f1SDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>;
40515ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4052fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ForceXForm:$dst, 1),
4053fe6060f1SDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), ForceXForm:$dst)>;
40545ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4055fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), XForm:$dst, 8),
4056fe6060f1SDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), XForm:$dst)>;
40575ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4058fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), DSForm:$dst, 8),
4059fe6060f1SDimitry Andric          (STXSD (XSCVDPUXDS f64:$src), DSForm:$dst)>;
40605ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4061fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 2),
4062fe6060f1SDimitry Andric          (STXSIHX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>;
40635ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
4064fe6060f1SDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ForceXForm:$dst, 1),
4065fe6060f1SDimitry Andric          (STXSIBX (XSCVDPUXWS f64:$src), ForceXForm:$dst)>;
40665ffd83dbSDimitry Andric
40675ffd83dbSDimitry Andric// Round & Convert QP -> DP/SP
40685ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpround f128:$src)), (f64 (XSCVQPDP $src))>;
40695ffd83dbSDimitry Andricdef : Pat<(f32 (any_fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
40705ffd83dbSDimitry Andric
40715ffd83dbSDimitry Andric// Convert SP -> QP
40725ffd83dbSDimitry Andricdef : Pat<(f128 (any_fpextend f32:$src)),
40735ffd83dbSDimitry Andric          (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
40745ffd83dbSDimitry Andric
40755ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)),
40765ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC),
40775ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
40785ffd83dbSDimitry Andric                                 VSSRC))>;
40795ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)),
40805ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC),
40815ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
40825ffd83dbSDimitry Andric                                 VSSRC))>;
40835ffd83dbSDimitry Andric
40840b57cec5SDimitry Andric// Endianness-neutral patterns for const splats with ISA 3.0 instructions.
4085fe6060f1SDimitry Andricdefm : ScalToVecWPermute<v4i32, (i32 i32:$A), (MTVSRWS $A),
4086fe6060f1SDimitry Andric                         (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
40870b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
40880b57cec5SDimitry Andric          (v4i32 (MTVSRWS $A))>;
40898bcb0991SDimitry Andricdef : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40908bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40918bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40928bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40938bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40948bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40958bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
40968bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
40970b57cec5SDimitry Andric          (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
4098fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4099fe6060f1SDimitry Andric  v4i32, FltToIntLoad.A,
4100fe6060f1SDimitry Andric  (XVCVSPSXWS (LXVWSX ForceXForm:$A)),
4101fe6060f1SDimitry Andric  (XVCVSPSXWS (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64))>;
4102fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4103fe6060f1SDimitry Andric  v4i32, FltToUIntLoad.A,
4104fe6060f1SDimitry Andric  (XVCVSPUXWS (LXVWSX ForceXForm:$A)),
4105fe6060f1SDimitry Andric  (XVCVSPUXWS (SUBREG_TO_REG (i64 1), (LIWZX ForceXForm:$A), sub_64))>;
41065ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41075ffd83dbSDimitry Andric  v4i32, DblToIntLoadP9.A,
4108fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 DSForm:$A)), sub_64), 1),
4109fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 DSForm:$A)), sub_64)>;
41105ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41115ffd83dbSDimitry Andric  v4i32, DblToUIntLoadP9.A,
4112fe6060f1SDimitry Andric  (XXSPLTW (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 DSForm:$A)), sub_64), 1),
4113fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 DSForm:$A)), sub_64)>;
41145ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41155ffd83dbSDimitry Andric  v2i64, FltToLongLoadP9.A,
4116fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), 0),
41175ffd83dbSDimitry Andric  (SUBREG_TO_REG
41185ffd83dbSDimitry Andric     (i64 1),
4119fe6060f1SDimitry Andric     (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), sub_64)>;
41205ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
41215ffd83dbSDimitry Andric  v2i64, FltToULongLoadP9.A,
4122fe6060f1SDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), 0),
41235ffd83dbSDimitry Andric  (SUBREG_TO_REG
41245ffd83dbSDimitry Andric     (i64 1),
4125fe6060f1SDimitry Andric     (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 DSForm:$A), VSFRC)), sub_64)>;
4126fe6060f1SDimitry Andricdef : Pat<(v4f32 (PPCldsplat ForceXForm:$A)),
4127fe6060f1SDimitry Andric          (v4f32 (LXVWSX ForceXForm:$A))>;
4128fe6060f1SDimitry Andricdef : Pat<(v4i32 (PPCldsplat ForceXForm:$A)),
4129fe6060f1SDimitry Andric          (v4i32 (LXVWSX ForceXForm:$A))>;
4130349cc55cSDimitry Andricdef : Pat<(v8i16 (PPCldsplat ForceXForm:$A)),
4131349cc55cSDimitry Andric          (v8i16 (VSPLTHs 3, (LXSIHZX ForceXForm:$A)))>;
4132349cc55cSDimitry Andricdef : Pat<(v16i8 (PPCldsplat ForceXForm:$A)),
4133349cc55cSDimitry Andric          (v16i8 (VSPLTBs 7, (LXSIBZX ForceXForm:$A)))>;
41345ffd83dbSDimitry Andric} // HasVSX, HasP9Vector
41355ffd83dbSDimitry Andric
4136fe6060f1SDimitry Andric// Any Power9 VSX subtarget with equivalent length but better Power10 VSX
4137fe6060f1SDimitry Andric// patterns.
4138fe6060f1SDimitry Andric// Two identical blocks are required due to the slightly different predicates:
4139fe6060f1SDimitry Andric// One without P10 instructions, the other is BigEndian only with P10 instructions.
4140fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, NoP10Vector] in {
4141fe6060f1SDimitry Andric// Little endian Power10 subtargets produce a shorter pattern but require a
4142fe6060f1SDimitry Andric// COPY_TO_REGCLASS. The COPY_TO_REGCLASS makes it appear to need two instructions
4143fe6060f1SDimitry Andric// to perform the operation, when only one instruction is produced in practice.
4144fe6060f1SDimitry Andric// The NoP10Vector predicate excludes these patterns from Power10 VSX subtargets.
4145fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4146fe6060f1SDimitry Andric  v16i8, ScalarLoads.Li8,
4147fe6060f1SDimitry Andric  (VSPLTBs 7, (LXSIBZX ForceXForm:$src)),
4148fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
4149fe6060f1SDimitry Andric// Build vectors from i16 loads
4150fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4151fe6060f1SDimitry Andric  v8i16, ScalarLoads.Li16,
4152fe6060f1SDimitry Andric  (VSPLTHs 3, (LXSIHZX ForceXForm:$src)),
4153fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
4154fe6060f1SDimitry Andric} // HasVSX, HasP9Vector, NoP10Vector
4155fe6060f1SDimitry Andric
4156fe6060f1SDimitry Andric// Any big endian Power9 VSX subtarget
4157fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian] in {
4158fe6060f1SDimitry Andric// Power10 VSX subtargets produce a shorter pattern for little endian targets
4159fe6060f1SDimitry Andric// but this is still the best pattern for Power9 and Power10 VSX big endian
4160fe6060f1SDimitry Andric// Build vectors from i8 loads
4161fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4162fe6060f1SDimitry Andric  v16i8, ScalarLoads.Li8,
4163fe6060f1SDimitry Andric  (VSPLTBs 7, (LXSIBZX ForceXForm:$src)),
4164fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIBZX ForceXForm:$src), sub_64)>;
4165fe6060f1SDimitry Andric// Build vectors from i16 loads
4166fe6060f1SDimitry Andricdefm : ScalToVecWPermute<
4167fe6060f1SDimitry Andric  v8i16, ScalarLoads.Li16,
4168fe6060f1SDimitry Andric  (VSPLTHs 3, (LXSIHZX ForceXForm:$src)),
4169fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (LXSIHZX ForceXForm:$src), sub_64)>;
4170fe6060f1SDimitry Andric
41715ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
41725ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
41735ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
41745ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
41755ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
41765ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
41775ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
41785ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
41795ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
41805ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
41815ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
41825ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
41835ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
41845ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
41855ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
41865ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
41875ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
41885ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
4189349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 0)),
4190349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4191349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4192349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4193349cc55cSDimitry Andric                            0))>;
4194349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 0)),
4195349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4196349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4197349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4198349cc55cSDimitry Andric                            0))>;
41995ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
42005ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
4201349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 1)),
4202349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4203349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4204349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4205349cc55cSDimitry Andric                            4))>;
4206349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 1)),
4207349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4208349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4209349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4210349cc55cSDimitry Andric                            4))>;
42115ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
42125ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
4213349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 2)),
4214349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4215349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4216349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4217349cc55cSDimitry Andric                            8))>;
4218349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 2)),
4219349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4220349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4221349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4222349cc55cSDimitry Andric                            8))>;
42235ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
42245ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
4225349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 3)),
4226349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4227349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4228349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4229349cc55cSDimitry Andric                            12))>;
4230349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 3)),
4231349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4232349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4233349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4234349cc55cSDimitry Andric                            12))>;
42355ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
42365ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
42375ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
42385ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
42395ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
42405ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
42415ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
42425ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
42435ffd83dbSDimitry Andric
4244fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 0)),
4245fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4246fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 0))>;
4247fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 1)),
4248fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4249fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 4))>;
4250fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 2)),
4251fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4252fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 8))>;
4253fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 3)),
4254fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4255fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 12))>;
4256fe6060f1SDimitry Andric
42575ffd83dbSDimitry Andric// Scalar stores of i8
4258fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), ForceXForm:$dst),
4259fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), ForceXForm:$dst)>;
4260fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), ForceXForm:$dst),
4261fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
4262fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), ForceXForm:$dst),
4263fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), ForceXForm:$dst)>;
4264fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), ForceXForm:$dst),
4265fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4266fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), ForceXForm:$dst),
4267fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), ForceXForm:$dst)>;
4268fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), ForceXForm:$dst),
4269fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4270fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), ForceXForm:$dst),
4271fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), ForceXForm:$dst)>;
4272fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), ForceXForm:$dst),
4273fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4274fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), ForceXForm:$dst),
4275fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), ForceXForm:$dst)>;
4276fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), ForceXForm:$dst),
4277fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4278fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), ForceXForm:$dst),
4279fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), ForceXForm:$dst)>;
4280fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), ForceXForm:$dst),
4281fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4282fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), ForceXForm:$dst),
4283fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), ForceXForm:$dst)>;
4284fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), ForceXForm:$dst),
4285fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4286fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), ForceXForm:$dst),
4287fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), ForceXForm:$dst)>;
4288fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), ForceXForm:$dst),
4289fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
42905ffd83dbSDimitry Andric
42915ffd83dbSDimitry Andric// Scalar stores of i16
4292fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), ForceXForm:$dst),
4293fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
4294fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), ForceXForm:$dst),
4295fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4296fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), ForceXForm:$dst),
4297fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4298fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), ForceXForm:$dst),
4299fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4300fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), ForceXForm:$dst),
4301fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4302fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), ForceXForm:$dst),
4303fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4304fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), ForceXForm:$dst),
4305fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4306fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), ForceXForm:$dst),
4307fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
4308fe6060f1SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian
43095ffd83dbSDimitry Andric
4310fe6060f1SDimitry Andric// Big endian 64Bit Power9 subtarget.
4311fe6060f1SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] in {
4312fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load DSForm:$src)))),
4313fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64))>;
4314fe6060f1SDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load XForm:$src)))),
4315fe6060f1SDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64))>;
43165ffd83dbSDimitry Andric
4317fe6060f1SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load DSForm:$src)))),
4318fe6060f1SDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64))>;
4319fe6060f1SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load XForm:$src)))),
4320fe6060f1SDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64))>;
4321fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), XForm:$src),
43225ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4323fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4324fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), XForm:$src),
43255ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4326fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4327fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), XForm:$src),
4328fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4329fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), XForm:$src),
4330fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4331fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), DSForm:$src),
43325ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4333fe6060f1SDimitry Andric                       sub_64), DSForm:$src)>;
4334fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), DSForm:$src),
43355ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4336fe6060f1SDimitry Andric                       sub_64), DSForm:$src)>;
4337fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), DSForm:$src),
4338fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
4339fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), DSForm:$src),
4340fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
43415ffd83dbSDimitry Andric
43425ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
43435ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
43445ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
43455ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
43465ffd83dbSDimitry Andric          (f128 (XSCVSDQP
43475ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
43485ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
43495ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
43505ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
43515ffd83dbSDimitry Andric          (f128 (XSCVUDQP
43525ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
43535ffd83dbSDimitry Andric
43545ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
43555ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
43565ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
43575ffd83dbSDimitry Andricforeach Idx = [0,2,3] in {
43585ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
43595ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
43605ffd83dbSDimitry Andric                            (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
43615ffd83dbSDimitry Andric}
43625ffd83dbSDimitry Andricforeach Idx = 0-3 in {
43635ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
43645ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
43650b57cec5SDimitry Andric}
43660b57cec5SDimitry Andric
4367fe6060f1SDimitry Andric// (Un)Signed HWord vector extract -> QP/DP/SP
43685ffd83dbSDimitry Andricforeach Idx = 0-7 in {
43695ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
43705ffd83dbSDimitry Andric                    (i32 (sext_inreg
43715ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, Idx), i16)))),
43725ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG
43735ffd83dbSDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
43745ffd83dbSDimitry Andric                            sub_64)))>;
43755ffd83dbSDimitry Andric  // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
43765ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
43775ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
43785ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
43795ffd83dbSDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4380fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4381fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz (and (i32 (vector_extract v8i16:$src, Idx)),
4382fe6060f1SDimitry Andric                                        65535))))),
4383fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4384fe6060f1SDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4385fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4386fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4387fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v8i16:$src, Idx),
4388fe6060f1SDimitry Andric                               i16)))))),
4389fe6060f1SDimitry Andric          (f32 (XSCVSXDSP (EXTRACT_SUBREG
4390fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
4391fe6060f1SDimitry Andric                            sub_64)))>;
4392fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4393fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4394fe6060f1SDimitry Andric                          (and (i32 (vector_extract v8i16:$src, Idx)),
4395fe6060f1SDimitry Andric                               65535))))),
4396fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4397fe6060f1SDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4398fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4399fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4400fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v8i16:$src, Idx),
4401fe6060f1SDimitry Andric                               i16)))))),
4402fe6060f1SDimitry Andric          (f64 (XSCVSXDDP (EXTRACT_SUBREG
4403fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
4404fe6060f1SDimitry Andric                            sub_64)))>;
44050b57cec5SDimitry Andric}
44060b57cec5SDimitry Andric
44075ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP
44085ffd83dbSDimitry Andricforeach Idx = 0-15 in {
44095ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
44105ffd83dbSDimitry Andric                    (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
44115ffd83dbSDimitry Andric                                     i8)))),
44125ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
44135ffd83dbSDimitry Andric                              (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
44145ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
44155ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
44165ffd83dbSDimitry Andric            (f128 (XSCVUDQP
44175ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
4418fe6060f1SDimitry Andric
4419fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4420fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4421fe6060f1SDimitry Andric                          (and (i32 (vector_extract v16i8:$src, Idx)),
4422fe6060f1SDimitry Andric                               255))))),
4423fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4424fe6060f1SDimitry Andric                              (VEXTRACTUB !add(Idx, Idx), $src), sub_64)))>;
4425fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4426fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4427fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
4428fe6060f1SDimitry Andric                               i8)))))),
4429fe6060f1SDimitry Andric          (f32 (XSCVSXDSP (EXTRACT_SUBREG
4430fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUB !add(Idx, Idx), $src)),
4431fe6060f1SDimitry Andric                            sub_64)))>;
4432fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4433fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4434fe6060f1SDimitry Andric                          (and (i32 (vector_extract v16i8:$src, Idx)),
4435fe6060f1SDimitry Andric                          255))))),
4436fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4437fe6060f1SDimitry Andric                              (VEXTRACTUB !add(Idx, Idx), $src), sub_64)))>;
4438fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4439fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4440fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
4441fe6060f1SDimitry Andric                               i8)))))),
4442fe6060f1SDimitry Andric          (f64 (XSCVSXDDP (EXTRACT_SUBREG
4443fe6060f1SDimitry Andric                            (VEXTSH2D (VEXTRACTUB !add(Idx, Idx), $src)),
4444fe6060f1SDimitry Andric                            sub_64)))>;
44450b57cec5SDimitry Andric}
44460b57cec5SDimitry Andric
44475ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
44485ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
44495ffd83dbSDimitry Andric          (f128 (XSCVUDQP
44505ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
4451e8d8bef9SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian, IsPPC64
44525ffd83dbSDimitry Andric
44535ffd83dbSDimitry Andric// Little endian Power9 subtarget.
44545ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in {
44555ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
44565ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
44575ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
44585ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
44595ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
44605ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
44615ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
44625ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
44635ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
44645ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
44655ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
44665ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
44675ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
44685ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
44695ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
44705ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
44715ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
44725ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
4473349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 0)),
4474349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4475349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4476349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4477349cc55cSDimitry Andric                            12))>;
4478349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 0)),
4479349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4480349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4481349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4482349cc55cSDimitry Andric                            12))>;
44835ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
44845ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
4485349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 1)),
4486349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4487349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4488349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4489349cc55cSDimitry Andric                            8))>;
4490349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 1)),
4491349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4492349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4493349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4494349cc55cSDimitry Andric                            8))>;
44955ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
44965ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
4497349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 2)),
4498349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4499349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4500349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4501349cc55cSDimitry Andric                            4))>;
4502349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 2)),
4503349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4504349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4505349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4506349cc55cSDimitry Andric                            4))>;
45075ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
45085ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
4509349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToInt.B, 3)),
4510349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4511349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4512349cc55cSDimitry Andric                                           (XSCVDPSXWS f64:$B), sub_64),
4513349cc55cSDimitry Andric                            0))>;
4514349cc55cSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, DblToUInt.B, 3)),
4515349cc55cSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A,
4516349cc55cSDimitry Andric                            (SUBREG_TO_REG (i64 1),
4517349cc55cSDimitry Andric                                           (XSCVDPUXWS f64:$B), sub_64),
4518349cc55cSDimitry Andric                            0))>;
45195ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
45205ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
45215ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
45225ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
45235ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
45245ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
45255ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
45265ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
45275ffd83dbSDimitry Andric
4528fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 0)),
4529fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4530fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 12))>;
4531fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 1)),
4532fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4533fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 8))>;
4534fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 2)),
4535fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4536fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 4))>;
4537fe6060f1SDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, (f32 (fpround f64:$B)), 3)),
4538fe6060f1SDimitry Andric          (v4f32 (XXINSERTW v4f32:$A,
4539fe6060f1SDimitry Andric                  (SUBREG_TO_REG (i64 1), (XSCVDPSP f64:$B), sub_64), 0))>;
45405ffd83dbSDimitry Andric
4541fe6060f1SDimitry Andricdef : Pat<(v8i16 (PPCld_vec_be ForceXForm:$src)),
4542fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LXVH8X ForceXForm:$src), VRRC)>;
4543fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v8i16:$rS, ForceXForm:$dst),
4544fe6060f1SDimitry Andric          (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), ForceXForm:$dst)>;
4545fe6060f1SDimitry Andric
4546fe6060f1SDimitry Andricdef : Pat<(v16i8 (PPCld_vec_be ForceXForm:$src)),
4547fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LXVB16X ForceXForm:$src), VRRC)>;
4548fe6060f1SDimitry Andricdef : Pat<(PPCst_vec_be v16i8:$rS, ForceXForm:$dst),
4549fe6060f1SDimitry Andric          (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), ForceXForm:$dst)>;
45505ffd83dbSDimitry Andric
45515ffd83dbSDimitry Andric// Scalar stores of i8
4552fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), ForceXForm:$dst),
4553fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
4554fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), ForceXForm:$dst),
4555fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), ForceXForm:$dst)>;
4556fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), ForceXForm:$dst),
4557fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4558fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), ForceXForm:$dst),
4559fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), ForceXForm:$dst)>;
4560fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), ForceXForm:$dst),
4561fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4562fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), ForceXForm:$dst),
4563fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), ForceXForm:$dst)>;
4564fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), ForceXForm:$dst),
4565fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4566fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), ForceXForm:$dst),
4567fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), ForceXForm:$dst)>;
4568fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), ForceXForm:$dst),
4569fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4570fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), ForceXForm:$dst),
4571fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), ForceXForm:$dst)>;
4572fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), ForceXForm:$dst),
4573fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4574fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), ForceXForm:$dst),
4575fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), ForceXForm:$dst)>;
4576fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), ForceXForm:$dst),
4577fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4578fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), ForceXForm:$dst),
4579fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), ForceXForm:$dst)>;
4580fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), ForceXForm:$dst),
4581fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
4582fe6060f1SDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), ForceXForm:$dst),
4583fe6060f1SDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), ForceXForm:$dst)>;
45845ffd83dbSDimitry Andric
45855ffd83dbSDimitry Andric// Scalar stores of i16
4586fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), ForceXForm:$dst),
4587fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), ForceXForm:$dst)>;
4588fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), ForceXForm:$dst),
4589fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), ForceXForm:$dst)>;
4590fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), ForceXForm:$dst),
4591fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), ForceXForm:$dst)>;
4592fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), ForceXForm:$dst),
4593fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), ForceXForm:$dst)>;
4594fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), ForceXForm:$dst),
4595fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), ForceXForm:$dst)>;
4596fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), ForceXForm:$dst),
4597fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), ForceXForm:$dst)>;
4598fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), ForceXForm:$dst),
4599fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), ForceXForm:$dst)>;
4600fe6060f1SDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), ForceXForm:$dst),
4601fe6060f1SDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), ForceXForm:$dst)>;
46025ffd83dbSDimitry Andric
46035ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4604fe6060f1SDimitry Andric  v2i64, (i64 (load DSForm:$src)),
4605fe6060f1SDimitry Andric  (XXPERMDIs (DFLOADf64 DSForm:$src), 2),
4606fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>;
46075ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4608fe6060f1SDimitry Andric  v2i64, (i64 (load XForm:$src)),
4609fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 XForm:$src), 2),
4610fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>;
46115ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4612fe6060f1SDimitry Andric  v2f64, (f64 (load DSForm:$src)),
4613fe6060f1SDimitry Andric  (XXPERMDIs (DFLOADf64 DSForm:$src), 2),
4614fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 DSForm:$src), sub_64)>;
46155ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4616fe6060f1SDimitry Andric  v2f64, (f64 (load XForm:$src)),
4617fe6060f1SDimitry Andric  (XXPERMDIs (XFLOADf64 XForm:$src), 2),
4618fe6060f1SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 XForm:$src), sub_64)>;
46195ffd83dbSDimitry Andric
4620fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), XForm:$src),
46215ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4622fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4623fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), XForm:$src),
46245ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4625fe6060f1SDimitry Andric                       sub_64), XForm:$src)>;
4626fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), XForm:$src),
4627fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4628fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), XForm:$src),
4629fe6060f1SDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), XForm:$src)>;
4630fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), DSForm:$src),
46315ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4632fe6060f1SDimitry Andric                       sub_64), DSForm:$src)>;
4633fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), DSForm:$src),
46345ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4635fe6060f1SDimitry Andric                      DSForm:$src)>;
4636fe6060f1SDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), DSForm:$src),
4637fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
4638fe6060f1SDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), DSForm:$src),
4639fe6060f1SDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), DSForm:$src)>;
46405ffd83dbSDimitry Andric
46415ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
46425ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
46435ffd83dbSDimitry Andric          (f128 (XSCVSDQP
46445ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
46455ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
46465ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
46475ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
46485ffd83dbSDimitry Andric          (f128 (XSCVUDQP
46495ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
46505ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
46515ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
46525ffd83dbSDimitry Andric
46535ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
46545ffd83dbSDimitry Andricforeach Idx = [[0,3],[1,2],[3,0]] in {
46555ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
46565ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
46575ffd83dbSDimitry Andric                              (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
46585ffd83dbSDimitry Andric                              sub_64)))>;
46595ffd83dbSDimitry Andric}
46605ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
46615ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
46625ffd83dbSDimitry Andric
46635ffd83dbSDimitry Andricforeach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
46645ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
46655ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
46660b57cec5SDimitry Andric}
46670b57cec5SDimitry Andric
4668fe6060f1SDimitry Andric// (Un)Signed HWord vector extract -> QP/DP/SP
46695ffd83dbSDimitry Andric// The Nested foreach lists identifies the vector element and corresponding
46705ffd83dbSDimitry Andric// register byte location.
46715ffd83dbSDimitry Andricforeach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
46725ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
46735ffd83dbSDimitry Andric                    (i32 (sext_inreg
46745ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, !head(Idx)), i16)))),
46755ffd83dbSDimitry Andric            (f128 (XSCVSDQP
46765ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
46775ffd83dbSDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
46785ffd83dbSDimitry Andric                                    sub_64)))>;
46795ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
46805ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, !head(Idx))),
46815ffd83dbSDimitry Andric                         65535))),
46825ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
46835ffd83dbSDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4684fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4685fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4686fe6060f1SDimitry Andric                          (and (i32 (vector_extract v8i16:$src, !head(Idx))),
4687fe6060f1SDimitry Andric                          65535))))),
4688fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4689fe6060f1SDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4690fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4691fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4692fe6060f1SDimitry Andric                          (i32 (sext_inreg (vector_extract v8i16:$src,
4693fe6060f1SDimitry Andric                                           !head(Idx)), i16)))))),
4694fe6060f1SDimitry Andric            (f32 (XSCVSXDSP
4695fe6060f1SDimitry Andric                    (EXTRACT_SUBREG
4696fe6060f1SDimitry Andric                     (VEXTSH2D (VEXTRACTUH !head(!tail(Idx)), $src)),
4697fe6060f1SDimitry Andric                     sub_64)))>;
4698fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4699fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4700fe6060f1SDimitry Andric                          (and (i32 (vector_extract v8i16:$src, !head(Idx))),
4701fe6060f1SDimitry Andric                          65535))))),
4702fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4703fe6060f1SDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4704fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4705fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4706fe6060f1SDimitry Andric                        (i32 (sext_inreg
4707fe6060f1SDimitry Andric                            (vector_extract v8i16:$src, !head(Idx)), i16)))))),
4708fe6060f1SDimitry Andric            (f64 (XSCVSXDDP
4709fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4710fe6060f1SDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
4711fe6060f1SDimitry Andric                                    sub_64)))>;
47120b57cec5SDimitry Andric}
47130b57cec5SDimitry Andric
4714fe6060f1SDimitry Andric// (Un)Signed Byte vector extract -> QP/DP/SP
47155ffd83dbSDimitry Andricforeach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
47165ffd83dbSDimitry Andric               [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
47175ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
47185ffd83dbSDimitry Andric                    (i32 (sext_inreg
47195ffd83dbSDimitry Andric                           (vector_extract v16i8:$src, !head(Idx)), i8)))),
47205ffd83dbSDimitry Andric            (f128 (XSCVSDQP
47215ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
47225ffd83dbSDimitry Andric                      (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
47235ffd83dbSDimitry Andric                      sub_64)))>;
47245ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
47255ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, !head(Idx))),
47265ffd83dbSDimitry Andric                         255))),
47275ffd83dbSDimitry Andric            (f128 (XSCVUDQP
47285ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
47295ffd83dbSDimitry Andric                      (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4730fe6060f1SDimitry Andric
4731fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfidus
4732fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4733fe6060f1SDimitry Andric                          (and (i32 (vector_extract v16i8:$src, !head(Idx))),
4734fe6060f1SDimitry Andric                          255))))),
4735fe6060f1SDimitry Andric            (f32 (XSCVUXDSP (EXTRACT_SUBREG
4736fe6060f1SDimitry Andric                              (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4737fe6060f1SDimitry Andric  def : Pat<(f32 (PPCfcfids
4738fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4739fe6060f1SDimitry Andric                          (i32 (sext_inreg
4740fe6060f1SDimitry Andric                            (vector_extract v16i8:$src, !head(Idx)), i8)))))),
4741fe6060f1SDimitry Andric            (f32 (XSCVSXDSP
4742fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4743fe6060f1SDimitry Andric                                      (VEXTRACTUB !head(!tail(Idx)), $src)),
4744fe6060f1SDimitry Andric                                    sub_64)))>;
4745fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4746fe6060f1SDimitry Andric                   (f64 (PPCmtvsrz
4747fe6060f1SDimitry Andric                          (and (i32
4748fe6060f1SDimitry Andric                            (vector_extract v16i8:$src, !head(Idx))), 255))))),
4749fe6060f1SDimitry Andric            (f64 (XSCVUXDDP (EXTRACT_SUBREG
4750fe6060f1SDimitry Andric                              (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4751fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfidu
4752fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4753fe6060f1SDimitry Andric                        (i32 (sext_inreg
4754fe6060f1SDimitry Andric                            (vector_extract v16i8:$src, !head(Idx)), i8)))))),
4755fe6060f1SDimitry Andric            (f64 (XSCVSXDDP
4756fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4757fe6060f1SDimitry Andric                                      (VEXTRACTUB !head(!tail(Idx)), $src)),
4758fe6060f1SDimitry Andric                                    sub_64)))>;
4759fe6060f1SDimitry Andric
4760fe6060f1SDimitry Andric  def : Pat<(f64 (PPCfcfid
4761fe6060f1SDimitry Andric                   (f64 (PPCmtvsra
4762fe6060f1SDimitry Andric                        (i32 (sext_inreg
4763fe6060f1SDimitry Andric                          (vector_extract v16i8:$src, !head(Idx)), i8)))))),
4764fe6060f1SDimitry Andric            (f64 (XSCVSXDDP
4765fe6060f1SDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4766fe6060f1SDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
4767fe6060f1SDimitry Andric                                    sub_64)))>;
47685ffd83dbSDimitry Andric}
47695ffd83dbSDimitry Andric
47705ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
47715ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
47725ffd83dbSDimitry Andric          (f128 (XSCVUDQP
47735ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
47745ffd83dbSDimitry Andric} // HasVSX, HasP9Vector, IsLittleEndian
47755ffd83dbSDimitry Andric
47765ffd83dbSDimitry Andric// Any Power9 VSX subtarget that supports Power9 Altivec.
47775ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec] in {
47780b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be
47790b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef.
47800b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
47810b57cec5SDimitry Andric          (v4i32 (VABSDUW $A, $B))>;
47820b57cec5SDimitry Andric
47830b57cec5SDimitry Andricdef : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
47840b57cec5SDimitry Andric          (v8i16 (VABSDUH $A, $B))>;
47850b57cec5SDimitry Andric
47860b57cec5SDimitry Andricdef : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
47870b57cec5SDimitry Andric          (v16i8 (VABSDUB $A, $B))>;
47880b57cec5SDimitry Andric
47890b57cec5SDimitry Andric// As PPCVABSD description, the last operand indicates whether do the
47900b57cec5SDimitry Andric// sign bit flip.
47910b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
47920b57cec5SDimitry Andric          (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
47935ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec
47945ffd83dbSDimitry Andric
4795e8d8bef9SDimitry Andric// Big endian Power9 64Bit VSX subtargets with P9 Altivec support.
4796e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] in {
47975ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
47985ffd83dbSDimitry Andric          (VEXTUBLX $Idx, $S)>;
47995ffd83dbSDimitry Andric
48005ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
48015ffd83dbSDimitry Andric          (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
48025ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
48035ffd83dbSDimitry Andric          (VEXTUHLX (LI8 0), $S)>;
48045ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
48055ffd83dbSDimitry Andric          (VEXTUHLX (LI8 2), $S)>;
48065ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
48075ffd83dbSDimitry Andric          (VEXTUHLX (LI8 4), $S)>;
48085ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
48095ffd83dbSDimitry Andric          (VEXTUHLX (LI8 6), $S)>;
48105ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
48115ffd83dbSDimitry Andric          (VEXTUHLX (LI8 8), $S)>;
48125ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
48135ffd83dbSDimitry Andric          (VEXTUHLX (LI8 10), $S)>;
48145ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
48155ffd83dbSDimitry Andric          (VEXTUHLX (LI8 12), $S)>;
48165ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
48175ffd83dbSDimitry Andric          (VEXTUHLX (LI8 14), $S)>;
48185ffd83dbSDimitry Andric
48195ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
48205ffd83dbSDimitry Andric          (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
48215ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
48225ffd83dbSDimitry Andric          (VEXTUWLX (LI8 0), $S)>;
48235ffd83dbSDimitry Andric
48245ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
48255ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
48265ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
48275ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
48285ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
48295ffd83dbSDimitry Andric          (VEXTUWLX (LI8 8), $S)>;
48305ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
48315ffd83dbSDimitry Andric          (VEXTUWLX (LI8 12), $S)>;
48325ffd83dbSDimitry Andric
48335ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
48345ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
48355ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
48365ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 0), $S))>;
48375ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
48385ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
48395ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
48405ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
48415ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
48425ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 8), $S))>;
48435ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
48445ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 12), $S))>;
48455ffd83dbSDimitry Andric
48465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
48475ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
48485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
48495ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
48505ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
48515ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
48525ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
48535ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
48545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
48555ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
48565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
48575ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
48585ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
48595ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
48605ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
48615ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
48625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
48635ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
48645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
48655ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
48665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
48675ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
48685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
48695ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
48705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
48715ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
48725ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
48735ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
48745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
48755ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
48765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
48775ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
48785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
48795ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
48805ffd83dbSDimitry Andric
48815ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
48825ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX
48835ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
48845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
48855ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
48865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
48875ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
48885ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
48895ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
48905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
48915ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
48925ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
48935ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
48945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
48955ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
48965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
48975ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
48985ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
48995ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
49005ffd83dbSDimitry Andric
49015ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
49025ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX
49035ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
49045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
49055ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
49065ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
49075ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
49085ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
49095ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
49105ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
49115ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
49125ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
49135ffd83dbSDimitry Andric
49145ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
49155ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
49165ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
49175ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
49185ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
49195ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
49205ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
49215ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
49225ffd83dbSDimitry Andric                  HWordToWord.BE_A2, HWordToWord.BE_A3)),
49235ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
49245ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
49255ffd83dbSDimitry Andric                  ByteToWord.BE_A2, ByteToWord.BE_A3)),
49265ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
49275ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
49285ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
4929e8d8bef9SDimitry Andric} // HasVSX, HasP9Altivec, IsBigEndian, IsPPC64
49305ffd83dbSDimitry Andric
49315ffd83dbSDimitry Andric// Little endian Power9 VSX subtargets with P9 Altivec support.
49325ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in {
49335ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
49345ffd83dbSDimitry Andric          (VEXTUBRX $Idx, $S)>;
49355ffd83dbSDimitry Andric
49365ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
49375ffd83dbSDimitry Andric          (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
49385ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
49395ffd83dbSDimitry Andric          (VEXTUHRX (LI8 0), $S)>;
49405ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
49415ffd83dbSDimitry Andric          (VEXTUHRX (LI8 2), $S)>;
49425ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
49435ffd83dbSDimitry Andric          (VEXTUHRX (LI8 4), $S)>;
49445ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
49455ffd83dbSDimitry Andric          (VEXTUHRX (LI8 6), $S)>;
49465ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
49475ffd83dbSDimitry Andric          (VEXTUHRX (LI8 8), $S)>;
49485ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
49495ffd83dbSDimitry Andric          (VEXTUHRX (LI8 10), $S)>;
49505ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
49515ffd83dbSDimitry Andric          (VEXTUHRX (LI8 12), $S)>;
49525ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
49535ffd83dbSDimitry Andric          (VEXTUHRX (LI8 14), $S)>;
49545ffd83dbSDimitry Andric
49555ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
49565ffd83dbSDimitry Andric          (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
49575ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
49585ffd83dbSDimitry Andric          (VEXTUWRX (LI8 0), $S)>;
49595ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
49605ffd83dbSDimitry Andric          (VEXTUWRX (LI8 4), $S)>;
49615ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
49625ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
49635ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
49645ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
49655ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
49665ffd83dbSDimitry Andric          (VEXTUWRX (LI8 12), $S)>;
49675ffd83dbSDimitry Andric
49685ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
49695ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
49705ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
49715ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 0), $S))>;
49725ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
49735ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 4), $S))>;
49745ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
49755ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
49765ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
49775ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
49785ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
49795ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 12), $S))>;
49805ffd83dbSDimitry Andric
49815ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
49825ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
49835ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
49845ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
49855ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
49865ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
49875ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
49885ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
49895ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
49905ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
49915ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
49925ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
49935ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
49945ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
49955ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
49965ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
49975ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
49985ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
49995ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
50005ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
50015ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
50025ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
50035ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
50045ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
50055ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
50065ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
50075ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
50085ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
50095ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
50105ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
50115ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
50125ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
50135ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
50145ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
50155ffd83dbSDimitry Andric
50165ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
50175ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX
50185ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
50195ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
50205ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
50215ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
50225ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
50235ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
50245ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
50255ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
50265ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
50275ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
50285ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
50295ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
50305ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
50315ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
50325ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
50335ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
50345ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
50355ffd83dbSDimitry Andric
50365ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
50375ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX
50385ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
50395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
50405ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
50415ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
50425ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
50435ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
50445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
50455ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
50465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
50475ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
50485ffd83dbSDimitry Andric
50495ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
50505ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
50515ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
50525ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
50535ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
50545ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
50555ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
50565ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
50575ffd83dbSDimitry Andric                  HWordToWord.LE_A2, HWordToWord.LE_A3)),
50585ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
50595ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
50605ffd83dbSDimitry Andric                  ByteToWord.LE_A2, ByteToWord.LE_A3)),
50615ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
50625ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
50635ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
50645ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec, IsLittleEndian
50655ffd83dbSDimitry Andric
5066e8d8bef9SDimitry Andric// Big endian 64Bit VSX subtarget that supports additional direct moves from
5067e8d8bef9SDimitry Andric// ISA3.0.
5068e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] in {
50695ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 1)),
50705ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
50715ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Big endian.
50725ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
50735ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
50745ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
50755ffd83dbSDimitry Andric          (MTVSRDD
50765ffd83dbSDimitry Andric            (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
50775ffd83dbSDimitry Andric            (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
50785ffd83dbSDimitry Andric
50795ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
50805ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
5081e8d8bef9SDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64
50825ffd83dbSDimitry Andric
50835ffd83dbSDimitry Andric// Little endian VSX subtarget that supports direct moves from ISA3.0.
50845ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in {
50855ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 0)),
50865ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
50875ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Little endian.
50885ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
50895ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
50905ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
50915ffd83dbSDimitry Andric          (MTVSRDD
50925ffd83dbSDimitry Andric            (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
50935ffd83dbSDimitry Andric            (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
50945ffd83dbSDimitry Andric
50955ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
50965ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
50975ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian
50985ffd83dbSDimitry Andric} // AddedComplexity = 400
50995ffd83dbSDimitry Andric
51005ffd83dbSDimitry Andric//---------------------------- Instruction aliases ---------------------------//
51015ffd83dbSDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB",
51025ffd83dbSDimitry Andric                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
51035ffd83dbSDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB",
51045ffd83dbSDimitry Andric                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
51055ffd83dbSDimitry Andric
5106e8d8bef9SDimitry Andric// Certain versions of the AIX assembler may missassemble these mnemonics.
5107e8d8bef9SDimitry Andriclet Predicates = [ModernAs] in {
51085ffd83dbSDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 0",
51095ffd83dbSDimitry Andric                  (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
51105ffd83dbSDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 1",
51115ffd83dbSDimitry Andric                  (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
5112e8d8bef9SDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 0",
5113e8d8bef9SDimitry Andric                  (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
5114e8d8bef9SDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 1",
5115e8d8bef9SDimitry Andric                  (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
5116e8d8bef9SDimitry Andric}
5117e8d8bef9SDimitry Andric
51185ffd83dbSDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB",
51195ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
51205ffd83dbSDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB",
51215ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
51225ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
51235ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
51245ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
51255ffd83dbSDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
51265ffd83dbSDimitry Andricdef : InstAlias<"mfvrd $rA, $XT",
51275ffd83dbSDimitry Andric                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
51285ffd83dbSDimitry Andricdef : InstAlias<"mffprd $rA, $src",
51295ffd83dbSDimitry Andric                (MFVSRD g8rc:$rA, f8rc:$src)>;
51305ffd83dbSDimitry Andricdef : InstAlias<"mtvrd $XT, $rA",
51315ffd83dbSDimitry Andric                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
51325ffd83dbSDimitry Andricdef : InstAlias<"mtfprd $dst, $rA",
51335ffd83dbSDimitry Andric                (MTVSRD f8rc:$dst, g8rc:$rA)>;
51345ffd83dbSDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT",
51355ffd83dbSDimitry Andric                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
51365ffd83dbSDimitry Andricdef : InstAlias<"mffprwz $rA, $src",
51375ffd83dbSDimitry Andric                (MFVSRWZ gprc:$rA, f8rc:$src)>;
51385ffd83dbSDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA",
51395ffd83dbSDimitry Andric                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
51405ffd83dbSDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA",
51415ffd83dbSDimitry Andric                (MTVSRWA f8rc:$dst, gprc:$rA)>;
51425ffd83dbSDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA",
51435ffd83dbSDimitry Andric                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
51445ffd83dbSDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA",
51455ffd83dbSDimitry Andric                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
5146