xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrVSX.td (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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]>;
1415ffd83dbSDimitry Andricdef PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED",
1425ffd83dbSDimitry Andric                     SDTypeProfile<1, 1, []>, []>;
1430b57cec5SDimitry Andric
1445ffd83dbSDimitry Andric//-------------------------- Predicate definitions ---------------------------//
1455ffd83dbSDimitry Andricdef HasVSX : Predicate<"Subtarget->hasVSX()">;
1465ffd83dbSDimitry Andricdef IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">;
1475ffd83dbSDimitry Andricdef IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">;
148*e8d8bef9SDimitry Andricdef IsPPC64 : Predicate<"Subtarget->isPPC64()">;
1495ffd83dbSDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">;
1505ffd83dbSDimitry Andricdef HasP8Vector : Predicate<"Subtarget->hasP8Vector()">;
1515ffd83dbSDimitry Andricdef HasDirectMove : Predicate<"Subtarget->hasDirectMove()">;
1525ffd83dbSDimitry Andricdef NoP9Vector : Predicate<"!Subtarget->hasP9Vector()">;
1535ffd83dbSDimitry Andricdef HasP9Vector : Predicate<"Subtarget->hasP9Vector()">;
1545ffd83dbSDimitry Andricdef NoP9Altivec : Predicate<"!Subtarget->hasP9Altivec()">;
1555ffd83dbSDimitry Andric
1565ffd83dbSDimitry Andric//--------------------- VSX-specific instruction formats ---------------------//
1575ffd83dbSDimitry Andric// By default, all VSX instructions are to be selected over their Altivec
1585ffd83dbSDimitry Andric// counter parts and they do not have unmodeled sideeffects.
1595ffd83dbSDimitry Andriclet AddedComplexity = 400, hasSideEffects = 0 in {
1600b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
1610b57cec5SDimitry Andric                    string asmstr, InstrItinClass itin, Intrinsic Int,
1620b57cec5SDimitry Andric                    ValueType OutTy, ValueType InTy> {
1630b57cec5SDimitry Andric  let BaseName = asmbase in {
1640b57cec5SDimitry Andric    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1650b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
1660b57cec5SDimitry Andric                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
1670b57cec5SDimitry Andric    let Defs = [CR6] in
168480093f4SDimitry Andric    def _rec    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1690b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1700b57cec5SDimitry Andric                       [(set InTy:$XT,
171*e8d8bef9SDimitry Andric                                (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>,
172480093f4SDimitry Andric                       isRecordForm;
1730b57cec5SDimitry Andric  }
1740b57cec5SDimitry Andric}
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as
1770b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained
1780b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained
1790b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though
1800b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction
1810b57cec5SDimitry Andric// to use the same register for both inputs.
1820b57cec5SDimitry Andric// For example, an output DAG such as this:
1830b57cec5SDimitry Andric//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
1840b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs
1850b57cec5SDimitry Andric// to the XXPERMDI instruction.
1860b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
1870b57cec5SDimitry Andric                 InstrItinClass itin, list<dag> pattern>
1880b57cec5SDimitry Andric  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
1890b57cec5SDimitry Andric    let XB = XA;
1900b57cec5SDimitry Andric}
1910b57cec5SDimitry Andric
1925ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
1935ffd83dbSDimitry Andricclass X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1945ffd83dbSDimitry Andric                    list<dag> pattern>
1955ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
1965ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1970b57cec5SDimitry Andric
1985ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
1995ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2005ffd83dbSDimitry Andric                       list<dag> pattern>
2015ffd83dbSDimitry Andric  : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm;
2025ffd83dbSDimitry Andric
2035ffd83dbSDimitry Andric// [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2045ffd83dbSDimitry Andric// So we use different operand class for VRB
2055ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2065ffd83dbSDimitry Andric                         RegisterOperand vbtype, list<dag> pattern>
2075ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2085ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2095ffd83dbSDimitry Andric
2105ffd83dbSDimitry Andric// [PO VRT XO VRB XO /]
2115ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2125ffd83dbSDimitry Andric                    list<dag> pattern>
2135ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
2145ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2155ffd83dbSDimitry Andric
2165ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2175ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2185ffd83dbSDimitry Andric                       list<dag> pattern>
2195ffd83dbSDimitry Andric  : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm;
2205ffd83dbSDimitry Andric
2215ffd83dbSDimitry Andric// [PO T XO B XO BX /]
2225ffd83dbSDimitry Andricclass XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2235ffd83dbSDimitry Andric                      list<dag> pattern>
2245ffd83dbSDimitry Andric  : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2255ffd83dbSDimitry Andric                    !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2265ffd83dbSDimitry Andric
2275ffd83dbSDimitry Andric// [PO T XO B XO BX TX]
2285ffd83dbSDimitry Andricclass XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2295ffd83dbSDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
2305ffd83dbSDimitry Andric  : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2315ffd83dbSDimitry Andric                    !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2325ffd83dbSDimitry Andric
2335ffd83dbSDimitry Andric// [PO T A B XO AX BX TX], src and dest register use different operand class
2345ffd83dbSDimitry Andricclass XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2355ffd83dbSDimitry Andric                RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2365ffd83dbSDimitry Andric                InstrItinClass itin, list<dag> pattern>
2375ffd83dbSDimitry Andric  : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2385ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2395ffd83dbSDimitry Andric
2405ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
2415ffd83dbSDimitry Andricclass X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2425ffd83dbSDimitry Andric                    list<dag> pattern>
2435ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2445ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2455ffd83dbSDimitry Andric
2465ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2475ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2485ffd83dbSDimitry Andric                       list<dag> pattern>
2495ffd83dbSDimitry Andric  : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm;
2505ffd83dbSDimitry Andric
2515ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
2525ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
2535ffd83dbSDimitry Andric                        list<dag> pattern>
2545ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
2555ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
2565ffd83dbSDimitry Andric            RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
2575ffd83dbSDimitry Andric
2585ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2595ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
2605ffd83dbSDimitry Andric                        list<dag> pattern>
2615ffd83dbSDimitry Andric  : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm;
2625ffd83dbSDimitry Andric
2635ffd83dbSDimitry Andricclass Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2645ffd83dbSDimitry Andric                              list<dag> pattern>
2655ffd83dbSDimitry Andric  : Z23Form_8<opcode, xo,
2665ffd83dbSDimitry Andric              (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2675ffd83dbSDimitry Andric              !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2685ffd83dbSDimitry Andric  let RC = ex;
2695ffd83dbSDimitry Andric}
2705ffd83dbSDimitry Andric
2715ffd83dbSDimitry Andric// [PO BF // VRA VRB XO /]
2725ffd83dbSDimitry Andricclass X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2735ffd83dbSDimitry Andric                    list<dag> pattern>
2745ffd83dbSDimitry Andric  : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2755ffd83dbSDimitry Andric             !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2765ffd83dbSDimitry Andric  let Pattern = pattern;
2775ffd83dbSDimitry Andric}
2785ffd83dbSDimitry Andric
2795ffd83dbSDimitry Andric// [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2805ffd83dbSDimitry Andric// "out" and "in" dag
2815ffd83dbSDimitry Andricclass X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2825ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
2835ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2845ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
2855ffd83dbSDimitry Andric
2865ffd83dbSDimitry Andric// [PO S RA RB XO SX]
2875ffd83dbSDimitry Andricclass X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2885ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
2895ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2905ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
2915ffd83dbSDimitry Andric} // Predicates = HasP9Vector
2925ffd83dbSDimitry Andric} // AddedComplexity = 400, hasSideEffects = 0
2935ffd83dbSDimitry Andric
2945ffd83dbSDimitry Andricmulticlass ScalToVecWPermute<ValueType Ty, dag In, dag NonPermOut, dag PermOut> {
2955ffd83dbSDimitry Andric  def : Pat<(Ty (scalar_to_vector In)), (Ty NonPermOut)>;
2965ffd83dbSDimitry Andric  def : Pat<(Ty (PPCSToV In)), (Ty PermOut)>;
2975ffd83dbSDimitry Andric}
2985ffd83dbSDimitry Andric
2995ffd83dbSDimitry Andric//-------------------------- Instruction definitions -------------------------//
3005ffd83dbSDimitry Andric// VSX instructions require the VSX feature, they are to be selected over
3015ffd83dbSDimitry Andric// equivalent Altivec patterns (as they address a larger register set) and
3025ffd83dbSDimitry Andric// they do not have unmodeled side effects.
3035ffd83dbSDimitry Andriclet Predicates = [HasVSX], AddedComplexity = 400 in {
3045ffd83dbSDimitry Andriclet hasSideEffects = 0 in {
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric  // Load indexed instructions
3070b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
3080b57cec5SDimitry Andric    let CodeSize = 3 in
3090b57cec5SDimitry Andric    def LXSDX : XX1Form_memOp<31, 588,
3100b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
3110b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
3120b57cec5SDimitry Andric                        []>;
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andric    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
3150b57cec5SDimitry Andric    let CodeSize = 3 in
3160b57cec5SDimitry Andric      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
3170b57cec5SDimitry Andric                              "#XFLOADf64",
3180b57cec5SDimitry Andric                              [(set f64:$XT, (load xoaddr:$src))]>;
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3210b57cec5SDimitry Andric    def LXVD2X : XX1Form_memOp<31, 844,
3220b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3230b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
3240b57cec5SDimitry Andric                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric    def LXVDSX : XX1Form_memOp<31, 332,
3270b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3280b57cec5SDimitry Andric                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3310b57cec5SDimitry Andric    def LXVW4X : XX1Form_memOp<31, 780,
3320b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3330b57cec5SDimitry Andric                         "lxvw4x $XT, $src", IIC_LdStLFD,
3340b57cec5SDimitry Andric                         []>;
3350b57cec5SDimitry Andric  } // mayLoad
3360b57cec5SDimitry Andric
3370b57cec5SDimitry Andric  // Store indexed instructions
3380b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
3390b57cec5SDimitry Andric    let CodeSize = 3 in
3400b57cec5SDimitry Andric    def STXSDX : XX1Form_memOp<31, 716,
3410b57cec5SDimitry Andric                        (outs), (ins vsfrc:$XT, memrr:$dst),
3420b57cec5SDimitry Andric                        "stxsdx $XT, $dst", IIC_LdStSTFD,
3430b57cec5SDimitry Andric                        []>;
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
3460b57cec5SDimitry Andric    let CodeSize = 3 in
3470b57cec5SDimitry Andric      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
3480b57cec5SDimitry Andric                              "#XFSTOREf64",
3490b57cec5SDimitry Andric                              [(store f64:$XT, xoaddr:$dst)]>;
3500b57cec5SDimitry Andric
3510b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3520b57cec5SDimitry Andric    // The behaviour of this instruction is endianness-specific so we provide no
3530b57cec5SDimitry Andric    // pattern to match it without considering endianness.
3540b57cec5SDimitry Andric    def STXVD2X : XX1Form_memOp<31, 972,
3550b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3560b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
3570b57cec5SDimitry Andric                         []>;
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric    def STXVW4X : XX1Form_memOp<31, 908,
3600b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3610b57cec5SDimitry Andric                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
3620b57cec5SDimitry Andric                         []>;
3630b57cec5SDimitry Andric    }
3640b57cec5SDimitry Andric  } // mayStore
3650b57cec5SDimitry Andric
366*e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
367*e8d8bef9SDimitry Andric  let Uses = [RM] in {
3680b57cec5SDimitry Andric  // Add/Mul Instructions
3690b57cec5SDimitry Andric  let isCommutable = 1 in {
3700b57cec5SDimitry Andric    def XSADDDP : XX3Form<60, 32,
3710b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3720b57cec5SDimitry Andric                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
3735ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>;
3740b57cec5SDimitry Andric    def XSMULDP : XX3Form<60, 48,
3750b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3760b57cec5SDimitry Andric                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
3775ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>;
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andric    def XVADDDP : XX3Form<60, 96,
3800b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3810b57cec5SDimitry Andric                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
3825ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>;
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric    def XVADDSP : XX3Form<60, 64,
3850b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3860b57cec5SDimitry Andric                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
3875ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric    def XVMULDP : XX3Form<60, 112,
3900b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3910b57cec5SDimitry Andric                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
3925ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>;
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andric    def XVMULSP : XX3Form<60, 80,
3950b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3960b57cec5SDimitry Andric                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
3975ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>;
3980b57cec5SDimitry Andric  }
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric  // Subtract Instructions
4010b57cec5SDimitry Andric  def XSSUBDP : XX3Form<60, 40,
4020b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
4030b57cec5SDimitry Andric                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
4045ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>;
4050b57cec5SDimitry Andric
4060b57cec5SDimitry Andric  def XVSUBDP : XX3Form<60, 104,
4070b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4080b57cec5SDimitry Andric                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
4095ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>;
4100b57cec5SDimitry Andric  def XVSUBSP : XX3Form<60, 72,
4110b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4120b57cec5SDimitry Andric                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
4135ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>;
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andric  // FMA Instructions
4160b57cec5SDimitry Andric  let BaseName = "XSMADDADP" in {
4170b57cec5SDimitry Andric  let isCommutable = 1 in
4180b57cec5SDimitry Andric  def XSMADDADP : XX3Form<60, 33,
4190b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4200b57cec5SDimitry Andric                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
4215ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, f64:$XTi))]>,
4220b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4230b57cec5SDimitry Andric                          AltVSXFMARel;
4240b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4250b57cec5SDimitry Andric  def XSMADDMDP : XX3Form<60, 41,
4260b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4270b57cec5SDimitry Andric                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4280b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4290b57cec5SDimitry Andric                          AltVSXFMARel;
4300b57cec5SDimitry Andric  }
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric  let BaseName = "XSMSUBADP" in {
4330b57cec5SDimitry Andric  let isCommutable = 1 in
4340b57cec5SDimitry Andric  def XSMSUBADP : XX3Form<60, 49,
4350b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4360b57cec5SDimitry Andric                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
4375ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
4380b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4390b57cec5SDimitry Andric                          AltVSXFMARel;
4400b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4410b57cec5SDimitry Andric  def XSMSUBMDP : XX3Form<60, 57,
4420b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4430b57cec5SDimitry Andric                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4440b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4450b57cec5SDimitry Andric                          AltVSXFMARel;
4460b57cec5SDimitry Andric  }
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andric  let BaseName = "XSNMADDADP" in {
4490b57cec5SDimitry Andric  let isCommutable = 1 in
4500b57cec5SDimitry Andric  def XSNMADDADP : XX3Form<60, 161,
4510b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4520b57cec5SDimitry Andric                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
4535ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, f64:$XTi)))]>,
4540b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4550b57cec5SDimitry Andric                          AltVSXFMARel;
4560b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4570b57cec5SDimitry Andric  def XSNMADDMDP : XX3Form<60, 169,
4580b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4590b57cec5SDimitry Andric                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4600b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4610b57cec5SDimitry Andric                          AltVSXFMARel;
4620b57cec5SDimitry Andric  }
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andric  let BaseName = "XSNMSUBADP" in {
4650b57cec5SDimitry Andric  let isCommutable = 1 in
4660b57cec5SDimitry Andric  def XSNMSUBADP : XX3Form<60, 177,
4670b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4680b57cec5SDimitry Andric                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
4695ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
4700b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4710b57cec5SDimitry Andric                          AltVSXFMARel;
4720b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4730b57cec5SDimitry Andric  def XSNMSUBMDP : XX3Form<60, 185,
4740b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4750b57cec5SDimitry Andric                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4760b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4770b57cec5SDimitry Andric                          AltVSXFMARel;
4780b57cec5SDimitry Andric  }
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andric  let BaseName = "XVMADDADP" in {
4810b57cec5SDimitry Andric  let isCommutable = 1 in
4820b57cec5SDimitry Andric  def XVMADDADP : XX3Form<60, 97,
4830b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4840b57cec5SDimitry Andric                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
4855ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
4860b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4870b57cec5SDimitry Andric                          AltVSXFMARel;
4880b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4890b57cec5SDimitry Andric  def XVMADDMDP : XX3Form<60, 105,
4900b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4910b57cec5SDimitry Andric                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4920b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4930b57cec5SDimitry Andric                          AltVSXFMARel;
4940b57cec5SDimitry Andric  }
4950b57cec5SDimitry Andric
4960b57cec5SDimitry Andric  let BaseName = "XVMADDASP" in {
4970b57cec5SDimitry Andric  let isCommutable = 1 in
4980b57cec5SDimitry Andric  def XVMADDASP : XX3Form<60, 65,
4990b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5000b57cec5SDimitry Andric                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
5015ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
5020b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5030b57cec5SDimitry Andric                          AltVSXFMARel;
5040b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5050b57cec5SDimitry Andric  def XVMADDMSP : XX3Form<60, 73,
5060b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5070b57cec5SDimitry Andric                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5080b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5090b57cec5SDimitry Andric                          AltVSXFMARel;
5100b57cec5SDimitry Andric  }
5110b57cec5SDimitry Andric
5120b57cec5SDimitry Andric  let BaseName = "XVMSUBADP" in {
5130b57cec5SDimitry Andric  let isCommutable = 1 in
5140b57cec5SDimitry Andric  def XVMSUBADP : XX3Form<60, 113,
5150b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5160b57cec5SDimitry Andric                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
5175ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
5180b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5190b57cec5SDimitry Andric                          AltVSXFMARel;
5200b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5210b57cec5SDimitry Andric  def XVMSUBMDP : XX3Form<60, 121,
5220b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5230b57cec5SDimitry Andric                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5240b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5250b57cec5SDimitry Andric                          AltVSXFMARel;
5260b57cec5SDimitry Andric  }
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric  let BaseName = "XVMSUBASP" in {
5290b57cec5SDimitry Andric  let isCommutable = 1 in
5300b57cec5SDimitry Andric  def XVMSUBASP : XX3Form<60, 81,
5310b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5320b57cec5SDimitry Andric                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
5335ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
5340b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5350b57cec5SDimitry Andric                          AltVSXFMARel;
5360b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5370b57cec5SDimitry Andric  def XVMSUBMSP : XX3Form<60, 89,
5380b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5390b57cec5SDimitry Andric                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
5400b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5410b57cec5SDimitry Andric                          AltVSXFMARel;
5420b57cec5SDimitry Andric  }
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andric  let BaseName = "XVNMADDADP" in {
5450b57cec5SDimitry Andric  let isCommutable = 1 in
5460b57cec5SDimitry Andric  def XVNMADDADP : XX3Form<60, 225,
5470b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5480b57cec5SDimitry Andric                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
5495ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
5500b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5510b57cec5SDimitry Andric                          AltVSXFMARel;
5520b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5530b57cec5SDimitry Andric  def XVNMADDMDP : XX3Form<60, 233,
5540b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5550b57cec5SDimitry Andric                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
5560b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5570b57cec5SDimitry Andric                          AltVSXFMARel;
5580b57cec5SDimitry Andric  }
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andric  let BaseName = "XVNMADDASP" in {
5610b57cec5SDimitry Andric  let isCommutable = 1 in
5620b57cec5SDimitry Andric  def XVNMADDASP : XX3Form<60, 193,
5630b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5640b57cec5SDimitry Andric                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
5650b57cec5SDimitry Andric                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
5660b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5670b57cec5SDimitry Andric                          AltVSXFMARel;
5680b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5690b57cec5SDimitry Andric  def XVNMADDMSP : XX3Form<60, 201,
5700b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5710b57cec5SDimitry Andric                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5720b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5730b57cec5SDimitry Andric                          AltVSXFMARel;
5740b57cec5SDimitry Andric  }
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric  let BaseName = "XVNMSUBADP" in {
5770b57cec5SDimitry Andric  let isCommutable = 1 in
5780b57cec5SDimitry Andric  def XVNMSUBADP : XX3Form<60, 241,
5790b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5800b57cec5SDimitry Andric                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
5815ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
5820b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5830b57cec5SDimitry Andric                          AltVSXFMARel;
5840b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5850b57cec5SDimitry Andric  def XVNMSUBMDP : XX3Form<60, 249,
5860b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5870b57cec5SDimitry Andric                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5880b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5890b57cec5SDimitry Andric                          AltVSXFMARel;
5900b57cec5SDimitry Andric  }
5910b57cec5SDimitry Andric
5920b57cec5SDimitry Andric  let BaseName = "XVNMSUBASP" in {
5930b57cec5SDimitry Andric  let isCommutable = 1 in
5940b57cec5SDimitry Andric  def XVNMSUBASP : XX3Form<60, 209,
5950b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5960b57cec5SDimitry Andric                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
5975ffd83dbSDimitry Andric                          [(set v4f32:$XT, (fneg (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
5980b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5990b57cec5SDimitry Andric                          AltVSXFMARel;
6000b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
6010b57cec5SDimitry Andric  def XVNMSUBMSP : XX3Form<60, 217,
6020b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
6030b57cec5SDimitry Andric                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
6040b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
6050b57cec5SDimitry Andric                          AltVSXFMARel;
6060b57cec5SDimitry Andric  }
6070b57cec5SDimitry Andric
6080b57cec5SDimitry Andric  // Division Instructions
6090b57cec5SDimitry Andric  def XSDIVDP : XX3Form<60, 56,
6100b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
6110b57cec5SDimitry Andric                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
6125ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>;
6130b57cec5SDimitry Andric  def XSSQRTDP : XX2Form<60, 75,
6140b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6150b57cec5SDimitry Andric                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
6165ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsqrt f64:$XB))]>;
6170b57cec5SDimitry Andric
6180b57cec5SDimitry Andric  def XSREDP : XX2Form<60, 90,
6190b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6200b57cec5SDimitry Andric                        "xsredp $XT, $XB", IIC_VecFP,
6210b57cec5SDimitry Andric                        [(set f64:$XT, (PPCfre f64:$XB))]>;
6220b57cec5SDimitry Andric  def XSRSQRTEDP : XX2Form<60, 74,
6230b57cec5SDimitry Andric                           (outs vsfrc:$XT), (ins vsfrc:$XB),
6240b57cec5SDimitry Andric                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
6250b57cec5SDimitry Andric                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
6260b57cec5SDimitry Andric
627*e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
6280b57cec5SDimitry Andric  def XSTDIVDP : XX3Form_1<60, 61,
6290b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6300b57cec5SDimitry Andric                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
6310b57cec5SDimitry Andric  def XSTSQRTDP : XX2Form_1<60, 106,
6320b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsfrc:$XB),
633*e8d8bef9SDimitry Andric                          "xstsqrtdp $crD, $XB", IIC_FPCompare,
634*e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt f64:$XB))]>;
635*e8d8bef9SDimitry Andric  def XVTDIVDP : XX3Form_1<60, 125,
636*e8d8bef9SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
637*e8d8bef9SDimitry Andric                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
638*e8d8bef9SDimitry Andric  def XVTDIVSP : XX3Form_1<60, 93,
639*e8d8bef9SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
640*e8d8bef9SDimitry Andric                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
641*e8d8bef9SDimitry Andric
642*e8d8bef9SDimitry Andric  def XVTSQRTDP : XX2Form_1<60, 234,
643*e8d8bef9SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
644*e8d8bef9SDimitry Andric                          "xvtsqrtdp $crD, $XB", IIC_FPCompare,
645*e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt v2f64:$XB))]>;
646*e8d8bef9SDimitry Andric  def XVTSQRTSP : XX2Form_1<60, 170,
647*e8d8bef9SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
648*e8d8bef9SDimitry Andric                          "xvtsqrtsp $crD, $XB", IIC_FPCompare,
649*e8d8bef9SDimitry Andric                          [(set i32:$crD, (PPCftsqrt v4f32:$XB))]>;
650*e8d8bef9SDimitry Andric  }
6510b57cec5SDimitry Andric
6520b57cec5SDimitry Andric  def XVDIVDP : XX3Form<60, 120,
6530b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6540b57cec5SDimitry Andric                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
6555ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>;
6560b57cec5SDimitry Andric  def XVDIVSP : XX3Form<60, 88,
6570b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6580b57cec5SDimitry Andric                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
6595ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>;
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andric  def XVSQRTDP : XX2Form<60, 203,
6620b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6630b57cec5SDimitry Andric                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
6645ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsqrt v2f64:$XB))]>;
6650b57cec5SDimitry Andric  def XVSQRTSP : XX2Form<60, 139,
6660b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6670b57cec5SDimitry Andric                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
6685ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsqrt v4f32:$XB))]>;
6690b57cec5SDimitry Andric
6700b57cec5SDimitry Andric  def XVREDP : XX2Form<60, 218,
6710b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6720b57cec5SDimitry Andric                        "xvredp $XT, $XB", IIC_VecFP,
6730b57cec5SDimitry Andric                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
6740b57cec5SDimitry Andric  def XVRESP : XX2Form<60, 154,
6750b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6760b57cec5SDimitry Andric                        "xvresp $XT, $XB", IIC_VecFP,
6770b57cec5SDimitry Andric                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
6780b57cec5SDimitry Andric
6790b57cec5SDimitry Andric  def XVRSQRTEDP : XX2Form<60, 202,
6800b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6810b57cec5SDimitry Andric                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
6820b57cec5SDimitry Andric                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
6830b57cec5SDimitry Andric  def XVRSQRTESP : XX2Form<60, 138,
6840b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6850b57cec5SDimitry Andric                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
6860b57cec5SDimitry Andric                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
6870b57cec5SDimitry Andric
6880b57cec5SDimitry Andric  // Compare Instructions
6890b57cec5SDimitry Andric  def XSCMPODP : XX3Form_1<60, 43,
6900b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6910b57cec5SDimitry Andric                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
6920b57cec5SDimitry Andric  def XSCMPUDP : XX3Form_1<60, 35,
6930b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6940b57cec5SDimitry Andric                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
6970b57cec5SDimitry Andric                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
6980b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
6990b57cec5SDimitry Andric  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
7000b57cec5SDimitry Andric                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
7010b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
7020b57cec5SDimitry Andric  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
7030b57cec5SDimitry Andric                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
7040b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
7050b57cec5SDimitry Andric  defm XVCMPGESP : XX3Form_Rcr<60, 83,
7060b57cec5SDimitry Andric                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
7070b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
7080b57cec5SDimitry Andric  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
7090b57cec5SDimitry Andric                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
7100b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
7110b57cec5SDimitry Andric  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
7120b57cec5SDimitry Andric                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
7130b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andric  // Move Instructions
716*e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
7170b57cec5SDimitry Andric  def XSABSDP : XX2Form<60, 345,
7180b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7190b57cec5SDimitry Andric                      "xsabsdp $XT, $XB", IIC_VecFP,
7200b57cec5SDimitry Andric                      [(set f64:$XT, (fabs f64:$XB))]>;
7210b57cec5SDimitry Andric  def XSNABSDP : XX2Form<60, 361,
7220b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7230b57cec5SDimitry Andric                      "xsnabsdp $XT, $XB", IIC_VecFP,
7240b57cec5SDimitry Andric                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
7250b57cec5SDimitry Andric  def XSNEGDP : XX2Form<60, 377,
7260b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7270b57cec5SDimitry Andric                      "xsnegdp $XT, $XB", IIC_VecFP,
7280b57cec5SDimitry Andric                      [(set f64:$XT, (fneg f64:$XB))]>;
7290b57cec5SDimitry Andric  def XSCPSGNDP : XX3Form<60, 176,
7300b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
7310b57cec5SDimitry Andric                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
7320b57cec5SDimitry Andric                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andric  def XVABSDP : XX2Form<60, 473,
7350b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7360b57cec5SDimitry Andric                      "xvabsdp $XT, $XB", IIC_VecFP,
7370b57cec5SDimitry Andric                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric  def XVABSSP : XX2Form<60, 409,
7400b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7410b57cec5SDimitry Andric                      "xvabssp $XT, $XB", IIC_VecFP,
7420b57cec5SDimitry Andric                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andric  def XVCPSGNDP : XX3Form<60, 240,
7450b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7460b57cec5SDimitry Andric                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
7470b57cec5SDimitry Andric                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
7480b57cec5SDimitry Andric  def XVCPSGNSP : XX3Form<60, 208,
7490b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7500b57cec5SDimitry Andric                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
7510b57cec5SDimitry Andric                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
7520b57cec5SDimitry Andric
7530b57cec5SDimitry Andric  def XVNABSDP : XX2Form<60, 489,
7540b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7550b57cec5SDimitry Andric                      "xvnabsdp $XT, $XB", IIC_VecFP,
7560b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
7570b57cec5SDimitry Andric  def XVNABSSP : XX2Form<60, 425,
7580b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7590b57cec5SDimitry Andric                      "xvnabssp $XT, $XB", IIC_VecFP,
7600b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric  def XVNEGDP : XX2Form<60, 505,
7630b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7640b57cec5SDimitry Andric                      "xvnegdp $XT, $XB", IIC_VecFP,
7650b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
7660b57cec5SDimitry Andric  def XVNEGSP : XX2Form<60, 441,
7670b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7680b57cec5SDimitry Andric                      "xvnegsp $XT, $XB", IIC_VecFP,
7690b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
770*e8d8bef9SDimitry Andric  }
7710b57cec5SDimitry Andric
7720b57cec5SDimitry Andric  // Conversion Instructions
7730b57cec5SDimitry Andric  def XSCVDPSP : XX2Form<60, 265,
7740b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7750b57cec5SDimitry Andric                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
7760b57cec5SDimitry Andric  def XSCVDPSXDS : XX2Form<60, 344,
7770b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7780b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
779*e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctidz f64:$XB))]>;
7800b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7810b57cec5SDimitry Andric  def XSCVDPSXDSs : XX2Form<60, 344,
7820b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7830b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
784*e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctidz f32:$XB))]>;
7850b57cec5SDimitry Andric  def XSCVDPSXWS : XX2Form<60, 88,
7860b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7870b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
788*e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>;
7890b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7900b57cec5SDimitry Andric  def XSCVDPSXWSs : XX2Form<60, 88,
7910b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7920b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
793*e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>;
7940b57cec5SDimitry Andric  def XSCVDPUXDS : XX2Form<60, 328,
7950b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7960b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
797*e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>;
7980b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7990b57cec5SDimitry Andric  def XSCVDPUXDSs : XX2Form<60, 328,
8000b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
8010b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
802*e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>;
8030b57cec5SDimitry Andric  def XSCVDPUXWS : XX2Form<60, 72,
8040b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8050b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
806*e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>;
8070b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
8080b57cec5SDimitry Andric  def XSCVDPUXWSs : XX2Form<60, 72,
8090b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
8100b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
811*e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>;
8120b57cec5SDimitry Andric  def XSCVSPDP : XX2Form<60, 329,
8130b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8140b57cec5SDimitry Andric                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
8150b57cec5SDimitry Andric  def XSCVSXDDP : XX2Form<60, 376,
8160b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8170b57cec5SDimitry Andric                      "xscvsxddp $XT, $XB", IIC_VecFP,
818*e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fcfid f64:$XB))]>;
8190b57cec5SDimitry Andric  def XSCVUXDDP : XX2Form<60, 360,
8200b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8210b57cec5SDimitry Andric                      "xscvuxddp $XT, $XB", IIC_VecFP,
822*e8d8bef9SDimitry Andric                      [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>;
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andric  def XVCVDPSP : XX2Form<60, 393,
8250b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8260b57cec5SDimitry Andric                      "xvcvdpsp $XT, $XB", IIC_VecFP,
8270b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
8280b57cec5SDimitry Andric  def XVCVDPSXDS : XX2Form<60, 472,
8290b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8300b57cec5SDimitry Andric                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
831*e8d8bef9SDimitry Andric                      [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>;
8320b57cec5SDimitry Andric  def XVCVDPSXWS : XX2Form<60, 216,
8330b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8340b57cec5SDimitry Andric                      "xvcvdpsxws $XT, $XB", IIC_VecFP,
8350b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
8360b57cec5SDimitry Andric  def XVCVDPUXDS : XX2Form<60, 456,
8370b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8380b57cec5SDimitry Andric                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
839*e8d8bef9SDimitry Andric                      [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>;
8400b57cec5SDimitry Andric  def XVCVDPUXWS : XX2Form<60, 200,
8410b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8420b57cec5SDimitry Andric                      "xvcvdpuxws $XT, $XB", IIC_VecFP,
8430b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
8440b57cec5SDimitry Andric
8450b57cec5SDimitry Andric  def XVCVSPDP : XX2Form<60, 457,
8460b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8470b57cec5SDimitry Andric                      "xvcvspdp $XT, $XB", IIC_VecFP,
8480b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
8490b57cec5SDimitry Andric  def XVCVSPSXDS : XX2Form<60, 408,
8500b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8510b57cec5SDimitry Andric                      "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
8520b57cec5SDimitry Andric  def XVCVSPSXWS : XX2Form<60, 152,
8530b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8540b57cec5SDimitry Andric                      "xvcvspsxws $XT, $XB", IIC_VecFP,
855*e8d8bef9SDimitry Andric                      [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>;
8560b57cec5SDimitry Andric  def XVCVSPUXDS : XX2Form<60, 392,
8570b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8580b57cec5SDimitry Andric                      "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
8590b57cec5SDimitry Andric  def XVCVSPUXWS : XX2Form<60, 136,
8600b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8610b57cec5SDimitry Andric                      "xvcvspuxws $XT, $XB", IIC_VecFP,
862*e8d8bef9SDimitry Andric                      [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>;
8630b57cec5SDimitry Andric  def XVCVSXDDP : XX2Form<60, 504,
8640b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8650b57cec5SDimitry Andric                      "xvcvsxddp $XT, $XB", IIC_VecFP,
866*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>;
8670b57cec5SDimitry Andric  def XVCVSXDSP : XX2Form<60, 440,
8680b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8690b57cec5SDimitry Andric                      "xvcvsxdsp $XT, $XB", IIC_VecFP,
8700b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
8710b57cec5SDimitry Andric  def XVCVSXWSP : XX2Form<60, 184,
8720b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8730b57cec5SDimitry Andric                      "xvcvsxwsp $XT, $XB", IIC_VecFP,
874*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>;
8750b57cec5SDimitry Andric  def XVCVUXDDP : XX2Form<60, 488,
8760b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8770b57cec5SDimitry Andric                      "xvcvuxddp $XT, $XB", IIC_VecFP,
878*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>;
8790b57cec5SDimitry Andric  def XVCVUXDSP : XX2Form<60, 424,
8800b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8810b57cec5SDimitry Andric                      "xvcvuxdsp $XT, $XB", IIC_VecFP,
8820b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
883*e8d8bef9SDimitry Andric  def XVCVUXWSP : XX2Form<60, 168,
884*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
885*e8d8bef9SDimitry Andric                      "xvcvuxwsp $XT, $XB", IIC_VecFP,
886*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>;
887*e8d8bef9SDimitry Andric
888*e8d8bef9SDimitry Andric  let mayRaiseFPException = 0 in {
889*e8d8bef9SDimitry Andric  def XVCVSXWDP : XX2Form<60, 248,
890*e8d8bef9SDimitry Andric                    (outs vsrc:$XT), (ins vsrc:$XB),
891*e8d8bef9SDimitry Andric                    "xvcvsxwdp $XT, $XB", IIC_VecFP,
892*e8d8bef9SDimitry Andric                    [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
8930b57cec5SDimitry Andric  def XVCVUXWDP : XX2Form<60, 232,
8940b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8950b57cec5SDimitry Andric                      "xvcvuxwdp $XT, $XB", IIC_VecFP,
8960b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
897*e8d8bef9SDimitry Andric  }
8980b57cec5SDimitry Andric
899*e8d8bef9SDimitry Andric  // Rounding Instructions respecting current rounding mode
9000b57cec5SDimitry Andric  def XSRDPIC : XX2Form<60, 107,
9010b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
9020b57cec5SDimitry Andric                      "xsrdpic $XT, $XB", IIC_VecFP,
903*e8d8bef9SDimitry Andric                      [(set f64:$XT, (fnearbyint f64:$XB))]>;
9040b57cec5SDimitry Andric  def XVRDPIC : XX2Form<60, 235,
9050b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9060b57cec5SDimitry Andric                      "xvrdpic $XT, $XB", IIC_VecFP,
907*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
9080b57cec5SDimitry Andric  def XVRSPIC : XX2Form<60, 171,
9090b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9100b57cec5SDimitry Andric                      "xvrspic $XT, $XB", IIC_VecFP,
911*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
9120b57cec5SDimitry Andric  // Max/Min Instructions
9130b57cec5SDimitry Andric  let isCommutable = 1 in {
9140b57cec5SDimitry Andric  def XSMAXDP : XX3Form<60, 160,
9150b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9160b57cec5SDimitry Andric                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
9170b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9180b57cec5SDimitry Andric                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
9190b57cec5SDimitry Andric  def XSMINDP : XX3Form<60, 168,
9200b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9210b57cec5SDimitry Andric                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
9220b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9230b57cec5SDimitry Andric                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
9240b57cec5SDimitry Andric
9250b57cec5SDimitry Andric  def XVMAXDP : XX3Form<60, 224,
9260b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9270b57cec5SDimitry Andric                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
9280b57cec5SDimitry Andric                        [(set vsrc:$XT,
9290b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
9300b57cec5SDimitry Andric  def XVMINDP : XX3Form<60, 232,
9310b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9320b57cec5SDimitry Andric                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
9330b57cec5SDimitry Andric                        [(set vsrc:$XT,
9340b57cec5SDimitry Andric                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
9350b57cec5SDimitry Andric
9360b57cec5SDimitry Andric  def XVMAXSP : XX3Form<60, 192,
9370b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9380b57cec5SDimitry Andric                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
9390b57cec5SDimitry Andric                        [(set vsrc:$XT,
9400b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
9410b57cec5SDimitry Andric  def XVMINSP : XX3Form<60, 200,
9420b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9430b57cec5SDimitry Andric                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
9440b57cec5SDimitry Andric                        [(set vsrc:$XT,
9450b57cec5SDimitry Andric                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
9460b57cec5SDimitry Andric  } // isCommutable
947*e8d8bef9SDimitry Andric  } // Uses = [RM]
948*e8d8bef9SDimitry Andric
949*e8d8bef9SDimitry Andric  // Rounding Instructions with static direction.
950*e8d8bef9SDimitry Andric  def XSRDPI : XX2Form<60, 73,
951*e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
952*e8d8bef9SDimitry Andric                      "xsrdpi $XT, $XB", IIC_VecFP,
953*e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_fround f64:$XB))]>;
954*e8d8bef9SDimitry Andric  def XSRDPIM : XX2Form<60, 121,
955*e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
956*e8d8bef9SDimitry Andric                      "xsrdpim $XT, $XB", IIC_VecFP,
957*e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_ffloor f64:$XB))]>;
958*e8d8bef9SDimitry Andric  def XSRDPIP : XX2Form<60, 105,
959*e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
960*e8d8bef9SDimitry Andric                      "xsrdpip $XT, $XB", IIC_VecFP,
961*e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_fceil f64:$XB))]>;
962*e8d8bef9SDimitry Andric  def XSRDPIZ : XX2Form<60, 89,
963*e8d8bef9SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
964*e8d8bef9SDimitry Andric                      "xsrdpiz $XT, $XB", IIC_VecFP,
965*e8d8bef9SDimitry Andric                      [(set f64:$XT, (any_ftrunc f64:$XB))]>;
966*e8d8bef9SDimitry Andric
967*e8d8bef9SDimitry Andric  def XVRDPI : XX2Form<60, 201,
968*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
969*e8d8bef9SDimitry Andric                      "xvrdpi $XT, $XB", IIC_VecFP,
970*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_fround v2f64:$XB))]>;
971*e8d8bef9SDimitry Andric  def XVRDPIM : XX2Form<60, 249,
972*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
973*e8d8bef9SDimitry Andric                      "xvrdpim $XT, $XB", IIC_VecFP,
974*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
975*e8d8bef9SDimitry Andric  def XVRDPIP : XX2Form<60, 233,
976*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
977*e8d8bef9SDimitry Andric                      "xvrdpip $XT, $XB", IIC_VecFP,
978*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
979*e8d8bef9SDimitry Andric  def XVRDPIZ : XX2Form<60, 217,
980*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
981*e8d8bef9SDimitry Andric                      "xvrdpiz $XT, $XB", IIC_VecFP,
982*e8d8bef9SDimitry Andric                      [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
983*e8d8bef9SDimitry Andric
984*e8d8bef9SDimitry Andric  def XVRSPI : XX2Form<60, 137,
985*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
986*e8d8bef9SDimitry Andric                      "xvrspi $XT, $XB", IIC_VecFP,
987*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_fround v4f32:$XB))]>;
988*e8d8bef9SDimitry Andric  def XVRSPIM : XX2Form<60, 185,
989*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
990*e8d8bef9SDimitry Andric                      "xvrspim $XT, $XB", IIC_VecFP,
991*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
992*e8d8bef9SDimitry Andric  def XVRSPIP : XX2Form<60, 169,
993*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
994*e8d8bef9SDimitry Andric                      "xvrspip $XT, $XB", IIC_VecFP,
995*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
996*e8d8bef9SDimitry Andric  def XVRSPIZ : XX2Form<60, 153,
997*e8d8bef9SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
998*e8d8bef9SDimitry Andric                      "xvrspiz $XT, $XB", IIC_VecFP,
999*e8d8bef9SDimitry Andric                      [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
1000*e8d8bef9SDimitry Andric  } // mayRaiseFPException
10010b57cec5SDimitry Andric
10020b57cec5SDimitry Andric  // Logical Instructions
10030b57cec5SDimitry Andric  let isCommutable = 1 in
10040b57cec5SDimitry Andric  def XXLAND : XX3Form<60, 130,
10050b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10060b57cec5SDimitry Andric                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
10070b57cec5SDimitry Andric                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
10080b57cec5SDimitry Andric  def XXLANDC : XX3Form<60, 138,
10090b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10100b57cec5SDimitry Andric                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
10110b57cec5SDimitry Andric                        [(set v4i32:$XT, (and v4i32:$XA,
10120b57cec5SDimitry Andric                                              (vnot_ppc v4i32:$XB)))]>;
10130b57cec5SDimitry Andric  let isCommutable = 1 in {
10140b57cec5SDimitry Andric  def XXLNOR : XX3Form<60, 162,
10150b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10160b57cec5SDimitry Andric                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
10170b57cec5SDimitry Andric                       [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
10180b57cec5SDimitry Andric                                                   v4i32:$XB)))]>;
10190b57cec5SDimitry Andric  def XXLOR : XX3Form<60, 146,
10200b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10210b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
10220b57cec5SDimitry Andric                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
10230b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10240b57cec5SDimitry Andric  def XXLORf: XX3Form<60, 146,
10250b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
10260b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
10270b57cec5SDimitry Andric  def XXLXOR : XX3Form<60, 154,
10280b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10290b57cec5SDimitry Andric                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
10300b57cec5SDimitry Andric                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
10310b57cec5SDimitry Andric  } // isCommutable
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
10340b57cec5SDimitry Andric      isReMaterializable = 1 in {
10358bcb0991SDimitry Andric    def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
10360b57cec5SDimitry Andric                       "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10370b57cec5SDimitry Andric                       [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
10388bcb0991SDimitry Andric    def XXLXORdpz : XX3Form_SameOp<60, 154,
10390b57cec5SDimitry Andric                         (outs vsfrc:$XT), (ins),
10400b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10410b57cec5SDimitry Andric                         [(set f64:$XT, (fpimm0))]>;
10428bcb0991SDimitry Andric    def XXLXORspz : XX3Form_SameOp<60, 154,
10430b57cec5SDimitry Andric                         (outs vssrc:$XT), (ins),
10440b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10450b57cec5SDimitry Andric                         [(set f32:$XT, (fpimm0))]>;
10460b57cec5SDimitry Andric  }
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andric  // Permutation Instructions
10490b57cec5SDimitry Andric  def XXMRGHW : XX3Form<60, 18,
10500b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10510b57cec5SDimitry Andric                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
10520b57cec5SDimitry Andric  def XXMRGLW : XX3Form<60, 50,
10530b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10540b57cec5SDimitry Andric                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
10550b57cec5SDimitry Andric
10560b57cec5SDimitry Andric  def XXPERMDI : XX3Form_2<60, 10,
10570b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
10580b57cec5SDimitry Andric                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
10590b57cec5SDimitry Andric                       [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
10600b57cec5SDimitry Andric                         imm32SExt16:$DM))]>;
10610b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10620b57cec5SDimitry Andric  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
10630b57cec5SDimitry Andric                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
10640b57cec5SDimitry Andric  def XXSEL : XX4Form<60, 3,
10650b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
10660b57cec5SDimitry Andric                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
10670b57cec5SDimitry Andric
10680b57cec5SDimitry Andric  def XXSLDWI : XX3Form_2<60, 2,
10690b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
10700b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
10710b57cec5SDimitry Andric                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
10720b57cec5SDimitry Andric                                                  imm32SExt16:$SHW))]>;
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10750b57cec5SDimitry Andric  def XXSLDWIs : XX3Form_2s<60, 2,
10760b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
10770b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
10780b57cec5SDimitry Andric
10790b57cec5SDimitry Andric  def XXSPLTW : XX2Form_2<60, 164,
10800b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
10810b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
10820b57cec5SDimitry Andric                       [(set v4i32:$XT,
10830b57cec5SDimitry Andric                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
10840b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10850b57cec5SDimitry Andric  def XXSPLTWs : XX2Form_2<60, 164,
10860b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
10870b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
10880b57cec5SDimitry Andric
10895ffd83dbSDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07
10905ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
10915ffd83dbSDimitry Andric  let isCommutable = 1 in {
10925ffd83dbSDimitry Andric    def XXLEQV : XX3Form<60, 186,
10935ffd83dbSDimitry Andric                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10945ffd83dbSDimitry Andric                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
10955ffd83dbSDimitry Andric                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
10965ffd83dbSDimitry Andric    def XXLNAND : XX3Form<60, 178,
10975ffd83dbSDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10985ffd83dbSDimitry Andric                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
10995ffd83dbSDimitry Andric                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
11005ffd83dbSDimitry Andric                                                    v4i32:$XB)))]>;
11015ffd83dbSDimitry Andric  } // isCommutable
11020b57cec5SDimitry Andric
11035ffd83dbSDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
11045ffd83dbSDimitry Andric      isReMaterializable = 1 in {
11055ffd83dbSDimitry Andric    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
11065ffd83dbSDimitry Andric                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
11075ffd83dbSDimitry Andric                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
11085ffd83dbSDimitry Andric  }
11095ffd83dbSDimitry Andric
11105ffd83dbSDimitry Andric  def XXLORC : XX3Form<60, 170,
11115ffd83dbSDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
11125ffd83dbSDimitry Andric                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
11135ffd83dbSDimitry Andric                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
11145ffd83dbSDimitry Andric
11155ffd83dbSDimitry Andric  // VSX scalar loads introduced in ISA 2.07
11165ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
11175ffd83dbSDimitry Andric    let CodeSize = 3 in
11185ffd83dbSDimitry Andric    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
11195ffd83dbSDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
11205ffd83dbSDimitry Andric    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
11215ffd83dbSDimitry Andric                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
11225ffd83dbSDimitry Andric    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
11235ffd83dbSDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
11245ffd83dbSDimitry Andric
11255ffd83dbSDimitry Andric    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
11265ffd83dbSDimitry Andric    let CodeSize = 3 in
11275ffd83dbSDimitry Andric    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
11285ffd83dbSDimitry Andric                            "#XFLOADf32",
11295ffd83dbSDimitry Andric                            [(set f32:$XT, (load xoaddr:$src))]>;
11305ffd83dbSDimitry Andric    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
11315ffd83dbSDimitry Andric    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
11325ffd83dbSDimitry Andric                       "#LIWAX",
11335ffd83dbSDimitry Andric                       [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
11345ffd83dbSDimitry Andric    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
11355ffd83dbSDimitry Andric    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
11365ffd83dbSDimitry Andric                       "#LIWZX",
11375ffd83dbSDimitry Andric                       [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
11385ffd83dbSDimitry Andric  } // mayLoad
11395ffd83dbSDimitry Andric
11405ffd83dbSDimitry Andric  // VSX scalar stores introduced in ISA 2.07
11415ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
11425ffd83dbSDimitry Andric    let CodeSize = 3 in
11435ffd83dbSDimitry Andric    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
11445ffd83dbSDimitry Andric                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
11455ffd83dbSDimitry Andric    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
11465ffd83dbSDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
11475ffd83dbSDimitry Andric
11485ffd83dbSDimitry Andric    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
11495ffd83dbSDimitry Andric    let CodeSize = 3 in
11505ffd83dbSDimitry Andric    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
11515ffd83dbSDimitry Andric                            "#XFSTOREf32",
11525ffd83dbSDimitry Andric                            [(store f32:$XT, xoaddr:$dst)]>;
11535ffd83dbSDimitry Andric    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
11545ffd83dbSDimitry Andric    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
11555ffd83dbSDimitry Andric                       "#STIWX",
11565ffd83dbSDimitry Andric                      [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
11575ffd83dbSDimitry Andric  } // mayStore
11585ffd83dbSDimitry Andric
11595ffd83dbSDimitry Andric  // VSX Elementary Scalar FP arithmetic (SP)
11605ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
11615ffd83dbSDimitry Andric  let isCommutable = 1 in {
11625ffd83dbSDimitry Andric    def XSADDSP : XX3Form<60, 0,
11635ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11645ffd83dbSDimitry Andric                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
11655ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>;
11665ffd83dbSDimitry Andric    def XSMULSP : XX3Form<60, 16,
11675ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11685ffd83dbSDimitry Andric                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
11695ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>;
11705ffd83dbSDimitry Andric  } // isCommutable
11715ffd83dbSDimitry Andric
11725ffd83dbSDimitry Andric  def XSSUBSP : XX3Form<60, 8,
11735ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11745ffd83dbSDimitry Andric                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
11755ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>;
11765ffd83dbSDimitry Andric  def XSDIVSP : XX3Form<60, 24,
11775ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
11785ffd83dbSDimitry Andric                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
11795ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>;
11805ffd83dbSDimitry Andric
11815ffd83dbSDimitry Andric  def XSRESP : XX2Form<60, 26,
11825ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
11835ffd83dbSDimitry Andric                        "xsresp $XT, $XB", IIC_VecFP,
11845ffd83dbSDimitry Andric                        [(set f32:$XT, (PPCfre f32:$XB))]>;
11855ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1186*e8d8bef9SDimitry Andric  let hasSideEffects = 1 in
11875ffd83dbSDimitry Andric  def XSRSP : XX2Form<60, 281,
11885ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vsfrc:$XB),
11895ffd83dbSDimitry Andric                        "xsrsp $XT, $XB", IIC_VecFP,
11905ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fpround f64:$XB))]>;
11915ffd83dbSDimitry Andric  def XSSQRTSP : XX2Form<60, 11,
11925ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
11935ffd83dbSDimitry Andric                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
11945ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsqrt f32:$XB))]>;
11955ffd83dbSDimitry Andric  def XSRSQRTESP : XX2Form<60, 10,
11965ffd83dbSDimitry Andric                           (outs vssrc:$XT), (ins vssrc:$XB),
11975ffd83dbSDimitry Andric                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
11985ffd83dbSDimitry Andric                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
11995ffd83dbSDimitry Andric
12005ffd83dbSDimitry Andric  // FMA Instructions
12015ffd83dbSDimitry Andric  let BaseName = "XSMADDASP" in {
12025ffd83dbSDimitry Andric  let isCommutable = 1 in
12035ffd83dbSDimitry Andric  def XSMADDASP : XX3Form<60, 1,
12045ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12055ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12065ffd83dbSDimitry Andric                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
12075ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB, f32:$XTi))]>,
12085ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12095ffd83dbSDimitry Andric                          AltVSXFMARel;
12105ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12115ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12125ffd83dbSDimitry Andric  def XSMADDMSP : XX3Form<60, 9,
12135ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12145ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12155ffd83dbSDimitry Andric                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
12165ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12175ffd83dbSDimitry Andric                          AltVSXFMARel;
12185ffd83dbSDimitry Andric  }
12195ffd83dbSDimitry Andric
12205ffd83dbSDimitry Andric  let BaseName = "XSMSUBASP" in {
12215ffd83dbSDimitry Andric  let isCommutable = 1 in
12225ffd83dbSDimitry Andric  def XSMSUBASP : XX3Form<60, 17,
12235ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12245ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12255ffd83dbSDimitry Andric                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
12265ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB,
12275ffd83dbSDimitry Andric                                              (fneg f32:$XTi)))]>,
12285ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12295ffd83dbSDimitry Andric                          AltVSXFMARel;
12305ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12315ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12325ffd83dbSDimitry Andric  def XSMSUBMSP : XX3Form<60, 25,
12335ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12345ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12355ffd83dbSDimitry Andric                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
12365ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12375ffd83dbSDimitry Andric                          AltVSXFMARel;
12385ffd83dbSDimitry Andric  }
12395ffd83dbSDimitry Andric
12405ffd83dbSDimitry Andric  let BaseName = "XSNMADDASP" in {
12415ffd83dbSDimitry Andric  let isCommutable = 1 in
12425ffd83dbSDimitry Andric  def XSNMADDASP : XX3Form<60, 129,
12435ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12445ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12455ffd83dbSDimitry Andric                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
12465ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
12475ffd83dbSDimitry Andric                                                    f32:$XTi)))]>,
12485ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12495ffd83dbSDimitry Andric                          AltVSXFMARel;
12505ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12515ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12525ffd83dbSDimitry Andric  def XSNMADDMSP : XX3Form<60, 137,
12535ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12545ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12555ffd83dbSDimitry Andric                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
12565ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12575ffd83dbSDimitry Andric                          AltVSXFMARel;
12585ffd83dbSDimitry Andric  }
12595ffd83dbSDimitry Andric
12605ffd83dbSDimitry Andric  let BaseName = "XSNMSUBASP" in {
12615ffd83dbSDimitry Andric  let isCommutable = 1 in
12625ffd83dbSDimitry Andric  def XSNMSUBASP : XX3Form<60, 145,
12635ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12645ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12655ffd83dbSDimitry Andric                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
12665ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
12675ffd83dbSDimitry Andric                                                    (fneg f32:$XTi))))]>,
12685ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12695ffd83dbSDimitry Andric                          AltVSXFMARel;
12705ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
12715ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
12725ffd83dbSDimitry Andric  def XSNMSUBMSP : XX3Form<60, 153,
12735ffd83dbSDimitry Andric                          (outs vssrc:$XT),
12745ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
12755ffd83dbSDimitry Andric                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
12765ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
12775ffd83dbSDimitry Andric                          AltVSXFMARel;
12785ffd83dbSDimitry Andric  }
12795ffd83dbSDimitry Andric
12805ffd83dbSDimitry Andric  // Single Precision Conversions (FP <-> INT)
12815ffd83dbSDimitry Andric  def XSCVSXDSP : XX2Form<60, 312,
12825ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
12835ffd83dbSDimitry Andric                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1284*e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fcfids f64:$XB))]>;
12855ffd83dbSDimitry Andric  def XSCVUXDSP : XX2Form<60, 296,
12865ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
12875ffd83dbSDimitry Andric                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1288*e8d8bef9SDimitry Andric                      [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>;
1289*e8d8bef9SDimitry Andric  } // mayRaiseFPException
12905ffd83dbSDimitry Andric
12915ffd83dbSDimitry Andric  // Conversions between vector and scalar single precision
12925ffd83dbSDimitry Andric  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
12935ffd83dbSDimitry Andric                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
12945ffd83dbSDimitry Andric  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
12955ffd83dbSDimitry Andric                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
12965ffd83dbSDimitry Andric
12975ffd83dbSDimitry Andric  let Predicates = [HasVSX, HasDirectMove] in {
12985ffd83dbSDimitry Andric  // VSX direct move instructions
12995ffd83dbSDimitry Andric  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
13005ffd83dbSDimitry Andric                              "mfvsrd $rA, $XT", IIC_VecGeneral,
13015ffd83dbSDimitry Andric                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
13025ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13035ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13045ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13055ffd83dbSDimitry Andric  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
13065ffd83dbSDimitry Andric                             "mfvsrd $rA, $XT", IIC_VecGeneral,
13075ffd83dbSDimitry Andric                             []>,
13085ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13095ffd83dbSDimitry Andric  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
13105ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
13115ffd83dbSDimitry Andric                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
13125ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13135ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13145ffd83dbSDimitry Andric  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
13155ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
13165ffd83dbSDimitry Andric                               []>;
13175ffd83dbSDimitry Andric  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
13185ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
13195ffd83dbSDimitry Andric                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
13205ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13215ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13225ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13235ffd83dbSDimitry Andric  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
13245ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
13255ffd83dbSDimitry Andric                              []>,
13265ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
13275ffd83dbSDimitry Andric  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
13285ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
13295ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
13305ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13315ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13325ffd83dbSDimitry Andric  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
13335ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
13345ffd83dbSDimitry Andric                               []>;
13355ffd83dbSDimitry Andric  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
13365ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
13375ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
13385ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
13395ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
13405ffd83dbSDimitry Andric  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
13415ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
13425ffd83dbSDimitry Andric                               []>;
13435ffd83dbSDimitry Andric  } // HasDirectMove
13445ffd83dbSDimitry Andric
13455ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
13465ffd83dbSDimitry Andric
13475ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove] in {
13485ffd83dbSDimitry Andricdef MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
13495ffd83dbSDimitry Andric                            "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
13505ffd83dbSDimitry Andric
13515ffd83dbSDimitry Andricdef MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
13525ffd83dbSDimitry Andric                     "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
13535ffd83dbSDimitry Andric                     []>, Requires<[In64BitMode]>;
13545ffd83dbSDimitry Andric
13555ffd83dbSDimitry Andricdef MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
13565ffd83dbSDimitry Andric                            "mfvsrld $rA, $XT", IIC_VecGeneral,
13575ffd83dbSDimitry Andric                            []>, Requires<[In64BitMode]>;
13585ffd83dbSDimitry Andric
13595ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove
13605ffd83dbSDimitry Andric
13615ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
13625ffd83dbSDimitry Andric  // Quad-Precision Scalar Move Instructions:
13635ffd83dbSDimitry Andric  // Copy Sign
13645ffd83dbSDimitry Andric  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
13655ffd83dbSDimitry Andric                                [(set f128:$vT,
13665ffd83dbSDimitry Andric                                      (fcopysign f128:$vB, f128:$vA))]>;
13675ffd83dbSDimitry Andric
13685ffd83dbSDimitry Andric  // Absolute/Negative-Absolute/Negate
13695ffd83dbSDimitry Andric  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
13705ffd83dbSDimitry Andric                                [(set f128:$vT, (fabs f128:$vB))]>;
13715ffd83dbSDimitry Andric  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
13725ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
13735ffd83dbSDimitry Andric  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
13745ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg f128:$vB))]>;
13755ffd83dbSDimitry Andric
13765ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
13775ffd83dbSDimitry Andric  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
13785ffd83dbSDimitry Andric
13795ffd83dbSDimitry Andric  // Add/Divide/Multiply/Subtract
13805ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
13815ffd83dbSDimitry Andric  let isCommutable = 1 in {
13825ffd83dbSDimitry Andric  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
13835ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>;
13845ffd83dbSDimitry Andric  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
13855ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>;
13865ffd83dbSDimitry Andric  }
13875ffd83dbSDimitry Andric  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
13885ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>;
13895ffd83dbSDimitry Andric  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
13905ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>;
13915ffd83dbSDimitry Andric  // Square-Root
13925ffd83dbSDimitry Andric  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
13935ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsqrt f128:$vB))]>;
13945ffd83dbSDimitry Andric  // (Negative) Multiply-{Add/Subtract}
13955ffd83dbSDimitry Andric  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
13965ffd83dbSDimitry Andric                                    [(set f128:$vT,
13975ffd83dbSDimitry Andric                                          (any_fma f128:$vA, f128:$vB, f128:$vTi))]>;
13985ffd83dbSDimitry Andric  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
13995ffd83dbSDimitry Andric                                       [(set f128:$vT,
14005ffd83dbSDimitry Andric                                             (any_fma f128:$vA, f128:$vB,
14015ffd83dbSDimitry Andric                                                      (fneg f128:$vTi)))]>;
14025ffd83dbSDimitry Andric  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
14035ffd83dbSDimitry Andric                                     [(set f128:$vT,
14045ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
14055ffd83dbSDimitry Andric                                                          f128:$vTi)))]>;
14065ffd83dbSDimitry Andric  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
14075ffd83dbSDimitry Andric                                     [(set f128:$vT,
14085ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
14095ffd83dbSDimitry Andric                                                          (fneg f128:$vTi))))]>;
14105ffd83dbSDimitry Andric
14115ffd83dbSDimitry Andric  let isCommutable = 1 in {
14125ffd83dbSDimitry Andric  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
14135ffd83dbSDimitry Andric                                  [(set f128:$vT,
14145ffd83dbSDimitry Andric                                  (int_ppc_addf128_round_to_odd
14155ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14165ffd83dbSDimitry Andric  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
14175ffd83dbSDimitry Andric                                  [(set f128:$vT,
14185ffd83dbSDimitry Andric                                  (int_ppc_mulf128_round_to_odd
14195ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14205ffd83dbSDimitry Andric  }
14215ffd83dbSDimitry Andric  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
14225ffd83dbSDimitry Andric                                  [(set f128:$vT,
14235ffd83dbSDimitry Andric                                  (int_ppc_subf128_round_to_odd
14245ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14255ffd83dbSDimitry Andric  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
14265ffd83dbSDimitry Andric                                  [(set f128:$vT,
14275ffd83dbSDimitry Andric                                  (int_ppc_divf128_round_to_odd
14285ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
14295ffd83dbSDimitry Andric  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
14305ffd83dbSDimitry Andric                                  [(set f128:$vT,
14315ffd83dbSDimitry Andric                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
14325ffd83dbSDimitry Andric
14335ffd83dbSDimitry Andric
14345ffd83dbSDimitry Andric  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
14355ffd83dbSDimitry Andric                                      [(set f128:$vT,
14365ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
14375ffd83dbSDimitry Andric                                      f128:$vA,f128:$vB,f128:$vTi))]>;
14385ffd83dbSDimitry Andric
14395ffd83dbSDimitry Andric  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
14405ffd83dbSDimitry Andric                                      [(set f128:$vT,
14415ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
14425ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
14435ffd83dbSDimitry Andric  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
14445ffd83dbSDimitry Andric                                      [(set f128:$vT,
14455ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
14465ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
14475ffd83dbSDimitry Andric  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
14485ffd83dbSDimitry Andric                                      [(set f128:$vT,
14495ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
14505ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
14515ffd83dbSDimitry Andric  } // mayRaiseFPException
14525ffd83dbSDimitry Andric
14535ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
14545ffd83dbSDimitry Andric  // QP Compare Ordered/Unordered
14555ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
14565ffd83dbSDimitry Andric    // DP/QP Compare Exponents
14575ffd83dbSDimitry Andric    def XSCMPEXPDP : XX3Form_1<60, 59,
14585ffd83dbSDimitry Andric                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
14595ffd83dbSDimitry Andric                               "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
14605ffd83dbSDimitry Andric    def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
14615ffd83dbSDimitry Andric
1462*e8d8bef9SDimitry Andric    let mayRaiseFPException = 1 in {
1463*e8d8bef9SDimitry Andric    def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1464*e8d8bef9SDimitry Andric    def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1465*e8d8bef9SDimitry Andric
14665ffd83dbSDimitry Andric    // DP Compare ==, >=, >, !=
14675ffd83dbSDimitry Andric    // Use vsrc for XT, because the entire register of XT is set.
14685ffd83dbSDimitry Andric    // XT.dword[1] = 0x0000_0000_0000_0000
14695ffd83dbSDimitry Andric    def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
14705ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14715ffd83dbSDimitry Andric    def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
14725ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14735ffd83dbSDimitry Andric    def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
14745ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
14755ffd83dbSDimitry Andric    }
1476*e8d8bef9SDimitry Andric  }
14775ffd83dbSDimitry Andric
14785ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
14795ffd83dbSDimitry Andric  // Quad-Precision Floating-Point Conversion Instructions:
14805ffd83dbSDimitry Andric
14815ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
14825ffd83dbSDimitry Andric    // Convert DP -> QP
14835ffd83dbSDimitry Andric    def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
14845ffd83dbSDimitry Andric                                       [(set f128:$vT, (any_fpextend f64:$vB))]>;
14855ffd83dbSDimitry Andric
14865ffd83dbSDimitry Andric    // Round & Convert QP -> DP (dword[1] is set to zero)
14875ffd83dbSDimitry Andric    def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
14885ffd83dbSDimitry Andric    def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
14895ffd83dbSDimitry Andric                                          [(set f64:$vT,
14905ffd83dbSDimitry Andric                                          (int_ppc_truncf128_round_to_odd
14915ffd83dbSDimitry Andric                                          f128:$vB))]>;
14925ffd83dbSDimitry Andric  }
14935ffd83dbSDimitry Andric
14945ffd83dbSDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
1495*e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
14965ffd83dbSDimitry Andric    def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
14975ffd83dbSDimitry Andric    def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
14985ffd83dbSDimitry Andric    def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
14995ffd83dbSDimitry Andric    def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
15005ffd83dbSDimitry Andric  }
15015ffd83dbSDimitry Andric
15025ffd83dbSDimitry Andric  // Convert (Un)Signed DWord -> QP.
15035ffd83dbSDimitry Andric  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
15045ffd83dbSDimitry Andric  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
15055ffd83dbSDimitry Andric
15065ffd83dbSDimitry Andric  // (Round &) Convert DP <-> HP
15075ffd83dbSDimitry Andric  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
15085ffd83dbSDimitry Andric  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
15095ffd83dbSDimitry Andric  // but we still use vsfrc for it.
15105ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1511*e8d8bef9SDimitry Andric  let hasSideEffects = 1, mayRaiseFPException = 1 in {
15125ffd83dbSDimitry Andric    def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
15135ffd83dbSDimitry Andric    def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
15145ffd83dbSDimitry Andric  }
15155ffd83dbSDimitry Andric
1516*e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
15175ffd83dbSDimitry Andric  // Vector HP -> SP
15185ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15195ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15205ffd83dbSDimitry Andric  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
15215ffd83dbSDimitry Andric  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
15225ffd83dbSDimitry Andric                                 [(set v4f32:$XT,
15235ffd83dbSDimitry Andric                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
15245ffd83dbSDimitry Andric
15255ffd83dbSDimitry Andric  // Round to Quad-Precision Integer [with Inexact]
15265ffd83dbSDimitry Andric  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
15275ffd83dbSDimitry Andric  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
15285ffd83dbSDimitry Andric
15295ffd83dbSDimitry Andric  // Round Quad-Precision to Double-Extended Precision (fp80)
15305ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15315ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15325ffd83dbSDimitry Andric  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
1533*e8d8bef9SDimitry Andric  }
15345ffd83dbSDimitry Andric
15355ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
15365ffd83dbSDimitry Andric  // Insert/Extract Instructions
15375ffd83dbSDimitry Andric
15385ffd83dbSDimitry Andric  // Insert Exponent DP/QP
15395ffd83dbSDimitry Andric  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
15405ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15415ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
15425ffd83dbSDimitry Andric    def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
15435ffd83dbSDimitry Andric                            "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
15445ffd83dbSDimitry Andric    // vB NOTE: only vB.dword[0] is used, that's why we don't use
15455ffd83dbSDimitry Andric    //          X_VT5_VA5_VB5 form
15465ffd83dbSDimitry Andric    def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
15475ffd83dbSDimitry Andric                            "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
15485ffd83dbSDimitry Andric  }
15495ffd83dbSDimitry Andric
15505ffd83dbSDimitry Andric  // Extract Exponent/Significand DP/QP
15515ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15525ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
15535ffd83dbSDimitry Andric    def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
15545ffd83dbSDimitry Andric    def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
15555ffd83dbSDimitry Andric
15565ffd83dbSDimitry Andric    def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
15575ffd83dbSDimitry Andric    def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
15585ffd83dbSDimitry Andric  }
15595ffd83dbSDimitry Andric
15605ffd83dbSDimitry Andric  // Vector Insert Word
15615ffd83dbSDimitry Andric  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
15625ffd83dbSDimitry Andric  def XXINSERTW   :
15635ffd83dbSDimitry Andric    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
15645ffd83dbSDimitry Andric                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
15655ffd83dbSDimitry Andric                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
15665ffd83dbSDimitry Andric                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
15675ffd83dbSDimitry Andric                                                   imm32SExt16:$UIM))]>,
15685ffd83dbSDimitry Andric                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
15695ffd83dbSDimitry Andric
15705ffd83dbSDimitry Andric  // Vector Extract Unsigned Word
15715ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15725ffd83dbSDimitry Andric  let hasSideEffects = 1 in
15735ffd83dbSDimitry Andric  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
15745ffd83dbSDimitry Andric                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
15755ffd83dbSDimitry Andric                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
15765ffd83dbSDimitry Andric
15775ffd83dbSDimitry Andric  // Vector Insert Exponent DP/SP
15785ffd83dbSDimitry Andric  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
15795ffd83dbSDimitry Andric    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
15805ffd83dbSDimitry Andric  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
15815ffd83dbSDimitry Andric    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
15825ffd83dbSDimitry Andric
15835ffd83dbSDimitry Andric  // Vector Extract Exponent/Significand DP/SP
15845ffd83dbSDimitry Andric  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
15855ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
15865ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
15875ffd83dbSDimitry Andric  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
15885ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
15895ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
15905ffd83dbSDimitry Andric  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
15915ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
15925ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
15935ffd83dbSDimitry Andric  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
15945ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
15955ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
15965ffd83dbSDimitry Andric
15975ffd83dbSDimitry Andric  // Test Data Class SP/DP/QP
15985ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
15995ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16005ffd83dbSDimitry Andric    def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
16015ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
16025ffd83dbSDimitry Andric                                "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
16035ffd83dbSDimitry Andric    def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
16045ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
16055ffd83dbSDimitry Andric                                "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
16065ffd83dbSDimitry Andric    def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
16075ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
16085ffd83dbSDimitry Andric                                "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
16095ffd83dbSDimitry Andric  }
16105ffd83dbSDimitry Andric
16115ffd83dbSDimitry Andric  // Vector Test Data Class SP/DP
16125ffd83dbSDimitry Andric  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
16135ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
16145ffd83dbSDimitry Andric                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
16155ffd83dbSDimitry Andric                              [(set v4i32: $XT,
16165ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
16175ffd83dbSDimitry Andric  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
16185ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
16195ffd83dbSDimitry Andric                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
16205ffd83dbSDimitry Andric                              [(set v2i64: $XT,
16215ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
16225ffd83dbSDimitry Andric
16235ffd83dbSDimitry Andric  // Maximum/Minimum Type-C/Type-J DP
1624*e8d8bef9SDimitry Andric  let mayRaiseFPException = 1 in {
16255ffd83dbSDimitry Andric  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
16265ffd83dbSDimitry Andric                                 IIC_VecFP,
16275ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
16285ffd83dbSDimitry Andric  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc,
16295ffd83dbSDimitry Andric                                 IIC_VecFP,
16305ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>;
16315ffd83dbSDimitry Andric
16325ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16335ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16345ffd83dbSDimitry Andric    def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
16355ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
16365ffd83dbSDimitry Andric    def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
16375ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
16385ffd83dbSDimitry Andric  }
1639*e8d8bef9SDimitry Andric  }
16405ffd83dbSDimitry Andric
16415ffd83dbSDimitry Andric  // Vector Byte-Reverse H/W/D/Q Word
16425ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16435ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16445ffd83dbSDimitry Andric  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
16455ffd83dbSDimitry Andric  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc,
16465ffd83dbSDimitry Andric    [(set v4i32:$XT, (bswap v4i32:$XB))]>;
16475ffd83dbSDimitry Andric  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc,
16485ffd83dbSDimitry Andric    [(set v2i64:$XT, (bswap v2i64:$XB))]>;
16495ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16505ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16515ffd83dbSDimitry Andric  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
16525ffd83dbSDimitry Andric
16535ffd83dbSDimitry Andric  // Vector Permute
16545ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16555ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
16565ffd83dbSDimitry Andric    def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
16575ffd83dbSDimitry Andric                                  IIC_VecPerm, []>;
16585ffd83dbSDimitry Andric    def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
16595ffd83dbSDimitry Andric                                  IIC_VecPerm, []>;
16605ffd83dbSDimitry Andric  }
16615ffd83dbSDimitry Andric
16625ffd83dbSDimitry Andric  // Vector Splat Immediate Byte
16635ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
16645ffd83dbSDimitry Andric  let hasSideEffects = 1 in
16655ffd83dbSDimitry Andric  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
16665ffd83dbSDimitry Andric                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
16675ffd83dbSDimitry Andric
16685ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
16695ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
16705ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
16715ffd83dbSDimitry Andric  // Load Vector
16725ffd83dbSDimitry Andric  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
16735ffd83dbSDimitry Andric                            "lxv $XT, $src", IIC_LdStLFD, []>;
16745ffd83dbSDimitry Andric  // Load DWord
16755ffd83dbSDimitry Andric  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
16765ffd83dbSDimitry Andric                       "lxsd $vD, $src", IIC_LdStLFD, []>;
16775ffd83dbSDimitry Andric  // Load SP from src, convert it to DP, and place in dword[0]
16785ffd83dbSDimitry Andric  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
16795ffd83dbSDimitry Andric                       "lxssp $vD, $src", IIC_LdStLFD, []>;
16805ffd83dbSDimitry Andric
16815ffd83dbSDimitry Andric  // Load as Integer Byte/Halfword & Zero Indexed
16825ffd83dbSDimitry Andric  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
16835ffd83dbSDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
16845ffd83dbSDimitry Andric  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
16855ffd83dbSDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
16865ffd83dbSDimitry Andric
16875ffd83dbSDimitry Andric  // Load Vector Halfword*8/Byte*16 Indexed
16885ffd83dbSDimitry Andric  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
16895ffd83dbSDimitry Andric  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
16905ffd83dbSDimitry Andric
16915ffd83dbSDimitry Andric  // Load Vector Indexed
16925ffd83dbSDimitry Andric  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
16935ffd83dbSDimitry Andric                [(set v2f64:$XT, (load xaddrX16:$src))]>;
16945ffd83dbSDimitry Andric  // Load Vector (Left-justified) with Length
16955ffd83dbSDimitry Andric  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
16965ffd83dbSDimitry Andric                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
16975ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
16985ffd83dbSDimitry Andric  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
16995ffd83dbSDimitry Andric                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
17005ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
17015ffd83dbSDimitry Andric
17025ffd83dbSDimitry Andric  // Load Vector Word & Splat Indexed
17035ffd83dbSDimitry Andric  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
17045ffd83dbSDimitry Andric  } // mayLoad
17055ffd83dbSDimitry Andric
17065ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
17075ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
17085ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
17095ffd83dbSDimitry Andric  // Store Vector
17105ffd83dbSDimitry Andric  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
17115ffd83dbSDimitry Andric                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
17125ffd83dbSDimitry Andric  // Store DWord
17135ffd83dbSDimitry Andric  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
17145ffd83dbSDimitry Andric                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
17155ffd83dbSDimitry Andric  // Convert DP of dword[0] to SP, and Store to dst
17165ffd83dbSDimitry Andric  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
17175ffd83dbSDimitry Andric                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
17185ffd83dbSDimitry Andric
17195ffd83dbSDimitry Andric  // Store as Integer Byte/Halfword Indexed
17205ffd83dbSDimitry Andric  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
17215ffd83dbSDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
17225ffd83dbSDimitry Andric  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
17235ffd83dbSDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
17245ffd83dbSDimitry Andric  let isCodeGenOnly = 1 in {
17255ffd83dbSDimitry Andric    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
17265ffd83dbSDimitry Andric    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
17275ffd83dbSDimitry Andric  }
17285ffd83dbSDimitry Andric
17295ffd83dbSDimitry Andric  // Store Vector Halfword*8/Byte*16 Indexed
17305ffd83dbSDimitry Andric  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
17315ffd83dbSDimitry Andric  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
17325ffd83dbSDimitry Andric
17335ffd83dbSDimitry Andric  // Store Vector Indexed
17345ffd83dbSDimitry Andric  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
17355ffd83dbSDimitry Andric                 [(store v2f64:$XT, xaddrX16:$dst)]>;
17365ffd83dbSDimitry Andric
17375ffd83dbSDimitry Andric  // Store Vector (Left-justified) with Length
17385ffd83dbSDimitry Andric  def STXVL : XX1Form_memOp<31, 397, (outs),
17395ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
17405ffd83dbSDimitry Andric                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
17415ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
17425ffd83dbSDimitry Andric                              i64:$rB)]>;
17435ffd83dbSDimitry Andric  def STXVLL : XX1Form_memOp<31, 429, (outs),
17445ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
17455ffd83dbSDimitry Andric                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
17465ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
17475ffd83dbSDimitry Andric                              i64:$rB)]>;
17485ffd83dbSDimitry Andric  } // mayStore
17495ffd83dbSDimitry Andric
17505ffd83dbSDimitry Andric  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
17515ffd83dbSDimitry Andric                          "#DFLOADf32",
17525ffd83dbSDimitry Andric                          [(set f32:$XT, (load iaddrX4:$src))]>;
17535ffd83dbSDimitry Andric  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
17545ffd83dbSDimitry Andric                          "#DFLOADf64",
17555ffd83dbSDimitry Andric                          [(set f64:$XT, (load iaddrX4:$src))]>;
17565ffd83dbSDimitry Andric  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
17575ffd83dbSDimitry Andric                          "#DFSTOREf32",
17585ffd83dbSDimitry Andric                          [(store f32:$XT, iaddrX4:$dst)]>;
17595ffd83dbSDimitry Andric  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
17605ffd83dbSDimitry Andric                          "#DFSTOREf64",
17615ffd83dbSDimitry Andric                          [(store f64:$XT, iaddrX4:$dst)]>;
17625ffd83dbSDimitry Andric
17635ffd83dbSDimitry Andric  let mayStore = 1 in {
17645ffd83dbSDimitry Andric    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
17655ffd83dbSDimitry Andric                                          (ins spilltovsrrc:$XT, memrr:$dst),
17665ffd83dbSDimitry Andric                                          "#SPILLTOVSR_STX", []>;
17675ffd83dbSDimitry Andric    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
17685ffd83dbSDimitry Andric                              "#SPILLTOVSR_ST", []>;
17695ffd83dbSDimitry Andric  }
17705ffd83dbSDimitry Andric  let mayLoad = 1 in {
17715ffd83dbSDimitry Andric    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
17725ffd83dbSDimitry Andric                                          (ins memrr:$src),
17735ffd83dbSDimitry Andric                                          "#SPILLTOVSR_LDX", []>;
17745ffd83dbSDimitry Andric    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
17755ffd83dbSDimitry Andric                              "#SPILLTOVSR_LD", []>;
17765ffd83dbSDimitry Andric
17775ffd83dbSDimitry Andric  }
17785ffd83dbSDimitry Andric  } // HasP9Vector
17795ffd83dbSDimitry Andric} // hasSideEffects = 0
17805ffd83dbSDimitry Andric
17815ffd83dbSDimitry Andriclet PPC970_Single = 1, AddedComplexity = 400 in {
17820b57cec5SDimitry Andric
17830b57cec5SDimitry Andric  def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17840b57cec5SDimitry Andric                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
17850b57cec5SDimitry Andric                             "#SELECT_CC_VSRC",
17860b57cec5SDimitry Andric                             []>;
17870b57cec5SDimitry Andric  def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17880b57cec5SDimitry Andric                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
17890b57cec5SDimitry Andric                          "#SELECT_VSRC",
17900b57cec5SDimitry Andric                          [(set v2f64:$dst,
17910b57cec5SDimitry Andric                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
17920b57cec5SDimitry Andric  def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
17930b57cec5SDimitry Andric                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
17940b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
17950b57cec5SDimitry Andric                              []>;
17960b57cec5SDimitry Andric  def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
17970b57cec5SDimitry Andric                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
17980b57cec5SDimitry Andric                           "#SELECT_VSFRC",
17990b57cec5SDimitry Andric                           [(set f64:$dst,
18000b57cec5SDimitry Andric                                 (select i1:$cond, f64:$T, f64:$F))]>;
18010b57cec5SDimitry Andric  def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
18020b57cec5SDimitry Andric                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
18030b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
18040b57cec5SDimitry Andric                              []>;
18050b57cec5SDimitry Andric  def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
18060b57cec5SDimitry Andric                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
18070b57cec5SDimitry Andric                           "#SELECT_VSSRC",
18080b57cec5SDimitry Andric                           [(set f32:$dst,
18090b57cec5SDimitry Andric                                 (select i1:$cond, f32:$T, f32:$F))]>;
18100b57cec5SDimitry Andric}
18110b57cec5SDimitry Andric}
18120b57cec5SDimitry Andric
18135ffd83dbSDimitry Andric//----------------------------- DAG Definitions ------------------------------//
1814480093f4SDimitry Andricdef FpMinMax {
1815480093f4SDimitry Andric  dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC),
1816480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1817480093f4SDimitry Andric                                 VSSRC);
1818480093f4SDimitry Andric  dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC),
1819480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1820480093f4SDimitry Andric                                 VSSRC);
1821480093f4SDimitry Andric}
1822480093f4SDimitry Andric
18230b57cec5SDimitry Andricdef ScalarLoads {
18240b57cec5SDimitry Andric  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
18250b57cec5SDimitry Andric  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
18260b57cec5SDimitry Andric  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
18270b57cec5SDimitry Andric  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
18280b57cec5SDimitry Andric  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
18290b57cec5SDimitry Andric
18300b57cec5SDimitry Andric  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
18310b57cec5SDimitry Andric  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
18320b57cec5SDimitry Andric  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
18330b57cec5SDimitry Andric  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
18340b57cec5SDimitry Andric  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
18350b57cec5SDimitry Andric
18360b57cec5SDimitry Andric  dag Li32 = (i32 (load xoaddr:$src));
18370b57cec5SDimitry Andric}
18380b57cec5SDimitry Andric
18390b57cec5SDimitry Andricdef DWToSPExtractConv {
18400b57cec5SDimitry Andric  dag El0US1 = (f32 (PPCfcfidus
18410b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18420b57cec5SDimitry Andric  dag El1US1 = (f32 (PPCfcfidus
18430b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18440b57cec5SDimitry Andric  dag El0US2 = (f32 (PPCfcfidus
18450b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18460b57cec5SDimitry Andric  dag El1US2 = (f32 (PPCfcfidus
18470b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18480b57cec5SDimitry Andric  dag El0SS1 = (f32 (PPCfcfids
18490b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18500b57cec5SDimitry Andric  dag El1SS1 = (f32 (PPCfcfids
18510b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18520b57cec5SDimitry Andric  dag El0SS2 = (f32 (PPCfcfids
18530b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18540b57cec5SDimitry Andric  dag El1SS2 = (f32 (PPCfcfids
18550b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18560b57cec5SDimitry Andric  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
18570b57cec5SDimitry Andric  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
18580b57cec5SDimitry Andric}
18590b57cec5SDimitry Andric
18605ffd83dbSDimitry Andricdef WToDPExtractConv {
18615ffd83dbSDimitry Andric  dag El0S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 0))));
18625ffd83dbSDimitry Andric  dag El1S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 1))));
18635ffd83dbSDimitry Andric  dag El2S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 2))));
18645ffd83dbSDimitry Andric  dag El3S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 3))));
18655ffd83dbSDimitry Andric  dag El0U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 0))));
18665ffd83dbSDimitry Andric  dag El1U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 1))));
18675ffd83dbSDimitry Andric  dag El2U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 2))));
18685ffd83dbSDimitry Andric  dag El3U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 3))));
18695ffd83dbSDimitry Andric  dag BV02S = (v2f64 (build_vector El0S, El2S));
18705ffd83dbSDimitry Andric  dag BV13S = (v2f64 (build_vector El1S, El3S));
18715ffd83dbSDimitry Andric  dag BV02U = (v2f64 (build_vector El0U, El2U));
18725ffd83dbSDimitry Andric  dag BV13U = (v2f64 (build_vector El1U, El3U));
18738bcb0991SDimitry Andric}
18748bcb0991SDimitry Andric
18750b57cec5SDimitry Andric/*  Direct moves of various widths from GPR's into VSR's. Each move lines
18760b57cec5SDimitry Andric    the value up into element 0 (both BE and LE). Namely, entities smaller than
18770b57cec5SDimitry Andric    a doubleword are shifted left and moved for BE. For LE, they're moved, then
18780b57cec5SDimitry Andric    swapped to go into the least significant element of the VSR.
18790b57cec5SDimitry Andric*/
18800b57cec5SDimitry Andricdef MovesToVSR {
18810b57cec5SDimitry Andric  dag BE_BYTE_0 =
18820b57cec5SDimitry Andric    (MTVSRD
18830b57cec5SDimitry Andric      (RLDICR
18840b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
18850b57cec5SDimitry Andric  dag BE_HALF_0 =
18860b57cec5SDimitry Andric    (MTVSRD
18870b57cec5SDimitry Andric      (RLDICR
18880b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
18890b57cec5SDimitry Andric  dag BE_WORD_0 =
18900b57cec5SDimitry Andric    (MTVSRD
18910b57cec5SDimitry Andric      (RLDICR
18920b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
18930b57cec5SDimitry Andric  dag BE_DWORD_0 = (MTVSRD $A);
18940b57cec5SDimitry Andric
18950b57cec5SDimitry Andric  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
18960b57cec5SDimitry Andric  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
18970b57cec5SDimitry Andric                                        LE_MTVSRW, sub_64));
18980b57cec5SDimitry Andric  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
18990b57cec5SDimitry Andric  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
19000b57cec5SDimitry Andric                                         BE_DWORD_0, sub_64));
19010b57cec5SDimitry Andric  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
19020b57cec5SDimitry Andric}
19030b57cec5SDimitry Andric
19040b57cec5SDimitry Andric/*  Patterns for extracting elements out of vectors. Integer elements are
19050b57cec5SDimitry Andric    extracted using direct move operations. Patterns for extracting elements
19060b57cec5SDimitry Andric    whose indices are not available at compile time are also provided with
19070b57cec5SDimitry Andric    various _VARIABLE_ patterns.
19080b57cec5SDimitry Andric    The numbering for the DAG's is for LE, but when used on BE, the correct
19090b57cec5SDimitry Andric    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
19100b57cec5SDimitry Andric*/
19110b57cec5SDimitry Andricdef VectorExtractions {
19120b57cec5SDimitry Andric  // Doubleword extraction
19130b57cec5SDimitry Andric  dag LE_DWORD_0 =
19140b57cec5SDimitry Andric    (MFVSRD
19150b57cec5SDimitry Andric      (EXTRACT_SUBREG
19160b57cec5SDimitry Andric        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
19170b57cec5SDimitry Andric                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
19180b57cec5SDimitry Andric  dag LE_DWORD_1 = (MFVSRD
19190b57cec5SDimitry Andric                     (EXTRACT_SUBREG
19200b57cec5SDimitry Andric                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19210b57cec5SDimitry Andric
19220b57cec5SDimitry Andric  // Word extraction
19230b57cec5SDimitry Andric  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
19240b57cec5SDimitry Andric  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
19250b57cec5SDimitry Andric  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
19260b57cec5SDimitry Andric                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19270b57cec5SDimitry Andric  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
19280b57cec5SDimitry Andric
19290b57cec5SDimitry Andric  // Halfword extraction
19300b57cec5SDimitry Andric  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
19310b57cec5SDimitry Andric  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
19320b57cec5SDimitry Andric  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
19330b57cec5SDimitry Andric  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
19340b57cec5SDimitry Andric  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
19350b57cec5SDimitry Andric  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
19360b57cec5SDimitry Andric  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
19370b57cec5SDimitry Andric  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andric  // Byte extraction
19400b57cec5SDimitry Andric  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
19410b57cec5SDimitry Andric  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
19420b57cec5SDimitry Andric  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
19430b57cec5SDimitry Andric  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
19440b57cec5SDimitry Andric  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
19450b57cec5SDimitry Andric  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
19460b57cec5SDimitry Andric  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
19470b57cec5SDimitry Andric  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
19480b57cec5SDimitry Andric  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
19490b57cec5SDimitry Andric  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
19500b57cec5SDimitry Andric  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
19510b57cec5SDimitry Andric  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
19520b57cec5SDimitry Andric  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
19530b57cec5SDimitry Andric  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
19540b57cec5SDimitry Andric  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
19550b57cec5SDimitry Andric  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric  /* Variable element number (BE and LE patterns must be specified separately)
19580b57cec5SDimitry Andric     This is a rather involved process.
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric     Conceptually, this is how the move is accomplished:
19610b57cec5SDimitry Andric     1. Identify which doubleword contains the element
19620b57cec5SDimitry Andric     2. Shift in the VMX register so that the correct doubleword is correctly
19630b57cec5SDimitry Andric        lined up for the MFVSRD
19640b57cec5SDimitry Andric     3. Perform the move so that the element (along with some extra stuff)
19650b57cec5SDimitry Andric        is in the GPR
19660b57cec5SDimitry Andric     4. Right shift within the GPR so that the element is right-justified
19670b57cec5SDimitry Andric
19680b57cec5SDimitry Andric     Of course, the index is an element number which has a different meaning
19690b57cec5SDimitry Andric     on LE/BE so the patterns have to be specified separately.
19700b57cec5SDimitry Andric
19710b57cec5SDimitry Andric     Note: The final result will be the element right-justified with high
19720b57cec5SDimitry Andric           order bits being arbitrarily defined (namely, whatever was in the
19730b57cec5SDimitry Andric           vector register to the left of the value originally).
19740b57cec5SDimitry Andric  */
19750b57cec5SDimitry Andric
19760b57cec5SDimitry Andric  /*  LE variable byte
19770b57cec5SDimitry Andric      Number 1. above:
19780b57cec5SDimitry Andric      - For elements 0-7, we shift left by 8 bytes since they're on the right
19790b57cec5SDimitry Andric      - For elements 8-15, we need not shift (shift left by zero bytes)
19800b57cec5SDimitry Andric      This is accomplished by inverting the bits of the index and AND-ing
19810b57cec5SDimitry Andric      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
19820b57cec5SDimitry Andric  */
19830b57cec5SDimitry Andric  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
19840b57cec5SDimitry Andric
19850b57cec5SDimitry Andric  //  Number 2. above:
19860b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
19870b57cec5SDimitry Andric  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
19880b57cec5SDimitry Andric
19890b57cec5SDimitry Andric  //  Number 3. above:
19900b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
19910b57cec5SDimitry Andric  dag LE_MV_VBYTE = (MFVSRD
19920b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19930b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
19940b57cec5SDimitry Andric                        sub_64));
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andric  /*  Number 4. above:
19970b57cec5SDimitry Andric      - Truncate the element number to the range 0-7 (8-15 are symmetrical
19980b57cec5SDimitry Andric        and out of range values are truncated accordingly)
19990b57cec5SDimitry Andric      - Multiply by 8 as we need to shift right by the number of bits, not bytes
20000b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20010b57cec5SDimitry Andric  */
20020b57cec5SDimitry Andric  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
20030b57cec5SDimitry Andric                                       sub_32);
20040b57cec5SDimitry Andric  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
20050b57cec5SDimitry Andric                                         sub_32);
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andric  /*  LE variable halfword
20080b57cec5SDimitry Andric      Number 1. above:
20090b57cec5SDimitry Andric      - For elements 0-3, we shift left by 8 since they're on the right
20100b57cec5SDimitry Andric      - For elements 4-7, we need not shift (shift left by zero bytes)
20110b57cec5SDimitry Andric      Similarly to the byte pattern, we invert the bits of the index, but we
20120b57cec5SDimitry Andric      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
20130b57cec5SDimitry Andric      Of course, the shift is still by 8 bytes, so we must multiply by 2.
20140b57cec5SDimitry Andric  */
20150b57cec5SDimitry Andric  dag LE_VHALF_PERM_VEC =
20160b57cec5SDimitry Andric    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andric  //  Number 2. above:
20190b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20200b57cec5SDimitry Andric  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
20210b57cec5SDimitry Andric
20220b57cec5SDimitry Andric  //  Number 3. above:
20230b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20240b57cec5SDimitry Andric  dag LE_MV_VHALF = (MFVSRD
20250b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20260b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
20270b57cec5SDimitry Andric                        sub_64));
20280b57cec5SDimitry Andric
20290b57cec5SDimitry Andric  /*  Number 4. above:
20300b57cec5SDimitry Andric      - Truncate the element number to the range 0-3 (4-7 are symmetrical
20310b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20320b57cec5SDimitry Andric      - Multiply by 16 as we need to shift right by the number of bits
20330b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20340b57cec5SDimitry Andric  */
20350b57cec5SDimitry Andric  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
20360b57cec5SDimitry Andric                                       sub_32);
20370b57cec5SDimitry Andric  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
20380b57cec5SDimitry Andric                                         sub_32);
20390b57cec5SDimitry Andric
20400b57cec5SDimitry Andric  /*  LE variable word
20410b57cec5SDimitry Andric      Number 1. above:
20420b57cec5SDimitry Andric      - For elements 0-1, we shift left by 8 since they're on the right
20430b57cec5SDimitry Andric      - For elements 2-3, we need not shift
20440b57cec5SDimitry Andric  */
20450b57cec5SDimitry Andric  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20460b57cec5SDimitry Andric                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
20470b57cec5SDimitry Andric
20480b57cec5SDimitry Andric  //  Number 2. above:
20490b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20500b57cec5SDimitry Andric  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
20510b57cec5SDimitry Andric
20520b57cec5SDimitry Andric  //  Number 3. above:
20530b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20540b57cec5SDimitry Andric  dag LE_MV_VWORD = (MFVSRD
20550b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20560b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
20570b57cec5SDimitry Andric                        sub_64));
20580b57cec5SDimitry Andric
20590b57cec5SDimitry Andric  /*  Number 4. above:
20600b57cec5SDimitry Andric      - Truncate the element number to the range 0-1 (2-3 are symmetrical
20610b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20620b57cec5SDimitry Andric      - Multiply by 32 as we need to shift right by the number of bits
20630b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20640b57cec5SDimitry Andric  */
20650b57cec5SDimitry Andric  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
20660b57cec5SDimitry Andric                                       sub_32);
20670b57cec5SDimitry Andric  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
20680b57cec5SDimitry Andric                                         sub_32);
20690b57cec5SDimitry Andric
20700b57cec5SDimitry Andric  /*  LE variable doubleword
20710b57cec5SDimitry Andric      Number 1. above:
20720b57cec5SDimitry Andric      - For element 0, we shift left by 8 since it's on the right
20730b57cec5SDimitry Andric      - For element 1, we need not shift
20740b57cec5SDimitry Andric  */
20750b57cec5SDimitry Andric  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20760b57cec5SDimitry Andric                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
20770b57cec5SDimitry Andric
20780b57cec5SDimitry Andric  //  Number 2. above:
20790b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20800b57cec5SDimitry Andric  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
20810b57cec5SDimitry Andric
20820b57cec5SDimitry Andric  // Number 3. above:
20830b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20840b57cec5SDimitry Andric  //  - Number 4. is not needed for the doubleword as the value is 64-bits
20850b57cec5SDimitry Andric  dag LE_VARIABLE_DWORD =
20860b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
20870b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
20880b57cec5SDimitry Andric                  sub_64));
20890b57cec5SDimitry Andric
20900b57cec5SDimitry Andric  /*  LE variable float
20910b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
20920b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
20930b57cec5SDimitry Andric  */
20940b57cec5SDimitry Andric  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
20950b57cec5SDimitry Andric                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
20960b57cec5SDimitry Andric  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
20970b57cec5SDimitry Andric  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
20980b57cec5SDimitry Andric
20990b57cec5SDimitry Andric  /*  LE variable double
21000b57cec5SDimitry Andric      Same as the LE doubleword except there is no move.
21010b57cec5SDimitry Andric  */
21020b57cec5SDimitry Andric  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21030b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21040b57cec5SDimitry Andric                                         LE_VDWORD_PERM_VEC));
21050b57cec5SDimitry Andric  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
21060b57cec5SDimitry Andric
21070b57cec5SDimitry Andric  /*  BE variable byte
21080b57cec5SDimitry Andric      The algorithm here is the same as the LE variable byte except:
21090b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
21100b57cec5SDimitry Andric        we simply AND the element number with 0x8
21110b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21120b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-7
21130b57cec5SDimitry Andric  */
2114480093f4SDimitry Andric  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8)));
21150b57cec5SDimitry Andric  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
21160b57cec5SDimitry Andric  dag BE_MV_VBYTE = (MFVSRD
21170b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21180b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
21190b57cec5SDimitry Andric                        sub_64));
21200b57cec5SDimitry Andric  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
21210b57cec5SDimitry Andric                                       sub_32);
21220b57cec5SDimitry Andric  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
21230b57cec5SDimitry Andric                                         sub_32);
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andric  /*  BE variable halfword
21260b57cec5SDimitry Andric      The algorithm here is the same as the LE variable halfword except:
21270b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
21280b57cec5SDimitry Andric        we simply AND the element number with 0x4 and multiply by 2
21290b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21300b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-3
21310b57cec5SDimitry Andric  */
21320b57cec5SDimitry Andric  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
2133480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 4), 1, 62)));
21340b57cec5SDimitry Andric  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
21350b57cec5SDimitry Andric  dag BE_MV_VHALF = (MFVSRD
21360b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21370b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
21380b57cec5SDimitry Andric                        sub_64));
21390b57cec5SDimitry Andric  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
21400b57cec5SDimitry Andric                                       sub_32);
21410b57cec5SDimitry Andric  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
21420b57cec5SDimitry Andric                                         sub_32);
21430b57cec5SDimitry Andric
21440b57cec5SDimitry Andric  /*  BE variable word
21450b57cec5SDimitry Andric      The algorithm is the same as the LE variable word except:
21460b57cec5SDimitry Andric      - The shift in the VMX register happens for opposite element numbers
21470b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21480b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-1
21490b57cec5SDimitry Andric  */
21500b57cec5SDimitry Andric  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2151480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 2), 2, 61)));
21520b57cec5SDimitry Andric  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
21530b57cec5SDimitry Andric  dag BE_MV_VWORD = (MFVSRD
21540b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21550b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
21560b57cec5SDimitry Andric                        sub_64));
21570b57cec5SDimitry Andric  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
21580b57cec5SDimitry Andric                                       sub_32);
21590b57cec5SDimitry Andric  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
21600b57cec5SDimitry Andric                                         sub_32);
21610b57cec5SDimitry Andric
21620b57cec5SDimitry Andric  /*  BE variable doubleword
21630b57cec5SDimitry Andric      Same as the LE doubleword except we shift in the VMX register for opposite
21640b57cec5SDimitry Andric      element indices.
21650b57cec5SDimitry Andric  */
21660b57cec5SDimitry Andric  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2167480093f4SDimitry Andric                                        (RLDICR (ANDI8_rec $Idx, 1), 3, 60)));
21680b57cec5SDimitry Andric  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
21690b57cec5SDimitry Andric  dag BE_VARIABLE_DWORD =
21700b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
21710b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
21720b57cec5SDimitry Andric                  sub_64));
21730b57cec5SDimitry Andric
21740b57cec5SDimitry Andric  /*  BE variable float
21750b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
21760b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
21770b57cec5SDimitry Andric  */
21780b57cec5SDimitry Andric  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
21790b57cec5SDimitry Andric  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
21800b57cec5SDimitry Andric  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
21810b57cec5SDimitry Andric
21820b57cec5SDimitry Andric  /* BE variable double
21830b57cec5SDimitry Andric      Same as the BE doubleword except there is no move.
21840b57cec5SDimitry Andric  */
21850b57cec5SDimitry Andric  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21860b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21870b57cec5SDimitry Andric                                         BE_VDWORD_PERM_VEC));
21880b57cec5SDimitry Andric  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
21890b57cec5SDimitry Andric}
21900b57cec5SDimitry Andric
21910b57cec5SDimitry Andricdef AlignValues {
21920b57cec5SDimitry Andric  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
21930b57cec5SDimitry Andric  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
21940b57cec5SDimitry Andric}
21950b57cec5SDimitry Andric
21960b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64
21970b57cec5SDimitry Andricdef AnyExts {
21980b57cec5SDimitry Andric  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
21990b57cec5SDimitry Andric  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
22000b57cec5SDimitry Andric  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
22010b57cec5SDimitry Andric  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
22020b57cec5SDimitry Andric}
22030b57cec5SDimitry Andric
22040b57cec5SDimitry Andricdef DblToFlt {
22055ffd83dbSDimitry Andric  dag A0 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 0))));
22065ffd83dbSDimitry Andric  dag A1 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 1))));
22075ffd83dbSDimitry Andric  dag B0 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 0))));
22085ffd83dbSDimitry Andric  dag B1 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 1))));
22090b57cec5SDimitry Andric}
22100b57cec5SDimitry Andric
22110b57cec5SDimitry Andricdef ExtDbl {
22120b57cec5SDimitry Andric  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
22130b57cec5SDimitry Andric  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
22140b57cec5SDimitry Andric  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
22150b57cec5SDimitry Andric  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
22160b57cec5SDimitry Andric  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
22170b57cec5SDimitry Andric  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
22180b57cec5SDimitry Andric  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
22190b57cec5SDimitry Andric  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
22200b57cec5SDimitry Andric}
22210b57cec5SDimitry Andric
22220b57cec5SDimitry Andricdef ByteToWord {
22230b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
22240b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
22250b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
22260b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
22270b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
22280b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
22290b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
22300b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
22310b57cec5SDimitry Andric}
22320b57cec5SDimitry Andric
22330b57cec5SDimitry Andricdef ByteToDWord {
22340b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22350b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
22360b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22370b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
22380b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22390b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
22400b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22410b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
22420b57cec5SDimitry Andric}
22430b57cec5SDimitry Andric
22440b57cec5SDimitry Andricdef HWordToWord {
22450b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
22460b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
22470b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
22480b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
22490b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
22500b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
22510b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
22520b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
22530b57cec5SDimitry Andric}
22540b57cec5SDimitry Andric
22550b57cec5SDimitry Andricdef HWordToDWord {
22560b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22570b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
22580b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22590b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
22600b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22610b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
22620b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22630b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
22640b57cec5SDimitry Andric}
22650b57cec5SDimitry Andric
22660b57cec5SDimitry Andricdef WordToDWord {
22670b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
22680b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
22690b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
22700b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
22710b57cec5SDimitry Andric}
22720b57cec5SDimitry Andric
22730b57cec5SDimitry Andricdef FltToIntLoad {
22740b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
22750b57cec5SDimitry Andric}
22760b57cec5SDimitry Andricdef FltToUIntLoad {
22770b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
22780b57cec5SDimitry Andric}
22790b57cec5SDimitry Andricdef FltToLongLoad {
22800b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
22810b57cec5SDimitry Andric}
22820b57cec5SDimitry Andricdef FltToLongLoadP9 {
22830b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A)))));
22840b57cec5SDimitry Andric}
22850b57cec5SDimitry Andricdef FltToULongLoad {
22860b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
22870b57cec5SDimitry Andric}
22880b57cec5SDimitry Andricdef FltToULongLoadP9 {
22890b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A)))));
22900b57cec5SDimitry Andric}
22910b57cec5SDimitry Andricdef FltToLong {
22920b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
22930b57cec5SDimitry Andric}
22940b57cec5SDimitry Andricdef FltToULong {
22950b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
22960b57cec5SDimitry Andric}
22970b57cec5SDimitry Andricdef DblToInt {
22980b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
22990b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
23000b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
23010b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
23020b57cec5SDimitry Andric}
23030b57cec5SDimitry Andricdef DblToUInt {
23040b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
23050b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
23060b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
23070b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
23080b57cec5SDimitry Andric}
23090b57cec5SDimitry Andricdef DblToLong {
23100b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
23110b57cec5SDimitry Andric}
23120b57cec5SDimitry Andricdef DblToULong {
23130b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
23140b57cec5SDimitry Andric}
23150b57cec5SDimitry Andricdef DblToIntLoad {
23160b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
23170b57cec5SDimitry Andric}
23180b57cec5SDimitry Andricdef DblToIntLoadP9 {
23190b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A)))));
23200b57cec5SDimitry Andric}
23210b57cec5SDimitry Andricdef DblToUIntLoad {
23220b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
23230b57cec5SDimitry Andric}
23240b57cec5SDimitry Andricdef DblToUIntLoadP9 {
23250b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A)))));
23260b57cec5SDimitry Andric}
23270b57cec5SDimitry Andricdef DblToLongLoad {
23280b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
23290b57cec5SDimitry Andric}
23300b57cec5SDimitry Andricdef DblToULongLoad {
23310b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
23320b57cec5SDimitry Andric}
23330b57cec5SDimitry Andric
2334480093f4SDimitry Andric// FP load dags (for f32 -> v4f32)
2335480093f4SDimitry Andricdef LoadFP {
2336480093f4SDimitry Andric  dag A = (f32 (load xoaddr:$A));
2337480093f4SDimitry Andric  dag B = (f32 (load xoaddr:$B));
2338480093f4SDimitry Andric  dag C = (f32 (load xoaddr:$C));
2339480093f4SDimitry Andric  dag D = (f32 (load xoaddr:$D));
2340480093f4SDimitry Andric}
2341480093f4SDimitry Andric
23420b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32)
23430b57cec5SDimitry Andricdef MrgFP {
2344480093f4SDimitry Andric  dag LD32A = (COPY_TO_REGCLASS (LIWZX xoaddr:$A), VSRC);
2345480093f4SDimitry Andric  dag LD32B = (COPY_TO_REGCLASS (LIWZX xoaddr:$B), VSRC);
2346480093f4SDimitry Andric  dag LD32C = (COPY_TO_REGCLASS (LIWZX xoaddr:$C), VSRC);
2347480093f4SDimitry Andric  dag LD32D = (COPY_TO_REGCLASS (LIWZX xoaddr:$D), VSRC);
23480b57cec5SDimitry Andric  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
23490b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $C, VSRC), 0));
23500b57cec5SDimitry Andric  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
23510b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $D, VSRC), 0));
23520b57cec5SDimitry Andric  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
23530b57cec5SDimitry Andric  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
23540b57cec5SDimitry Andric  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
23550b57cec5SDimitry Andric  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
23560b57cec5SDimitry Andric}
23570b57cec5SDimitry Andric
23580b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors.
23590b57cec5SDimitry Andricdef MrgWords {
23600b57cec5SDimitry Andric  // For big endian, we merge low and hi doublewords (A, B).
23610b57cec5SDimitry Andric  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
23620b57cec5SDimitry Andric  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
23630b57cec5SDimitry Andric  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
23640b57cec5SDimitry Andric  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
23650b57cec5SDimitry Andric  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
23660b57cec5SDimitry Andric  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
23670b57cec5SDimitry Andric
23680b57cec5SDimitry Andric  // For little endian, we merge low and hi doublewords (B, A).
23690b57cec5SDimitry Andric  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
23700b57cec5SDimitry Andric  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
23710b57cec5SDimitry Andric  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
23720b57cec5SDimitry Andric  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
23730b57cec5SDimitry Andric  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
23740b57cec5SDimitry Andric  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
23750b57cec5SDimitry Andric
23760b57cec5SDimitry Andric  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
23770b57cec5SDimitry Andric  // then merge.
23780b57cec5SDimitry Andric  dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
23790b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$C, VSRC), 0));
23800b57cec5SDimitry Andric  dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
23810b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$D, VSRC), 0));
23820b57cec5SDimitry Andric  dag CVACS = (v4i32 (XVCVDPSXWS AC));
23830b57cec5SDimitry Andric  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
23840b57cec5SDimitry Andric  dag CVACU = (v4i32 (XVCVDPUXWS AC));
23850b57cec5SDimitry Andric  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
23860b57cec5SDimitry Andric
23870b57cec5SDimitry Andric  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
23880b57cec5SDimitry Andric  // then merge.
23890b57cec5SDimitry Andric  dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
23900b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$B, VSRC), 0));
23910b57cec5SDimitry Andric  dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
23920b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$A, VSRC), 0));
23930b57cec5SDimitry Andric  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
23940b57cec5SDimitry Andric  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
23950b57cec5SDimitry Andric  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
23960b57cec5SDimitry Andric  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
23970b57cec5SDimitry Andric}
23980b57cec5SDimitry Andric
23995ffd83dbSDimitry Andric//---------------------------- Anonymous Patterns ----------------------------//
24005ffd83dbSDimitry Andric// Predicate combinations are kept in roughly chronological order in terms of
24015ffd83dbSDimitry Andric// instruction availability in the architecture. For example, VSX came in with
24025ffd83dbSDimitry Andric// ISA 2.06 (Power7). There have since been additions in ISA 2.07 (Power8) and
24035ffd83dbSDimitry Andric// ISA 3.0 (Power9). However, the granularity of features on later subtargets
24045ffd83dbSDimitry Andric// is finer for various reasons. For example, we have Power8Vector,
24055ffd83dbSDimitry Andric// Power8Altivec, DirectMove that all came in with ISA 2.07. The situation is
24065ffd83dbSDimitry Andric// similar with ISA 3.0 with Power9Vector, Power9Altivec, IsISA3_0. Then there
24075ffd83dbSDimitry Andric// are orthogonal predicates such as endianness for which the order was
24085ffd83dbSDimitry Andric// arbitrarily chosen to be Big, Little.
24095ffd83dbSDimitry Andric//
24105ffd83dbSDimitry Andric// Predicate combinations available:
2411*e8d8bef9SDimitry Andric// [HasVSX, IsLittleEndian, HasP8Altivec] Altivec patterns using VSX instr.
2412*e8d8bef9SDimitry Andric// [HasVSX, IsBigEndian, HasP8Altivec] Altivec patterns using VSX instr.
24135ffd83dbSDimitry Andric// [HasVSX]
24145ffd83dbSDimitry Andric// [HasVSX, IsBigEndian]
24155ffd83dbSDimitry Andric// [HasVSX, IsLittleEndian]
24165ffd83dbSDimitry Andric// [HasVSX, NoP9Vector]
2417*e8d8bef9SDimitry Andric// [HasVSX, NoP9Vector, IsLittleEndian]
24185ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps]
24195ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps, IsBigEndian]
24205ffd83dbSDimitry Andric// [HasVSX, HasP8Vector]
2421*e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian, IsPPC64]
24225ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, IsLittleEndian]
2423*e8d8bef9SDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64]
24245ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian]
24255ffd83dbSDimitry Andric// [HasVSX, HasDirectMove]
24265ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsBigEndian]
24275ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsLittleEndian]
2428*e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian, IsPPC64]
2429*e8d8bef9SDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64]
24305ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian]
24315ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian]
24325ffd83dbSDimitry Andric// [HasVSX, HasP9Vector]
2433*e8d8bef9SDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian, IsPPC64]
24345ffd83dbSDimitry Andric// [HasVSX, HasP9Vector, IsLittleEndian]
24355ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec]
2436*e8d8bef9SDimitry Andric// [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64]
24375ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec, IsLittleEndian]
2438*e8d8bef9SDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64]
24395ffd83dbSDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian]
24400b57cec5SDimitry Andric
2441*e8d8bef9SDimitry Andric// These Altivec patterns are here because we need a VSX instruction to match
2442*e8d8bef9SDimitry Andric// the intrinsic (but only for little endian system).
2443*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsLittleEndian, HasP8Altivec] in
2444*e8d8bef9SDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
2445*e8d8bef9SDimitry Andric                                                    v16i8:$b, v16i8:$c)),
2446*e8d8bef9SDimitry Andric            (v16i8 (VPERMXOR $a, $b, (XXLNOR (COPY_TO_REGCLASS $c, VSRC),
2447*e8d8bef9SDimitry Andric                                             (COPY_TO_REGCLASS $c, VSRC))))>;
2448*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsBigEndian, HasP8Altivec] in
2449*e8d8bef9SDimitry Andric  def : Pat<(v16i8 (int_ppc_altivec_crypto_vpermxor v16i8:$a,
2450*e8d8bef9SDimitry Andric                                                    v16i8:$b, v16i8:$c)),
2451*e8d8bef9SDimitry Andric            (v16i8 (VPERMXOR $a, $b, $c))>;
2452*e8d8bef9SDimitry Andric
24535ffd83dbSDimitry Andriclet AddedComplexity = 400 in {
24545ffd83dbSDimitry Andric// Valid for any VSX subtarget, regardless of endianness.
24550b57cec5SDimitry Andriclet Predicates = [HasVSX] in {
24565ffd83dbSDimitry Andricdef : Pat<(v4i32 (vnot_ppc v4i32:$A)),
24575ffd83dbSDimitry Andric          (v4i32 (XXLNOR $A, $A))>;
24585ffd83dbSDimitry Andricdef : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A),
24595ffd83dbSDimitry Andric                     (and v4i32:$B, v4i32:$C))),
24605ffd83dbSDimitry Andric          (v4i32 (XXSEL $A, $B, $C))>;
24615ffd83dbSDimitry Andric
24625ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
24635ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
24645ffd83dbSDimitry Andric          (XSNMSUBADP $C, $A, $B)>;
24655ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
24665ffd83dbSDimitry Andric          (XSMSUBADP $C, $A, $B)>;
24675ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
24685ffd83dbSDimitry Andric          (XSNMADDADP $C, $A, $B)>;
24695ffd83dbSDimitry Andric
24705ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C),
24715ffd83dbSDimitry Andric          (XVNMSUBADP $C, $A, $B)>;
24725ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)),
24735ffd83dbSDimitry Andric          (XVMSUBADP $C, $A, $B)>;
24745ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)),
24755ffd83dbSDimitry Andric          (XVNMADDADP $C, $A, $B)>;
24765ffd83dbSDimitry Andric
24775ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C),
24785ffd83dbSDimitry Andric          (XVNMSUBASP $C, $A, $B)>;
24795ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
24805ffd83dbSDimitry Andric          (XVMSUBASP $C, $A, $B)>;
24815ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
24825ffd83dbSDimitry Andric          (XVNMADDASP $C, $A, $B)>;
24835ffd83dbSDimitry Andric
2484*e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt f64:$frA), (XSSQRTDP $frA)>;
2485*e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v2f64:$frA), (XVSQRTDP $frA)>;
2486*e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt v4f32:$frA), (XVSQRTSP $frA)>;
2487*e8d8bef9SDimitry Andric
24885ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)),
24895ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
24905ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)),
24915ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
24925ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)),
24935ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
24945ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)),
24955ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
24965ffd83dbSDimitry Andric
24975ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)),
24985ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
24995ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)),
25005ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25015ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)),
25025ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25035ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)),
25045ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25055ffd83dbSDimitry Andric
25065ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)),
25075ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25085ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)),
25095ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25105ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)),
25115ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25125ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)),
25135ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
25145ffd83dbSDimitry Andric
25155ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)),
25165ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25175ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)),
25185ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25195ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)),
25205ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25215ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)),
25225ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25235ffd83dbSDimitry Andric
25245ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)),
25255ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25265ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)),
25275ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25285ffd83dbSDimitry Andric
25295ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)),
25305ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25315ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)),
25325ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25335ffd83dbSDimitry Andric
25345ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)),
25355ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25365ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)),
25375ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25385ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)),
25395ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25405ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)),
25415ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
25425ffd83dbSDimitry Andric
25435ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
25445ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
25455ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
25465ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
25475ffd83dbSDimitry Andric
25485ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
25495ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
25505ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
25515ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
25525ffd83dbSDimitry Andric
25535ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
25545ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
25555ffd83dbSDimitry Andric
25565ffd83dbSDimitry Andric// Permutes.
25575ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
25585ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
25595ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
25605ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
25615ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
25625ffd83dbSDimitry Andric
25635ffd83dbSDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
25645ffd83dbSDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
25655ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)),
25665ffd83dbSDimitry Andric          (XXPERMDI $src, $src, 2)>;
25675ffd83dbSDimitry Andric
25685ffd83dbSDimitry Andric// Selects.
25695ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
25705ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
25715ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
25725ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
25735ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
25745ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
25755ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
25765ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
25775ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
25785ffd83dbSDimitry Andric          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
25795ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
25805ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
25815ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
25825ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
25835ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
25845ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
25855ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
25865ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
25875ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
25885ffd83dbSDimitry Andric          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
25895ffd83dbSDimitry Andric
25905ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
25915ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
25925ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
25935ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
25945ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
25955ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
25965ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
25975ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
25985ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
25995ffd83dbSDimitry Andric          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
26005ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
26015ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
26025ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
26035ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
26045ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
26055ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
26065ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
26075ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
26085ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
26095ffd83dbSDimitry Andric          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
26105ffd83dbSDimitry Andric
26115ffd83dbSDimitry Andric// Divides.
26125ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
26135ffd83dbSDimitry Andric          (XVDIVSP $A, $B)>;
26145ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
26155ffd83dbSDimitry Andric          (XVDIVDP $A, $B)>;
26165ffd83dbSDimitry Andric
2617*e8d8bef9SDimitry Andric// Vector test for software divide and sqrt.
2618*e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)),
2619*e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>;
2620*e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)),
2621*e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>;
2622*e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)),
2623*e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>;
2624*e8d8bef9SDimitry Andricdef : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)),
2625*e8d8bef9SDimitry Andric          (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>;
2626*e8d8bef9SDimitry Andric
26275ffd83dbSDimitry Andric// Reciprocal estimate
26285ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A),
26295ffd83dbSDimitry Andric          (XVRESP $A)>;
26305ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A),
26315ffd83dbSDimitry Andric          (XVREDP $A)>;
26325ffd83dbSDimitry Andric
26335ffd83dbSDimitry Andric// Recip. square root estimate
26345ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
26355ffd83dbSDimitry Andric          (XVRSQRTESP $A)>;
26365ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
26375ffd83dbSDimitry Andric          (XVRSQRTEDP $A)>;
26385ffd83dbSDimitry Andric
26395ffd83dbSDimitry Andric// Vector selection
26405ffd83dbSDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
26415ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
26425ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
26435ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
26445ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
26455ffd83dbSDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
26465ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
26475ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
26485ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
26495ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
26505ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
26515ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
26525ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
26535ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
26545ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
26555ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
26565ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
26575ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
26585ffd83dbSDimitry Andric
26595ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fmaxnum v4f32:$src1, v4f32:$src2)),
26605ffd83dbSDimitry Andric          (v4f32 (XVMAXSP $src1, $src2))>;
26615ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fminnum v4f32:$src1, v4f32:$src2)),
26625ffd83dbSDimitry Andric          (v4f32 (XVMINSP $src1, $src2))>;
26635ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fmaxnum v2f64:$src1, v2f64:$src2)),
26645ffd83dbSDimitry Andric          (v2f64 (XVMAXDP $src1, $src2))>;
26655ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fminnum v2f64:$src1, v2f64:$src2)),
26665ffd83dbSDimitry Andric          (v2f64 (XVMINDP $src1, $src2))>;
26675ffd83dbSDimitry Andric
26685ffd83dbSDimitry Andric// f32 abs
26695ffd83dbSDimitry Andricdef : Pat<(f32 (fabs f32:$S)),
26705ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSABSDP
26715ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
26725ffd83dbSDimitry Andric
26735ffd83dbSDimitry Andric// f32 nabs
26745ffd83dbSDimitry Andricdef : Pat<(f32 (fneg (fabs f32:$S))),
26755ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNABSDP
26765ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
26775ffd83dbSDimitry Andric
26785ffd83dbSDimitry Andric// f32 Min.
26795ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)),
26805ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
26815ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)),
26825ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
26835ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))),
26845ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
26855ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
26865ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
26875ffd83dbSDimitry Andric// F32 Max.
26885ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)),
26895ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
26905ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)),
26915ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
26925ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))),
26935ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
26945ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
26955ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
26965ffd83dbSDimitry Andric
26975ffd83dbSDimitry Andric// f64 Min.
26985ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)),
26995ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27005ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)),
27015ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27025ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))),
27035ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27045ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
27055ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
27065ffd83dbSDimitry Andric// f64 Max.
27075ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)),
27085ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27095ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)),
27105ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27115ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))),
27125ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27135ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
27145ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
27155ffd83dbSDimitry Andric
27165ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
27175ffd83dbSDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
27185ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
27195ffd83dbSDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
27205ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
27215ffd83dbSDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
27225ffd83dbSDimitry Andric
27235ffd83dbSDimitry Andric// Rounding for single precision.
27245ffd83dbSDimitry Andricdef : Pat<(f32 (any_fround f32:$S)),
27255ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPI
27265ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2727*e8d8bef9SDimitry Andricdef : Pat<(f32 (fnearbyint f32:$S)),
27285ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
27295ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27305ffd83dbSDimitry Andricdef : Pat<(f32 (any_ffloor f32:$S)),
27315ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIM
27325ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27335ffd83dbSDimitry Andricdef : Pat<(f32 (any_fceil f32:$S)),
27345ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIP
27355ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27365ffd83dbSDimitry Andricdef : Pat<(f32 (any_ftrunc f32:$S)),
27375ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIZ
27385ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
27395ffd83dbSDimitry Andricdef : Pat<(f32 (any_frint f32:$S)),
27405ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
27415ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2742*e8d8bef9SDimitry Andricdef : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
27435ffd83dbSDimitry Andric
27445ffd83dbSDimitry Andric// Rounding for double precision.
2745*e8d8bef9SDimitry Andricdef : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>;
2746*e8d8bef9SDimitry Andricdef : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
27475ffd83dbSDimitry Andric
27485ffd83dbSDimitry Andric// Materialize a zero-vector of long long
27495ffd83dbSDimitry Andricdef : Pat<(v2i64 immAllZerosV),
27505ffd83dbSDimitry Andric          (v2i64 (XXLXORz))>;
27515ffd83dbSDimitry Andric
27520b57cec5SDimitry Andric// Build vectors of floating point converted to i32.
27530b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
27540b57cec5SDimitry Andric                               DblToInt.A, DblToInt.A)),
27550b57cec5SDimitry Andric          (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
27560b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
27570b57cec5SDimitry Andric                               DblToUInt.A, DblToUInt.A)),
27580b57cec5SDimitry Andric          (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
27590b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
27600b57cec5SDimitry Andric          (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
27610b57cec5SDimitry Andric                           (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
27620b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
27630b57cec5SDimitry Andric          (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
27640b57cec5SDimitry Andric                           (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
27655ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
27665ffd83dbSDimitry Andric  v4i32, FltToIntLoad.A,
27675ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1),
27685ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC)>;
27695ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
27705ffd83dbSDimitry Andric  v4i32, FltToUIntLoad.A,
27715ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1),
27725ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC)>;
27730b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
27740b57cec5SDimitry Andric          (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
27758bcb0991SDimitry Andricdef : Pat<(v2f64 (PPCldsplat xoaddr:$A)),
27768bcb0991SDimitry Andric          (v2f64 (LXVDSX xoaddr:$A))>;
27778bcb0991SDimitry Andricdef : Pat<(v2i64 (PPCldsplat xoaddr:$A)),
27788bcb0991SDimitry Andric          (v2i64 (LXVDSX xoaddr:$A))>;
27790b57cec5SDimitry Andric
27800b57cec5SDimitry Andric// Build vectors of floating point converted to i64.
27810b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
27820b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
27830b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
27840b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
27850b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
27860b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
27875ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
27885ffd83dbSDimitry Andric  v2i64, DblToLongLoad.A,
27895ffd83dbSDimitry Andric  (XVCVDPSXDS (LXVDSX xoaddr:$A)), (XVCVDPSXDS (LXVDSX xoaddr:$A))>;
27905ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
27915ffd83dbSDimitry Andric  v2i64, DblToULongLoad.A,
27925ffd83dbSDimitry Andric  (XVCVDPUXDS (LXVDSX xoaddr:$A)), (XVCVDPUXDS (LXVDSX xoaddr:$A))>;
27935ffd83dbSDimitry Andric} // HasVSX
27940b57cec5SDimitry Andric
27955ffd83dbSDimitry Andric// Any big endian VSX subtarget.
27965ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsBigEndian] in {
27975ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)),
27985ffd83dbSDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
27990b57cec5SDimitry Andric
28005ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
28015ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
28025ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
28035ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
28045ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
28055ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
28065ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
28075ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
28085ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
28095ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
28105ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
28115ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
28120b57cec5SDimitry Andric
28135ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
28145ffd83dbSDimitry Andric          (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
28150b57cec5SDimitry Andric
28160b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
28170b57cec5SDimitry Andric          (v2f64 (XXPERMDI
28180b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $A, VSRC),
28190b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $B, VSRC), 0))>;
2820480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
2821480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
2822480093f4SDimitry Andric// XXPERMDI for 2 reasons:
2823480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
2824480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
2825480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
2826480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
2827480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2828480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
2829480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2830480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B),
2831480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>;
28320b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
28330b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
28340b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
28350b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
28360b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
28370b57cec5SDimitry Andric
28380b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
28390b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
28400b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
28410b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
28420b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
28430b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
28440b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
28450b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
28460b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
28470b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
28480b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
28490b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
28500b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
28515ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
28525ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
28535ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
28545ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
28555ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
28565ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
28575ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
28585ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
28595ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
28605ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
28615ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
28625ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
28635ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>;
28645ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
28655ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
28665ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
28675ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
28685ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
28695ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
28705ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
28715ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
28725ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
28735ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>;
28745ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
28755ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
28765ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3),
28775ffd83dbSDimitry Andric                                    (XXPERMDI $A, $B, 3), 1)))>;
28785ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
28795ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
28805ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
28815ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 3)))>;
28825ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
28835ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
28845ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
28855ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 3)))>;
28865ffd83dbSDimitry Andric} // HasVSX, IsBigEndian
28870b57cec5SDimitry Andric
28885ffd83dbSDimitry Andric// Any little endian VSX subtarget.
28895ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsLittleEndian] in {
28905ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2f64, (f64 f64:$A),
28915ffd83dbSDimitry Andric                         (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
28925ffd83dbSDimitry Andric                                   (SUBREG_TO_REG (i64 1), $A, sub_64), 0),
28935ffd83dbSDimitry Andric                         (SUBREG_TO_REG (i64 1), $A, sub_64)>;
28940b57cec5SDimitry Andric
28955ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
28965ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
28975ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
28985ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
28990b57cec5SDimitry Andric
29005ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
29015ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
29025ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
29035ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v4f32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
29045ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
29055ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
29065ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
29075ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v4i32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
29085ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
29095ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
29105ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
29115ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
29125ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
29135ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
29145ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
29155ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
29160b57cec5SDimitry Andric
29175ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
29185ffd83dbSDimitry Andric          (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
29195ffd83dbSDimitry Andric
29200b57cec5SDimitry Andric// Little endian, available on all targets with VSX
29210b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
29220b57cec5SDimitry Andric          (v2f64 (XXPERMDI
29230b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $B, VSRC),
29240b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $A, VSRC), 0))>;
2925480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
2926480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
2927480093f4SDimitry Andric// XXPERMDI for 2 reasons:
2928480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
2929480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
2930480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
2931480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
2932480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2933480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
2934480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2935480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C),
2936480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>;
29370b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
29380b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
29390b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
29400b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
29410b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
29420b57cec5SDimitry Andric
29430b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
29440b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
29450b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
29460b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
29470b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
29480b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
29490b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
29500b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
29510b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
29520b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
29530b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
29540b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
29550b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
29565ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29575ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
29585ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
29595ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
29605ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
29615ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
29625ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
29635ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29645ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
29655ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>;
29665ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
29675ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
29685ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
29695ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
29705ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
29715ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
29725ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
29735ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
29745ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
29755ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
29765ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
29775ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
29785ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3),
29795ffd83dbSDimitry Andric                                    (XXPERMDI $B, $A, 3), 1)))>;
29805ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
29815ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
29825ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>;
29835ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
29845ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
29855ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
29865ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
29875ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
29885ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
29895ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
29905ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
29915ffd83dbSDimitry Andric} // HasVSX, IsLittleEndian
29920b57cec5SDimitry Andric
29935ffd83dbSDimitry Andric// Any pre-Power9 VSX subtarget.
29945ffd83dbSDimitry Andriclet Predicates = [HasVSX, NoP9Vector] in {
29955ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
29965ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
29975ffd83dbSDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
29985ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
29995ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
30005ffd83dbSDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
30015ffd83dbSDimitry Andric
30025ffd83dbSDimitry Andric// Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
30035ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
30045ffd83dbSDimitry Andric  v4i32, DblToIntLoad.A,
30055ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1),
30065ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC)>;
30075ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
30085ffd83dbSDimitry Andric  v4i32, DblToUIntLoad.A,
30095ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1),
30105ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC)>;
30115ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
30125ffd83dbSDimitry Andric  v2i64, FltToLongLoad.A,
30135ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A), VSFRC)), 0),
30145ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A),
30155ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
30165ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
30175ffd83dbSDimitry Andric  v2i64, FltToULongLoad.A,
30185ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A), VSFRC)), 0),
30195ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A),
30205ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
30215ffd83dbSDimitry Andric} // HasVSX, NoP9Vector
30225ffd83dbSDimitry Andric
3023*e8d8bef9SDimitry Andric// Any little endian pre-Power9 VSX subtarget.
3024*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, NoP9Vector, IsLittleEndian] in {
3025*e8d8bef9SDimitry Andric// Load-and-splat using only X-Form VSX loads.
3026*e8d8bef9SDimitry Andricdefm : ScalToVecWPermute<
3027*e8d8bef9SDimitry Andric  v2i64, (i64 (load xoaddr:$src)),
3028*e8d8bef9SDimitry Andric  (XXPERMDIs (XFLOADf64 xoaddr:$src), 2),
3029*e8d8bef9SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 xoaddr:$src), sub_64)>;
3030*e8d8bef9SDimitry Andricdefm : ScalToVecWPermute<
3031*e8d8bef9SDimitry Andric  v2f64, (f64 (load xoaddr:$src)),
3032*e8d8bef9SDimitry Andric  (XXPERMDIs (XFLOADf64 xoaddr:$src), 2),
3033*e8d8bef9SDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 xoaddr:$src), sub_64)>;
3034*e8d8bef9SDimitry Andric} // HasVSX, NoP9Vector, IsLittleEndian
3035*e8d8bef9SDimitry Andric
30365ffd83dbSDimitry Andric// Any VSX subtarget that only has loads and stores that load in big endian
30375ffd83dbSDimitry Andric// order regardless of endianness. This is really pre-Power9 subtargets.
30385ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in {
30395ffd83dbSDimitry Andric  def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
30405ffd83dbSDimitry Andric
30415ffd83dbSDimitry Andric  // Stores.
30425ffd83dbSDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
30435ffd83dbSDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
30445ffd83dbSDimitry Andric  def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
30455ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps
30465ffd83dbSDimitry Andric
3047*e8d8bef9SDimitry Andric// Big endian VSX subtarget that only has loads and stores that always
3048*e8d8bef9SDimitry Andric// load in big endian order. Really big endian pre-Power9 subtargets.
30495ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in {
30505ffd83dbSDimitry Andric  def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
30515ffd83dbSDimitry Andric  def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
30525ffd83dbSDimitry Andric  def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
30535ffd83dbSDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
30545ffd83dbSDimitry Andric  def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
30555ffd83dbSDimitry Andric  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
30565ffd83dbSDimitry Andric  def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
30575ffd83dbSDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
30585ffd83dbSDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
30595ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps, IsBigEndian
30605ffd83dbSDimitry Andric
30615ffd83dbSDimitry Andric// Any Power8 VSX subtarget.
30625ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
30635ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
30645ffd83dbSDimitry Andric          (XXLEQV $A, $B)>;
30655ffd83dbSDimitry Andricdef : Pat<(f64 (extloadf32 xoaddr:$src)),
30665ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
30675ffd83dbSDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
30685ffd83dbSDimitry Andric          (f32 (XFLOADf32 xoaddr:$src))>;
30695ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpextend f32:$src)),
30705ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $src, VSFRC)>;
30715ffd83dbSDimitry Andric
30725ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
30735ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
30745ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
30755ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
30765ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
30775ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
30785ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
30795ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
30805ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
30815ffd83dbSDimitry Andric          (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
30825ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
30835ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
30845ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
30855ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
30865ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
30875ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
30885ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
30895ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
30905ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
30915ffd83dbSDimitry Andric          (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
30925ffd83dbSDimitry Andric
30935ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
30945ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
30955ffd83dbSDimitry Andric          (XSNMSUBASP $C, $A, $B)>;
30965ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
30975ffd83dbSDimitry Andric          (XSMSUBASP $C, $A, $B)>;
30985ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
30995ffd83dbSDimitry Andric          (XSNMADDASP $C, $A, $B)>;
31005ffd83dbSDimitry Andric
31015ffd83dbSDimitry Andric// f32 neg
31025ffd83dbSDimitry Andric// Although XSNEGDP is available in P7, we want to select it starting from P8,
31035ffd83dbSDimitry Andric// so that FNMSUBS can be selected for fneg-fmsub pattern on P7. (VSX version,
31045ffd83dbSDimitry Andric// XSNMSUBASP, is available since P8)
31055ffd83dbSDimitry Andricdef : Pat<(f32 (fneg f32:$S)),
31065ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNEGDP
31075ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
31085ffd83dbSDimitry Andric
31095ffd83dbSDimitry Andric// Instructions for converting float to i32 feeding a store.
31105ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
31115ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
31125ffd83dbSDimitry Andric          (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
31135ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
31145ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
31155ffd83dbSDimitry Andric          (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
31165ffd83dbSDimitry Andric
31175ffd83dbSDimitry Andricdef : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
31185ffd83dbSDimitry Andric          (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
31195ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
31205ffd83dbSDimitry Andricdef : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
31215ffd83dbSDimitry Andric          (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
31225ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
31235ffd83dbSDimitry Andricdef : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
31245ffd83dbSDimitry Andric          (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
31255ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
31265ffd83dbSDimitry Andricdef : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
31275ffd83dbSDimitry Andric          (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
31285ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
31295ffd83dbSDimitry Andric
31305ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
31315ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
31325ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
31335ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
31345ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
31355ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
31365ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
31375ffd83dbSDimitry Andric          (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
31385ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
31395ffd83dbSDimitry Andric
31405ffd83dbSDimitry Andric// Big endian Power8 VSX subtarget.
3141*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian, IsPPC64] in {
31425ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
31435ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
31445ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
31455ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
31465ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
31475ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
31485ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
31495ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
31505ffd83dbSDimitry Andric
31515ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (BE)
31525ffd83dbSDimitry Andricdef : Pat<(v4f32 (scalar_to_vector f32:$A)),
31535ffd83dbSDimitry Andric          (v4f32 (XSCVDPSPN $A))>;
31545ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
31555ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
31565ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
31575ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
31585ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
31595ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
31605ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
31615ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
31625ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
31635ffd83dbSDimitry Andric          (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
31645ffd83dbSDimitry Andric
31655ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
31665ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
31675ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
31685ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
31695ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
31705ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
31715ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
31725ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
31735ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
31745ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
31755ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
31765ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
31775ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
31785ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
31795ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
31805ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
31815ffd83dbSDimitry Andric
31825ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
31835ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
31845ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
31855ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
31865ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
31875ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
31885ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
31895ffd83dbSDimitry Andricdef : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
31905ffd83dbSDimitry Andric          (v4i32 (XXSLDWIs
31915ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
31925ffd83dbSDimitry Andricdef : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
31935ffd83dbSDimitry Andric          (v4f32 (XXSLDWIs
31945ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
31955ffd83dbSDimitry Andric
31965ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
31975ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
31985ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
31995ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
32005ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
32015ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
32025ffd83dbSDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src),
32035ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
32045ffd83dbSDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src),
32055ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
32065ffd83dbSDimitry Andric
32075ffd83dbSDimitry Andric// Elements in a register on a BE system are in order <0, 1, 2, 3>.
32085ffd83dbSDimitry Andric// The store instructions store the second word from the left.
32095ffd83dbSDimitry Andric// So to align element zero, we need to modulo-left-shift by 3 words.
32105ffd83dbSDimitry Andric// Similar logic applies for elements 2 and 3.
32115ffd83dbSDimitry Andricforeach Idx = [ [0,3], [2,1], [3,2] ] in {
32125ffd83dbSDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
32135ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
32145ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
32155ffd83dbSDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
32165ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
32175ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
32185ffd83dbSDimitry Andric}
3219*e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian, IsPPC64
32205ffd83dbSDimitry Andric
32215ffd83dbSDimitry Andric// Little endian Power8 VSX subtarget.
32225ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in {
32235ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
32245ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
32255ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
32265ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS
32275ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
32285ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
32295ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
32305ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
32315ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS
32325ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
32335ffd83dbSDimitry Andric
32345ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (LE)
32355ffd83dbSDimitry Andric  // The permuted version is no better than the version that puts the value
32365ffd83dbSDimitry Andric  // into the right element because XSCVDPSPN is different from all the other
32375ffd83dbSDimitry Andric  // instructions used for PPCSToV.
32385ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4f32, (f32 f32:$A),
32395ffd83dbSDimitry Andric                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1),
32405ffd83dbSDimitry Andric                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 3)>;
32415ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
32425ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
32435ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
32445ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
32455ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
32465ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
32475ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
32485ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
32495ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
32505ffd83dbSDimitry Andric          (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
32515ffd83dbSDimitry Andric
32525ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
32535ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
32545ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
32555ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
32565ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
32575ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
32585ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
32595ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
32605ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
32615ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
32625ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
32635ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
32645ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
32655ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
32665ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
32675ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
32685ffd83dbSDimitry Andric
32695ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
32705ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
32715ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
32725ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
32735ffd83dbSDimitry Andric  v2i64, (i64 (sextloadi32 xoaddr:$src)),
32745ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSFRC), 2),
32755ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWAX xoaddr:$src), sub_64)>;
32765ffd83dbSDimitry Andric
32775ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
32785ffd83dbSDimitry Andric  v2i64, (i64 (zextloadi32 xoaddr:$src)),
32795ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
32805ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
32815ffd83dbSDimitry Andric
32825ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
32835ffd83dbSDimitry Andric  v4i32, (i32 (load xoaddr:$src)),
32845ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
32855ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
32865ffd83dbSDimitry Andric
32875ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
32885ffd83dbSDimitry Andric  v4f32, (f32 (load xoaddr:$src)),
32895ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
32905ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
32915ffd83dbSDimitry Andric
32925ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
32935ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
32945ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
32955ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
32965ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
32975ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
32985ffd83dbSDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src),
32995ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
33005ffd83dbSDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src),
33015ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
33025ffd83dbSDimitry Andric
33035ffd83dbSDimitry Andric// Elements in a register on a LE system are in order <3, 2, 1, 0>.
33045ffd83dbSDimitry Andric// The store instructions store the second word from the left.
33055ffd83dbSDimitry Andric// So to align element 3, we need to modulo-left-shift by 3 words.
33065ffd83dbSDimitry Andric// Similar logic applies for elements 0 and 1.
33075ffd83dbSDimitry Andricforeach Idx = [ [0,2], [1,1], [3,3] ] in {
33085ffd83dbSDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
33095ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
33105ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
33115ffd83dbSDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
33125ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
33135ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
33145ffd83dbSDimitry Andric}
33155ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, IsLittleEndian
33165ffd83dbSDimitry Andric
33175ffd83dbSDimitry Andric// Big endian pre-Power9 VSX subtarget.
3318*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64] in {
33195ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
33205ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
33215ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
33225ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
33235ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
33245ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
33255ffd83dbSDimitry Andric                      xoaddr:$src)>;
33265ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
33275ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
33285ffd83dbSDimitry Andric                      xoaddr:$src)>;
3329*e8d8bef9SDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian, IsPPC64
33305ffd83dbSDimitry Andric
33315ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget.
33325ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in {
33335ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
33345ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
33355ffd83dbSDimitry Andric                      xoaddr:$src)>;
33365ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
33375ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
33385ffd83dbSDimitry Andric                      xoaddr:$src)>;
33395ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
33405ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
33415ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
33425ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
33435ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian
33445ffd83dbSDimitry Andric
33455ffd83dbSDimitry Andric// Any VSX target with direct moves.
33465ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove] in {
33475ffd83dbSDimitry Andric// bitconvert f32 -> i32
33485ffd83dbSDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR)
33495ffd83dbSDimitry Andricdef : Pat<(i32 (bitconvert f32:$S)),
33505ffd83dbSDimitry Andric          (i32 (MFVSRWZ (EXTRACT_SUBREG
33515ffd83dbSDimitry Andric                          (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
33525ffd83dbSDimitry Andric                          sub_64)))>;
33535ffd83dbSDimitry Andric// bitconvert i32 -> f32
33545ffd83dbSDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single)
33555ffd83dbSDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)),
33565ffd83dbSDimitry Andric          (f32 (XSCVSPDPN
33575ffd83dbSDimitry Andric                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
33585ffd83dbSDimitry Andric
33595ffd83dbSDimitry Andric// bitconvert f64 -> i64
33605ffd83dbSDimitry Andric// (move to GPR, nothing else needed)
33615ffd83dbSDimitry Andricdef : Pat<(i64 (bitconvert f64:$S)),
33625ffd83dbSDimitry Andric          (i64 (MFVSRD $S))>;
33635ffd83dbSDimitry Andric
33645ffd83dbSDimitry Andric// bitconvert i64 -> f64
33655ffd83dbSDimitry Andric// (move to FPR, nothing else needed)
33665ffd83dbSDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)),
33675ffd83dbSDimitry Andric          (f64 (MTVSRD $S))>;
33685ffd83dbSDimitry Andric
33695ffd83dbSDimitry Andric// Rounding to integer.
33705ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f64:$S)),
33715ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
33725ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f32:$S)),
33735ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
33745ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f64:$S)),
33755ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
33765ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f32:$S)),
33775ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
33785ffd83dbSDimitry Andricdef : Pat<(i64 (lround f64:$S)),
33795ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
33805ffd83dbSDimitry Andricdef : Pat<(i64 (lround f32:$S)),
33815ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
33825ffd83dbSDimitry Andricdef : Pat<(i64 (llround f64:$S)),
33835ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
33845ffd83dbSDimitry Andricdef : Pat<(i64 (llround f32:$S)),
33855ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
33865ffd83dbSDimitry Andric
33875ffd83dbSDimitry Andric// Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
33885ffd83dbSDimitry Andric// of f64
33895ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCmtvsrz i32:$A)),
33905ffd83dbSDimitry Andric          (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
33915ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCmtvsrz i32:$A)),
33925ffd83dbSDimitry Andric          (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
33935ffd83dbSDimitry Andric
33940b57cec5SDimitry Andric// Endianness-neutral constant splat on P8 and newer targets. The reason
33950b57cec5SDimitry Andric// for this pattern is that on targets with direct moves, we don't expand
33960b57cec5SDimitry Andric// BUILD_VECTOR nodes for v4i32.
33970b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
33980b57cec5SDimitry Andric                               immSExt5NonZero:$A, immSExt5NonZero:$A)),
33990b57cec5SDimitry Andric          (v4i32 (VSPLTISW imm:$A))>;
34005ffd83dbSDimitry Andric} // HasVSX, HasDirectMove
34010b57cec5SDimitry Andric
34025ffd83dbSDimitry Andric// Big endian VSX subtarget with direct moves.
34035ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsBigEndian] in {
34045ffd83dbSDimitry Andric// v16i8 scalar <-> vector conversions (BE)
34055ffd83dbSDimitry Andricdef : Pat<(v16i8 (scalar_to_vector i32:$A)),
34065ffd83dbSDimitry Andric          (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
34075ffd83dbSDimitry Andricdef : Pat<(v8i16 (scalar_to_vector i32:$A)),
34085ffd83dbSDimitry Andric          (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
34095ffd83dbSDimitry Andricdef : Pat<(v4i32 (scalar_to_vector i32:$A)),
34105ffd83dbSDimitry Andric          (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
34115ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector i64:$A)),
34125ffd83dbSDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
34135ffd83dbSDimitry Andric
34145ffd83dbSDimitry Andric// v2i64 scalar <-> vector conversions (BE)
34155ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 0)),
34165ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_1)>;
34175ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 1)),
34185ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_0)>;
34195ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
34205ffd83dbSDimitry Andric          (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
34215ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsBigEndian
34225ffd83dbSDimitry Andric
34235ffd83dbSDimitry Andric// Little endian VSX subtarget with direct moves.
34245ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsLittleEndian] in {
34255ffd83dbSDimitry Andric  // v16i8 scalar <-> vector conversions (LE)
34265ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v16i8, (i32 i32:$A),
34275ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
34285ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
34295ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v8i16, (i32 i32:$A),
34305ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
34315ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
34325ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4i32, (i32 i32:$A), MovesToVSR.LE_WORD_0,
34335ffd83dbSDimitry Andric                           (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
34345ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v2i64, (i64 i64:$A), MovesToVSR.LE_DWORD_0,
34355ffd83dbSDimitry Andric                           MovesToVSR.LE_DWORD_1>;
34365ffd83dbSDimitry Andric
34375ffd83dbSDimitry Andric  // v2i64 scalar <-> vector conversions (LE)
34385ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
34395ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
34405ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
34415ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
34425ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
34435ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
34445ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsLittleEndian
34455ffd83dbSDimitry Andric
34465ffd83dbSDimitry Andric// Big endian pre-P9 VSX subtarget with direct moves.
34475ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian] in {
34485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
34495ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
34505ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
34515ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
34525ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
34535ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
34545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
34555ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
34565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
34575ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
34585ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
34595ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
34605ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
34615ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
34625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
34635ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
34645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
34655ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
34665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
34675ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
34685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
34695ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
34705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
34715ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
34725ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
34735ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
34745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
34755ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
34765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
34775ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
34785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
34795ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
34805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
34815ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
34825ffd83dbSDimitry Andric
34835ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (BE)
34845ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
34855ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
34865ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
34875ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
34885ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
34895ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
34905ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
34915ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
34925ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
34935ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
34945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
34955ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
34965ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
34975ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
34985ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
34995ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
35005ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
35015ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_HALF)>;
35025ffd83dbSDimitry Andric
35035ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (BE)
35045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
35055ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
35065ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
35075ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
35085ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
35095ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
35105ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
35115ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
35125ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
35135ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_WORD)>;
35145ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian
35155ffd83dbSDimitry Andric
35165ffd83dbSDimitry Andric// Little endian pre-P9 VSX subtarget with direct moves.
35175ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] in {
35185ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
35195ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
35205ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
35215ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
35225ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
35235ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
35245ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
35255ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
35265ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
35275ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
35285ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
35295ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
35305ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
35315ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
35325ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
35335ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
35345ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
35355ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
35365ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
35375ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
35385ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
35395ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
35405ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
35415ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
35425ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
35435ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
35445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
35455ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
35465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
35475ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
35485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
35495ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
35505ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
35515ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
35525ffd83dbSDimitry Andric
35535ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (LE)
35545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
35555ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
35565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
35575ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
35585ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
35595ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
35605ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
35615ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
35625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
35635ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
35645ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
35655ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
35665ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
35675ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
35685ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
35695ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
35705ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
35715ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_HALF)>;
35725ffd83dbSDimitry Andric
35735ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (LE)
35745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
35755ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
35765ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
35775ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
35785ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
35795ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
35805ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
35815ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
35825ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
35835ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_WORD)>;
35845ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian
35855ffd83dbSDimitry Andric
3586*e8d8bef9SDimitry Andric// Big endian pre-Power9 64Bit VSX subtarget that has direct moves.
3587*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64] in {
35880b57cec5SDimitry Andric// Big endian integer vectors using direct moves.
35890b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
35900b57cec5SDimitry Andric          (v2i64 (XXPERMDI
35910b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
35920b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
35930b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
35940b57cec5SDimitry Andric          (XXPERMDI
35950b57cec5SDimitry Andric            (COPY_TO_REGCLASS
35960b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
35970b57cec5SDimitry Andric            (COPY_TO_REGCLASS
35980b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
35990b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
36000b57cec5SDimitry Andric          (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3601*e8d8bef9SDimitry Andric} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian, IsPPC64
36020b57cec5SDimitry Andric
36035ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget that has direct moves.
36045ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in {
36050b57cec5SDimitry Andric// Little endian integer vectors using direct moves.
36060b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
36070b57cec5SDimitry Andric          (v2i64 (XXPERMDI
36080b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
36090b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
36100b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
36110b57cec5SDimitry Andric          (XXPERMDI
36120b57cec5SDimitry Andric            (COPY_TO_REGCLASS
36130b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
36140b57cec5SDimitry Andric            (COPY_TO_REGCLASS
36150b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
36160b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
36170b57cec5SDimitry Andric          (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
36180b57cec5SDimitry Andric}
36190b57cec5SDimitry Andric
36205ffd83dbSDimitry Andric// Any Power9 VSX subtarget.
36215ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
36225ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
36235ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C),
36245ffd83dbSDimitry Andric          (XSNMSUBQP $C, $A, $B)>;
36255ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
36265ffd83dbSDimitry Andric          (XSMSUBQP $C, $A, $B)>;
36275ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
36285ffd83dbSDimitry Andric          (XSNMADDQP $C, $A, $B)>;
36298bcb0991SDimitry Andric
3630*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i64:$src)),
36315ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3632*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))),
36335ffd83dbSDimitry Andric          (f128 (XSCVSDQP $src))>;
3634*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))),
36355ffd83dbSDimitry Andric          (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
3636*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i64:$src)),
36375ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3638*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))),
36395ffd83dbSDimitry Andric          (f128 (XSCVUDQP $src))>;
36405ffd83dbSDimitry Andric
36415ffd83dbSDimitry Andric// Convert (Un)Signed Word -> QP.
3642*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp i32:$src)),
36435ffd83dbSDimitry Andric          (f128 (XSCVSDQP (MTVSRWA $src)))>;
3644*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_sint_to_fp (i32 (load xoaddr:$src)))),
36455ffd83dbSDimitry Andric          (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
3646*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp i32:$src)),
36475ffd83dbSDimitry Andric          (f128 (XSCVUDQP (MTVSRWZ $src)))>;
3648*e8d8bef9SDimitry Andricdef : Pat<(f128 (any_uint_to_fp (i32 (load xoaddr:$src)))),
36495ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
36505ffd83dbSDimitry Andric
36515ffd83dbSDimitry Andric// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
36525ffd83dbSDimitry Andric// separate pattern so that it can convert the input register class from
36535ffd83dbSDimitry Andric// VRRC(v8i16) to VSRC.
36545ffd83dbSDimitry Andricdef : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
36555ffd83dbSDimitry Andric          (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
36565ffd83dbSDimitry Andric
36575ffd83dbSDimitry Andric// Use current rounding mode
36585ffd83dbSDimitry Andricdef : Pat<(f128 (any_fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
36595ffd83dbSDimitry Andric// Round to nearest, ties away from zero
36605ffd83dbSDimitry Andricdef : Pat<(f128 (any_fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
36615ffd83dbSDimitry Andric// Round towards Zero
36625ffd83dbSDimitry Andricdef : Pat<(f128 (any_ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
36635ffd83dbSDimitry Andric// Round towards +Inf
36645ffd83dbSDimitry Andricdef : Pat<(f128 (any_fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
36655ffd83dbSDimitry Andric// Round towards -Inf
36665ffd83dbSDimitry Andricdef : Pat<(f128 (any_ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
36675ffd83dbSDimitry Andric// Use current rounding mode, [with Inexact]
36685ffd83dbSDimitry Andricdef : Pat<(f128 (any_frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
36695ffd83dbSDimitry Andric
36705ffd83dbSDimitry Andricdef : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
36715ffd83dbSDimitry Andric          (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
36725ffd83dbSDimitry Andric
36735ffd83dbSDimitry Andricdef : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
36745ffd83dbSDimitry Andric          (i64 (MFVSRD (EXTRACT_SUBREG
36755ffd83dbSDimitry Andric                          (v2i64 (XSXEXPQP $vA)), sub_64)))>;
36765ffd83dbSDimitry Andric
36775ffd83dbSDimitry Andric// Extra patterns expanding to vector Extract Word/Insert Word
36785ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
36795ffd83dbSDimitry Andric          (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
36805ffd83dbSDimitry Andricdef : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
36815ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
36825ffd83dbSDimitry Andric
36835ffd83dbSDimitry Andric// Vector Reverse
36845ffd83dbSDimitry Andricdef : Pat<(v8i16 (bswap v8i16 :$A)),
36855ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
36865ffd83dbSDimitry Andricdef : Pat<(v1i128 (bswap v1i128 :$A)),
36875ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
36885ffd83dbSDimitry Andric
36895ffd83dbSDimitry Andric// D-Form Load/Store
36905ffd83dbSDimitry Andricdef : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
36915ffd83dbSDimitry Andricdef : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
36925ffd83dbSDimitry Andricdef : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
36935ffd83dbSDimitry Andricdef : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
36945ffd83dbSDimitry Andricdef : Pat<(f128  (quadwOffsetLoad iaddrX16:$src)),
36955ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
36965ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>;
36975ffd83dbSDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>;
36985ffd83dbSDimitry Andric
36995ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
37005ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
37015ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
37025ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore  f128:$rS, iaddrX16:$dst),
37035ffd83dbSDimitry Andric          (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
37045ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
37055ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst),
37065ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
37075ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst),
37085ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
37095ffd83dbSDimitry Andric
37105ffd83dbSDimitry Andricdef : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
37115ffd83dbSDimitry Andricdef : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
37125ffd83dbSDimitry Andricdef : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
37135ffd83dbSDimitry Andricdef : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
37145ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
37155ffd83dbSDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
37165ffd83dbSDimitry Andricdef : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
37175ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
37185ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
37195ffd83dbSDimitry Andric          (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
37205ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
37215ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
37225ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
37235ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
37245ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
37255ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
37265ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
37275ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
37285ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
37295ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
37305ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
37315ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
37325ffd83dbSDimitry Andric
37335ffd83dbSDimitry Andric// Build vectors from i8 loads
37345ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v16i8, ScalarLoads.Li8,
37355ffd83dbSDimitry Andric                         (VSPLTBs 7, (LXSIBZX xoaddr:$src)),
37365ffd83dbSDimitry Andric                         (VSPLTBs 7, (LXSIBZX xoaddr:$src))>;
37375ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.ZELi8,
37385ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIBZX xoaddr:$src)),
37395ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIBZX xoaddr:$src))>;
37405ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi8,
37415ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIBZX xoaddr:$src), 1),
37425ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIBZX xoaddr:$src), 1)>;
37435ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi8i64,
37445ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIBZX xoaddr:$src), 0),
37455ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIBZX xoaddr:$src), 0)>;
37465ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.SELi8,
37475ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1),
37485ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1)>;
37495ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.SELi8i64,
37505ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0),
37515ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0)>;
37525ffd83dbSDimitry Andric
37535ffd83dbSDimitry Andric// Build vectors from i16 loads
37545ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.Li16,
37555ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIHZX xoaddr:$src)),
37565ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIHZX xoaddr:$src))>;
37575ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi16,
37585ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIHZX xoaddr:$src), 1),
37595ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIHZX xoaddr:$src), 1)>;
37605ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi16i64,
37615ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIHZX xoaddr:$src), 0),
37625ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIHZX xoaddr:$src), 0)>;
37635ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.SELi16,
37645ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1),
37655ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1)>;
37665ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.SELi16i64,
37675ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0),
37685ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0)>;
37695ffd83dbSDimitry Andric
37705ffd83dbSDimitry Andric// Load/convert and convert/store patterns for f16.
37715ffd83dbSDimitry Andricdef : Pat<(f64 (extloadf16 xoaddr:$src)),
37725ffd83dbSDimitry Andric          (f64 (XSCVHPDP (LXSIHZX xoaddr:$src)))>;
37735ffd83dbSDimitry Andricdef : Pat<(truncstoref16 f64:$src, xoaddr:$dst),
37745ffd83dbSDimitry Andric          (STXSIHX (XSCVDPHP $src), xoaddr:$dst)>;
37755ffd83dbSDimitry Andricdef : Pat<(f32 (extloadf16 xoaddr:$src)),
37765ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX xoaddr:$src)), VSSRC))>;
37775ffd83dbSDimitry Andricdef : Pat<(truncstoref16 f32:$src, xoaddr:$dst),
37785ffd83dbSDimitry Andric          (STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), xoaddr:$dst)>;
37795ffd83dbSDimitry Andricdef : Pat<(f64 (f16_to_fp i32:$A)),
37805ffd83dbSDimitry Andric          (f64 (XSCVHPDP (MTVSRWZ $A)))>;
37815ffd83dbSDimitry Andricdef : Pat<(f32 (f16_to_fp i32:$A)),
37825ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (MTVSRWZ $A)), VSSRC))>;
37835ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f32:$A)),
37845ffd83dbSDimitry Andric          (i32 (MFVSRWZ (XSCVDPHP (COPY_TO_REGCLASS $A, VSFRC))))>;
37855ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f64:$A)), (i32 (MFVSRWZ (XSCVDPHP $A)))>;
37865ffd83dbSDimitry Andric
37875ffd83dbSDimitry Andric// Vector sign extensions
37885ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 1)),
37895ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
37905ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 2)),
37915ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
37925ffd83dbSDimitry Andric
37935ffd83dbSDimitry Andricdef : Pat<(f64 (extloadf32 iaddrX4:$src)),
37945ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>;
37955ffd83dbSDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))),
37965ffd83dbSDimitry Andric          (f32 (DFLOADf32 iaddrX4:$src))>;
37975ffd83dbSDimitry Andric
37985ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh xaddr:$src)),
37995ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>;
38005ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)),
38015ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>;
38025ffd83dbSDimitry Andric
38035ffd83dbSDimitry Andric// Convert (Un)Signed DWord in memory -> QP
38045ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))),
38055ffd83dbSDimitry Andric          (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>;
38065ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))),
38075ffd83dbSDimitry Andric          (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>;
38085ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))),
38095ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>;
38105ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))),
38115ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>;
38125ffd83dbSDimitry Andric
38135ffd83dbSDimitry Andric// Convert Unsigned HWord in memory -> QP
38145ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
38155ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
38165ffd83dbSDimitry Andric
38175ffd83dbSDimitry Andric// Convert Unsigned Byte in memory -> QP
38185ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
38195ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
38205ffd83dbSDimitry Andric
38215ffd83dbSDimitry Andric// Truncate & Convert QP -> (Un)Signed (D)Word.
3822*e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3823*e8d8bef9SDimitry Andricdef : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3824*e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_sint f128:$src)),
38255ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
3826*e8d8bef9SDimitry Andricdef : Pat<(i32 (any_fp_to_uint f128:$src)),
38275ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
38285ffd83dbSDimitry Andric
38295ffd83dbSDimitry Andric// Instructions for store(fptosi).
38305ffd83dbSDimitry Andric// The 8-byte version is repeated here due to availability of D-Form STXSD.
38315ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38325ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8),
38335ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
38345ffd83dbSDimitry Andric                  xaddrX4:$dst)>;
38355ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38365ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8),
38375ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
38385ffd83dbSDimitry Andric                 iaddrX4:$dst)>;
38395ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38405ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
38415ffd83dbSDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
38425ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38435ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
38445ffd83dbSDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
38455ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38465ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
38475ffd83dbSDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
38485ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38495ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8),
38505ffd83dbSDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>;
38515ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38525ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8),
38535ffd83dbSDimitry Andric          (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>;
38545ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38555ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
38565ffd83dbSDimitry Andric          (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
38575ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38585ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
38595ffd83dbSDimitry Andric          (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
38605ffd83dbSDimitry Andric
38615ffd83dbSDimitry Andric// Instructions for store(fptoui).
38625ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38635ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8),
38645ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
38655ffd83dbSDimitry Andric                  xaddrX4:$dst)>;
38665ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38675ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8),
38685ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
38695ffd83dbSDimitry Andric                 iaddrX4:$dst)>;
38705ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38715ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
38725ffd83dbSDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
38735ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38745ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
38755ffd83dbSDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
38765ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38775ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
38785ffd83dbSDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
38795ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38805ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8),
38815ffd83dbSDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>;
38825ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38835ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8),
38845ffd83dbSDimitry Andric          (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>;
38855ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38865ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
38875ffd83dbSDimitry Andric          (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
38885ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
38895ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
38905ffd83dbSDimitry Andric          (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
38915ffd83dbSDimitry Andric
38925ffd83dbSDimitry Andric// Round & Convert QP -> DP/SP
38935ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpround f128:$src)), (f64 (XSCVQPDP $src))>;
38945ffd83dbSDimitry Andricdef : Pat<(f32 (any_fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
38955ffd83dbSDimitry Andric
38965ffd83dbSDimitry Andric// Convert SP -> QP
38975ffd83dbSDimitry Andricdef : Pat<(f128 (any_fpextend f32:$src)),
38985ffd83dbSDimitry Andric          (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
38995ffd83dbSDimitry Andric
39005ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)),
39015ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC),
39025ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
39035ffd83dbSDimitry Andric                                 VSSRC))>;
39045ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)),
39055ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC),
39065ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
39075ffd83dbSDimitry Andric                                 VSSRC))>;
39085ffd83dbSDimitry Andric
39090b57cec5SDimitry Andric// Endianness-neutral patterns for const splats with ISA 3.0 instructions.
39105ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, (i32 i32:$A), (MTVSRWS $A), (MTVSRWS $A)>;
39110b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
39120b57cec5SDimitry Andric          (v4i32 (MTVSRWS $A))>;
39138bcb0991SDimitry Andricdef : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39148bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39158bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39168bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39178bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39188bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39198bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
39208bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
39210b57cec5SDimitry Andric          (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
39225ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, FltToIntLoad.A,
39235ffd83dbSDimitry Andric                         (XVCVSPSXWS (LXVWSX xoaddr:$A)),
39245ffd83dbSDimitry Andric                         (XVCVSPSXWS (LXVWSX xoaddr:$A))>;
39255ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, FltToUIntLoad.A,
39265ffd83dbSDimitry Andric                         (XVCVSPUXWS (LXVWSX xoaddr:$A)),
39275ffd83dbSDimitry Andric                         (XVCVSPUXWS (LXVWSX xoaddr:$A))>;
39285ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
39295ffd83dbSDimitry Andric  v4i32, DblToIntLoadP9.A,
39305ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1),
39315ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), sub_64)>;
39325ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
39335ffd83dbSDimitry Andric  v4i32, DblToUIntLoadP9.A,
39345ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1),
39355ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), sub_64)>;
39365ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
39375ffd83dbSDimitry Andric  v2i64, FltToLongLoadP9.A,
39385ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), 0),
39395ffd83dbSDimitry Andric  (SUBREG_TO_REG
39405ffd83dbSDimitry Andric     (i64 1),
39415ffd83dbSDimitry Andric     (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), sub_64)>;
39425ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
39435ffd83dbSDimitry Andric  v2i64, FltToULongLoadP9.A,
39445ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), 0),
39455ffd83dbSDimitry Andric  (SUBREG_TO_REG
39465ffd83dbSDimitry Andric     (i64 1),
39475ffd83dbSDimitry Andric     (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), sub_64)>;
39488bcb0991SDimitry Andricdef : Pat<(v4f32 (PPCldsplat xoaddr:$A)),
39498bcb0991SDimitry Andric          (v4f32 (LXVWSX xoaddr:$A))>;
39508bcb0991SDimitry Andricdef : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
39518bcb0991SDimitry Andric          (v4i32 (LXVWSX xoaddr:$A))>;
39525ffd83dbSDimitry Andric} // HasVSX, HasP9Vector
39535ffd83dbSDimitry Andric
3954*e8d8bef9SDimitry Andric// Big endian 64Bit Power9 subtarget.
3955*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian, IsPPC64] in {
39565ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
39575ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
39585ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
39595ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
39605ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
39615ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
39625ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
39635ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
39645ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
39655ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
39665ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
39675ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
39685ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
39695ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
39705ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
39715ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
39725ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
39735ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
39745ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
39755ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
39765ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
39775ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
39785ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
39795ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
39805ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
39815ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
39825ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
39835ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
39845ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
39855ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
39865ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
39875ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
39885ffd83dbSDimitry Andric
39895ffd83dbSDimitry Andric// Scalar stores of i8
39905ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
39915ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
39925ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
39935ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
39945ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
39955ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
39965ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
39975ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
39985ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
39995ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
40005ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
40015ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
40025ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
40035ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
40045ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
40055ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
40065ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
40075ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
40085ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
40095ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
40105ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
40115ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
40125ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
40135ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
40145ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
40155ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
40165ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
40175ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
40185ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
40195ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
40205ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
40215ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
40225ffd83dbSDimitry Andric
40235ffd83dbSDimitry Andric// Scalar stores of i16
40245ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
40255ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
40265ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
40275ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
40285ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
40295ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
40305ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
40315ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
40325ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
40335ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
40345ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
40355ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
40365ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
40375ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
40385ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
40395ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
40405ffd83dbSDimitry Andric
40415ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
40425ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
40435ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
40445ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
40455ffd83dbSDimitry Andric
40465ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
40475ffd83dbSDimitry Andric          (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
40485ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
40495ffd83dbSDimitry Andric          (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
40505ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
40515ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
40525ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
40535ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
40545ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
40555ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
40565ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
40575ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
40585ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
40595ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
40605ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
40615ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
40625ffd83dbSDimitry Andric                       sub_64), iaddrX4:$src)>;
40635ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
40645ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
40655ffd83dbSDimitry Andric                       sub_64), iaddrX4:$src)>;
40665ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
40675ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
40685ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
40695ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
40705ffd83dbSDimitry Andric
40715ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
40725ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
40735ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
40745ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
40755ffd83dbSDimitry Andric          (f128 (XSCVSDQP
40765ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
40775ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
40785ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
40795ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
40805ffd83dbSDimitry Andric          (f128 (XSCVUDQP
40815ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
40825ffd83dbSDimitry Andric
40835ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
40845ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
40855ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
40865ffd83dbSDimitry Andricforeach Idx = [0,2,3] in {
40875ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
40885ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
40895ffd83dbSDimitry Andric                            (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
40905ffd83dbSDimitry Andric}
40915ffd83dbSDimitry Andricforeach Idx = 0-3 in {
40925ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
40935ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
40940b57cec5SDimitry Andric}
40950b57cec5SDimitry Andric
40965ffd83dbSDimitry Andric// (Un)Signed HWord vector extract -> QP
40975ffd83dbSDimitry Andricforeach Idx = 0-7 in {
40985ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
40995ffd83dbSDimitry Andric                    (i32 (sext_inreg
41005ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, Idx), i16)))),
41015ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG
41025ffd83dbSDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
41035ffd83dbSDimitry Andric                            sub_64)))>;
41045ffd83dbSDimitry Andric  // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
41055ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
41065ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
41075ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
41085ffd83dbSDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
41090b57cec5SDimitry Andric}
41100b57cec5SDimitry Andric
41115ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP
41125ffd83dbSDimitry Andricforeach Idx = 0-15 in {
41135ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
41145ffd83dbSDimitry Andric                    (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
41155ffd83dbSDimitry Andric                                     i8)))),
41165ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
41175ffd83dbSDimitry Andric                              (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
41185ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
41195ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
41205ffd83dbSDimitry Andric            (f128 (XSCVUDQP
41215ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
41220b57cec5SDimitry Andric}
41230b57cec5SDimitry Andric
41245ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
41255ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
41265ffd83dbSDimitry Andric          (f128 (XSCVUDQP
41275ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
4128*e8d8bef9SDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian, IsPPC64
41295ffd83dbSDimitry Andric
41305ffd83dbSDimitry Andric// Little endian Power9 subtarget.
41315ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in {
41325ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
41335ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
41345ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
41355ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
41365ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
41375ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
41385ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
41395ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
41405ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
41415ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
41425ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
41435ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
41445ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
41455ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
41465ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
41475ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
41485ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
41495ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
41505ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
41515ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
41525ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
41535ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
41545ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
41555ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
41565ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
41575ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
41585ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
41595ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
41605ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
41615ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
41625ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
41635ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
41645ffd83dbSDimitry Andric
41655ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCld_vec_be xoaddr:$src)),
41665ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXVH8X xoaddr:$src), VRRC)>;
41675ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v8i16:$rS, xoaddr:$dst),
41685ffd83dbSDimitry Andric          (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
41695ffd83dbSDimitry Andric
41705ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCld_vec_be xoaddr:$src)),
41715ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXVB16X xoaddr:$src), VRRC)>;
41725ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v16i8:$rS, xoaddr:$dst),
41735ffd83dbSDimitry Andric          (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
41745ffd83dbSDimitry Andric
41755ffd83dbSDimitry Andric// Scalar stores of i8
41765ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
41775ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
41785ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
41795ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
41805ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
41815ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
41825ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
41835ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
41845ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
41855ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
41865ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
41875ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
41885ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
41895ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
41905ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
41915ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
41925ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
41935ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
41945ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
41955ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
41965ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
41975ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
41985ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
41995ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
42005ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
42015ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
42025ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
42035ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
42045ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
42055ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
42065ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
42075ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
42085ffd83dbSDimitry Andric
42095ffd83dbSDimitry Andric// Scalar stores of i16
42105ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
42115ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
42125ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
42135ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
42145ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
42155ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
42165ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
42175ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
42185ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
42195ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
42205ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
42215ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
42225ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
42235ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
42245ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
42255ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
42265ffd83dbSDimitry Andric
42275ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
42285ffd83dbSDimitry Andric  v2i64, (i64 (load iaddrX4:$src)),
42295ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSFRC), 2),
42305ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 iaddrX4:$src), sub_64)>;
42315ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
42325ffd83dbSDimitry Andric  v2i64, (i64 (load xaddrX4:$src)),
42335ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSFRC), 2),
42345ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 xaddrX4:$src), sub_64)>;
42355ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
42365ffd83dbSDimitry Andric  v2f64, (f64 (load iaddrX4:$src)),
42375ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSFRC), 2),
42385ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 iaddrX4:$src), sub_64)>;
42395ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
42405ffd83dbSDimitry Andric  v2f64, (f64 (load xaddrX4:$src)),
42415ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSFRC), 2),
42425ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 xaddrX4:$src), sub_64)>;
42435ffd83dbSDimitry Andric
42445ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
42455ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
42465ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
42475ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
42485ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
42495ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
42505ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
42515ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
42525ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
42535ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
42545ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
42555ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
42565ffd83dbSDimitry Andric                       sub_64), iaddrX4:$src)>;
42575ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
42585ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
42595ffd83dbSDimitry Andric                      iaddrX4:$src)>;
42605ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
42615ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
42625ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
42635ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
42645ffd83dbSDimitry Andric
42655ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
42665ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
42675ffd83dbSDimitry Andric          (f128 (XSCVSDQP
42685ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
42695ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
42705ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
42715ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
42725ffd83dbSDimitry Andric          (f128 (XSCVUDQP
42735ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
42745ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
42755ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
42765ffd83dbSDimitry Andric
42775ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
42785ffd83dbSDimitry Andricforeach Idx = [[0,3],[1,2],[3,0]] in {
42795ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
42805ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
42815ffd83dbSDimitry Andric                              (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
42825ffd83dbSDimitry Andric                              sub_64)))>;
42835ffd83dbSDimitry Andric}
42845ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
42855ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
42865ffd83dbSDimitry Andric
42875ffd83dbSDimitry Andricforeach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
42885ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
42895ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
42900b57cec5SDimitry Andric}
42910b57cec5SDimitry Andric
42925ffd83dbSDimitry Andric// (Un)Signed HWord vector extract -> QP
42935ffd83dbSDimitry Andric// The Nested foreach lists identifies the vector element and corresponding
42945ffd83dbSDimitry Andric// register byte location.
42955ffd83dbSDimitry Andricforeach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
42965ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
42975ffd83dbSDimitry Andric                    (i32 (sext_inreg
42985ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, !head(Idx)), i16)))),
42995ffd83dbSDimitry Andric            (f128 (XSCVSDQP
43005ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
43015ffd83dbSDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
43025ffd83dbSDimitry Andric                                    sub_64)))>;
43035ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
43045ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, !head(Idx))),
43055ffd83dbSDimitry Andric                         65535))),
43065ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
43075ffd83dbSDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
43080b57cec5SDimitry Andric}
43090b57cec5SDimitry Andric
43105ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP
43115ffd83dbSDimitry Andricforeach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
43125ffd83dbSDimitry Andric               [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
43135ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
43145ffd83dbSDimitry Andric                    (i32 (sext_inreg
43155ffd83dbSDimitry Andric                           (vector_extract v16i8:$src, !head(Idx)), i8)))),
43165ffd83dbSDimitry Andric            (f128 (XSCVSDQP
43175ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
43185ffd83dbSDimitry Andric                      (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
43195ffd83dbSDimitry Andric                      sub_64)))>;
43205ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
43215ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, !head(Idx))),
43225ffd83dbSDimitry Andric                         255))),
43235ffd83dbSDimitry Andric            (f128 (XSCVUDQP
43245ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
43255ffd83dbSDimitry Andric                      (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
43265ffd83dbSDimitry Andric}
43275ffd83dbSDimitry Andric
43285ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
43295ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
43305ffd83dbSDimitry Andric          (f128 (XSCVUDQP
43315ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
43325ffd83dbSDimitry Andric} // HasVSX, HasP9Vector, IsLittleEndian
43335ffd83dbSDimitry Andric
43345ffd83dbSDimitry Andric// Any Power9 VSX subtarget that supports Power9 Altivec.
43355ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec] in {
43360b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be
43370b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef.
43380b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
43390b57cec5SDimitry Andric          (v4i32 (VABSDUW $A, $B))>;
43400b57cec5SDimitry Andric
43410b57cec5SDimitry Andricdef : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
43420b57cec5SDimitry Andric          (v8i16 (VABSDUH $A, $B))>;
43430b57cec5SDimitry Andric
43440b57cec5SDimitry Andricdef : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
43450b57cec5SDimitry Andric          (v16i8 (VABSDUB $A, $B))>;
43460b57cec5SDimitry Andric
43470b57cec5SDimitry Andric// As PPCVABSD description, the last operand indicates whether do the
43480b57cec5SDimitry Andric// sign bit flip.
43490b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
43500b57cec5SDimitry Andric          (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
43515ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec
43525ffd83dbSDimitry Andric
4353*e8d8bef9SDimitry Andric// Big endian Power9 64Bit VSX subtargets with P9 Altivec support.
4354*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsBigEndian, IsPPC64] in {
43555ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
43565ffd83dbSDimitry Andric          (VEXTUBLX $Idx, $S)>;
43575ffd83dbSDimitry Andric
43585ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
43595ffd83dbSDimitry Andric          (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
43605ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
43615ffd83dbSDimitry Andric          (VEXTUHLX (LI8 0), $S)>;
43625ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
43635ffd83dbSDimitry Andric          (VEXTUHLX (LI8 2), $S)>;
43645ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
43655ffd83dbSDimitry Andric          (VEXTUHLX (LI8 4), $S)>;
43665ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
43675ffd83dbSDimitry Andric          (VEXTUHLX (LI8 6), $S)>;
43685ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
43695ffd83dbSDimitry Andric          (VEXTUHLX (LI8 8), $S)>;
43705ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
43715ffd83dbSDimitry Andric          (VEXTUHLX (LI8 10), $S)>;
43725ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
43735ffd83dbSDimitry Andric          (VEXTUHLX (LI8 12), $S)>;
43745ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
43755ffd83dbSDimitry Andric          (VEXTUHLX (LI8 14), $S)>;
43765ffd83dbSDimitry Andric
43775ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
43785ffd83dbSDimitry Andric          (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
43795ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
43805ffd83dbSDimitry Andric          (VEXTUWLX (LI8 0), $S)>;
43815ffd83dbSDimitry Andric
43825ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
43835ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
43845ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
43855ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
43865ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
43875ffd83dbSDimitry Andric          (VEXTUWLX (LI8 8), $S)>;
43885ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
43895ffd83dbSDimitry Andric          (VEXTUWLX (LI8 12), $S)>;
43905ffd83dbSDimitry Andric
43915ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
43925ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
43935ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
43945ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 0), $S))>;
43955ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
43965ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
43975ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
43985ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
43995ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
44005ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 8), $S))>;
44015ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
44025ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 12), $S))>;
44035ffd83dbSDimitry Andric
44045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
44055ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
44065ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
44075ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
44085ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
44095ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
44105ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
44115ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
44125ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
44135ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
44145ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
44155ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
44165ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
44175ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
44185ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
44195ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
44205ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
44215ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
44225ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
44235ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
44245ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
44255ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
44265ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
44275ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
44285ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
44295ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
44305ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
44315ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
44325ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
44335ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
44345ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
44355ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
44365ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
44375ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
44385ffd83dbSDimitry Andric
44395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
44405ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX
44415ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
44425ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
44435ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
44445ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
44455ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
44465ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
44475ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
44485ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
44495ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
44505ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
44515ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
44525ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
44535ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
44545ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
44555ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
44565ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
44575ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
44585ffd83dbSDimitry Andric
44595ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
44605ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX
44615ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
44625ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
44635ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
44645ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
44655ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
44665ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
44675ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
44685ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
44695ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
44705ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
44715ffd83dbSDimitry Andric
44725ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
44735ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
44745ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
44755ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
44765ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
44775ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
44785ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
44795ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
44805ffd83dbSDimitry Andric                  HWordToWord.BE_A2, HWordToWord.BE_A3)),
44815ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
44825ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
44835ffd83dbSDimitry Andric                  ByteToWord.BE_A2, ByteToWord.BE_A3)),
44845ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
44855ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
44865ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
4487*e8d8bef9SDimitry Andric} // HasVSX, HasP9Altivec, IsBigEndian, IsPPC64
44885ffd83dbSDimitry Andric
44895ffd83dbSDimitry Andric// Little endian Power9 VSX subtargets with P9 Altivec support.
44905ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in {
44915ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
44925ffd83dbSDimitry Andric          (VEXTUBRX $Idx, $S)>;
44935ffd83dbSDimitry Andric
44945ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
44955ffd83dbSDimitry Andric          (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
44965ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
44975ffd83dbSDimitry Andric          (VEXTUHRX (LI8 0), $S)>;
44985ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
44995ffd83dbSDimitry Andric          (VEXTUHRX (LI8 2), $S)>;
45005ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
45015ffd83dbSDimitry Andric          (VEXTUHRX (LI8 4), $S)>;
45025ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
45035ffd83dbSDimitry Andric          (VEXTUHRX (LI8 6), $S)>;
45045ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
45055ffd83dbSDimitry Andric          (VEXTUHRX (LI8 8), $S)>;
45065ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
45075ffd83dbSDimitry Andric          (VEXTUHRX (LI8 10), $S)>;
45085ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
45095ffd83dbSDimitry Andric          (VEXTUHRX (LI8 12), $S)>;
45105ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
45115ffd83dbSDimitry Andric          (VEXTUHRX (LI8 14), $S)>;
45125ffd83dbSDimitry Andric
45135ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
45145ffd83dbSDimitry Andric          (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
45155ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
45165ffd83dbSDimitry Andric          (VEXTUWRX (LI8 0), $S)>;
45175ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
45185ffd83dbSDimitry Andric          (VEXTUWRX (LI8 4), $S)>;
45195ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
45205ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
45215ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
45225ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
45235ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
45245ffd83dbSDimitry Andric          (VEXTUWRX (LI8 12), $S)>;
45255ffd83dbSDimitry Andric
45265ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
45275ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
45285ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
45295ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 0), $S))>;
45305ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
45315ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 4), $S))>;
45325ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
45335ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
45345ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
45355ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
45365ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
45375ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 12), $S))>;
45385ffd83dbSDimitry Andric
45395ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
45405ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
45415ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
45425ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
45435ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
45445ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
45455ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
45465ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
45475ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
45485ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
45495ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
45505ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
45515ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
45525ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
45535ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
45545ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
45555ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
45565ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
45575ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
45585ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
45595ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
45605ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
45615ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
45625ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
45635ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
45645ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
45655ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
45665ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
45675ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
45685ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
45695ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
45705ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
45715ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
45725ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
45735ffd83dbSDimitry Andric
45745ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
45755ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX
45765ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
45775ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
45785ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
45795ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
45805ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
45815ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
45825ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
45835ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
45845ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
45855ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
45865ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
45875ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
45885ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
45895ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
45905ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
45915ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
45925ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
45935ffd83dbSDimitry Andric
45945ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
45955ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX
45965ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
45975ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
45985ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
45995ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
46005ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
46015ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
46025ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
46035ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
46045ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
46055ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
46065ffd83dbSDimitry Andric
46075ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
46085ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
46095ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
46105ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
46115ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
46125ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
46135ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
46145ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
46155ffd83dbSDimitry Andric                  HWordToWord.LE_A2, HWordToWord.LE_A3)),
46165ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
46175ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
46185ffd83dbSDimitry Andric                  ByteToWord.LE_A2, ByteToWord.LE_A3)),
46195ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
46205ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
46215ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
46225ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec, IsLittleEndian
46235ffd83dbSDimitry Andric
4624*e8d8bef9SDimitry Andric// Big endian 64Bit VSX subtarget that supports additional direct moves from
4625*e8d8bef9SDimitry Andric// ISA3.0.
4626*e8d8bef9SDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64] in {
46275ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 1)),
46285ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
46295ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Big endian.
46305ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
46315ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
46325ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
46335ffd83dbSDimitry Andric          (MTVSRDD
46345ffd83dbSDimitry Andric            (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
46355ffd83dbSDimitry Andric            (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
46365ffd83dbSDimitry Andric
46375ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
46385ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
4639*e8d8bef9SDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian, IsPPC64
46405ffd83dbSDimitry Andric
46415ffd83dbSDimitry Andric// Little endian VSX subtarget that supports direct moves from ISA3.0.
46425ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in {
46435ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 0)),
46445ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
46455ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Little endian.
46465ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
46475ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
46485ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
46495ffd83dbSDimitry Andric          (MTVSRDD
46505ffd83dbSDimitry Andric            (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
46515ffd83dbSDimitry Andric            (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
46525ffd83dbSDimitry Andric
46535ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
46545ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
46555ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian
46565ffd83dbSDimitry Andric} // AddedComplexity = 400
46575ffd83dbSDimitry Andric
46585ffd83dbSDimitry Andric//---------------------------- Instruction aliases ---------------------------//
46595ffd83dbSDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB",
46605ffd83dbSDimitry Andric                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
46615ffd83dbSDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB",
46625ffd83dbSDimitry Andric                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
46635ffd83dbSDimitry Andric
4664*e8d8bef9SDimitry Andric// Certain versions of the AIX assembler may missassemble these mnemonics.
4665*e8d8bef9SDimitry Andriclet Predicates = [ModernAs] in {
46665ffd83dbSDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 0",
46675ffd83dbSDimitry Andric                  (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
46685ffd83dbSDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 1",
46695ffd83dbSDimitry Andric                  (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
4670*e8d8bef9SDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 0",
4671*e8d8bef9SDimitry Andric                  (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
4672*e8d8bef9SDimitry Andric  def : InstAlias<"xxspltd $XT, $XB, 1",
4673*e8d8bef9SDimitry Andric                  (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
4674*e8d8bef9SDimitry Andric}
4675*e8d8bef9SDimitry Andric
46765ffd83dbSDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB",
46775ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
46785ffd83dbSDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB",
46795ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
46805ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
46815ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
46825ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
46835ffd83dbSDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
46845ffd83dbSDimitry Andricdef : InstAlias<"mfvrd $rA, $XT",
46855ffd83dbSDimitry Andric                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
46865ffd83dbSDimitry Andricdef : InstAlias<"mffprd $rA, $src",
46875ffd83dbSDimitry Andric                (MFVSRD g8rc:$rA, f8rc:$src)>;
46885ffd83dbSDimitry Andricdef : InstAlias<"mtvrd $XT, $rA",
46895ffd83dbSDimitry Andric                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
46905ffd83dbSDimitry Andricdef : InstAlias<"mtfprd $dst, $rA",
46915ffd83dbSDimitry Andric                (MTVSRD f8rc:$dst, g8rc:$rA)>;
46925ffd83dbSDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT",
46935ffd83dbSDimitry Andric                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
46945ffd83dbSDimitry Andricdef : InstAlias<"mffprwz $rA, $src",
46955ffd83dbSDimitry Andric                (MFVSRWZ gprc:$rA, f8rc:$src)>;
46965ffd83dbSDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA",
46975ffd83dbSDimitry Andric                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
46985ffd83dbSDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA",
46995ffd83dbSDimitry Andric                (MTVSRWA f8rc:$dst, gprc:$rA)>;
47005ffd83dbSDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA",
47015ffd83dbSDimitry Andric                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
47025ffd83dbSDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA",
47035ffd83dbSDimitry Andric                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
4704