xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrVSX.td (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
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
28*5ffd83dbSDimitry Andric// *********************************** NOTE ***********************************
29*5ffd83dbSDimitry Andric// ** When adding new anonymous patterns to this file, please add them to    **
30*5ffd83dbSDimitry Andric// ** the section titled Anonymous Patterns. Chances are that the existing   **
31*5ffd83dbSDimitry Andric// ** predicate blocks already contain a combination of features that you    **
32*5ffd83dbSDimitry Andric// ** are after. There is a list of blocks at the top of the section. If     **
33*5ffd83dbSDimitry Andric// ** you definitely need a new combination of predicates, please add that   **
34*5ffd83dbSDimitry Andric// ** combination to the list.                                               **
35*5ffd83dbSDimitry Andric// ** File Structure:                                                        **
36*5ffd83dbSDimitry Andric// ** - Custom PPCISD node definitions                                       **
37*5ffd83dbSDimitry Andric// ** - Predicate definitions: predicates to specify the subtargets for      **
38*5ffd83dbSDimitry Andric// **   which an instruction or pattern can be emitted.                      **
39*5ffd83dbSDimitry Andric// ** - Instruction formats: classes instantiated by the instructions.       **
40*5ffd83dbSDimitry Andric// **   These generally correspond to instruction formats in section 1.6 of  **
41*5ffd83dbSDimitry Andric// **   the ISA document.                                                    **
42*5ffd83dbSDimitry Andric// ** - Instruction definitions: the actual definitions of the instructions  **
43*5ffd83dbSDimitry Andric// **   often including input patterns that they match.                      **
44*5ffd83dbSDimitry Andric// ** - Helper DAG definitions: We define a number of dag objects to use as  **
45*5ffd83dbSDimitry Andric// **   input or output patterns for consciseness of the code.               **
46*5ffd83dbSDimitry Andric// ** - Anonymous patterns: input patterns that an instruction matches can   **
47*5ffd83dbSDimitry Andric// **   often not be specified as part of the instruction definition, so an  **
48*5ffd83dbSDimitry Andric// **   anonymous pattern must be specified mapping an input pattern to an   **
49*5ffd83dbSDimitry Andric// **   output pattern. These are generally guarded by subtarget predicates. **
50*5ffd83dbSDimitry Andric// ** - Instruction aliases: used to define extended mnemonics for assembly  **
51*5ffd83dbSDimitry Andric// **   printing (for example: xxswapd for xxpermdi with 0x2 as the imm).    **
52*5ffd83dbSDimitry Andric// ****************************************************************************
53*5ffd83dbSDimitry 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
118*5ffd83dbSDimitry 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]>;
141*5ffd83dbSDimitry Andricdef PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED",
142*5ffd83dbSDimitry Andric                     SDTypeProfile<1, 1, []>, []>;
1430b57cec5SDimitry Andric
144*5ffd83dbSDimitry Andric//-------------------------- Predicate definitions ---------------------------//
145*5ffd83dbSDimitry Andricdef HasVSX : Predicate<"Subtarget->hasVSX()">;
146*5ffd83dbSDimitry Andricdef IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">;
147*5ffd83dbSDimitry Andricdef IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">;
148*5ffd83dbSDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">;
149*5ffd83dbSDimitry Andricdef HasP8Vector : Predicate<"Subtarget->hasP8Vector()">;
150*5ffd83dbSDimitry Andricdef HasDirectMove : Predicate<"Subtarget->hasDirectMove()">;
151*5ffd83dbSDimitry Andricdef NoP9Vector : Predicate<"!Subtarget->hasP9Vector()">;
152*5ffd83dbSDimitry Andricdef HasP9Vector : Predicate<"Subtarget->hasP9Vector()">;
153*5ffd83dbSDimitry Andricdef NoP9Altivec : Predicate<"!Subtarget->hasP9Altivec()">;
154*5ffd83dbSDimitry Andric
155*5ffd83dbSDimitry Andric//--------------------- VSX-specific instruction formats ---------------------//
156*5ffd83dbSDimitry Andric// By default, all VSX instructions are to be selected over their Altivec
157*5ffd83dbSDimitry Andric// counter parts and they do not have unmodeled sideeffects.
158*5ffd83dbSDimitry Andriclet AddedComplexity = 400, hasSideEffects = 0 in {
1590b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
1600b57cec5SDimitry Andric                    string asmstr, InstrItinClass itin, Intrinsic Int,
1610b57cec5SDimitry Andric                    ValueType OutTy, ValueType InTy> {
1620b57cec5SDimitry Andric  let BaseName = asmbase in {
1630b57cec5SDimitry Andric    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1640b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
1650b57cec5SDimitry Andric                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
1660b57cec5SDimitry Andric    let Defs = [CR6] in
167480093f4SDimitry Andric    def _rec    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1680b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1690b57cec5SDimitry Andric                       [(set InTy:$XT,
1700b57cec5SDimitry Andric                                (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>,
171480093f4SDimitry Andric                       isRecordForm;
1720b57cec5SDimitry Andric  }
1730b57cec5SDimitry Andric}
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as
1760b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained
1770b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained
1780b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though
1790b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction
1800b57cec5SDimitry Andric// to use the same register for both inputs.
1810b57cec5SDimitry Andric// For example, an output DAG such as this:
1820b57cec5SDimitry Andric//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
1830b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs
1840b57cec5SDimitry Andric// to the XXPERMDI instruction.
1850b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
1860b57cec5SDimitry Andric                 InstrItinClass itin, list<dag> pattern>
1870b57cec5SDimitry Andric  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
1880b57cec5SDimitry Andric    let XB = XA;
1890b57cec5SDimitry Andric}
1900b57cec5SDimitry Andric
191*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
192*5ffd83dbSDimitry Andricclass X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
193*5ffd83dbSDimitry Andric                    list<dag> pattern>
194*5ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
195*5ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1960b57cec5SDimitry Andric
197*5ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
198*5ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
199*5ffd83dbSDimitry Andric                       list<dag> pattern>
200*5ffd83dbSDimitry Andric  : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm;
201*5ffd83dbSDimitry Andric
202*5ffd83dbSDimitry Andric// [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
203*5ffd83dbSDimitry Andric// So we use different operand class for VRB
204*5ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
205*5ffd83dbSDimitry Andric                         RegisterOperand vbtype, list<dag> pattern>
206*5ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
207*5ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
208*5ffd83dbSDimitry Andric
209*5ffd83dbSDimitry Andric// [PO VRT XO VRB XO /]
210*5ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
211*5ffd83dbSDimitry Andric                    list<dag> pattern>
212*5ffd83dbSDimitry Andric  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
213*5ffd83dbSDimitry Andric                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
214*5ffd83dbSDimitry Andric
215*5ffd83dbSDimitry Andric// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
216*5ffd83dbSDimitry Andricclass X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
217*5ffd83dbSDimitry Andric                       list<dag> pattern>
218*5ffd83dbSDimitry Andric  : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm;
219*5ffd83dbSDimitry Andric
220*5ffd83dbSDimitry Andric// [PO T XO B XO BX /]
221*5ffd83dbSDimitry Andricclass XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
222*5ffd83dbSDimitry Andric                      list<dag> pattern>
223*5ffd83dbSDimitry Andric  : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
224*5ffd83dbSDimitry Andric                    !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
225*5ffd83dbSDimitry Andric
226*5ffd83dbSDimitry Andric// [PO T XO B XO BX TX]
227*5ffd83dbSDimitry Andricclass XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
228*5ffd83dbSDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
229*5ffd83dbSDimitry Andric  : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
230*5ffd83dbSDimitry Andric                    !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
231*5ffd83dbSDimitry Andric
232*5ffd83dbSDimitry Andric// [PO T A B XO AX BX TX], src and dest register use different operand class
233*5ffd83dbSDimitry Andricclass XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
234*5ffd83dbSDimitry Andric                RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
235*5ffd83dbSDimitry Andric                InstrItinClass itin, list<dag> pattern>
236*5ffd83dbSDimitry Andric  : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
237*5ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
238*5ffd83dbSDimitry Andric
239*5ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
240*5ffd83dbSDimitry Andricclass X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
241*5ffd83dbSDimitry Andric                    list<dag> pattern>
242*5ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
243*5ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
244*5ffd83dbSDimitry Andric
245*5ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
246*5ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
247*5ffd83dbSDimitry Andric                       list<dag> pattern>
248*5ffd83dbSDimitry Andric  : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm;
249*5ffd83dbSDimitry Andric
250*5ffd83dbSDimitry Andric// [PO VRT VRA VRB XO /]
251*5ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
252*5ffd83dbSDimitry Andric                        list<dag> pattern>
253*5ffd83dbSDimitry Andric  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
254*5ffd83dbSDimitry Andric            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
255*5ffd83dbSDimitry Andric            RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
256*5ffd83dbSDimitry Andric
257*5ffd83dbSDimitry Andric// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
258*5ffd83dbSDimitry Andricclass X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
259*5ffd83dbSDimitry Andric                        list<dag> pattern>
260*5ffd83dbSDimitry Andric  : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm;
261*5ffd83dbSDimitry Andric
262*5ffd83dbSDimitry Andricclass Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
263*5ffd83dbSDimitry Andric                              list<dag> pattern>
264*5ffd83dbSDimitry Andric  : Z23Form_8<opcode, xo,
265*5ffd83dbSDimitry Andric              (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
266*5ffd83dbSDimitry Andric              !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
267*5ffd83dbSDimitry Andric  let RC = ex;
268*5ffd83dbSDimitry Andric}
269*5ffd83dbSDimitry Andric
270*5ffd83dbSDimitry Andric// [PO BF // VRA VRB XO /]
271*5ffd83dbSDimitry Andricclass X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
272*5ffd83dbSDimitry Andric                    list<dag> pattern>
273*5ffd83dbSDimitry Andric  : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
274*5ffd83dbSDimitry Andric             !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
275*5ffd83dbSDimitry Andric  let Pattern = pattern;
276*5ffd83dbSDimitry Andric}
277*5ffd83dbSDimitry Andric
278*5ffd83dbSDimitry Andric// [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
279*5ffd83dbSDimitry Andric// "out" and "in" dag
280*5ffd83dbSDimitry Andricclass X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
281*5ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
282*5ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
283*5ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
284*5ffd83dbSDimitry Andric
285*5ffd83dbSDimitry Andric// [PO S RA RB XO SX]
286*5ffd83dbSDimitry Andricclass X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
287*5ffd83dbSDimitry Andric                    RegisterOperand vtype, list<dag> pattern>
288*5ffd83dbSDimitry Andric  : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
289*5ffd83dbSDimitry Andric            !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
290*5ffd83dbSDimitry Andric} // Predicates = HasP9Vector
291*5ffd83dbSDimitry Andric} // AddedComplexity = 400, hasSideEffects = 0
292*5ffd83dbSDimitry Andric
293*5ffd83dbSDimitry Andricmulticlass ScalToVecWPermute<ValueType Ty, dag In, dag NonPermOut, dag PermOut> {
294*5ffd83dbSDimitry Andric  def : Pat<(Ty (scalar_to_vector In)), (Ty NonPermOut)>;
295*5ffd83dbSDimitry Andric  def : Pat<(Ty (PPCSToV In)), (Ty PermOut)>;
296*5ffd83dbSDimitry Andric}
297*5ffd83dbSDimitry Andric
298*5ffd83dbSDimitry Andric//-------------------------- Instruction definitions -------------------------//
299*5ffd83dbSDimitry Andric// VSX instructions require the VSX feature, they are to be selected over
300*5ffd83dbSDimitry Andric// equivalent Altivec patterns (as they address a larger register set) and
301*5ffd83dbSDimitry Andric// they do not have unmodeled side effects.
302*5ffd83dbSDimitry Andriclet Predicates = [HasVSX], AddedComplexity = 400 in {
303*5ffd83dbSDimitry Andriclet hasSideEffects = 0 in {
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric  // Load indexed instructions
3060b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
3070b57cec5SDimitry Andric    let CodeSize = 3 in
3080b57cec5SDimitry Andric    def LXSDX : XX1Form_memOp<31, 588,
3090b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
3100b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
3110b57cec5SDimitry Andric                        []>;
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andric    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
3140b57cec5SDimitry Andric    let CodeSize = 3 in
3150b57cec5SDimitry Andric      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
3160b57cec5SDimitry Andric                              "#XFLOADf64",
3170b57cec5SDimitry Andric                              [(set f64:$XT, (load xoaddr:$src))]>;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3200b57cec5SDimitry Andric    def LXVD2X : XX1Form_memOp<31, 844,
3210b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3220b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
3230b57cec5SDimitry Andric                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric    def LXVDSX : XX1Form_memOp<31, 332,
3260b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3270b57cec5SDimitry Andric                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
3300b57cec5SDimitry Andric    def LXVW4X : XX1Form_memOp<31, 780,
3310b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
3320b57cec5SDimitry Andric                         "lxvw4x $XT, $src", IIC_LdStLFD,
3330b57cec5SDimitry Andric                         []>;
3340b57cec5SDimitry Andric  } // mayLoad
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andric  // Store indexed instructions
3370b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
3380b57cec5SDimitry Andric    let CodeSize = 3 in
3390b57cec5SDimitry Andric    def STXSDX : XX1Form_memOp<31, 716,
3400b57cec5SDimitry Andric                        (outs), (ins vsfrc:$XT, memrr:$dst),
3410b57cec5SDimitry Andric                        "stxsdx $XT, $dst", IIC_LdStSTFD,
3420b57cec5SDimitry Andric                        []>;
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
3450b57cec5SDimitry Andric    let CodeSize = 3 in
3460b57cec5SDimitry Andric      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
3470b57cec5SDimitry Andric                              "#XFSTOREf64",
3480b57cec5SDimitry Andric                              [(store f64:$XT, xoaddr:$dst)]>;
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3510b57cec5SDimitry Andric    // The behaviour of this instruction is endianness-specific so we provide no
3520b57cec5SDimitry Andric    // pattern to match it without considering endianness.
3530b57cec5SDimitry Andric    def STXVD2X : XX1Form_memOp<31, 972,
3540b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3550b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
3560b57cec5SDimitry Andric                         []>;
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric    def STXVW4X : XX1Form_memOp<31, 908,
3590b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
3600b57cec5SDimitry Andric                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
3610b57cec5SDimitry Andric                         []>;
3620b57cec5SDimitry Andric    }
3630b57cec5SDimitry Andric  } // mayStore
3640b57cec5SDimitry Andric
365*5ffd83dbSDimitry Andric  let Uses = [RM], mayRaiseFPException = 1 in {
3660b57cec5SDimitry Andric  // Add/Mul Instructions
3670b57cec5SDimitry Andric  let isCommutable = 1 in {
3680b57cec5SDimitry Andric    def XSADDDP : XX3Form<60, 32,
3690b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3700b57cec5SDimitry Andric                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
371*5ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>;
3720b57cec5SDimitry Andric    def XSMULDP : XX3Form<60, 48,
3730b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
3740b57cec5SDimitry Andric                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
375*5ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>;
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andric    def XVADDDP : XX3Form<60, 96,
3780b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3790b57cec5SDimitry Andric                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
380*5ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>;
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric    def XVADDSP : XX3Form<60, 64,
3830b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3840b57cec5SDimitry Andric                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
385*5ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>;
3860b57cec5SDimitry Andric
3870b57cec5SDimitry Andric    def XVMULDP : XX3Form<60, 112,
3880b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3890b57cec5SDimitry Andric                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
390*5ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>;
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric    def XVMULSP : XX3Form<60, 80,
3930b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
3940b57cec5SDimitry Andric                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
395*5ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>;
3960b57cec5SDimitry Andric  }
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric  // Subtract Instructions
3990b57cec5SDimitry Andric  def XSSUBDP : XX3Form<60, 40,
4000b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
4010b57cec5SDimitry Andric                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
402*5ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric  def XVSUBDP : XX3Form<60, 104,
4050b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4060b57cec5SDimitry Andric                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
407*5ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>;
4080b57cec5SDimitry Andric  def XVSUBSP : XX3Form<60, 72,
4090b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4100b57cec5SDimitry Andric                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
411*5ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>;
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric  // FMA Instructions
4140b57cec5SDimitry Andric  let BaseName = "XSMADDADP" in {
4150b57cec5SDimitry Andric  let isCommutable = 1 in
4160b57cec5SDimitry Andric  def XSMADDADP : XX3Form<60, 33,
4170b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4180b57cec5SDimitry Andric                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
419*5ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, f64:$XTi))]>,
4200b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4210b57cec5SDimitry Andric                          AltVSXFMARel;
4220b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4230b57cec5SDimitry Andric  def XSMADDMDP : XX3Form<60, 41,
4240b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4250b57cec5SDimitry Andric                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4260b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4270b57cec5SDimitry Andric                          AltVSXFMARel;
4280b57cec5SDimitry Andric  }
4290b57cec5SDimitry Andric
4300b57cec5SDimitry Andric  let BaseName = "XSMSUBADP" in {
4310b57cec5SDimitry Andric  let isCommutable = 1 in
4320b57cec5SDimitry Andric  def XSMSUBADP : XX3Form<60, 49,
4330b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4340b57cec5SDimitry Andric                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
435*5ffd83dbSDimitry Andric                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
4360b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4370b57cec5SDimitry Andric                          AltVSXFMARel;
4380b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4390b57cec5SDimitry Andric  def XSMSUBMDP : XX3Form<60, 57,
4400b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4410b57cec5SDimitry Andric                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4420b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4430b57cec5SDimitry Andric                          AltVSXFMARel;
4440b57cec5SDimitry Andric  }
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric  let BaseName = "XSNMADDADP" in {
4470b57cec5SDimitry Andric  let isCommutable = 1 in
4480b57cec5SDimitry Andric  def XSNMADDADP : XX3Form<60, 161,
4490b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4500b57cec5SDimitry Andric                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
451*5ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, f64:$XTi)))]>,
4520b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4530b57cec5SDimitry Andric                          AltVSXFMARel;
4540b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4550b57cec5SDimitry Andric  def XSNMADDMDP : XX3Form<60, 169,
4560b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4570b57cec5SDimitry Andric                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4580b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4590b57cec5SDimitry Andric                          AltVSXFMARel;
4600b57cec5SDimitry Andric  }
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andric  let BaseName = "XSNMSUBADP" in {
4630b57cec5SDimitry Andric  let isCommutable = 1 in
4640b57cec5SDimitry Andric  def XSNMSUBADP : XX3Form<60, 177,
4650b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4660b57cec5SDimitry Andric                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
467*5ffd83dbSDimitry Andric                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
4680b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4690b57cec5SDimitry Andric                          AltVSXFMARel;
4700b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4710b57cec5SDimitry Andric  def XSNMSUBMDP : XX3Form<60, 185,
4720b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
4730b57cec5SDimitry Andric                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4740b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4750b57cec5SDimitry Andric                          AltVSXFMARel;
4760b57cec5SDimitry Andric  }
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andric  let BaseName = "XVMADDADP" in {
4790b57cec5SDimitry Andric  let isCommutable = 1 in
4800b57cec5SDimitry Andric  def XVMADDADP : XX3Form<60, 97,
4810b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4820b57cec5SDimitry Andric                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
483*5ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
4840b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4850b57cec5SDimitry Andric                          AltVSXFMARel;
4860b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4870b57cec5SDimitry Andric  def XVMADDMDP : XX3Form<60, 105,
4880b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4890b57cec5SDimitry Andric                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4900b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4910b57cec5SDimitry Andric                          AltVSXFMARel;
4920b57cec5SDimitry Andric  }
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andric  let BaseName = "XVMADDASP" in {
4950b57cec5SDimitry Andric  let isCommutable = 1 in
4960b57cec5SDimitry Andric  def XVMADDASP : XX3Form<60, 65,
4970b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4980b57cec5SDimitry Andric                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
499*5ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
5000b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5010b57cec5SDimitry Andric                          AltVSXFMARel;
5020b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5030b57cec5SDimitry Andric  def XVMADDMSP : XX3Form<60, 73,
5040b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5050b57cec5SDimitry Andric                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5060b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5070b57cec5SDimitry Andric                          AltVSXFMARel;
5080b57cec5SDimitry Andric  }
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric  let BaseName = "XVMSUBADP" in {
5110b57cec5SDimitry Andric  let isCommutable = 1 in
5120b57cec5SDimitry Andric  def XVMSUBADP : XX3Form<60, 113,
5130b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5140b57cec5SDimitry Andric                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
515*5ffd83dbSDimitry Andric                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
5160b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5170b57cec5SDimitry Andric                          AltVSXFMARel;
5180b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5190b57cec5SDimitry Andric  def XVMSUBMDP : XX3Form<60, 121,
5200b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5210b57cec5SDimitry Andric                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5220b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5230b57cec5SDimitry Andric                          AltVSXFMARel;
5240b57cec5SDimitry Andric  }
5250b57cec5SDimitry Andric
5260b57cec5SDimitry Andric  let BaseName = "XVMSUBASP" in {
5270b57cec5SDimitry Andric  let isCommutable = 1 in
5280b57cec5SDimitry Andric  def XVMSUBASP : XX3Form<60, 81,
5290b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5300b57cec5SDimitry Andric                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
531*5ffd83dbSDimitry Andric                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
5320b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5330b57cec5SDimitry Andric                          AltVSXFMARel;
5340b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5350b57cec5SDimitry Andric  def XVMSUBMSP : XX3Form<60, 89,
5360b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5370b57cec5SDimitry Andric                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
5380b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5390b57cec5SDimitry Andric                          AltVSXFMARel;
5400b57cec5SDimitry Andric  }
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andric  let BaseName = "XVNMADDADP" in {
5430b57cec5SDimitry Andric  let isCommutable = 1 in
5440b57cec5SDimitry Andric  def XVNMADDADP : XX3Form<60, 225,
5450b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5460b57cec5SDimitry Andric                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
547*5ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
5480b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5490b57cec5SDimitry Andric                          AltVSXFMARel;
5500b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5510b57cec5SDimitry Andric  def XVNMADDMDP : XX3Form<60, 233,
5520b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5530b57cec5SDimitry Andric                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
5540b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5550b57cec5SDimitry Andric                          AltVSXFMARel;
5560b57cec5SDimitry Andric  }
5570b57cec5SDimitry Andric
5580b57cec5SDimitry Andric  let BaseName = "XVNMADDASP" in {
5590b57cec5SDimitry Andric  let isCommutable = 1 in
5600b57cec5SDimitry Andric  def XVNMADDASP : XX3Form<60, 193,
5610b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5620b57cec5SDimitry Andric                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
5630b57cec5SDimitry Andric                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
5640b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5650b57cec5SDimitry Andric                          AltVSXFMARel;
5660b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5670b57cec5SDimitry Andric  def XVNMADDMSP : XX3Form<60, 201,
5680b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5690b57cec5SDimitry Andric                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
5700b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5710b57cec5SDimitry Andric                          AltVSXFMARel;
5720b57cec5SDimitry Andric  }
5730b57cec5SDimitry Andric
5740b57cec5SDimitry Andric  let BaseName = "XVNMSUBADP" in {
5750b57cec5SDimitry Andric  let isCommutable = 1 in
5760b57cec5SDimitry Andric  def XVNMSUBADP : XX3Form<60, 241,
5770b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5780b57cec5SDimitry Andric                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
579*5ffd83dbSDimitry Andric                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
5800b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5810b57cec5SDimitry Andric                          AltVSXFMARel;
5820b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5830b57cec5SDimitry Andric  def XVNMSUBMDP : XX3Form<60, 249,
5840b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5850b57cec5SDimitry Andric                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
5860b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5870b57cec5SDimitry Andric                          AltVSXFMARel;
5880b57cec5SDimitry Andric  }
5890b57cec5SDimitry Andric
5900b57cec5SDimitry Andric  let BaseName = "XVNMSUBASP" in {
5910b57cec5SDimitry Andric  let isCommutable = 1 in
5920b57cec5SDimitry Andric  def XVNMSUBASP : XX3Form<60, 209,
5930b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
5940b57cec5SDimitry Andric                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
595*5ffd83dbSDimitry Andric                          [(set v4f32:$XT, (fneg (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
5960b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
5970b57cec5SDimitry Andric                          AltVSXFMARel;
5980b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
5990b57cec5SDimitry Andric  def XVNMSUBMSP : XX3Form<60, 217,
6000b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
6010b57cec5SDimitry Andric                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
6020b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
6030b57cec5SDimitry Andric                          AltVSXFMARel;
6040b57cec5SDimitry Andric  }
6050b57cec5SDimitry Andric
6060b57cec5SDimitry Andric  // Division Instructions
6070b57cec5SDimitry Andric  def XSDIVDP : XX3Form<60, 56,
6080b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
6090b57cec5SDimitry Andric                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
610*5ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>;
6110b57cec5SDimitry Andric  def XSSQRTDP : XX2Form<60, 75,
6120b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6130b57cec5SDimitry Andric                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
614*5ffd83dbSDimitry Andric                        [(set f64:$XT, (any_fsqrt f64:$XB))]>;
6150b57cec5SDimitry Andric
6160b57cec5SDimitry Andric  def XSREDP : XX2Form<60, 90,
6170b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
6180b57cec5SDimitry Andric                        "xsredp $XT, $XB", IIC_VecFP,
6190b57cec5SDimitry Andric                        [(set f64:$XT, (PPCfre f64:$XB))]>;
6200b57cec5SDimitry Andric  def XSRSQRTEDP : XX2Form<60, 74,
6210b57cec5SDimitry Andric                           (outs vsfrc:$XT), (ins vsfrc:$XB),
6220b57cec5SDimitry Andric                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
6230b57cec5SDimitry Andric                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
6240b57cec5SDimitry Andric
6250b57cec5SDimitry Andric  def XSTDIVDP : XX3Form_1<60, 61,
6260b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6270b57cec5SDimitry Andric                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
6280b57cec5SDimitry Andric  def XSTSQRTDP : XX2Form_1<60, 106,
6290b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsfrc:$XB),
6300b57cec5SDimitry Andric                          "xstsqrtdp $crD, $XB", IIC_FPCompare, []>;
6310b57cec5SDimitry Andric
6320b57cec5SDimitry Andric  def XVDIVDP : XX3Form<60, 120,
6330b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6340b57cec5SDimitry Andric                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
635*5ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>;
6360b57cec5SDimitry Andric  def XVDIVSP : XX3Form<60, 88,
6370b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
6380b57cec5SDimitry Andric                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
639*5ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>;
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andric  def XVSQRTDP : XX2Form<60, 203,
6420b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6430b57cec5SDimitry Andric                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
644*5ffd83dbSDimitry Andric                        [(set v2f64:$XT, (any_fsqrt v2f64:$XB))]>;
6450b57cec5SDimitry Andric  def XVSQRTSP : XX2Form<60, 139,
6460b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6470b57cec5SDimitry Andric                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
648*5ffd83dbSDimitry Andric                        [(set v4f32:$XT, (any_fsqrt v4f32:$XB))]>;
6490b57cec5SDimitry Andric
6500b57cec5SDimitry Andric  def XVTDIVDP : XX3Form_1<60, 125,
6510b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
6520b57cec5SDimitry Andric                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
6530b57cec5SDimitry Andric  def XVTDIVSP : XX3Form_1<60, 93,
6540b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
6550b57cec5SDimitry Andric                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
6560b57cec5SDimitry Andric
6570b57cec5SDimitry Andric  def XVTSQRTDP : XX2Form_1<60, 234,
6580b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
6590b57cec5SDimitry Andric                          "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
6600b57cec5SDimitry Andric  def XVTSQRTSP : XX2Form_1<60, 170,
6610b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
6620b57cec5SDimitry Andric                          "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
6630b57cec5SDimitry Andric
6640b57cec5SDimitry Andric  def XVREDP : XX2Form<60, 218,
6650b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6660b57cec5SDimitry Andric                        "xvredp $XT, $XB", IIC_VecFP,
6670b57cec5SDimitry Andric                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
6680b57cec5SDimitry Andric  def XVRESP : XX2Form<60, 154,
6690b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
6700b57cec5SDimitry Andric                        "xvresp $XT, $XB", IIC_VecFP,
6710b57cec5SDimitry Andric                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
6720b57cec5SDimitry Andric
6730b57cec5SDimitry Andric  def XVRSQRTEDP : XX2Form<60, 202,
6740b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6750b57cec5SDimitry Andric                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
6760b57cec5SDimitry Andric                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
6770b57cec5SDimitry Andric  def XVRSQRTESP : XX2Form<60, 138,
6780b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
6790b57cec5SDimitry Andric                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
6800b57cec5SDimitry Andric                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
6810b57cec5SDimitry Andric
6820b57cec5SDimitry Andric  // Compare Instructions
6830b57cec5SDimitry Andric  def XSCMPODP : XX3Form_1<60, 43,
6840b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6850b57cec5SDimitry Andric                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
6860b57cec5SDimitry Andric  def XSCMPUDP : XX3Form_1<60, 35,
6870b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
6880b57cec5SDimitry Andric                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
6890b57cec5SDimitry Andric
6900b57cec5SDimitry Andric  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
6910b57cec5SDimitry Andric                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
6920b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
6930b57cec5SDimitry Andric  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
6940b57cec5SDimitry Andric                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
6950b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
6960b57cec5SDimitry Andric  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
6970b57cec5SDimitry Andric                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
6980b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
6990b57cec5SDimitry Andric  defm XVCMPGESP : XX3Form_Rcr<60, 83,
7000b57cec5SDimitry Andric                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
7010b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
7020b57cec5SDimitry Andric  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
7030b57cec5SDimitry Andric                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
7040b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
7050b57cec5SDimitry Andric  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
7060b57cec5SDimitry Andric                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
7070b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
7080b57cec5SDimitry Andric
7090b57cec5SDimitry Andric  // Move Instructions
7100b57cec5SDimitry Andric  def XSABSDP : XX2Form<60, 345,
7110b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7120b57cec5SDimitry Andric                      "xsabsdp $XT, $XB", IIC_VecFP,
7130b57cec5SDimitry Andric                      [(set f64:$XT, (fabs f64:$XB))]>;
7140b57cec5SDimitry Andric  def XSNABSDP : XX2Form<60, 361,
7150b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7160b57cec5SDimitry Andric                      "xsnabsdp $XT, $XB", IIC_VecFP,
7170b57cec5SDimitry Andric                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
7180b57cec5SDimitry Andric  def XSNEGDP : XX2Form<60, 377,
7190b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7200b57cec5SDimitry Andric                      "xsnegdp $XT, $XB", IIC_VecFP,
7210b57cec5SDimitry Andric                      [(set f64:$XT, (fneg f64:$XB))]>;
7220b57cec5SDimitry Andric  def XSCPSGNDP : XX3Form<60, 176,
7230b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
7240b57cec5SDimitry Andric                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
7250b57cec5SDimitry Andric                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric  def XVABSDP : XX2Form<60, 473,
7280b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7290b57cec5SDimitry Andric                      "xvabsdp $XT, $XB", IIC_VecFP,
7300b57cec5SDimitry Andric                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
7310b57cec5SDimitry Andric
7320b57cec5SDimitry Andric  def XVABSSP : XX2Form<60, 409,
7330b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7340b57cec5SDimitry Andric                      "xvabssp $XT, $XB", IIC_VecFP,
7350b57cec5SDimitry Andric                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
7360b57cec5SDimitry Andric
7370b57cec5SDimitry Andric  def XVCPSGNDP : XX3Form<60, 240,
7380b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7390b57cec5SDimitry Andric                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
7400b57cec5SDimitry Andric                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
7410b57cec5SDimitry Andric  def XVCPSGNSP : XX3Form<60, 208,
7420b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
7430b57cec5SDimitry Andric                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
7440b57cec5SDimitry Andric                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
7450b57cec5SDimitry Andric
7460b57cec5SDimitry Andric  def XVNABSDP : XX2Form<60, 489,
7470b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7480b57cec5SDimitry Andric                      "xvnabsdp $XT, $XB", IIC_VecFP,
7490b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
7500b57cec5SDimitry Andric  def XVNABSSP : XX2Form<60, 425,
7510b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7520b57cec5SDimitry Andric                      "xvnabssp $XT, $XB", IIC_VecFP,
7530b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andric  def XVNEGDP : XX2Form<60, 505,
7560b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7570b57cec5SDimitry Andric                      "xvnegdp $XT, $XB", IIC_VecFP,
7580b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
7590b57cec5SDimitry Andric  def XVNEGSP : XX2Form<60, 441,
7600b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7610b57cec5SDimitry Andric                      "xvnegsp $XT, $XB", IIC_VecFP,
7620b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
7630b57cec5SDimitry Andric
7640b57cec5SDimitry Andric  // Conversion Instructions
7650b57cec5SDimitry Andric  def XSCVDPSP : XX2Form<60, 265,
7660b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7670b57cec5SDimitry Andric                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
7680b57cec5SDimitry Andric  def XSCVDPSXDS : XX2Form<60, 344,
7690b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7700b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
7710b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctidz f64:$XB))]>;
7720b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7730b57cec5SDimitry Andric  def XSCVDPSXDSs : XX2Form<60, 344,
7740b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7750b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
7760b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctidz f32:$XB))]>;
7770b57cec5SDimitry Andric  def XSCVDPSXWS : XX2Form<60, 88,
7780b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7790b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
7800b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctiwz f64:$XB))]>;
7810b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7820b57cec5SDimitry Andric  def XSCVDPSXWSs : XX2Form<60, 88,
7830b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7840b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
7850b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctiwz f32:$XB))]>;
7860b57cec5SDimitry Andric  def XSCVDPUXDS : XX2Form<60, 328,
7870b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7880b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
7890b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctiduz f64:$XB))]>;
7900b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
7910b57cec5SDimitry Andric  def XSCVDPUXDSs : XX2Form<60, 328,
7920b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
7930b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
7940b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctiduz f32:$XB))]>;
7950b57cec5SDimitry Andric  def XSCVDPUXWS : XX2Form<60, 72,
7960b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7970b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
7980b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctiwuz f64:$XB))]>;
7990b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
8000b57cec5SDimitry Andric  def XSCVDPUXWSs : XX2Form<60, 72,
8010b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
8020b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
8030b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctiwuz f32:$XB))]>;
8040b57cec5SDimitry Andric  def XSCVSPDP : XX2Form<60, 329,
8050b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8060b57cec5SDimitry Andric                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
8070b57cec5SDimitry Andric  def XSCVSXDDP : XX2Form<60, 376,
8080b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8090b57cec5SDimitry Andric                      "xscvsxddp $XT, $XB", IIC_VecFP,
8100b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfcfid f64:$XB))]>;
8110b57cec5SDimitry Andric  def XSCVUXDDP : XX2Form<60, 360,
8120b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8130b57cec5SDimitry Andric                      "xscvuxddp $XT, $XB", IIC_VecFP,
8140b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfcfidu f64:$XB))]>;
8150b57cec5SDimitry Andric
8160b57cec5SDimitry Andric  def XVCVDPSP : XX2Form<60, 393,
8170b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8180b57cec5SDimitry Andric                      "xvcvdpsp $XT, $XB", IIC_VecFP,
8190b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
8200b57cec5SDimitry Andric  def XVCVDPSXDS : XX2Form<60, 472,
8210b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8220b57cec5SDimitry Andric                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
8230b57cec5SDimitry Andric                      [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>;
8240b57cec5SDimitry Andric  def XVCVDPSXWS : XX2Form<60, 216,
8250b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8260b57cec5SDimitry Andric                      "xvcvdpsxws $XT, $XB", IIC_VecFP,
8270b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
8280b57cec5SDimitry Andric  def XVCVDPUXDS : XX2Form<60, 456,
8290b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8300b57cec5SDimitry Andric                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
8310b57cec5SDimitry Andric                      [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>;
8320b57cec5SDimitry Andric  def XVCVDPUXWS : XX2Form<60, 200,
8330b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8340b57cec5SDimitry Andric                      "xvcvdpuxws $XT, $XB", IIC_VecFP,
8350b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
8360b57cec5SDimitry Andric
8370b57cec5SDimitry Andric  def XVCVSPDP : XX2Form<60, 457,
8380b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8390b57cec5SDimitry Andric                      "xvcvspdp $XT, $XB", IIC_VecFP,
8400b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
8410b57cec5SDimitry Andric  def XVCVSPSXDS : XX2Form<60, 408,
8420b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8430b57cec5SDimitry Andric                      "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
8440b57cec5SDimitry Andric  def XVCVSPSXWS : XX2Form<60, 152,
8450b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8460b57cec5SDimitry Andric                      "xvcvspsxws $XT, $XB", IIC_VecFP,
8470b57cec5SDimitry Andric                      [(set v4i32:$XT, (fp_to_sint v4f32:$XB))]>;
8480b57cec5SDimitry Andric  def XVCVSPUXDS : XX2Form<60, 392,
8490b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8500b57cec5SDimitry Andric                      "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
8510b57cec5SDimitry Andric  def XVCVSPUXWS : XX2Form<60, 136,
8520b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8530b57cec5SDimitry Andric                      "xvcvspuxws $XT, $XB", IIC_VecFP,
8540b57cec5SDimitry Andric                      [(set v4i32:$XT, (fp_to_uint v4f32:$XB))]>;
8550b57cec5SDimitry Andric  def XVCVSXDDP : XX2Form<60, 504,
8560b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8570b57cec5SDimitry Andric                      "xvcvsxddp $XT, $XB", IIC_VecFP,
8580b57cec5SDimitry Andric                      [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>;
8590b57cec5SDimitry Andric  def XVCVSXDSP : XX2Form<60, 440,
8600b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8610b57cec5SDimitry Andric                      "xvcvsxdsp $XT, $XB", IIC_VecFP,
8620b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
8630b57cec5SDimitry Andric  def XVCVSXWDP : XX2Form<60, 248,
8640b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8650b57cec5SDimitry Andric                      "xvcvsxwdp $XT, $XB", IIC_VecFP,
8660b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
8670b57cec5SDimitry Andric  def XVCVSXWSP : XX2Form<60, 184,
8680b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8690b57cec5SDimitry Andric                      "xvcvsxwsp $XT, $XB", IIC_VecFP,
8700b57cec5SDimitry Andric                      [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>;
8710b57cec5SDimitry Andric  def XVCVUXDDP : XX2Form<60, 488,
8720b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8730b57cec5SDimitry Andric                      "xvcvuxddp $XT, $XB", IIC_VecFP,
8740b57cec5SDimitry Andric                      [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>;
8750b57cec5SDimitry Andric  def XVCVUXDSP : XX2Form<60, 424,
8760b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8770b57cec5SDimitry Andric                      "xvcvuxdsp $XT, $XB", IIC_VecFP,
8780b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
8790b57cec5SDimitry Andric  def XVCVUXWDP : XX2Form<60, 232,
8800b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8810b57cec5SDimitry Andric                      "xvcvuxwdp $XT, $XB", IIC_VecFP,
8820b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
8830b57cec5SDimitry Andric  def XVCVUXWSP : XX2Form<60, 168,
8840b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8850b57cec5SDimitry Andric                      "xvcvuxwsp $XT, $XB", IIC_VecFP,
8860b57cec5SDimitry Andric                      [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>;
8870b57cec5SDimitry Andric
8880b57cec5SDimitry Andric  // Rounding Instructions
8890b57cec5SDimitry Andric  def XSRDPI : XX2Form<60, 73,
8900b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8910b57cec5SDimitry Andric                      "xsrdpi $XT, $XB", IIC_VecFP,
892*5ffd83dbSDimitry Andric                      [(set f64:$XT, (any_fround f64:$XB))]>;
8930b57cec5SDimitry Andric  def XSRDPIC : XX2Form<60, 107,
8940b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8950b57cec5SDimitry Andric                      "xsrdpic $XT, $XB", IIC_VecFP,
896*5ffd83dbSDimitry Andric                      [(set f64:$XT, (any_fnearbyint f64:$XB))]>;
8970b57cec5SDimitry Andric  def XSRDPIM : XX2Form<60, 121,
8980b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
8990b57cec5SDimitry Andric                      "xsrdpim $XT, $XB", IIC_VecFP,
900*5ffd83dbSDimitry Andric                      [(set f64:$XT, (any_ffloor f64:$XB))]>;
9010b57cec5SDimitry Andric  def XSRDPIP : XX2Form<60, 105,
9020b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
9030b57cec5SDimitry Andric                      "xsrdpip $XT, $XB", IIC_VecFP,
904*5ffd83dbSDimitry Andric                      [(set f64:$XT, (any_fceil f64:$XB))]>;
9050b57cec5SDimitry Andric  def XSRDPIZ : XX2Form<60, 89,
9060b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
9070b57cec5SDimitry Andric                      "xsrdpiz $XT, $XB", IIC_VecFP,
908*5ffd83dbSDimitry Andric                      [(set f64:$XT, (any_ftrunc f64:$XB))]>;
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andric  def XVRDPI : XX2Form<60, 201,
9110b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9120b57cec5SDimitry Andric                      "xvrdpi $XT, $XB", IIC_VecFP,
913*5ffd83dbSDimitry Andric                      [(set v2f64:$XT, (any_fround v2f64:$XB))]>;
9140b57cec5SDimitry Andric  def XVRDPIC : XX2Form<60, 235,
9150b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9160b57cec5SDimitry Andric                      "xvrdpic $XT, $XB", IIC_VecFP,
917*5ffd83dbSDimitry Andric                      [(set v2f64:$XT, (any_fnearbyint v2f64:$XB))]>;
9180b57cec5SDimitry Andric  def XVRDPIM : XX2Form<60, 249,
9190b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9200b57cec5SDimitry Andric                      "xvrdpim $XT, $XB", IIC_VecFP,
921*5ffd83dbSDimitry Andric                      [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
9220b57cec5SDimitry Andric  def XVRDPIP : XX2Form<60, 233,
9230b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9240b57cec5SDimitry Andric                      "xvrdpip $XT, $XB", IIC_VecFP,
925*5ffd83dbSDimitry Andric                      [(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
9260b57cec5SDimitry Andric  def XVRDPIZ : XX2Form<60, 217,
9270b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9280b57cec5SDimitry Andric                      "xvrdpiz $XT, $XB", IIC_VecFP,
929*5ffd83dbSDimitry Andric                      [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andric  def XVRSPI : XX2Form<60, 137,
9320b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9330b57cec5SDimitry Andric                      "xvrspi $XT, $XB", IIC_VecFP,
934*5ffd83dbSDimitry Andric                      [(set v4f32:$XT, (any_fround v4f32:$XB))]>;
9350b57cec5SDimitry Andric  def XVRSPIC : XX2Form<60, 171,
9360b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9370b57cec5SDimitry Andric                      "xvrspic $XT, $XB", IIC_VecFP,
938*5ffd83dbSDimitry Andric                      [(set v4f32:$XT, (any_fnearbyint v4f32:$XB))]>;
9390b57cec5SDimitry Andric  def XVRSPIM : XX2Form<60, 185,
9400b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9410b57cec5SDimitry Andric                      "xvrspim $XT, $XB", IIC_VecFP,
942*5ffd83dbSDimitry Andric                      [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
9430b57cec5SDimitry Andric  def XVRSPIP : XX2Form<60, 169,
9440b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9450b57cec5SDimitry Andric                      "xvrspip $XT, $XB", IIC_VecFP,
946*5ffd83dbSDimitry Andric                      [(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
9470b57cec5SDimitry Andric  def XVRSPIZ : XX2Form<60, 153,
9480b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
9490b57cec5SDimitry Andric                      "xvrspiz $XT, $XB", IIC_VecFP,
950*5ffd83dbSDimitry Andric                      [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
9510b57cec5SDimitry Andric
9520b57cec5SDimitry Andric  // Max/Min Instructions
9530b57cec5SDimitry Andric  let isCommutable = 1 in {
9540b57cec5SDimitry Andric  def XSMAXDP : XX3Form<60, 160,
9550b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9560b57cec5SDimitry Andric                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
9570b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9580b57cec5SDimitry Andric                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
9590b57cec5SDimitry Andric  def XSMINDP : XX3Form<60, 168,
9600b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
9610b57cec5SDimitry Andric                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
9620b57cec5SDimitry Andric                        [(set vsfrc:$XT,
9630b57cec5SDimitry Andric                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andric  def XVMAXDP : XX3Form<60, 224,
9660b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9670b57cec5SDimitry Andric                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
9680b57cec5SDimitry Andric                        [(set vsrc:$XT,
9690b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
9700b57cec5SDimitry Andric  def XVMINDP : XX3Form<60, 232,
9710b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9720b57cec5SDimitry Andric                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
9730b57cec5SDimitry Andric                        [(set vsrc:$XT,
9740b57cec5SDimitry Andric                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric  def XVMAXSP : XX3Form<60, 192,
9770b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9780b57cec5SDimitry Andric                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
9790b57cec5SDimitry Andric                        [(set vsrc:$XT,
9800b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
9810b57cec5SDimitry Andric  def XVMINSP : XX3Form<60, 200,
9820b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9830b57cec5SDimitry Andric                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
9840b57cec5SDimitry Andric                        [(set vsrc:$XT,
9850b57cec5SDimitry Andric                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
9860b57cec5SDimitry Andric  } // isCommutable
987*5ffd83dbSDimitry Andric  } // Uses = [RM], mayRaiseFPException
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andric  // Logical Instructions
9900b57cec5SDimitry Andric  let isCommutable = 1 in
9910b57cec5SDimitry Andric  def XXLAND : XX3Form<60, 130,
9920b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9930b57cec5SDimitry Andric                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
9940b57cec5SDimitry Andric                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
9950b57cec5SDimitry Andric  def XXLANDC : XX3Form<60, 138,
9960b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
9970b57cec5SDimitry Andric                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
9980b57cec5SDimitry Andric                        [(set v4i32:$XT, (and v4i32:$XA,
9990b57cec5SDimitry Andric                                              (vnot_ppc v4i32:$XB)))]>;
10000b57cec5SDimitry Andric  let isCommutable = 1 in {
10010b57cec5SDimitry Andric  def XXLNOR : XX3Form<60, 162,
10020b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10030b57cec5SDimitry Andric                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
10040b57cec5SDimitry Andric                       [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
10050b57cec5SDimitry Andric                                                   v4i32:$XB)))]>;
10060b57cec5SDimitry Andric  def XXLOR : XX3Form<60, 146,
10070b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10080b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
10090b57cec5SDimitry Andric                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
10100b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10110b57cec5SDimitry Andric  def XXLORf: XX3Form<60, 146,
10120b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
10130b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
10140b57cec5SDimitry Andric  def XXLXOR : XX3Form<60, 154,
10150b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10160b57cec5SDimitry Andric                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
10170b57cec5SDimitry Andric                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
10180b57cec5SDimitry Andric  } // isCommutable
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
10210b57cec5SDimitry Andric      isReMaterializable = 1 in {
10228bcb0991SDimitry Andric    def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
10230b57cec5SDimitry Andric                       "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10240b57cec5SDimitry Andric                       [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
10258bcb0991SDimitry Andric    def XXLXORdpz : XX3Form_SameOp<60, 154,
10260b57cec5SDimitry Andric                         (outs vsfrc:$XT), (ins),
10270b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10280b57cec5SDimitry Andric                         [(set f64:$XT, (fpimm0))]>;
10298bcb0991SDimitry Andric    def XXLXORspz : XX3Form_SameOp<60, 154,
10300b57cec5SDimitry Andric                         (outs vssrc:$XT), (ins),
10310b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
10320b57cec5SDimitry Andric                         [(set f32:$XT, (fpimm0))]>;
10330b57cec5SDimitry Andric  }
10340b57cec5SDimitry Andric
10350b57cec5SDimitry Andric  // Permutation Instructions
10360b57cec5SDimitry Andric  def XXMRGHW : XX3Form<60, 18,
10370b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10380b57cec5SDimitry Andric                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
10390b57cec5SDimitry Andric  def XXMRGLW : XX3Form<60, 50,
10400b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
10410b57cec5SDimitry Andric                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
10420b57cec5SDimitry Andric
10430b57cec5SDimitry Andric  def XXPERMDI : XX3Form_2<60, 10,
10440b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
10450b57cec5SDimitry Andric                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
10460b57cec5SDimitry Andric                       [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
10470b57cec5SDimitry Andric                         imm32SExt16:$DM))]>;
10480b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10490b57cec5SDimitry Andric  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
10500b57cec5SDimitry Andric                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
10510b57cec5SDimitry Andric  def XXSEL : XX4Form<60, 3,
10520b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
10530b57cec5SDimitry Andric                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric  def XXSLDWI : XX3Form_2<60, 2,
10560b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
10570b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
10580b57cec5SDimitry Andric                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
10590b57cec5SDimitry Andric                                                  imm32SExt16:$SHW))]>;
10600b57cec5SDimitry Andric
10610b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10620b57cec5SDimitry Andric  def XXSLDWIs : XX3Form_2s<60, 2,
10630b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
10640b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
10650b57cec5SDimitry Andric
10660b57cec5SDimitry Andric  def XXSPLTW : XX2Form_2<60, 164,
10670b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
10680b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
10690b57cec5SDimitry Andric                       [(set v4i32:$XT,
10700b57cec5SDimitry Andric                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
10710b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
10720b57cec5SDimitry Andric  def XXSPLTWs : XX2Form_2<60, 164,
10730b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
10740b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
10750b57cec5SDimitry Andric
1076*5ffd83dbSDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07
1077*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
1078*5ffd83dbSDimitry Andric  let isCommutable = 1 in {
1079*5ffd83dbSDimitry Andric    def XXLEQV : XX3Form<60, 186,
1080*5ffd83dbSDimitry Andric                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1081*5ffd83dbSDimitry Andric                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1082*5ffd83dbSDimitry Andric                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1083*5ffd83dbSDimitry Andric    def XXLNAND : XX3Form<60, 178,
1084*5ffd83dbSDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1085*5ffd83dbSDimitry Andric                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1086*5ffd83dbSDimitry Andric                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1087*5ffd83dbSDimitry Andric                                                    v4i32:$XB)))]>;
1088*5ffd83dbSDimitry Andric  } // isCommutable
10890b57cec5SDimitry Andric
1090*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
1091*5ffd83dbSDimitry Andric      isReMaterializable = 1 in {
1092*5ffd83dbSDimitry Andric    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
1093*5ffd83dbSDimitry Andric                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
1094*5ffd83dbSDimitry Andric                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
1095*5ffd83dbSDimitry Andric  }
1096*5ffd83dbSDimitry Andric
1097*5ffd83dbSDimitry Andric  def XXLORC : XX3Form<60, 170,
1098*5ffd83dbSDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1099*5ffd83dbSDimitry Andric                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1100*5ffd83dbSDimitry Andric                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1101*5ffd83dbSDimitry Andric
1102*5ffd83dbSDimitry Andric  // VSX scalar loads introduced in ISA 2.07
1103*5ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
1104*5ffd83dbSDimitry Andric    let CodeSize = 3 in
1105*5ffd83dbSDimitry Andric    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1106*5ffd83dbSDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
1107*5ffd83dbSDimitry Andric    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1108*5ffd83dbSDimitry Andric                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
1109*5ffd83dbSDimitry Andric    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1110*5ffd83dbSDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
1111*5ffd83dbSDimitry Andric
1112*5ffd83dbSDimitry Andric    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
1113*5ffd83dbSDimitry Andric    let CodeSize = 3 in
1114*5ffd83dbSDimitry Andric    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
1115*5ffd83dbSDimitry Andric                            "#XFLOADf32",
1116*5ffd83dbSDimitry Andric                            [(set f32:$XT, (load xoaddr:$src))]>;
1117*5ffd83dbSDimitry Andric    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
1118*5ffd83dbSDimitry Andric    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1119*5ffd83dbSDimitry Andric                       "#LIWAX",
1120*5ffd83dbSDimitry Andric                       [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1121*5ffd83dbSDimitry Andric    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
1122*5ffd83dbSDimitry Andric    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1123*5ffd83dbSDimitry Andric                       "#LIWZX",
1124*5ffd83dbSDimitry Andric                       [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1125*5ffd83dbSDimitry Andric  } // mayLoad
1126*5ffd83dbSDimitry Andric
1127*5ffd83dbSDimitry Andric  // VSX scalar stores introduced in ISA 2.07
1128*5ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
1129*5ffd83dbSDimitry Andric    let CodeSize = 3 in
1130*5ffd83dbSDimitry Andric    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1131*5ffd83dbSDimitry Andric                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
1132*5ffd83dbSDimitry Andric    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1133*5ffd83dbSDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
1134*5ffd83dbSDimitry Andric
1135*5ffd83dbSDimitry Andric    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
1136*5ffd83dbSDimitry Andric    let CodeSize = 3 in
1137*5ffd83dbSDimitry Andric    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
1138*5ffd83dbSDimitry Andric                            "#XFSTOREf32",
1139*5ffd83dbSDimitry Andric                            [(store f32:$XT, xoaddr:$dst)]>;
1140*5ffd83dbSDimitry Andric    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
1141*5ffd83dbSDimitry Andric    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1142*5ffd83dbSDimitry Andric                       "#STIWX",
1143*5ffd83dbSDimitry Andric                      [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1144*5ffd83dbSDimitry Andric  } // mayStore
1145*5ffd83dbSDimitry Andric
1146*5ffd83dbSDimitry Andric  // VSX Elementary Scalar FP arithmetic (SP)
1147*5ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
1148*5ffd83dbSDimitry Andric  let isCommutable = 1 in {
1149*5ffd83dbSDimitry Andric    def XSADDSP : XX3Form<60, 0,
1150*5ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1151*5ffd83dbSDimitry Andric                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1152*5ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>;
1153*5ffd83dbSDimitry Andric    def XSMULSP : XX3Form<60, 16,
1154*5ffd83dbSDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1155*5ffd83dbSDimitry Andric                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1156*5ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>;
1157*5ffd83dbSDimitry Andric  } // isCommutable
1158*5ffd83dbSDimitry Andric
1159*5ffd83dbSDimitry Andric  def XSSUBSP : XX3Form<60, 8,
1160*5ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1161*5ffd83dbSDimitry Andric                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
1162*5ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>;
1163*5ffd83dbSDimitry Andric  def XSDIVSP : XX3Form<60, 24,
1164*5ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1165*5ffd83dbSDimitry Andric                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1166*5ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>;
1167*5ffd83dbSDimitry Andric
1168*5ffd83dbSDimitry Andric  def XSRESP : XX2Form<60, 26,
1169*5ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
1170*5ffd83dbSDimitry Andric                        "xsresp $XT, $XB", IIC_VecFP,
1171*5ffd83dbSDimitry Andric                        [(set f32:$XT, (PPCfre f32:$XB))]>;
1172*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1173*5ffd83dbSDimitry Andric  let hasSideEffects = 1, mayRaiseFPException = 1 in
1174*5ffd83dbSDimitry Andric  def XSRSP : XX2Form<60, 281,
1175*5ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vsfrc:$XB),
1176*5ffd83dbSDimitry Andric                        "xsrsp $XT, $XB", IIC_VecFP,
1177*5ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fpround f64:$XB))]>;
1178*5ffd83dbSDimitry Andric  def XSSQRTSP : XX2Form<60, 11,
1179*5ffd83dbSDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
1180*5ffd83dbSDimitry Andric                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1181*5ffd83dbSDimitry Andric                        [(set f32:$XT, (any_fsqrt f32:$XB))]>;
1182*5ffd83dbSDimitry Andric  def XSRSQRTESP : XX2Form<60, 10,
1183*5ffd83dbSDimitry Andric                           (outs vssrc:$XT), (ins vssrc:$XB),
1184*5ffd83dbSDimitry Andric                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
1185*5ffd83dbSDimitry Andric                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1186*5ffd83dbSDimitry Andric
1187*5ffd83dbSDimitry Andric  // FMA Instructions
1188*5ffd83dbSDimitry Andric  let BaseName = "XSMADDASP" in {
1189*5ffd83dbSDimitry Andric  let isCommutable = 1 in
1190*5ffd83dbSDimitry Andric  def XSMADDASP : XX3Form<60, 1,
1191*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1192*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1193*5ffd83dbSDimitry Andric                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1194*5ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB, f32:$XTi))]>,
1195*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1196*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1197*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1198*5ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1199*5ffd83dbSDimitry Andric  def XSMADDMSP : XX3Form<60, 9,
1200*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1201*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1202*5ffd83dbSDimitry Andric                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1203*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1204*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1205*5ffd83dbSDimitry Andric  }
1206*5ffd83dbSDimitry Andric
1207*5ffd83dbSDimitry Andric  let BaseName = "XSMSUBASP" in {
1208*5ffd83dbSDimitry Andric  let isCommutable = 1 in
1209*5ffd83dbSDimitry Andric  def XSMSUBASP : XX3Form<60, 17,
1210*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1211*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1212*5ffd83dbSDimitry Andric                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1213*5ffd83dbSDimitry Andric                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB,
1214*5ffd83dbSDimitry Andric                                              (fneg f32:$XTi)))]>,
1215*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1216*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1217*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1218*5ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1219*5ffd83dbSDimitry Andric  def XSMSUBMSP : XX3Form<60, 25,
1220*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1221*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1222*5ffd83dbSDimitry Andric                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1223*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1224*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1225*5ffd83dbSDimitry Andric  }
1226*5ffd83dbSDimitry Andric
1227*5ffd83dbSDimitry Andric  let BaseName = "XSNMADDASP" in {
1228*5ffd83dbSDimitry Andric  let isCommutable = 1 in
1229*5ffd83dbSDimitry Andric  def XSNMADDASP : XX3Form<60, 129,
1230*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1231*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1232*5ffd83dbSDimitry Andric                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1233*5ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
1234*5ffd83dbSDimitry Andric                                                    f32:$XTi)))]>,
1235*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1236*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1237*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1238*5ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1239*5ffd83dbSDimitry Andric  def XSNMADDMSP : XX3Form<60, 137,
1240*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1241*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1242*5ffd83dbSDimitry Andric                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1243*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1244*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1245*5ffd83dbSDimitry Andric  }
1246*5ffd83dbSDimitry Andric
1247*5ffd83dbSDimitry Andric  let BaseName = "XSNMSUBASP" in {
1248*5ffd83dbSDimitry Andric  let isCommutable = 1 in
1249*5ffd83dbSDimitry Andric  def XSNMSUBASP : XX3Form<60, 145,
1250*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1251*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1252*5ffd83dbSDimitry Andric                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1253*5ffd83dbSDimitry Andric                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
1254*5ffd83dbSDimitry Andric                                                    (fneg f32:$XTi))))]>,
1255*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1256*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1257*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1258*5ffd83dbSDimitry Andric  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1259*5ffd83dbSDimitry Andric  def XSNMSUBMSP : XX3Form<60, 153,
1260*5ffd83dbSDimitry Andric                          (outs vssrc:$XT),
1261*5ffd83dbSDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1262*5ffd83dbSDimitry Andric                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1263*5ffd83dbSDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1264*5ffd83dbSDimitry Andric                          AltVSXFMARel;
1265*5ffd83dbSDimitry Andric  }
1266*5ffd83dbSDimitry Andric
1267*5ffd83dbSDimitry Andric  // Single Precision Conversions (FP <-> INT)
1268*5ffd83dbSDimitry Andric  def XSCVSXDSP : XX2Form<60, 312,
1269*5ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
1270*5ffd83dbSDimitry Andric                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1271*5ffd83dbSDimitry Andric                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1272*5ffd83dbSDimitry Andric  def XSCVUXDSP : XX2Form<60, 296,
1273*5ffd83dbSDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
1274*5ffd83dbSDimitry Andric                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1275*5ffd83dbSDimitry Andric                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1276*5ffd83dbSDimitry Andric
1277*5ffd83dbSDimitry Andric  // Conversions between vector and scalar single precision
1278*5ffd83dbSDimitry Andric  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1279*5ffd83dbSDimitry Andric                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1280*5ffd83dbSDimitry Andric  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1281*5ffd83dbSDimitry Andric                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1282*5ffd83dbSDimitry Andric  } // mayRaiseFPException
1283*5ffd83dbSDimitry Andric
1284*5ffd83dbSDimitry Andric  let Predicates = [HasVSX, HasDirectMove] in {
1285*5ffd83dbSDimitry Andric  // VSX direct move instructions
1286*5ffd83dbSDimitry Andric  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1287*5ffd83dbSDimitry Andric                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1288*5ffd83dbSDimitry Andric                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1289*5ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
1290*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1291*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
1292*5ffd83dbSDimitry Andric  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
1293*5ffd83dbSDimitry Andric                             "mfvsrd $rA, $XT", IIC_VecGeneral,
1294*5ffd83dbSDimitry Andric                             []>,
1295*5ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
1296*5ffd83dbSDimitry Andric  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1297*5ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1298*5ffd83dbSDimitry Andric                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1299*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1300*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
1301*5ffd83dbSDimitry Andric  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
1302*5ffd83dbSDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1303*5ffd83dbSDimitry Andric                               []>;
1304*5ffd83dbSDimitry Andric  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1305*5ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1306*5ffd83dbSDimitry Andric                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1307*5ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
1308*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1309*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
1310*5ffd83dbSDimitry Andric  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
1311*5ffd83dbSDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1312*5ffd83dbSDimitry Andric                              []>,
1313*5ffd83dbSDimitry Andric      Requires<[In64BitMode]>;
1314*5ffd83dbSDimitry Andric  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1315*5ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1316*5ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1317*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1318*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
1319*5ffd83dbSDimitry Andric  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
1320*5ffd83dbSDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1321*5ffd83dbSDimitry Andric                               []>;
1322*5ffd83dbSDimitry Andric  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1323*5ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1324*5ffd83dbSDimitry Andric                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1325*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1326*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1, hasSideEffects = 1 in
1327*5ffd83dbSDimitry Andric  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
1328*5ffd83dbSDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1329*5ffd83dbSDimitry Andric                               []>;
1330*5ffd83dbSDimitry Andric  } // HasDirectMove
1331*5ffd83dbSDimitry Andric
1332*5ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
1333*5ffd83dbSDimitry Andric
1334*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove] in {
1335*5ffd83dbSDimitry Andricdef MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1336*5ffd83dbSDimitry Andric                            "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1337*5ffd83dbSDimitry Andric
1338*5ffd83dbSDimitry Andricdef MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1339*5ffd83dbSDimitry Andric                     "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1340*5ffd83dbSDimitry Andric                     []>, Requires<[In64BitMode]>;
1341*5ffd83dbSDimitry Andric
1342*5ffd83dbSDimitry Andricdef MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1343*5ffd83dbSDimitry Andric                            "mfvsrld $rA, $XT", IIC_VecGeneral,
1344*5ffd83dbSDimitry Andric                            []>, Requires<[In64BitMode]>;
1345*5ffd83dbSDimitry Andric
1346*5ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove
1347*5ffd83dbSDimitry Andric
1348*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
1349*5ffd83dbSDimitry Andric  // Quad-Precision Scalar Move Instructions:
1350*5ffd83dbSDimitry Andric  // Copy Sign
1351*5ffd83dbSDimitry Andric  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
1352*5ffd83dbSDimitry Andric                                [(set f128:$vT,
1353*5ffd83dbSDimitry Andric                                      (fcopysign f128:$vB, f128:$vA))]>;
1354*5ffd83dbSDimitry Andric
1355*5ffd83dbSDimitry Andric  // Absolute/Negative-Absolute/Negate
1356*5ffd83dbSDimitry Andric  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
1357*5ffd83dbSDimitry Andric                                [(set f128:$vT, (fabs f128:$vB))]>;
1358*5ffd83dbSDimitry Andric  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
1359*5ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
1360*5ffd83dbSDimitry Andric  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
1361*5ffd83dbSDimitry Andric                                [(set f128:$vT, (fneg f128:$vB))]>;
1362*5ffd83dbSDimitry Andric
1363*5ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
1364*5ffd83dbSDimitry Andric  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
1365*5ffd83dbSDimitry Andric
1366*5ffd83dbSDimitry Andric  // Add/Divide/Multiply/Subtract
1367*5ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
1368*5ffd83dbSDimitry Andric  let isCommutable = 1 in {
1369*5ffd83dbSDimitry Andric  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
1370*5ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>;
1371*5ffd83dbSDimitry Andric  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
1372*5ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>;
1373*5ffd83dbSDimitry Andric  }
1374*5ffd83dbSDimitry Andric  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
1375*5ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>;
1376*5ffd83dbSDimitry Andric  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
1377*5ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>;
1378*5ffd83dbSDimitry Andric  // Square-Root
1379*5ffd83dbSDimitry Andric  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
1380*5ffd83dbSDimitry Andric                                   [(set f128:$vT, (any_fsqrt f128:$vB))]>;
1381*5ffd83dbSDimitry Andric  // (Negative) Multiply-{Add/Subtract}
1382*5ffd83dbSDimitry Andric  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
1383*5ffd83dbSDimitry Andric                                    [(set f128:$vT,
1384*5ffd83dbSDimitry Andric                                          (any_fma f128:$vA, f128:$vB, f128:$vTi))]>;
1385*5ffd83dbSDimitry Andric  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
1386*5ffd83dbSDimitry Andric                                       [(set f128:$vT,
1387*5ffd83dbSDimitry Andric                                             (any_fma f128:$vA, f128:$vB,
1388*5ffd83dbSDimitry Andric                                                      (fneg f128:$vTi)))]>;
1389*5ffd83dbSDimitry Andric  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
1390*5ffd83dbSDimitry Andric                                     [(set f128:$vT,
1391*5ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
1392*5ffd83dbSDimitry Andric                                                          f128:$vTi)))]>;
1393*5ffd83dbSDimitry Andric  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
1394*5ffd83dbSDimitry Andric                                     [(set f128:$vT,
1395*5ffd83dbSDimitry Andric                                           (fneg (any_fma f128:$vA, f128:$vB,
1396*5ffd83dbSDimitry Andric                                                          (fneg f128:$vTi))))]>;
1397*5ffd83dbSDimitry Andric
1398*5ffd83dbSDimitry Andric  let isCommutable = 1 in {
1399*5ffd83dbSDimitry Andric  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
1400*5ffd83dbSDimitry Andric                                  [(set f128:$vT,
1401*5ffd83dbSDimitry Andric                                  (int_ppc_addf128_round_to_odd
1402*5ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
1403*5ffd83dbSDimitry Andric  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
1404*5ffd83dbSDimitry Andric                                  [(set f128:$vT,
1405*5ffd83dbSDimitry Andric                                  (int_ppc_mulf128_round_to_odd
1406*5ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
1407*5ffd83dbSDimitry Andric  }
1408*5ffd83dbSDimitry Andric  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
1409*5ffd83dbSDimitry Andric                                  [(set f128:$vT,
1410*5ffd83dbSDimitry Andric                                  (int_ppc_subf128_round_to_odd
1411*5ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
1412*5ffd83dbSDimitry Andric  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
1413*5ffd83dbSDimitry Andric                                  [(set f128:$vT,
1414*5ffd83dbSDimitry Andric                                  (int_ppc_divf128_round_to_odd
1415*5ffd83dbSDimitry Andric                                  f128:$vA, f128:$vB))]>;
1416*5ffd83dbSDimitry Andric  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
1417*5ffd83dbSDimitry Andric                                  [(set f128:$vT,
1418*5ffd83dbSDimitry Andric                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
1419*5ffd83dbSDimitry Andric
1420*5ffd83dbSDimitry Andric
1421*5ffd83dbSDimitry Andric  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
1422*5ffd83dbSDimitry Andric                                      [(set f128:$vT,
1423*5ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
1424*5ffd83dbSDimitry Andric                                      f128:$vA,f128:$vB,f128:$vTi))]>;
1425*5ffd83dbSDimitry Andric
1426*5ffd83dbSDimitry Andric  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
1427*5ffd83dbSDimitry Andric                                      [(set f128:$vT,
1428*5ffd83dbSDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
1429*5ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
1430*5ffd83dbSDimitry Andric  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
1431*5ffd83dbSDimitry Andric                                      [(set f128:$vT,
1432*5ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
1433*5ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
1434*5ffd83dbSDimitry Andric  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
1435*5ffd83dbSDimitry Andric                                      [(set f128:$vT,
1436*5ffd83dbSDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
1437*5ffd83dbSDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
1438*5ffd83dbSDimitry Andric  } // mayRaiseFPException
1439*5ffd83dbSDimitry Andric
1440*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1441*5ffd83dbSDimitry Andric  // QP Compare Ordered/Unordered
1442*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1443*5ffd83dbSDimitry Andric    def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1444*5ffd83dbSDimitry Andric    def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1445*5ffd83dbSDimitry Andric
1446*5ffd83dbSDimitry Andric    // DP/QP Compare Exponents
1447*5ffd83dbSDimitry Andric    def XSCMPEXPDP : XX3Form_1<60, 59,
1448*5ffd83dbSDimitry Andric                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
1449*5ffd83dbSDimitry Andric                               "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
1450*5ffd83dbSDimitry Andric    def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
1451*5ffd83dbSDimitry Andric
1452*5ffd83dbSDimitry Andric    // DP Compare ==, >=, >, !=
1453*5ffd83dbSDimitry Andric    // Use vsrc for XT, because the entire register of XT is set.
1454*5ffd83dbSDimitry Andric    // XT.dword[1] = 0x0000_0000_0000_0000
1455*5ffd83dbSDimitry Andric    def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
1456*5ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
1457*5ffd83dbSDimitry Andric    def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
1458*5ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
1459*5ffd83dbSDimitry Andric    def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
1460*5ffd83dbSDimitry Andric                                    IIC_FPCompare, []>;
1461*5ffd83dbSDimitry Andric  }
1462*5ffd83dbSDimitry Andric
1463*5ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
1464*5ffd83dbSDimitry Andric  // Quad-Precision Floating-Point Conversion Instructions:
1465*5ffd83dbSDimitry Andric
1466*5ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
1467*5ffd83dbSDimitry Andric    // Convert DP -> QP
1468*5ffd83dbSDimitry Andric    def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
1469*5ffd83dbSDimitry Andric                                       [(set f128:$vT, (any_fpextend f64:$vB))]>;
1470*5ffd83dbSDimitry Andric
1471*5ffd83dbSDimitry Andric    // Round & Convert QP -> DP (dword[1] is set to zero)
1472*5ffd83dbSDimitry Andric    def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
1473*5ffd83dbSDimitry Andric    def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
1474*5ffd83dbSDimitry Andric                                          [(set f64:$vT,
1475*5ffd83dbSDimitry Andric                                          (int_ppc_truncf128_round_to_odd
1476*5ffd83dbSDimitry Andric                                          f128:$vB))]>;
1477*5ffd83dbSDimitry Andric  }
1478*5ffd83dbSDimitry Andric
1479*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1480*5ffd83dbSDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
1481*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1482*5ffd83dbSDimitry Andric    def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
1483*5ffd83dbSDimitry Andric    def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
1484*5ffd83dbSDimitry Andric    def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
1485*5ffd83dbSDimitry Andric    def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
1486*5ffd83dbSDimitry Andric  }
1487*5ffd83dbSDimitry Andric
1488*5ffd83dbSDimitry Andric  // Convert (Un)Signed DWord -> QP.
1489*5ffd83dbSDimitry Andric  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
1490*5ffd83dbSDimitry Andric  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
1491*5ffd83dbSDimitry Andric
1492*5ffd83dbSDimitry Andric  // (Round &) Convert DP <-> HP
1493*5ffd83dbSDimitry Andric  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
1494*5ffd83dbSDimitry Andric  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
1495*5ffd83dbSDimitry Andric  // but we still use vsfrc for it.
1496*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1497*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1498*5ffd83dbSDimitry Andric    def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
1499*5ffd83dbSDimitry Andric    def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
1500*5ffd83dbSDimitry Andric  }
1501*5ffd83dbSDimitry Andric
1502*5ffd83dbSDimitry Andric  // Vector HP -> SP
1503*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1504*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in
1505*5ffd83dbSDimitry Andric  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
1506*5ffd83dbSDimitry Andric  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
1507*5ffd83dbSDimitry Andric                                 [(set v4f32:$XT,
1508*5ffd83dbSDimitry Andric                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
1509*5ffd83dbSDimitry Andric
1510*5ffd83dbSDimitry Andric  let mayRaiseFPException = 1 in {
1511*5ffd83dbSDimitry Andric    // Round to Quad-Precision Integer [with Inexact]
1512*5ffd83dbSDimitry Andric    def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
1513*5ffd83dbSDimitry Andric    def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
1514*5ffd83dbSDimitry Andric  }
1515*5ffd83dbSDimitry Andric
1516*5ffd83dbSDimitry Andric  // Round Quad-Precision to Double-Extended Precision (fp80)
1517*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1518*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in
1519*5ffd83dbSDimitry Andric  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
1520*5ffd83dbSDimitry Andric
1521*5ffd83dbSDimitry Andric  //===--------------------------------------------------------------------===//
1522*5ffd83dbSDimitry Andric  // Insert/Extract Instructions
1523*5ffd83dbSDimitry Andric
1524*5ffd83dbSDimitry Andric  // Insert Exponent DP/QP
1525*5ffd83dbSDimitry Andric  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
1526*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1527*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1528*5ffd83dbSDimitry Andric    def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
1529*5ffd83dbSDimitry Andric                            "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
1530*5ffd83dbSDimitry Andric    // vB NOTE: only vB.dword[0] is used, that's why we don't use
1531*5ffd83dbSDimitry Andric    //          X_VT5_VA5_VB5 form
1532*5ffd83dbSDimitry Andric    def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
1533*5ffd83dbSDimitry Andric                            "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
1534*5ffd83dbSDimitry Andric  }
1535*5ffd83dbSDimitry Andric
1536*5ffd83dbSDimitry Andric  // Extract Exponent/Significand DP/QP
1537*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1538*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1539*5ffd83dbSDimitry Andric    def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
1540*5ffd83dbSDimitry Andric    def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
1541*5ffd83dbSDimitry Andric
1542*5ffd83dbSDimitry Andric    def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
1543*5ffd83dbSDimitry Andric    def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
1544*5ffd83dbSDimitry Andric  }
1545*5ffd83dbSDimitry Andric
1546*5ffd83dbSDimitry Andric  // Vector Insert Word
1547*5ffd83dbSDimitry Andric  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
1548*5ffd83dbSDimitry Andric  def XXINSERTW   :
1549*5ffd83dbSDimitry Andric    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
1550*5ffd83dbSDimitry Andric                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
1551*5ffd83dbSDimitry Andric                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
1552*5ffd83dbSDimitry Andric                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
1553*5ffd83dbSDimitry Andric                                                   imm32SExt16:$UIM))]>,
1554*5ffd83dbSDimitry Andric                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
1555*5ffd83dbSDimitry Andric
1556*5ffd83dbSDimitry Andric  // Vector Extract Unsigned Word
1557*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1558*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in
1559*5ffd83dbSDimitry Andric  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
1560*5ffd83dbSDimitry Andric                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
1561*5ffd83dbSDimitry Andric                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
1562*5ffd83dbSDimitry Andric
1563*5ffd83dbSDimitry Andric  // Vector Insert Exponent DP/SP
1564*5ffd83dbSDimitry Andric  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
1565*5ffd83dbSDimitry Andric    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
1566*5ffd83dbSDimitry Andric  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
1567*5ffd83dbSDimitry Andric    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
1568*5ffd83dbSDimitry Andric
1569*5ffd83dbSDimitry Andric  // Vector Extract Exponent/Significand DP/SP
1570*5ffd83dbSDimitry Andric  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
1571*5ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
1572*5ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
1573*5ffd83dbSDimitry Andric  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
1574*5ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
1575*5ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
1576*5ffd83dbSDimitry Andric  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
1577*5ffd83dbSDimitry Andric                                 [(set v2i64: $XT,
1578*5ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
1579*5ffd83dbSDimitry Andric  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
1580*5ffd83dbSDimitry Andric                                 [(set v4i32: $XT,
1581*5ffd83dbSDimitry Andric                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
1582*5ffd83dbSDimitry Andric
1583*5ffd83dbSDimitry Andric  // Test Data Class SP/DP/QP
1584*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1585*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1586*5ffd83dbSDimitry Andric    def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
1587*5ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
1588*5ffd83dbSDimitry Andric                                "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
1589*5ffd83dbSDimitry Andric    def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
1590*5ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
1591*5ffd83dbSDimitry Andric                                "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
1592*5ffd83dbSDimitry Andric    def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
1593*5ffd83dbSDimitry Andric                                (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
1594*5ffd83dbSDimitry Andric                                "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
1595*5ffd83dbSDimitry Andric  }
1596*5ffd83dbSDimitry Andric
1597*5ffd83dbSDimitry Andric  // Vector Test Data Class SP/DP
1598*5ffd83dbSDimitry Andric  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
1599*5ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
1600*5ffd83dbSDimitry Andric                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
1601*5ffd83dbSDimitry Andric                              [(set v4i32: $XT,
1602*5ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
1603*5ffd83dbSDimitry Andric  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
1604*5ffd83dbSDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
1605*5ffd83dbSDimitry Andric                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
1606*5ffd83dbSDimitry Andric                              [(set v2i64: $XT,
1607*5ffd83dbSDimitry Andric                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
1608*5ffd83dbSDimitry Andric
1609*5ffd83dbSDimitry Andric  // Maximum/Minimum Type-C/Type-J DP
1610*5ffd83dbSDimitry Andric  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
1611*5ffd83dbSDimitry Andric                                 IIC_VecFP,
1612*5ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
1613*5ffd83dbSDimitry Andric  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc,
1614*5ffd83dbSDimitry Andric                                 IIC_VecFP,
1615*5ffd83dbSDimitry Andric                                 [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>;
1616*5ffd83dbSDimitry Andric
1617*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1618*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1619*5ffd83dbSDimitry Andric    def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
1620*5ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
1621*5ffd83dbSDimitry Andric    def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
1622*5ffd83dbSDimitry Andric                                   IIC_VecFP, []>;
1623*5ffd83dbSDimitry Andric  }
1624*5ffd83dbSDimitry Andric
1625*5ffd83dbSDimitry Andric  // Vector Byte-Reverse H/W/D/Q Word
1626*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1627*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in
1628*5ffd83dbSDimitry Andric  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
1629*5ffd83dbSDimitry Andric  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc,
1630*5ffd83dbSDimitry Andric    [(set v4i32:$XT, (bswap v4i32:$XB))]>;
1631*5ffd83dbSDimitry Andric  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc,
1632*5ffd83dbSDimitry Andric    [(set v2i64:$XT, (bswap v2i64:$XB))]>;
1633*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1634*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in
1635*5ffd83dbSDimitry Andric  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
1636*5ffd83dbSDimitry Andric
1637*5ffd83dbSDimitry Andric  // Vector Permute
1638*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1639*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in {
1640*5ffd83dbSDimitry Andric    def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
1641*5ffd83dbSDimitry Andric                                  IIC_VecPerm, []>;
1642*5ffd83dbSDimitry Andric    def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
1643*5ffd83dbSDimitry Andric                                  IIC_VecPerm, []>;
1644*5ffd83dbSDimitry Andric  }
1645*5ffd83dbSDimitry Andric
1646*5ffd83dbSDimitry Andric  // Vector Splat Immediate Byte
1647*5ffd83dbSDimitry Andric  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1648*5ffd83dbSDimitry Andric  let hasSideEffects = 1 in
1649*5ffd83dbSDimitry Andric  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
1650*5ffd83dbSDimitry Andric                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
1651*5ffd83dbSDimitry Andric
1652*5ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
1653*5ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
1654*5ffd83dbSDimitry Andric  let mayLoad = 1, mayStore = 0 in {
1655*5ffd83dbSDimitry Andric  // Load Vector
1656*5ffd83dbSDimitry Andric  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
1657*5ffd83dbSDimitry Andric                            "lxv $XT, $src", IIC_LdStLFD, []>;
1658*5ffd83dbSDimitry Andric  // Load DWord
1659*5ffd83dbSDimitry Andric  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
1660*5ffd83dbSDimitry Andric                       "lxsd $vD, $src", IIC_LdStLFD, []>;
1661*5ffd83dbSDimitry Andric  // Load SP from src, convert it to DP, and place in dword[0]
1662*5ffd83dbSDimitry Andric  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
1663*5ffd83dbSDimitry Andric                       "lxssp $vD, $src", IIC_LdStLFD, []>;
1664*5ffd83dbSDimitry Andric
1665*5ffd83dbSDimitry Andric  // Load as Integer Byte/Halfword & Zero Indexed
1666*5ffd83dbSDimitry Andric  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
1667*5ffd83dbSDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
1668*5ffd83dbSDimitry Andric  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
1669*5ffd83dbSDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
1670*5ffd83dbSDimitry Andric
1671*5ffd83dbSDimitry Andric  // Load Vector Halfword*8/Byte*16 Indexed
1672*5ffd83dbSDimitry Andric  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
1673*5ffd83dbSDimitry Andric  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
1674*5ffd83dbSDimitry Andric
1675*5ffd83dbSDimitry Andric  // Load Vector Indexed
1676*5ffd83dbSDimitry Andric  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
1677*5ffd83dbSDimitry Andric                [(set v2f64:$XT, (load xaddrX16:$src))]>;
1678*5ffd83dbSDimitry Andric  // Load Vector (Left-justified) with Length
1679*5ffd83dbSDimitry Andric  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
1680*5ffd83dbSDimitry Andric                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
1681*5ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
1682*5ffd83dbSDimitry Andric  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
1683*5ffd83dbSDimitry Andric                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
1684*5ffd83dbSDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
1685*5ffd83dbSDimitry Andric
1686*5ffd83dbSDimitry Andric  // Load Vector Word & Splat Indexed
1687*5ffd83dbSDimitry Andric  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
1688*5ffd83dbSDimitry Andric  } // mayLoad
1689*5ffd83dbSDimitry Andric
1690*5ffd83dbSDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
1691*5ffd83dbSDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
1692*5ffd83dbSDimitry Andric  let mayStore = 1, mayLoad = 0 in {
1693*5ffd83dbSDimitry Andric  // Store Vector
1694*5ffd83dbSDimitry Andric  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
1695*5ffd83dbSDimitry Andric                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
1696*5ffd83dbSDimitry Andric  // Store DWord
1697*5ffd83dbSDimitry Andric  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
1698*5ffd83dbSDimitry Andric                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
1699*5ffd83dbSDimitry Andric  // Convert DP of dword[0] to SP, and Store to dst
1700*5ffd83dbSDimitry Andric  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
1701*5ffd83dbSDimitry Andric                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
1702*5ffd83dbSDimitry Andric
1703*5ffd83dbSDimitry Andric  // Store as Integer Byte/Halfword Indexed
1704*5ffd83dbSDimitry Andric  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
1705*5ffd83dbSDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
1706*5ffd83dbSDimitry Andric  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
1707*5ffd83dbSDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
1708*5ffd83dbSDimitry Andric  let isCodeGenOnly = 1 in {
1709*5ffd83dbSDimitry Andric    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
1710*5ffd83dbSDimitry Andric    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
1711*5ffd83dbSDimitry Andric  }
1712*5ffd83dbSDimitry Andric
1713*5ffd83dbSDimitry Andric  // Store Vector Halfword*8/Byte*16 Indexed
1714*5ffd83dbSDimitry Andric  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
1715*5ffd83dbSDimitry Andric  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
1716*5ffd83dbSDimitry Andric
1717*5ffd83dbSDimitry Andric  // Store Vector Indexed
1718*5ffd83dbSDimitry Andric  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
1719*5ffd83dbSDimitry Andric                 [(store v2f64:$XT, xaddrX16:$dst)]>;
1720*5ffd83dbSDimitry Andric
1721*5ffd83dbSDimitry Andric  // Store Vector (Left-justified) with Length
1722*5ffd83dbSDimitry Andric  def STXVL : XX1Form_memOp<31, 397, (outs),
1723*5ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
1724*5ffd83dbSDimitry Andric                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
1725*5ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
1726*5ffd83dbSDimitry Andric                              i64:$rB)]>;
1727*5ffd83dbSDimitry Andric  def STXVLL : XX1Form_memOp<31, 429, (outs),
1728*5ffd83dbSDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
1729*5ffd83dbSDimitry Andric                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
1730*5ffd83dbSDimitry Andric                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
1731*5ffd83dbSDimitry Andric                              i64:$rB)]>;
1732*5ffd83dbSDimitry Andric  } // mayStore
1733*5ffd83dbSDimitry Andric
1734*5ffd83dbSDimitry Andric  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
1735*5ffd83dbSDimitry Andric                          "#DFLOADf32",
1736*5ffd83dbSDimitry Andric                          [(set f32:$XT, (load iaddrX4:$src))]>;
1737*5ffd83dbSDimitry Andric  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
1738*5ffd83dbSDimitry Andric                          "#DFLOADf64",
1739*5ffd83dbSDimitry Andric                          [(set f64:$XT, (load iaddrX4:$src))]>;
1740*5ffd83dbSDimitry Andric  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
1741*5ffd83dbSDimitry Andric                          "#DFSTOREf32",
1742*5ffd83dbSDimitry Andric                          [(store f32:$XT, iaddrX4:$dst)]>;
1743*5ffd83dbSDimitry Andric  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
1744*5ffd83dbSDimitry Andric                          "#DFSTOREf64",
1745*5ffd83dbSDimitry Andric                          [(store f64:$XT, iaddrX4:$dst)]>;
1746*5ffd83dbSDimitry Andric
1747*5ffd83dbSDimitry Andric  let mayStore = 1 in {
1748*5ffd83dbSDimitry Andric    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
1749*5ffd83dbSDimitry Andric                                          (ins spilltovsrrc:$XT, memrr:$dst),
1750*5ffd83dbSDimitry Andric                                          "#SPILLTOVSR_STX", []>;
1751*5ffd83dbSDimitry Andric    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
1752*5ffd83dbSDimitry Andric                              "#SPILLTOVSR_ST", []>;
1753*5ffd83dbSDimitry Andric  }
1754*5ffd83dbSDimitry Andric  let mayLoad = 1 in {
1755*5ffd83dbSDimitry Andric    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
1756*5ffd83dbSDimitry Andric                                          (ins memrr:$src),
1757*5ffd83dbSDimitry Andric                                          "#SPILLTOVSR_LDX", []>;
1758*5ffd83dbSDimitry Andric    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
1759*5ffd83dbSDimitry Andric                              "#SPILLTOVSR_LD", []>;
1760*5ffd83dbSDimitry Andric
1761*5ffd83dbSDimitry Andric  }
1762*5ffd83dbSDimitry Andric  } // HasP9Vector
1763*5ffd83dbSDimitry Andric} // hasSideEffects = 0
1764*5ffd83dbSDimitry Andric
1765*5ffd83dbSDimitry Andriclet PPC970_Single = 1, AddedComplexity = 400 in {
17660b57cec5SDimitry Andric
17670b57cec5SDimitry Andric  def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17680b57cec5SDimitry Andric                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
17690b57cec5SDimitry Andric                             "#SELECT_CC_VSRC",
17700b57cec5SDimitry Andric                             []>;
17710b57cec5SDimitry Andric  def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
17720b57cec5SDimitry Andric                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
17730b57cec5SDimitry Andric                          "#SELECT_VSRC",
17740b57cec5SDimitry Andric                          [(set v2f64:$dst,
17750b57cec5SDimitry Andric                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
17760b57cec5SDimitry Andric  def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
17770b57cec5SDimitry Andric                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
17780b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
17790b57cec5SDimitry Andric                              []>;
17800b57cec5SDimitry Andric  def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
17810b57cec5SDimitry Andric                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
17820b57cec5SDimitry Andric                           "#SELECT_VSFRC",
17830b57cec5SDimitry Andric                           [(set f64:$dst,
17840b57cec5SDimitry Andric                                 (select i1:$cond, f64:$T, f64:$F))]>;
17850b57cec5SDimitry Andric  def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
17860b57cec5SDimitry Andric                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
17870b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
17880b57cec5SDimitry Andric                              []>;
17890b57cec5SDimitry Andric  def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
17900b57cec5SDimitry Andric                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
17910b57cec5SDimitry Andric                           "#SELECT_VSSRC",
17920b57cec5SDimitry Andric                           [(set f32:$dst,
17930b57cec5SDimitry Andric                                 (select i1:$cond, f32:$T, f32:$F))]>;
17940b57cec5SDimitry Andric}
17950b57cec5SDimitry Andric}
17960b57cec5SDimitry Andric
1797*5ffd83dbSDimitry Andric//----------------------------- DAG Definitions ------------------------------//
1798480093f4SDimitry Andricdef FpMinMax {
1799480093f4SDimitry Andric  dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC),
1800480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1801480093f4SDimitry Andric                                 VSSRC);
1802480093f4SDimitry Andric  dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC),
1803480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1804480093f4SDimitry Andric                                 VSSRC);
1805480093f4SDimitry Andric}
1806480093f4SDimitry Andric
18070b57cec5SDimitry Andricdef ScalarLoads {
18080b57cec5SDimitry Andric  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
18090b57cec5SDimitry Andric  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
18100b57cec5SDimitry Andric  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
18110b57cec5SDimitry Andric  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
18120b57cec5SDimitry Andric  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
18130b57cec5SDimitry Andric
18140b57cec5SDimitry Andric  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
18150b57cec5SDimitry Andric  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
18160b57cec5SDimitry Andric  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
18170b57cec5SDimitry Andric  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
18180b57cec5SDimitry Andric  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
18190b57cec5SDimitry Andric
18200b57cec5SDimitry Andric  dag Li32 = (i32 (load xoaddr:$src));
18210b57cec5SDimitry Andric}
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andricdef DWToSPExtractConv {
18240b57cec5SDimitry Andric  dag El0US1 = (f32 (PPCfcfidus
18250b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18260b57cec5SDimitry Andric  dag El1US1 = (f32 (PPCfcfidus
18270b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18280b57cec5SDimitry Andric  dag El0US2 = (f32 (PPCfcfidus
18290b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18300b57cec5SDimitry Andric  dag El1US2 = (f32 (PPCfcfidus
18310b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18320b57cec5SDimitry Andric  dag El0SS1 = (f32 (PPCfcfids
18330b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
18340b57cec5SDimitry Andric  dag El1SS1 = (f32 (PPCfcfids
18350b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
18360b57cec5SDimitry Andric  dag El0SS2 = (f32 (PPCfcfids
18370b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
18380b57cec5SDimitry Andric  dag El1SS2 = (f32 (PPCfcfids
18390b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
18400b57cec5SDimitry Andric  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
18410b57cec5SDimitry Andric  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
18420b57cec5SDimitry Andric}
18430b57cec5SDimitry Andric
1844*5ffd83dbSDimitry Andricdef WToDPExtractConv {
1845*5ffd83dbSDimitry Andric  dag El0S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 0))));
1846*5ffd83dbSDimitry Andric  dag El1S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 1))));
1847*5ffd83dbSDimitry Andric  dag El2S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 2))));
1848*5ffd83dbSDimitry Andric  dag El3S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 3))));
1849*5ffd83dbSDimitry Andric  dag El0U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 0))));
1850*5ffd83dbSDimitry Andric  dag El1U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 1))));
1851*5ffd83dbSDimitry Andric  dag El2U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 2))));
1852*5ffd83dbSDimitry Andric  dag El3U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 3))));
1853*5ffd83dbSDimitry Andric  dag BV02S = (v2f64 (build_vector El0S, El2S));
1854*5ffd83dbSDimitry Andric  dag BV13S = (v2f64 (build_vector El1S, El3S));
1855*5ffd83dbSDimitry Andric  dag BV02U = (v2f64 (build_vector El0U, El2U));
1856*5ffd83dbSDimitry Andric  dag BV13U = (v2f64 (build_vector El1U, El3U));
18578bcb0991SDimitry Andric}
18588bcb0991SDimitry Andric
18590b57cec5SDimitry Andric/*  Direct moves of various widths from GPR's into VSR's. Each move lines
18600b57cec5SDimitry Andric    the value up into element 0 (both BE and LE). Namely, entities smaller than
18610b57cec5SDimitry Andric    a doubleword are shifted left and moved for BE. For LE, they're moved, then
18620b57cec5SDimitry Andric    swapped to go into the least significant element of the VSR.
18630b57cec5SDimitry Andric*/
18640b57cec5SDimitry Andricdef MovesToVSR {
18650b57cec5SDimitry Andric  dag BE_BYTE_0 =
18660b57cec5SDimitry Andric    (MTVSRD
18670b57cec5SDimitry Andric      (RLDICR
18680b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
18690b57cec5SDimitry Andric  dag BE_HALF_0 =
18700b57cec5SDimitry Andric    (MTVSRD
18710b57cec5SDimitry Andric      (RLDICR
18720b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
18730b57cec5SDimitry Andric  dag BE_WORD_0 =
18740b57cec5SDimitry Andric    (MTVSRD
18750b57cec5SDimitry Andric      (RLDICR
18760b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
18770b57cec5SDimitry Andric  dag BE_DWORD_0 = (MTVSRD $A);
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andric  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
18800b57cec5SDimitry Andric  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
18810b57cec5SDimitry Andric                                        LE_MTVSRW, sub_64));
18820b57cec5SDimitry Andric  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
18830b57cec5SDimitry Andric  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
18840b57cec5SDimitry Andric                                         BE_DWORD_0, sub_64));
18850b57cec5SDimitry Andric  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
18860b57cec5SDimitry Andric}
18870b57cec5SDimitry Andric
18880b57cec5SDimitry Andric/*  Patterns for extracting elements out of vectors. Integer elements are
18890b57cec5SDimitry Andric    extracted using direct move operations. Patterns for extracting elements
18900b57cec5SDimitry Andric    whose indices are not available at compile time are also provided with
18910b57cec5SDimitry Andric    various _VARIABLE_ patterns.
18920b57cec5SDimitry Andric    The numbering for the DAG's is for LE, but when used on BE, the correct
18930b57cec5SDimitry Andric    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
18940b57cec5SDimitry Andric*/
18950b57cec5SDimitry Andricdef VectorExtractions {
18960b57cec5SDimitry Andric  // Doubleword extraction
18970b57cec5SDimitry Andric  dag LE_DWORD_0 =
18980b57cec5SDimitry Andric    (MFVSRD
18990b57cec5SDimitry Andric      (EXTRACT_SUBREG
19000b57cec5SDimitry Andric        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
19010b57cec5SDimitry Andric                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
19020b57cec5SDimitry Andric  dag LE_DWORD_1 = (MFVSRD
19030b57cec5SDimitry Andric                     (EXTRACT_SUBREG
19040b57cec5SDimitry Andric                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19050b57cec5SDimitry Andric
19060b57cec5SDimitry Andric  // Word extraction
19070b57cec5SDimitry Andric  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
19080b57cec5SDimitry Andric  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
19090b57cec5SDimitry Andric  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
19100b57cec5SDimitry Andric                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
19110b57cec5SDimitry Andric  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
19120b57cec5SDimitry Andric
19130b57cec5SDimitry Andric  // Halfword extraction
19140b57cec5SDimitry Andric  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
19150b57cec5SDimitry Andric  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
19160b57cec5SDimitry Andric  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
19170b57cec5SDimitry Andric  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
19180b57cec5SDimitry Andric  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
19190b57cec5SDimitry Andric  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
19200b57cec5SDimitry Andric  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
19210b57cec5SDimitry Andric  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
19220b57cec5SDimitry Andric
19230b57cec5SDimitry Andric  // Byte extraction
19240b57cec5SDimitry Andric  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
19250b57cec5SDimitry Andric  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
19260b57cec5SDimitry Andric  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
19270b57cec5SDimitry Andric  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
19280b57cec5SDimitry Andric  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
19290b57cec5SDimitry Andric  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
19300b57cec5SDimitry Andric  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
19310b57cec5SDimitry Andric  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
19320b57cec5SDimitry Andric  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
19330b57cec5SDimitry Andric  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
19340b57cec5SDimitry Andric  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
19350b57cec5SDimitry Andric  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
19360b57cec5SDimitry Andric  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
19370b57cec5SDimitry Andric  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
19380b57cec5SDimitry Andric  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
19390b57cec5SDimitry Andric  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
19400b57cec5SDimitry Andric
19410b57cec5SDimitry Andric  /* Variable element number (BE and LE patterns must be specified separately)
19420b57cec5SDimitry Andric     This is a rather involved process.
19430b57cec5SDimitry Andric
19440b57cec5SDimitry Andric     Conceptually, this is how the move is accomplished:
19450b57cec5SDimitry Andric     1. Identify which doubleword contains the element
19460b57cec5SDimitry Andric     2. Shift in the VMX register so that the correct doubleword is correctly
19470b57cec5SDimitry Andric        lined up for the MFVSRD
19480b57cec5SDimitry Andric     3. Perform the move so that the element (along with some extra stuff)
19490b57cec5SDimitry Andric        is in the GPR
19500b57cec5SDimitry Andric     4. Right shift within the GPR so that the element is right-justified
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andric     Of course, the index is an element number which has a different meaning
19530b57cec5SDimitry Andric     on LE/BE so the patterns have to be specified separately.
19540b57cec5SDimitry Andric
19550b57cec5SDimitry Andric     Note: The final result will be the element right-justified with high
19560b57cec5SDimitry Andric           order bits being arbitrarily defined (namely, whatever was in the
19570b57cec5SDimitry Andric           vector register to the left of the value originally).
19580b57cec5SDimitry Andric  */
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric  /*  LE variable byte
19610b57cec5SDimitry Andric      Number 1. above:
19620b57cec5SDimitry Andric      - For elements 0-7, we shift left by 8 bytes since they're on the right
19630b57cec5SDimitry Andric      - For elements 8-15, we need not shift (shift left by zero bytes)
19640b57cec5SDimitry Andric      This is accomplished by inverting the bits of the index and AND-ing
19650b57cec5SDimitry Andric      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
19660b57cec5SDimitry Andric  */
19670b57cec5SDimitry Andric  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andric  //  Number 2. above:
19700b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
19710b57cec5SDimitry Andric  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
19720b57cec5SDimitry Andric
19730b57cec5SDimitry Andric  //  Number 3. above:
19740b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
19750b57cec5SDimitry Andric  dag LE_MV_VBYTE = (MFVSRD
19760b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19770b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
19780b57cec5SDimitry Andric                        sub_64));
19790b57cec5SDimitry Andric
19800b57cec5SDimitry Andric  /*  Number 4. above:
19810b57cec5SDimitry Andric      - Truncate the element number to the range 0-7 (8-15 are symmetrical
19820b57cec5SDimitry Andric        and out of range values are truncated accordingly)
19830b57cec5SDimitry Andric      - Multiply by 8 as we need to shift right by the number of bits, not bytes
19840b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
19850b57cec5SDimitry Andric  */
19860b57cec5SDimitry Andric  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
19870b57cec5SDimitry Andric                                       sub_32);
19880b57cec5SDimitry Andric  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
19890b57cec5SDimitry Andric                                         sub_32);
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andric  /*  LE variable halfword
19920b57cec5SDimitry Andric      Number 1. above:
19930b57cec5SDimitry Andric      - For elements 0-3, we shift left by 8 since they're on the right
19940b57cec5SDimitry Andric      - For elements 4-7, we need not shift (shift left by zero bytes)
19950b57cec5SDimitry Andric      Similarly to the byte pattern, we invert the bits of the index, but we
19960b57cec5SDimitry Andric      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
19970b57cec5SDimitry Andric      Of course, the shift is still by 8 bytes, so we must multiply by 2.
19980b57cec5SDimitry Andric  */
19990b57cec5SDimitry Andric  dag LE_VHALF_PERM_VEC =
20000b57cec5SDimitry Andric    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
20010b57cec5SDimitry Andric
20020b57cec5SDimitry Andric  //  Number 2. above:
20030b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20040b57cec5SDimitry Andric  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andric  //  Number 3. above:
20070b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20080b57cec5SDimitry Andric  dag LE_MV_VHALF = (MFVSRD
20090b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20100b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
20110b57cec5SDimitry Andric                        sub_64));
20120b57cec5SDimitry Andric
20130b57cec5SDimitry Andric  /*  Number 4. above:
20140b57cec5SDimitry Andric      - Truncate the element number to the range 0-3 (4-7 are symmetrical
20150b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20160b57cec5SDimitry Andric      - Multiply by 16 as we need to shift right by the number of bits
20170b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20180b57cec5SDimitry Andric  */
20190b57cec5SDimitry Andric  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
20200b57cec5SDimitry Andric                                       sub_32);
20210b57cec5SDimitry Andric  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
20220b57cec5SDimitry Andric                                         sub_32);
20230b57cec5SDimitry Andric
20240b57cec5SDimitry Andric  /*  LE variable word
20250b57cec5SDimitry Andric      Number 1. above:
20260b57cec5SDimitry Andric      - For elements 0-1, we shift left by 8 since they're on the right
20270b57cec5SDimitry Andric      - For elements 2-3, we need not shift
20280b57cec5SDimitry Andric  */
20290b57cec5SDimitry Andric  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20300b57cec5SDimitry Andric                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
20310b57cec5SDimitry Andric
20320b57cec5SDimitry Andric  //  Number 2. above:
20330b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20340b57cec5SDimitry Andric  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
20350b57cec5SDimitry Andric
20360b57cec5SDimitry Andric  //  Number 3. above:
20370b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20380b57cec5SDimitry Andric  dag LE_MV_VWORD = (MFVSRD
20390b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20400b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
20410b57cec5SDimitry Andric                        sub_64));
20420b57cec5SDimitry Andric
20430b57cec5SDimitry Andric  /*  Number 4. above:
20440b57cec5SDimitry Andric      - Truncate the element number to the range 0-1 (2-3 are symmetrical
20450b57cec5SDimitry Andric        and out of range values are truncated accordingly)
20460b57cec5SDimitry Andric      - Multiply by 32 as we need to shift right by the number of bits
20470b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
20480b57cec5SDimitry Andric  */
20490b57cec5SDimitry Andric  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
20500b57cec5SDimitry Andric                                       sub_32);
20510b57cec5SDimitry Andric  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
20520b57cec5SDimitry Andric                                         sub_32);
20530b57cec5SDimitry Andric
20540b57cec5SDimitry Andric  /*  LE variable doubleword
20550b57cec5SDimitry Andric      Number 1. above:
20560b57cec5SDimitry Andric      - For element 0, we shift left by 8 since it's on the right
20570b57cec5SDimitry Andric      - For element 1, we need not shift
20580b57cec5SDimitry Andric  */
20590b57cec5SDimitry Andric  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
20600b57cec5SDimitry Andric                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
20610b57cec5SDimitry Andric
20620b57cec5SDimitry Andric  //  Number 2. above:
20630b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
20640b57cec5SDimitry Andric  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
20650b57cec5SDimitry Andric
20660b57cec5SDimitry Andric  // Number 3. above:
20670b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
20680b57cec5SDimitry Andric  //  - Number 4. is not needed for the doubleword as the value is 64-bits
20690b57cec5SDimitry Andric  dag LE_VARIABLE_DWORD =
20700b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
20710b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
20720b57cec5SDimitry Andric                  sub_64));
20730b57cec5SDimitry Andric
20740b57cec5SDimitry Andric  /*  LE variable float
20750b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
20760b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
20770b57cec5SDimitry Andric  */
20780b57cec5SDimitry Andric  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
20790b57cec5SDimitry Andric                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
20800b57cec5SDimitry Andric  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
20810b57cec5SDimitry Andric  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
20820b57cec5SDimitry Andric
20830b57cec5SDimitry Andric  /*  LE variable double
20840b57cec5SDimitry Andric      Same as the LE doubleword except there is no move.
20850b57cec5SDimitry Andric  */
20860b57cec5SDimitry Andric  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
20870b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
20880b57cec5SDimitry Andric                                         LE_VDWORD_PERM_VEC));
20890b57cec5SDimitry Andric  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
20900b57cec5SDimitry Andric
20910b57cec5SDimitry Andric  /*  BE variable byte
20920b57cec5SDimitry Andric      The algorithm here is the same as the LE variable byte except:
20930b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
20940b57cec5SDimitry Andric        we simply AND the element number with 0x8
20950b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
20960b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-7
20970b57cec5SDimitry Andric  */
2098480093f4SDimitry Andric  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8)));
20990b57cec5SDimitry Andric  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
21000b57cec5SDimitry Andric  dag BE_MV_VBYTE = (MFVSRD
21010b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21020b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
21030b57cec5SDimitry Andric                        sub_64));
21040b57cec5SDimitry Andric  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
21050b57cec5SDimitry Andric                                       sub_32);
21060b57cec5SDimitry Andric  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
21070b57cec5SDimitry Andric                                         sub_32);
21080b57cec5SDimitry Andric
21090b57cec5SDimitry Andric  /*  BE variable halfword
21100b57cec5SDimitry Andric      The algorithm here is the same as the LE variable halfword except:
21110b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
21120b57cec5SDimitry Andric        we simply AND the element number with 0x4 and multiply by 2
21130b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21140b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-3
21150b57cec5SDimitry Andric  */
21160b57cec5SDimitry Andric  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
2117480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 4), 1, 62)));
21180b57cec5SDimitry Andric  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
21190b57cec5SDimitry Andric  dag BE_MV_VHALF = (MFVSRD
21200b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21210b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
21220b57cec5SDimitry Andric                        sub_64));
21230b57cec5SDimitry Andric  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
21240b57cec5SDimitry Andric                                       sub_32);
21250b57cec5SDimitry Andric  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
21260b57cec5SDimitry Andric                                         sub_32);
21270b57cec5SDimitry Andric
21280b57cec5SDimitry Andric  /*  BE variable word
21290b57cec5SDimitry Andric      The algorithm is the same as the LE variable word except:
21300b57cec5SDimitry Andric      - The shift in the VMX register happens for opposite element numbers
21310b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
21320b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-1
21330b57cec5SDimitry Andric  */
21340b57cec5SDimitry Andric  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2135480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 2), 2, 61)));
21360b57cec5SDimitry Andric  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
21370b57cec5SDimitry Andric  dag BE_MV_VWORD = (MFVSRD
21380b57cec5SDimitry Andric                      (EXTRACT_SUBREG
21390b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
21400b57cec5SDimitry Andric                        sub_64));
21410b57cec5SDimitry Andric  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
21420b57cec5SDimitry Andric                                       sub_32);
21430b57cec5SDimitry Andric  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
21440b57cec5SDimitry Andric                                         sub_32);
21450b57cec5SDimitry Andric
21460b57cec5SDimitry Andric  /*  BE variable doubleword
21470b57cec5SDimitry Andric      Same as the LE doubleword except we shift in the VMX register for opposite
21480b57cec5SDimitry Andric      element indices.
21490b57cec5SDimitry Andric  */
21500b57cec5SDimitry Andric  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2151480093f4SDimitry Andric                                        (RLDICR (ANDI8_rec $Idx, 1), 3, 60)));
21520b57cec5SDimitry Andric  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
21530b57cec5SDimitry Andric  dag BE_VARIABLE_DWORD =
21540b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
21550b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
21560b57cec5SDimitry Andric                  sub_64));
21570b57cec5SDimitry Andric
21580b57cec5SDimitry Andric  /*  BE variable float
21590b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
21600b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
21610b57cec5SDimitry Andric  */
21620b57cec5SDimitry Andric  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
21630b57cec5SDimitry Andric  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
21640b57cec5SDimitry Andric  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
21650b57cec5SDimitry Andric
21660b57cec5SDimitry Andric  /* BE variable double
21670b57cec5SDimitry Andric      Same as the BE doubleword except there is no move.
21680b57cec5SDimitry Andric  */
21690b57cec5SDimitry Andric  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21700b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
21710b57cec5SDimitry Andric                                         BE_VDWORD_PERM_VEC));
21720b57cec5SDimitry Andric  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
21730b57cec5SDimitry Andric}
21740b57cec5SDimitry Andric
21750b57cec5SDimitry Andricdef AlignValues {
21760b57cec5SDimitry Andric  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
21770b57cec5SDimitry Andric  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
21780b57cec5SDimitry Andric}
21790b57cec5SDimitry Andric
21800b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64
21810b57cec5SDimitry Andricdef AnyExts {
21820b57cec5SDimitry Andric  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
21830b57cec5SDimitry Andric  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
21840b57cec5SDimitry Andric  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
21850b57cec5SDimitry Andric  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
21860b57cec5SDimitry Andric}
21870b57cec5SDimitry Andric
21880b57cec5SDimitry Andricdef DblToFlt {
2189*5ffd83dbSDimitry Andric  dag A0 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 0))));
2190*5ffd83dbSDimitry Andric  dag A1 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 1))));
2191*5ffd83dbSDimitry Andric  dag B0 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 0))));
2192*5ffd83dbSDimitry Andric  dag B1 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 1))));
21930b57cec5SDimitry Andric}
21940b57cec5SDimitry Andric
21950b57cec5SDimitry Andricdef ExtDbl {
21960b57cec5SDimitry Andric  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
21970b57cec5SDimitry Andric  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
21980b57cec5SDimitry Andric  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
21990b57cec5SDimitry Andric  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
22000b57cec5SDimitry Andric  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
22010b57cec5SDimitry Andric  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
22020b57cec5SDimitry Andric  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
22030b57cec5SDimitry Andric  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
22040b57cec5SDimitry Andric}
22050b57cec5SDimitry Andric
22060b57cec5SDimitry Andricdef ByteToWord {
22070b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
22080b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
22090b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
22100b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
22110b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
22120b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
22130b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
22140b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
22150b57cec5SDimitry Andric}
22160b57cec5SDimitry Andric
22170b57cec5SDimitry Andricdef ByteToDWord {
22180b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22190b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
22200b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22210b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
22220b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22230b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
22240b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22250b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
22260b57cec5SDimitry Andric}
22270b57cec5SDimitry Andric
22280b57cec5SDimitry Andricdef HWordToWord {
22290b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
22300b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
22310b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
22320b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
22330b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
22340b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
22350b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
22360b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
22370b57cec5SDimitry Andric}
22380b57cec5SDimitry Andric
22390b57cec5SDimitry Andricdef HWordToDWord {
22400b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
22410b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
22420b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
22430b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
22440b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
22450b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
22460b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
22470b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
22480b57cec5SDimitry Andric}
22490b57cec5SDimitry Andric
22500b57cec5SDimitry Andricdef WordToDWord {
22510b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
22520b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
22530b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
22540b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
22550b57cec5SDimitry Andric}
22560b57cec5SDimitry Andric
22570b57cec5SDimitry Andricdef FltToIntLoad {
22580b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
22590b57cec5SDimitry Andric}
22600b57cec5SDimitry Andricdef FltToUIntLoad {
22610b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
22620b57cec5SDimitry Andric}
22630b57cec5SDimitry Andricdef FltToLongLoad {
22640b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
22650b57cec5SDimitry Andric}
22660b57cec5SDimitry Andricdef FltToLongLoadP9 {
22670b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A)))));
22680b57cec5SDimitry Andric}
22690b57cec5SDimitry Andricdef FltToULongLoad {
22700b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
22710b57cec5SDimitry Andric}
22720b57cec5SDimitry Andricdef FltToULongLoadP9 {
22730b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A)))));
22740b57cec5SDimitry Andric}
22750b57cec5SDimitry Andricdef FltToLong {
22760b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
22770b57cec5SDimitry Andric}
22780b57cec5SDimitry Andricdef FltToULong {
22790b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
22800b57cec5SDimitry Andric}
22810b57cec5SDimitry Andricdef DblToInt {
22820b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
22830b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
22840b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
22850b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
22860b57cec5SDimitry Andric}
22870b57cec5SDimitry Andricdef DblToUInt {
22880b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
22890b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
22900b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
22910b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
22920b57cec5SDimitry Andric}
22930b57cec5SDimitry Andricdef DblToLong {
22940b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
22950b57cec5SDimitry Andric}
22960b57cec5SDimitry Andricdef DblToULong {
22970b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
22980b57cec5SDimitry Andric}
22990b57cec5SDimitry Andricdef DblToIntLoad {
23000b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
23010b57cec5SDimitry Andric}
23020b57cec5SDimitry Andricdef DblToIntLoadP9 {
23030b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A)))));
23040b57cec5SDimitry Andric}
23050b57cec5SDimitry Andricdef DblToUIntLoad {
23060b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
23070b57cec5SDimitry Andric}
23080b57cec5SDimitry Andricdef DblToUIntLoadP9 {
23090b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A)))));
23100b57cec5SDimitry Andric}
23110b57cec5SDimitry Andricdef DblToLongLoad {
23120b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
23130b57cec5SDimitry Andric}
23140b57cec5SDimitry Andricdef DblToULongLoad {
23150b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
23160b57cec5SDimitry Andric}
23170b57cec5SDimitry Andric
2318480093f4SDimitry Andric// FP load dags (for f32 -> v4f32)
2319480093f4SDimitry Andricdef LoadFP {
2320480093f4SDimitry Andric  dag A = (f32 (load xoaddr:$A));
2321480093f4SDimitry Andric  dag B = (f32 (load xoaddr:$B));
2322480093f4SDimitry Andric  dag C = (f32 (load xoaddr:$C));
2323480093f4SDimitry Andric  dag D = (f32 (load xoaddr:$D));
2324480093f4SDimitry Andric}
2325480093f4SDimitry Andric
23260b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32)
23270b57cec5SDimitry Andricdef MrgFP {
2328480093f4SDimitry Andric  dag LD32A = (COPY_TO_REGCLASS (LIWZX xoaddr:$A), VSRC);
2329480093f4SDimitry Andric  dag LD32B = (COPY_TO_REGCLASS (LIWZX xoaddr:$B), VSRC);
2330480093f4SDimitry Andric  dag LD32C = (COPY_TO_REGCLASS (LIWZX xoaddr:$C), VSRC);
2331480093f4SDimitry Andric  dag LD32D = (COPY_TO_REGCLASS (LIWZX xoaddr:$D), VSRC);
23320b57cec5SDimitry Andric  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
23330b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $C, VSRC), 0));
23340b57cec5SDimitry Andric  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
23350b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $D, VSRC), 0));
23360b57cec5SDimitry Andric  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
23370b57cec5SDimitry Andric  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
23380b57cec5SDimitry Andric  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
23390b57cec5SDimitry Andric  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
23400b57cec5SDimitry Andric}
23410b57cec5SDimitry Andric
23420b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors.
23430b57cec5SDimitry Andricdef MrgWords {
23440b57cec5SDimitry Andric  // For big endian, we merge low and hi doublewords (A, B).
23450b57cec5SDimitry Andric  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
23460b57cec5SDimitry Andric  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
23470b57cec5SDimitry Andric  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
23480b57cec5SDimitry Andric  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
23490b57cec5SDimitry Andric  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
23500b57cec5SDimitry Andric  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
23510b57cec5SDimitry Andric
23520b57cec5SDimitry Andric  // For little endian, we merge low and hi doublewords (B, A).
23530b57cec5SDimitry Andric  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
23540b57cec5SDimitry Andric  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
23550b57cec5SDimitry Andric  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
23560b57cec5SDimitry Andric  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
23570b57cec5SDimitry Andric  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
23580b57cec5SDimitry Andric  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
23590b57cec5SDimitry Andric
23600b57cec5SDimitry Andric  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
23610b57cec5SDimitry Andric  // then merge.
23620b57cec5SDimitry Andric  dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
23630b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$C, VSRC), 0));
23640b57cec5SDimitry Andric  dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
23650b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$D, VSRC), 0));
23660b57cec5SDimitry Andric  dag CVACS = (v4i32 (XVCVDPSXWS AC));
23670b57cec5SDimitry Andric  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
23680b57cec5SDimitry Andric  dag CVACU = (v4i32 (XVCVDPUXWS AC));
23690b57cec5SDimitry Andric  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
23700b57cec5SDimitry Andric
23710b57cec5SDimitry Andric  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
23720b57cec5SDimitry Andric  // then merge.
23730b57cec5SDimitry Andric  dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
23740b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$B, VSRC), 0));
23750b57cec5SDimitry Andric  dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
23760b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$A, VSRC), 0));
23770b57cec5SDimitry Andric  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
23780b57cec5SDimitry Andric  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
23790b57cec5SDimitry Andric  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
23800b57cec5SDimitry Andric  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
23810b57cec5SDimitry Andric}
23820b57cec5SDimitry Andric
2383*5ffd83dbSDimitry Andric//---------------------------- Anonymous Patterns ----------------------------//
2384*5ffd83dbSDimitry Andric// Predicate combinations are kept in roughly chronological order in terms of
2385*5ffd83dbSDimitry Andric// instruction availability in the architecture. For example, VSX came in with
2386*5ffd83dbSDimitry Andric// ISA 2.06 (Power7). There have since been additions in ISA 2.07 (Power8) and
2387*5ffd83dbSDimitry Andric// ISA 3.0 (Power9). However, the granularity of features on later subtargets
2388*5ffd83dbSDimitry Andric// is finer for various reasons. For example, we have Power8Vector,
2389*5ffd83dbSDimitry Andric// Power8Altivec, DirectMove that all came in with ISA 2.07. The situation is
2390*5ffd83dbSDimitry Andric// similar with ISA 3.0 with Power9Vector, Power9Altivec, IsISA3_0. Then there
2391*5ffd83dbSDimitry Andric// are orthogonal predicates such as endianness for which the order was
2392*5ffd83dbSDimitry Andric// arbitrarily chosen to be Big, Little.
2393*5ffd83dbSDimitry Andric//
2394*5ffd83dbSDimitry Andric// Predicate combinations available:
2395*5ffd83dbSDimitry Andric// [HasVSX]
2396*5ffd83dbSDimitry Andric// [HasVSX, IsBigEndian]
2397*5ffd83dbSDimitry Andric// [HasVSX, IsLittleEndian]
2398*5ffd83dbSDimitry Andric// [HasVSX, NoP9Vector]
2399*5ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps]
2400*5ffd83dbSDimitry Andric// [HasVSX, HasOnlySwappingMemOps, IsBigEndian]
2401*5ffd83dbSDimitry Andric// [HasVSX, HasP8Vector]
2402*5ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, IsBigEndian]
2403*5ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, IsLittleEndian]
2404*5ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian]
2405*5ffd83dbSDimitry Andric// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian]
2406*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove]
2407*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsBigEndian]
2408*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, IsLittleEndian]
2409*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian]
2410*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian]
2411*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian]
2412*5ffd83dbSDimitry Andric// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian]
2413*5ffd83dbSDimitry Andric// [HasVSX, HasP9Vector]
2414*5ffd83dbSDimitry Andric// [HasVSX, HasP9Vector, IsBigEndian]
2415*5ffd83dbSDimitry Andric// [HasVSX, HasP9Vector, IsLittleEndian]
2416*5ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec]
2417*5ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec, IsBigEndian]
2418*5ffd83dbSDimitry Andric// [HasVSX, HasP9Altivec, IsLittleEndian]
2419*5ffd83dbSDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian]
2420*5ffd83dbSDimitry Andric// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian]
24210b57cec5SDimitry Andric
2422*5ffd83dbSDimitry Andriclet AddedComplexity = 400 in {
2423*5ffd83dbSDimitry Andric// Valid for any VSX subtarget, regardless of endianness.
24240b57cec5SDimitry Andriclet Predicates = [HasVSX] in {
2425*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (vnot_ppc v4i32:$A)),
2426*5ffd83dbSDimitry Andric          (v4i32 (XXLNOR $A, $A))>;
2427*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A),
2428*5ffd83dbSDimitry Andric                     (and v4i32:$B, v4i32:$C))),
2429*5ffd83dbSDimitry Andric          (v4i32 (XXSEL $A, $B, $C))>;
2430*5ffd83dbSDimitry Andric
2431*5ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
2432*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
2433*5ffd83dbSDimitry Andric          (XSNMSUBADP $C, $A, $B)>;
2434*5ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
2435*5ffd83dbSDimitry Andric          (XSMSUBADP $C, $A, $B)>;
2436*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
2437*5ffd83dbSDimitry Andric          (XSNMADDADP $C, $A, $B)>;
2438*5ffd83dbSDimitry Andric
2439*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C),
2440*5ffd83dbSDimitry Andric          (XVNMSUBADP $C, $A, $B)>;
2441*5ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)),
2442*5ffd83dbSDimitry Andric          (XVMSUBADP $C, $A, $B)>;
2443*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)),
2444*5ffd83dbSDimitry Andric          (XVNMADDADP $C, $A, $B)>;
2445*5ffd83dbSDimitry Andric
2446*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C),
2447*5ffd83dbSDimitry Andric          (XVNMSUBASP $C, $A, $B)>;
2448*5ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
2449*5ffd83dbSDimitry Andric          (XVMSUBASP $C, $A, $B)>;
2450*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
2451*5ffd83dbSDimitry Andric          (XVNMADDASP $C, $A, $B)>;
2452*5ffd83dbSDimitry Andric
2453*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)),
2454*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2455*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)),
2456*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2457*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)),
2458*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2459*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)),
2460*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2461*5ffd83dbSDimitry Andric
2462*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)),
2463*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2464*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)),
2465*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2466*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)),
2467*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2468*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)),
2469*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2470*5ffd83dbSDimitry Andric
2471*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)),
2472*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2473*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)),
2474*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2475*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)),
2476*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2477*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)),
2478*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
2479*5ffd83dbSDimitry Andric
2480*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)),
2481*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2482*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)),
2483*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2484*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)),
2485*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2486*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)),
2487*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2488*5ffd83dbSDimitry Andric
2489*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)),
2490*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2491*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)),
2492*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2493*5ffd83dbSDimitry Andric
2494*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)),
2495*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2496*5ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)),
2497*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2498*5ffd83dbSDimitry Andric
2499*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)),
2500*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2501*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)),
2502*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2503*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)),
2504*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2505*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)),
2506*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
2507*5ffd83dbSDimitry Andric
2508*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
2509*5ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
2510*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
2511*5ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
2512*5ffd83dbSDimitry Andric
2513*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
2514*5ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
2515*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
2516*5ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
2517*5ffd83dbSDimitry Andric
2518*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
2519*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
2520*5ffd83dbSDimitry Andric
2521*5ffd83dbSDimitry Andric// Permutes.
2522*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
2523*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
2524*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
2525*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
2526*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
2527*5ffd83dbSDimitry Andric
2528*5ffd83dbSDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
2529*5ffd83dbSDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
2530*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)),
2531*5ffd83dbSDimitry Andric          (XXPERMDI $src, $src, 2)>;
2532*5ffd83dbSDimitry Andric
2533*5ffd83dbSDimitry Andric// Selects.
2534*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
2535*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2536*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
2537*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2538*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
2539*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2540*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
2541*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2542*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
2543*5ffd83dbSDimitry Andric          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
2544*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
2545*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2546*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
2547*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2548*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
2549*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2550*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
2551*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2552*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
2553*5ffd83dbSDimitry Andric          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
2554*5ffd83dbSDimitry Andric
2555*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
2556*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2557*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
2558*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2559*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
2560*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2561*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
2562*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2563*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
2564*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
2565*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
2566*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2567*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
2568*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2569*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
2570*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2571*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
2572*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2573*5ffd83dbSDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
2574*5ffd83dbSDimitry Andric          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
2575*5ffd83dbSDimitry Andric
2576*5ffd83dbSDimitry Andric// Divides.
2577*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
2578*5ffd83dbSDimitry Andric          (XVDIVSP $A, $B)>;
2579*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
2580*5ffd83dbSDimitry Andric          (XVDIVDP $A, $B)>;
2581*5ffd83dbSDimitry Andric
2582*5ffd83dbSDimitry Andric// Reciprocal estimate
2583*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A),
2584*5ffd83dbSDimitry Andric          (XVRESP $A)>;
2585*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A),
2586*5ffd83dbSDimitry Andric          (XVREDP $A)>;
2587*5ffd83dbSDimitry Andric
2588*5ffd83dbSDimitry Andric// Recip. square root estimate
2589*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
2590*5ffd83dbSDimitry Andric          (XVRSQRTESP $A)>;
2591*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
2592*5ffd83dbSDimitry Andric          (XVRSQRTEDP $A)>;
2593*5ffd83dbSDimitry Andric
2594*5ffd83dbSDimitry Andric// Vector selection
2595*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
2596*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
2597*5ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
2598*5ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
2599*5ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
2600*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
2601*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS
2602*5ffd83dbSDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
2603*5ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
2604*5ffd83dbSDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
2605*5ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
2606*5ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
2607*5ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
2608*5ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
2609*5ffd83dbSDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
2610*5ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
2611*5ffd83dbSDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
2612*5ffd83dbSDimitry Andric          (XXSEL $vC, $vB, $vA)>;
2613*5ffd83dbSDimitry Andric
2614*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fmaxnum v4f32:$src1, v4f32:$src2)),
2615*5ffd83dbSDimitry Andric          (v4f32 (XVMAXSP $src1, $src2))>;
2616*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (any_fminnum v4f32:$src1, v4f32:$src2)),
2617*5ffd83dbSDimitry Andric          (v4f32 (XVMINSP $src1, $src2))>;
2618*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fmaxnum v2f64:$src1, v2f64:$src2)),
2619*5ffd83dbSDimitry Andric          (v2f64 (XVMAXDP $src1, $src2))>;
2620*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (any_fminnum v2f64:$src1, v2f64:$src2)),
2621*5ffd83dbSDimitry Andric          (v2f64 (XVMINDP $src1, $src2))>;
2622*5ffd83dbSDimitry Andric
2623*5ffd83dbSDimitry Andric// f32 abs
2624*5ffd83dbSDimitry Andricdef : Pat<(f32 (fabs f32:$S)),
2625*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSABSDP
2626*5ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2627*5ffd83dbSDimitry Andric
2628*5ffd83dbSDimitry Andric// f32 nabs
2629*5ffd83dbSDimitry Andricdef : Pat<(f32 (fneg (fabs f32:$S))),
2630*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNABSDP
2631*5ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2632*5ffd83dbSDimitry Andric
2633*5ffd83dbSDimitry Andric// f32 Min.
2634*5ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)),
2635*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
2636*5ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)),
2637*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
2638*5ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))),
2639*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
2640*5ffd83dbSDimitry Andricdef : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
2641*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Min)>;
2642*5ffd83dbSDimitry Andric// F32 Max.
2643*5ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)),
2644*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
2645*5ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)),
2646*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
2647*5ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))),
2648*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
2649*5ffd83dbSDimitry Andricdef : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
2650*5ffd83dbSDimitry Andric          (f32 FpMinMax.F32Max)>;
2651*5ffd83dbSDimitry Andric
2652*5ffd83dbSDimitry Andric// f64 Min.
2653*5ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)),
2654*5ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
2655*5ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)),
2656*5ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
2657*5ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))),
2658*5ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
2659*5ffd83dbSDimitry Andricdef : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
2660*5ffd83dbSDimitry Andric          (f64 (XSMINDP $A, $B))>;
2661*5ffd83dbSDimitry Andric// f64 Max.
2662*5ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)),
2663*5ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
2664*5ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)),
2665*5ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
2666*5ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))),
2667*5ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
2668*5ffd83dbSDimitry Andricdef : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
2669*5ffd83dbSDimitry Andric          (f64 (XSMAXDP $A, $B))>;
2670*5ffd83dbSDimitry Andric
2671*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
2672*5ffd83dbSDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
2673*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
2674*5ffd83dbSDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
2675*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2676*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2677*5ffd83dbSDimitry Andric
2678*5ffd83dbSDimitry Andric// Rounding for single precision.
2679*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_fround f32:$S)),
2680*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPI
2681*5ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2682*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_fnearbyint f32:$S)),
2683*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
2684*5ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2685*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_ffloor f32:$S)),
2686*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIM
2687*5ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2688*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_fceil f32:$S)),
2689*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIP
2690*5ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2691*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_ftrunc f32:$S)),
2692*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIZ
2693*5ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2694*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_frint f32:$S)),
2695*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
2696*5ffd83dbSDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2697*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
2698*5ffd83dbSDimitry Andric
2699*5ffd83dbSDimitry Andric// Rounding for double precision.
2700*5ffd83dbSDimitry Andricdef : Pat<(f64 (frint f64:$S)), (f64 (XSRDPIC $S))>;
2701*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
2702*5ffd83dbSDimitry Andric
2703*5ffd83dbSDimitry Andric// Materialize a zero-vector of long long
2704*5ffd83dbSDimitry Andricdef : Pat<(v2i64 immAllZerosV),
2705*5ffd83dbSDimitry Andric          (v2i64 (XXLXORz))>;
2706*5ffd83dbSDimitry Andric
27070b57cec5SDimitry Andric// Build vectors of floating point converted to i32.
27080b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
27090b57cec5SDimitry Andric                               DblToInt.A, DblToInt.A)),
27100b57cec5SDimitry Andric          (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
27110b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
27120b57cec5SDimitry Andric                               DblToUInt.A, DblToUInt.A)),
27130b57cec5SDimitry Andric          (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
27140b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
27150b57cec5SDimitry Andric          (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
27160b57cec5SDimitry Andric                           (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
27170b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
27180b57cec5SDimitry Andric          (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
27190b57cec5SDimitry Andric                           (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
2720*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2721*5ffd83dbSDimitry Andric  v4i32, FltToIntLoad.A,
2722*5ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1),
2723*5ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC)>;
2724*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2725*5ffd83dbSDimitry Andric  v4i32, FltToUIntLoad.A,
2726*5ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1),
2727*5ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC)>;
27280b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
27290b57cec5SDimitry Andric          (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
27308bcb0991SDimitry Andricdef : Pat<(v2f64 (PPCldsplat xoaddr:$A)),
27318bcb0991SDimitry Andric          (v2f64 (LXVDSX xoaddr:$A))>;
27328bcb0991SDimitry Andricdef : Pat<(v2i64 (PPCldsplat xoaddr:$A)),
27338bcb0991SDimitry Andric          (v2i64 (LXVDSX xoaddr:$A))>;
27340b57cec5SDimitry Andric
27350b57cec5SDimitry Andric// Build vectors of floating point converted to i64.
27360b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
27370b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
27380b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
27390b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
27400b57cec5SDimitry Andric          (v2i64 (XXPERMDIs
27410b57cec5SDimitry Andric                   (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
2742*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2743*5ffd83dbSDimitry Andric  v2i64, DblToLongLoad.A,
2744*5ffd83dbSDimitry Andric  (XVCVDPSXDS (LXVDSX xoaddr:$A)), (XVCVDPSXDS (LXVDSX xoaddr:$A))>;
2745*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2746*5ffd83dbSDimitry Andric  v2i64, DblToULongLoad.A,
2747*5ffd83dbSDimitry Andric  (XVCVDPUXDS (LXVDSX xoaddr:$A)), (XVCVDPUXDS (LXVDSX xoaddr:$A))>;
2748*5ffd83dbSDimitry Andric} // HasVSX
27490b57cec5SDimitry Andric
2750*5ffd83dbSDimitry Andric// Any big endian VSX subtarget.
2751*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsBigEndian] in {
2752*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)),
2753*5ffd83dbSDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
27540b57cec5SDimitry Andric
2755*5ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
2756*5ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
2757*5ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
2758*5ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
2759*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2760*5ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
2761*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2762*5ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2763*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2764*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
2765*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2766*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
27670b57cec5SDimitry Andric
2768*5ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2769*5ffd83dbSDimitry Andric          (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
27700b57cec5SDimitry Andric
27710b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
27720b57cec5SDimitry Andric          (v2f64 (XXPERMDI
27730b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $A, VSRC),
27740b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $B, VSRC), 0))>;
2775480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
2776480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
2777480093f4SDimitry Andric// XXPERMDI for 2 reasons:
2778480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
2779480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
2780480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
2781480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
2782480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2783480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
2784480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2785480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B),
2786480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>;
27870b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
27880b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
27890b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
27900b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
27910b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
27920b57cec5SDimitry Andric
27930b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
27940b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
27950b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
27960b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
27970b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
27980b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
27990b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
28000b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
28010b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
28020b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
28030b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
28040b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
28050b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
2806*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2807*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
2808*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
2809*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2810*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
2811*5ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
2812*5ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
2813*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2814*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2815*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
2816*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2817*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2818*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>;
2819*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
2820*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2821*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
2822*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2823*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2824*5ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
2825*5ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
2826*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2827*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
2828*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>;
2829*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2830*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
2831*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3),
2832*5ffd83dbSDimitry Andric                                    (XXPERMDI $A, $B, 3), 1)))>;
2833*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
2834*5ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
2835*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
2836*5ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 3)))>;
2837*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
2838*5ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
2839*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
2840*5ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 3)))>;
2841*5ffd83dbSDimitry Andric} // HasVSX, IsBigEndian
28420b57cec5SDimitry Andric
2843*5ffd83dbSDimitry Andric// Any little endian VSX subtarget.
2844*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsLittleEndian] in {
2845*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2f64, (f64 f64:$A),
2846*5ffd83dbSDimitry Andric                         (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
2847*5ffd83dbSDimitry Andric                                   (SUBREG_TO_REG (i64 1), $A, sub_64), 0),
2848*5ffd83dbSDimitry Andric                         (SUBREG_TO_REG (i64 1), $A, sub_64)>;
28490b57cec5SDimitry Andric
2850*5ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
2851*5ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
2852*5ffd83dbSDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
2853*5ffd83dbSDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
28540b57cec5SDimitry Andric
2855*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2856*5ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2857*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2858*5ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v4f32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
2859*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2860*5ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2861*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2862*5ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v4i32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
2863*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2864*5ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2865*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2866*5ffd83dbSDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
2867*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2868*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2869*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2870*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
28710b57cec5SDimitry Andric
2872*5ffd83dbSDimitry Andricdef : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2873*5ffd83dbSDimitry Andric          (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
2874*5ffd83dbSDimitry Andric
28750b57cec5SDimitry Andric// Little endian, available on all targets with VSX
28760b57cec5SDimitry Andricdef : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
28770b57cec5SDimitry Andric          (v2f64 (XXPERMDI
28780b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $B, VSRC),
28790b57cec5SDimitry Andric                    (COPY_TO_REGCLASS $A, VSRC), 0))>;
2880480093f4SDimitry Andric// Using VMRGEW to assemble the final vector would be a lower latency
2881480093f4SDimitry Andric// solution. However, we choose to go with the slightly higher latency
2882480093f4SDimitry Andric// XXPERMDI for 2 reasons:
2883480093f4SDimitry Andric// 1. This is likely to occur in unrolled loops where regpressure is high,
2884480093f4SDimitry Andric//    so we want to use the latter as it has access to all 64 VSX registers.
2885480093f4SDimitry Andric// 2. Using Altivec instructions in this sequence would likely cause the
2886480093f4SDimitry Andric//    allocation of Altivec registers even for the loads which in turn would
2887480093f4SDimitry Andric//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2888480093f4SDimitry Andric//    each of the loads which would otherwise be able to use LFIWZX.
2889480093f4SDimitry Andricdef : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2890480093f4SDimitry Andric          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C),
2891480093f4SDimitry Andric                           (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>;
28920b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
28930b57cec5SDimitry Andric          (VMRGEW MrgFP.AC, MrgFP.BD)>;
28940b57cec5SDimitry Andricdef : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
28950b57cec5SDimitry Andric                               DblToFlt.B0, DblToFlt.B1)),
28960b57cec5SDimitry Andric          (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
28970b57cec5SDimitry Andric
28980b57cec5SDimitry Andric// Convert 4 doubles to a vector of ints.
28990b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
29000b57cec5SDimitry Andric                               DblToInt.C, DblToInt.D)),
29010b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
29020b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
29030b57cec5SDimitry Andric                               DblToUInt.C, DblToUInt.D)),
29040b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
29050b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
29060b57cec5SDimitry Andric                               ExtDbl.B0S, ExtDbl.B1S)),
29070b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
29080b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
29090b57cec5SDimitry Andric                               ExtDbl.B0U, ExtDbl.B1U)),
29100b57cec5SDimitry Andric          (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
2911*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2912*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
2913*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
2914*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2915*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
2916*5ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
2917*5ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
2918*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2919*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2920*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>;
2921*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2922*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2923*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP $A))>;
2924*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
2925*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2926*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
2927*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2928*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2929*5ffd83dbSDimitry Andric          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
2930*5ffd83dbSDimitry Andric                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
2931*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2932*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
2933*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3),
2934*5ffd83dbSDimitry Andric                                    (XXPERMDI $B, $A, 3), 1)))>;
2935*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2936*5ffd83dbSDimitry Andric                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
2937*5ffd83dbSDimitry Andric          (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>;
2938*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02S,
2939*5ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
2940*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13S,
2941*5ffd83dbSDimitry Andric          (v2f64 (XVCVSXWDP $A))>;
2942*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV02U,
2943*5ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
2944*5ffd83dbSDimitry Andricdef : Pat<WToDPExtractConv.BV13U,
2945*5ffd83dbSDimitry Andric          (v2f64 (XVCVUXWDP $A))>;
2946*5ffd83dbSDimitry Andric} // HasVSX, IsLittleEndian
29470b57cec5SDimitry Andric
2948*5ffd83dbSDimitry Andric// Any pre-Power9 VSX subtarget.
2949*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, NoP9Vector] in {
2950*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
2951*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
2952*5ffd83dbSDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
2953*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
2954*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
2955*5ffd83dbSDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
2956*5ffd83dbSDimitry Andric
2957*5ffd83dbSDimitry Andric// Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
2958*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2959*5ffd83dbSDimitry Andric  v4i32, DblToIntLoad.A,
2960*5ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1),
2961*5ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC)>;
2962*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2963*5ffd83dbSDimitry Andric  v4i32, DblToUIntLoad.A,
2964*5ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1),
2965*5ffd83dbSDimitry Andric  (COPY_TO_REGCLASS (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC)>;
2966*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2967*5ffd83dbSDimitry Andric  v2i64, FltToLongLoad.A,
2968*5ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A), VSFRC)), 0),
2969*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A),
2970*5ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
2971*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
2972*5ffd83dbSDimitry Andric  v2i64, FltToULongLoad.A,
2973*5ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A), VSFRC)), 0),
2974*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A),
2975*5ffd83dbSDimitry Andric                                                        VSFRC)), sub_64)>;
2976*5ffd83dbSDimitry Andric} // HasVSX, NoP9Vector
2977*5ffd83dbSDimitry Andric
2978*5ffd83dbSDimitry Andric// Any VSX subtarget that only has loads and stores that load in big endian
2979*5ffd83dbSDimitry Andric// order regardless of endianness. This is really pre-Power9 subtargets.
2980*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in {
2981*5ffd83dbSDimitry Andric  def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2982*5ffd83dbSDimitry Andric
2983*5ffd83dbSDimitry Andric  // Stores.
2984*5ffd83dbSDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
2985*5ffd83dbSDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
2986*5ffd83dbSDimitry Andric  def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2987*5ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps
2988*5ffd83dbSDimitry Andric
2989*5ffd83dbSDimitry Andric// Big endian VSX subtarget that only has loads and stores that always load
2990*5ffd83dbSDimitry Andric// in big endian order. Really big endian pre-Power9 subtargets.
2991*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in {
2992*5ffd83dbSDimitry Andric  def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2993*5ffd83dbSDimitry Andric  def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2994*5ffd83dbSDimitry Andric  def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2995*5ffd83dbSDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2996*5ffd83dbSDimitry Andric  def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2997*5ffd83dbSDimitry Andric  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2998*5ffd83dbSDimitry Andric  def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
2999*5ffd83dbSDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3000*5ffd83dbSDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
3001*5ffd83dbSDimitry Andric} // HasVSX, HasOnlySwappingMemOps, IsBigEndian
3002*5ffd83dbSDimitry Andric
3003*5ffd83dbSDimitry Andric// Any Power8 VSX subtarget.
3004*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector] in {
3005*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
3006*5ffd83dbSDimitry Andric          (XXLEQV $A, $B)>;
3007*5ffd83dbSDimitry Andricdef : Pat<(f64 (extloadf32 xoaddr:$src)),
3008*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
3009*5ffd83dbSDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
3010*5ffd83dbSDimitry Andric          (f32 (XFLOADf32 xoaddr:$src))>;
3011*5ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpextend f32:$src)),
3012*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS $src, VSFRC)>;
3013*5ffd83dbSDimitry Andric
3014*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
3015*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
3016*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
3017*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
3018*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
3019*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
3020*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
3021*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
3022*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
3023*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
3024*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
3025*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
3026*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
3027*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
3028*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
3029*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
3030*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
3031*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
3032*5ffd83dbSDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
3033*5ffd83dbSDimitry Andric          (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
3034*5ffd83dbSDimitry Andric
3035*5ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
3036*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
3037*5ffd83dbSDimitry Andric          (XSNMSUBASP $C, $A, $B)>;
3038*5ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
3039*5ffd83dbSDimitry Andric          (XSMSUBASP $C, $A, $B)>;
3040*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
3041*5ffd83dbSDimitry Andric          (XSNMADDASP $C, $A, $B)>;
3042*5ffd83dbSDimitry Andric
3043*5ffd83dbSDimitry Andric// f32 neg
3044*5ffd83dbSDimitry Andric// Although XSNEGDP is available in P7, we want to select it starting from P8,
3045*5ffd83dbSDimitry Andric// so that FNMSUBS can be selected for fneg-fmsub pattern on P7. (VSX version,
3046*5ffd83dbSDimitry Andric// XSNMSUBASP, is available since P8)
3047*5ffd83dbSDimitry Andricdef : Pat<(f32 (fneg f32:$S)),
3048*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSNEGDP
3049*5ffd83dbSDimitry Andric               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
3050*5ffd83dbSDimitry Andric
3051*5ffd83dbSDimitry Andric// Instructions for converting float to i32 feeding a store.
3052*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3053*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
3054*5ffd83dbSDimitry Andric          (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3055*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3056*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
3057*5ffd83dbSDimitry Andric          (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3058*5ffd83dbSDimitry Andric
3059*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
3060*5ffd83dbSDimitry Andric          (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
3061*5ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3062*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
3063*5ffd83dbSDimitry Andric          (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
3064*5ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3065*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
3066*5ffd83dbSDimitry Andric          (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
3067*5ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3068*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
3069*5ffd83dbSDimitry Andric          (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
3070*5ffd83dbSDimitry Andric                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3071*5ffd83dbSDimitry Andric
3072*5ffd83dbSDimitry Andricdef : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
3073*5ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3074*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
3075*5ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3076*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
3077*5ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3078*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
3079*5ffd83dbSDimitry Andric          (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3080*5ffd83dbSDimitry Andric} // HasVSX, HasP8Vector
3081*5ffd83dbSDimitry Andric
3082*5ffd83dbSDimitry Andric// Big endian Power8 VSX subtarget.
3083*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsBigEndian] in {
3084*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
3085*5ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
3086*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
3087*5ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3088*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
3089*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
3090*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
3091*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3092*5ffd83dbSDimitry Andric
3093*5ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (BE)
3094*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (scalar_to_vector f32:$A)),
3095*5ffd83dbSDimitry Andric          (v4f32 (XSCVDPSPN $A))>;
3096*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
3097*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
3098*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
3099*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
3100*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
3101*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
3102*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
3103*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
3104*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
3105*5ffd83dbSDimitry Andric          (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
3106*5ffd83dbSDimitry Andric
3107*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3108*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
3109*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3110*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
3111*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3112*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
3113*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3114*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
3115*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3116*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
3117*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3118*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
3119*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3120*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
3121*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3122*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
3123*5ffd83dbSDimitry Andric
3124*5ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
3125*5ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
3126*5ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
3127*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
3128*5ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
3129*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
3130*5ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
3131*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3132*5ffd83dbSDimitry Andric          (v4i32 (XXSLDWIs
3133*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3134*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3135*5ffd83dbSDimitry Andric          (v4f32 (XXSLDWIs
3136*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3137*5ffd83dbSDimitry Andric
3138*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
3139*5ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
3140*5ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
3141*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
3142*5ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
3143*5ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
3144*5ffd83dbSDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src),
3145*5ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3146*5ffd83dbSDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src),
3147*5ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3148*5ffd83dbSDimitry Andric
3149*5ffd83dbSDimitry Andric// Elements in a register on a BE system are in order <0, 1, 2, 3>.
3150*5ffd83dbSDimitry Andric// The store instructions store the second word from the left.
3151*5ffd83dbSDimitry Andric// So to align element zero, we need to modulo-left-shift by 3 words.
3152*5ffd83dbSDimitry Andric// Similar logic applies for elements 2 and 3.
3153*5ffd83dbSDimitry Andricforeach Idx = [ [0,3], [2,1], [3,2] ] in {
3154*5ffd83dbSDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
3155*5ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3156*5ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
3157*5ffd83dbSDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
3158*5ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3159*5ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
3160*5ffd83dbSDimitry Andric}
3161*5ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, IsBigEndian
3162*5ffd83dbSDimitry Andric
3163*5ffd83dbSDimitry Andric// Little endian Power8 VSX subtarget.
3164*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in {
3165*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0SS1,
3166*5ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3167*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1SS1,
3168*5ffd83dbSDimitry Andric          (f32 (XSCVSXDSP (COPY_TO_REGCLASS
3169*5ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
3170*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El0US1,
3171*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3172*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.El1US1,
3173*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (COPY_TO_REGCLASS
3174*5ffd83dbSDimitry Andric                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
3175*5ffd83dbSDimitry Andric
3176*5ffd83dbSDimitry Andric// v4f32 scalar <-> vector conversions (LE)
3177*5ffd83dbSDimitry Andric  // The permuted version is no better than the version that puts the value
3178*5ffd83dbSDimitry Andric  // into the right element because XSCVDPSPN is different from all the other
3179*5ffd83dbSDimitry Andric  // instructions used for PPCSToV.
3180*5ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4f32, (f32 f32:$A),
3181*5ffd83dbSDimitry Andric                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1),
3182*5ffd83dbSDimitry Andric                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 3)>;
3183*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 0)),
3184*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
3185*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 1)),
3186*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
3187*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 2)),
3188*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
3189*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, 3)),
3190*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN $S))>;
3191*5ffd83dbSDimitry Andricdef : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
3192*5ffd83dbSDimitry Andric          (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
3193*5ffd83dbSDimitry Andric
3194*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3195*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
3196*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3197*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
3198*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3199*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
3200*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3201*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
3202*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3203*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
3204*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3205*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
3206*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3207*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
3208*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3209*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
3210*5ffd83dbSDimitry Andric
3211*5ffd83dbSDimitry Andric// LIWAX - This instruction is used for sign extending i32 -> i64.
3212*5ffd83dbSDimitry Andric// LIWZX - This instruction will be emitted for i32, f32, and when
3213*5ffd83dbSDimitry Andric//         zero-extending i32 to i64 (zext i32 -> i64).
3214*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3215*5ffd83dbSDimitry Andric  v2i64, (i64 (sextloadi32 xoaddr:$src)),
3216*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSFRC), 2),
3217*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWAX xoaddr:$src), sub_64)>;
3218*5ffd83dbSDimitry Andric
3219*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3220*5ffd83dbSDimitry Andric  v2i64, (i64 (zextloadi32 xoaddr:$src)),
3221*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
3222*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
3223*5ffd83dbSDimitry Andric
3224*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3225*5ffd83dbSDimitry Andric  v4i32, (i32 (load xoaddr:$src)),
3226*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
3227*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
3228*5ffd83dbSDimitry Andric
3229*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3230*5ffd83dbSDimitry Andric  v4f32, (f32 (load xoaddr:$src)),
3231*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
3232*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
3233*5ffd83dbSDimitry Andric
3234*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVU,
3235*5ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
3236*5ffd83dbSDimitry Andric                          (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
3237*5ffd83dbSDimitry Andricdef : Pat<DWToSPExtractConv.BVS,
3238*5ffd83dbSDimitry Andric          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
3239*5ffd83dbSDimitry Andric                          (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
3240*5ffd83dbSDimitry Andricdef : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src),
3241*5ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3242*5ffd83dbSDimitry Andricdef : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src),
3243*5ffd83dbSDimitry Andric          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3244*5ffd83dbSDimitry Andric
3245*5ffd83dbSDimitry Andric// Elements in a register on a LE system are in order <3, 2, 1, 0>.
3246*5ffd83dbSDimitry Andric// The store instructions store the second word from the left.
3247*5ffd83dbSDimitry Andric// So to align element 3, we need to modulo-left-shift by 3 words.
3248*5ffd83dbSDimitry Andric// Similar logic applies for elements 0 and 1.
3249*5ffd83dbSDimitry Andricforeach Idx = [ [0,2], [1,1], [3,3] ] in {
3250*5ffd83dbSDimitry Andric  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
3251*5ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3252*5ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
3253*5ffd83dbSDimitry Andric  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
3254*5ffd83dbSDimitry Andric            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3255*5ffd83dbSDimitry Andric                                   sub_64), xoaddr:$src)>;
3256*5ffd83dbSDimitry Andric}
3257*5ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, IsLittleEndian
3258*5ffd83dbSDimitry Andric
3259*5ffd83dbSDimitry Andric// Big endian pre-Power9 VSX subtarget.
3260*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian] in {
3261*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
3262*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3263*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
3264*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3265*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
3266*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3267*5ffd83dbSDimitry Andric                      xoaddr:$src)>;
3268*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
3269*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3270*5ffd83dbSDimitry Andric                      xoaddr:$src)>;
3271*5ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian
3272*5ffd83dbSDimitry Andric
3273*5ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget.
3274*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in {
3275*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
3276*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3277*5ffd83dbSDimitry Andric                      xoaddr:$src)>;
3278*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
3279*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3280*5ffd83dbSDimitry Andric                      xoaddr:$src)>;
3281*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
3282*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3283*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
3284*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3285*5ffd83dbSDimitry Andric} // HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian
3286*5ffd83dbSDimitry Andric
3287*5ffd83dbSDimitry Andric// Any VSX target with direct moves.
3288*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove] in {
3289*5ffd83dbSDimitry Andric// bitconvert f32 -> i32
3290*5ffd83dbSDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR)
3291*5ffd83dbSDimitry Andricdef : Pat<(i32 (bitconvert f32:$S)),
3292*5ffd83dbSDimitry Andric          (i32 (MFVSRWZ (EXTRACT_SUBREG
3293*5ffd83dbSDimitry Andric                          (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
3294*5ffd83dbSDimitry Andric                          sub_64)))>;
3295*5ffd83dbSDimitry Andric// bitconvert i32 -> f32
3296*5ffd83dbSDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single)
3297*5ffd83dbSDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)),
3298*5ffd83dbSDimitry Andric          (f32 (XSCVSPDPN
3299*5ffd83dbSDimitry Andric                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
3300*5ffd83dbSDimitry Andric
3301*5ffd83dbSDimitry Andric// bitconvert f64 -> i64
3302*5ffd83dbSDimitry Andric// (move to GPR, nothing else needed)
3303*5ffd83dbSDimitry Andricdef : Pat<(i64 (bitconvert f64:$S)),
3304*5ffd83dbSDimitry Andric          (i64 (MFVSRD $S))>;
3305*5ffd83dbSDimitry Andric
3306*5ffd83dbSDimitry Andric// bitconvert i64 -> f64
3307*5ffd83dbSDimitry Andric// (move to FPR, nothing else needed)
3308*5ffd83dbSDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)),
3309*5ffd83dbSDimitry Andric          (f64 (MTVSRD $S))>;
3310*5ffd83dbSDimitry Andric
3311*5ffd83dbSDimitry Andric// Rounding to integer.
3312*5ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f64:$S)),
3313*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
3314*5ffd83dbSDimitry Andricdef : Pat<(i64 (lrint f32:$S)),
3315*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
3316*5ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f64:$S)),
3317*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
3318*5ffd83dbSDimitry Andricdef : Pat<(i64 (llrint f32:$S)),
3319*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
3320*5ffd83dbSDimitry Andricdef : Pat<(i64 (lround f64:$S)),
3321*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
3322*5ffd83dbSDimitry Andricdef : Pat<(i64 (lround f32:$S)),
3323*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
3324*5ffd83dbSDimitry Andricdef : Pat<(i64 (llround f64:$S)),
3325*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
3326*5ffd83dbSDimitry Andricdef : Pat<(i64 (llround f32:$S)),
3327*5ffd83dbSDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
3328*5ffd83dbSDimitry Andric
3329*5ffd83dbSDimitry Andric// Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
3330*5ffd83dbSDimitry Andric// of f64
3331*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCmtvsrz i32:$A)),
3332*5ffd83dbSDimitry Andric          (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
3333*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCmtvsrz i32:$A)),
3334*5ffd83dbSDimitry Andric          (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
3335*5ffd83dbSDimitry Andric
33360b57cec5SDimitry Andric// Endianness-neutral constant splat on P8 and newer targets. The reason
33370b57cec5SDimitry Andric// for this pattern is that on targets with direct moves, we don't expand
33380b57cec5SDimitry Andric// BUILD_VECTOR nodes for v4i32.
33390b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
33400b57cec5SDimitry Andric                               immSExt5NonZero:$A, immSExt5NonZero:$A)),
33410b57cec5SDimitry Andric          (v4i32 (VSPLTISW imm:$A))>;
3342*5ffd83dbSDimitry Andric} // HasVSX, HasDirectMove
33430b57cec5SDimitry Andric
3344*5ffd83dbSDimitry Andric// Big endian VSX subtarget with direct moves.
3345*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsBigEndian] in {
3346*5ffd83dbSDimitry Andric// v16i8 scalar <-> vector conversions (BE)
3347*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (scalar_to_vector i32:$A)),
3348*5ffd83dbSDimitry Andric          (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
3349*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (scalar_to_vector i32:$A)),
3350*5ffd83dbSDimitry Andric          (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
3351*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (scalar_to_vector i32:$A)),
3352*5ffd83dbSDimitry Andric          (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
3353*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector i64:$A)),
3354*5ffd83dbSDimitry Andric          (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
3355*5ffd83dbSDimitry Andric
3356*5ffd83dbSDimitry Andric// v2i64 scalar <-> vector conversions (BE)
3357*5ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 0)),
3358*5ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_1)>;
3359*5ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, 1)),
3360*5ffd83dbSDimitry Andric          (i64 VectorExtractions.LE_DWORD_0)>;
3361*5ffd83dbSDimitry Andricdef : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
3362*5ffd83dbSDimitry Andric          (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
3363*5ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsBigEndian
3364*5ffd83dbSDimitry Andric
3365*5ffd83dbSDimitry Andric// Little endian VSX subtarget with direct moves.
3366*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, IsLittleEndian] in {
3367*5ffd83dbSDimitry Andric  // v16i8 scalar <-> vector conversions (LE)
3368*5ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v16i8, (i32 i32:$A),
3369*5ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
3370*5ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
3371*5ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v8i16, (i32 i32:$A),
3372*5ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
3373*5ffd83dbSDimitry Andric                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
3374*5ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v4i32, (i32 i32:$A), MovesToVSR.LE_WORD_0,
3375*5ffd83dbSDimitry Andric                           (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
3376*5ffd83dbSDimitry Andric  defm : ScalToVecWPermute<v2i64, (i64 i64:$A), MovesToVSR.LE_DWORD_0,
3377*5ffd83dbSDimitry Andric                           MovesToVSR.LE_DWORD_1>;
3378*5ffd83dbSDimitry Andric
3379*5ffd83dbSDimitry Andric  // v2i64 scalar <-> vector conversions (LE)
3380*5ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
3381*5ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
3382*5ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
3383*5ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
3384*5ffd83dbSDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
3385*5ffd83dbSDimitry Andric            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
3386*5ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, IsLittleEndian
3387*5ffd83dbSDimitry Andric
3388*5ffd83dbSDimitry Andric// Big endian pre-P9 VSX subtarget with direct moves.
3389*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian] in {
3390*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
3391*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
3392*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
3393*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
3394*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
3395*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
3396*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
3397*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
3398*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
3399*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
3400*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
3401*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
3402*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
3403*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
3404*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
3405*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
3406*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
3407*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
3408*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
3409*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
3410*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
3411*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
3412*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
3413*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
3414*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
3415*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
3416*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
3417*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
3418*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
3419*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
3420*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
3421*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
3422*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
3423*5ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
3424*5ffd83dbSDimitry Andric
3425*5ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (BE)
3426*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
3427*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
3428*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
3429*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
3430*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
3431*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
3432*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
3433*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
3434*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
3435*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
3436*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
3437*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
3438*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
3439*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
3440*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
3441*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
3442*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
3443*5ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_HALF)>;
3444*5ffd83dbSDimitry Andric
3445*5ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (BE)
3446*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
3447*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
3448*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
3449*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
3450*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
3451*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
3452*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
3453*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
3454*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
3455*5ffd83dbSDimitry Andric          (i32 VectorExtractions.BE_VARIABLE_WORD)>;
3456*5ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian
3457*5ffd83dbSDimitry Andric
3458*5ffd83dbSDimitry Andric// Little endian pre-P9 VSX subtarget with direct moves.
3459*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] in {
3460*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
3461*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_0)>;
3462*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
3463*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_1)>;
3464*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
3465*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_2)>;
3466*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
3467*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_3)>;
3468*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
3469*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_4)>;
3470*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
3471*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_5)>;
3472*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
3473*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_6)>;
3474*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
3475*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_7)>;
3476*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
3477*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_8)>;
3478*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
3479*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_9)>;
3480*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
3481*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_10)>;
3482*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
3483*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_11)>;
3484*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
3485*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_12)>;
3486*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
3487*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_13)>;
3488*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
3489*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_14)>;
3490*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
3491*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_BYTE_15)>;
3492*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
3493*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
3494*5ffd83dbSDimitry Andric
3495*5ffd83dbSDimitry Andric// v8i16 scalar <-> vector conversions (LE)
3496*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
3497*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_0)>;
3498*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
3499*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_1)>;
3500*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
3501*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_2)>;
3502*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
3503*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_3)>;
3504*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
3505*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_4)>;
3506*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
3507*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_5)>;
3508*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
3509*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_6)>;
3510*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 7)),
3511*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_HALF_7)>;
3512*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
3513*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_HALF)>;
3514*5ffd83dbSDimitry Andric
3515*5ffd83dbSDimitry Andric// v4i32 scalar <-> vector conversions (LE)
3516*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
3517*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_0)>;
3518*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
3519*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_1)>;
3520*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
3521*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
3522*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
3523*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_3)>;
3524*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
3525*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_VARIABLE_WORD)>;
3526*5ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian
3527*5ffd83dbSDimitry Andric
3528*5ffd83dbSDimitry Andric// Big endian pre-Power9 VSX subtarget that has direct moves.
3529*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian] in {
35300b57cec5SDimitry Andric// Big endian integer vectors using direct moves.
35310b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
35320b57cec5SDimitry Andric          (v2i64 (XXPERMDI
35330b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
35340b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
35350b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
35360b57cec5SDimitry Andric          (XXPERMDI
35370b57cec5SDimitry Andric            (COPY_TO_REGCLASS
35380b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
35390b57cec5SDimitry Andric            (COPY_TO_REGCLASS
35400b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
35410b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
35420b57cec5SDimitry Andric          (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3543*5ffd83dbSDimitry Andric} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian
35440b57cec5SDimitry Andric
3545*5ffd83dbSDimitry Andric// Little endian pre-Power9 VSX subtarget that has direct moves.
3546*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in {
35470b57cec5SDimitry Andric// Little endian integer vectors using direct moves.
35480b57cec5SDimitry Andricdef : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
35490b57cec5SDimitry Andric          (v2i64 (XXPERMDI
35500b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
35510b57cec5SDimitry Andric                    (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
35520b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
35530b57cec5SDimitry Andric          (XXPERMDI
35540b57cec5SDimitry Andric            (COPY_TO_REGCLASS
35550b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
35560b57cec5SDimitry Andric            (COPY_TO_REGCLASS
35570b57cec5SDimitry Andric              (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
35580b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
35590b57cec5SDimitry Andric          (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
35600b57cec5SDimitry Andric}
35610b57cec5SDimitry Andric
3562*5ffd83dbSDimitry Andric// Any Power9 VSX subtarget.
3563*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector] in {
3564*5ffd83dbSDimitry Andric// Additional fnmsub pattern for PPC specific ISD opcode
3565*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C),
3566*5ffd83dbSDimitry Andric          (XSNMSUBQP $C, $A, $B)>;
3567*5ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
3568*5ffd83dbSDimitry Andric          (XSMSUBQP $C, $A, $B)>;
3569*5ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
3570*5ffd83dbSDimitry Andric          (XSNMADDQP $C, $A, $B)>;
35718bcb0991SDimitry Andric
3572*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp i64:$src)),
3573*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3574*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))),
3575*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP $src))>;
3576*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))),
3577*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
3578*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp i64:$src)),
3579*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3580*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))),
3581*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP $src))>;
3582*5ffd83dbSDimitry Andric
3583*5ffd83dbSDimitry Andric// Convert (Un)Signed Word -> QP.
3584*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp i32:$src)),
3585*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (MTVSRWA $src)))>;
3586*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
3587*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
3588*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp i32:$src)),
3589*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (MTVSRWZ $src)))>;
3590*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))),
3591*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
3592*5ffd83dbSDimitry Andric
3593*5ffd83dbSDimitry Andric// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
3594*5ffd83dbSDimitry Andric// separate pattern so that it can convert the input register class from
3595*5ffd83dbSDimitry Andric// VRRC(v8i16) to VSRC.
3596*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
3597*5ffd83dbSDimitry Andric          (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
3598*5ffd83dbSDimitry Andric
3599*5ffd83dbSDimitry Andric// Use current rounding mode
3600*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
3601*5ffd83dbSDimitry Andric// Round to nearest, ties away from zero
3602*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
3603*5ffd83dbSDimitry Andric// Round towards Zero
3604*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
3605*5ffd83dbSDimitry Andric// Round towards +Inf
3606*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
3607*5ffd83dbSDimitry Andric// Round towards -Inf
3608*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
3609*5ffd83dbSDimitry Andric// Use current rounding mode, [with Inexact]
3610*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
3611*5ffd83dbSDimitry Andric
3612*5ffd83dbSDimitry Andricdef : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
3613*5ffd83dbSDimitry Andric          (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
3614*5ffd83dbSDimitry Andric
3615*5ffd83dbSDimitry Andricdef : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
3616*5ffd83dbSDimitry Andric          (i64 (MFVSRD (EXTRACT_SUBREG
3617*5ffd83dbSDimitry Andric                          (v2i64 (XSXEXPQP $vA)), sub_64)))>;
3618*5ffd83dbSDimitry Andric
3619*5ffd83dbSDimitry Andric// Extra patterns expanding to vector Extract Word/Insert Word
3620*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
3621*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
3622*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
3623*5ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
3624*5ffd83dbSDimitry Andric
3625*5ffd83dbSDimitry Andric// Vector Reverse
3626*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (bswap v8i16 :$A)),
3627*5ffd83dbSDimitry Andric          (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
3628*5ffd83dbSDimitry Andricdef : Pat<(v1i128 (bswap v1i128 :$A)),
3629*5ffd83dbSDimitry Andric          (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
3630*5ffd83dbSDimitry Andric
3631*5ffd83dbSDimitry Andric// D-Form Load/Store
3632*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3633*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3634*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3635*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3636*5ffd83dbSDimitry Andricdef : Pat<(f128  (quadwOffsetLoad iaddrX16:$src)),
3637*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3638*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>;
3639*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>;
3640*5ffd83dbSDimitry Andric
3641*5ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3642*5ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3643*5ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3644*5ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore  f128:$rS, iaddrX16:$dst),
3645*5ffd83dbSDimitry Andric          (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3646*5ffd83dbSDimitry Andricdef : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3647*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst),
3648*5ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
3649*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst),
3650*5ffd83dbSDimitry Andric          (STXV $rS, memrix16:$dst)>;
3651*5ffd83dbSDimitry Andric
3652*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3653*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3654*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3655*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3656*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
3657*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
3658*5ffd83dbSDimitry Andricdef : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
3659*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
3660*5ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
3661*5ffd83dbSDimitry Andric          (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3662*5ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
3663*5ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
3664*5ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
3665*5ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
3666*5ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
3667*5ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
3668*5ffd83dbSDimitry Andricdef : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
3669*5ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
3670*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3671*5ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
3672*5ffd83dbSDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
3673*5ffd83dbSDimitry Andric          (STXVX $rS, xoaddr:$dst)>;
3674*5ffd83dbSDimitry Andric
3675*5ffd83dbSDimitry Andric// Build vectors from i8 loads
3676*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v16i8, ScalarLoads.Li8,
3677*5ffd83dbSDimitry Andric                         (VSPLTBs 7, (LXSIBZX xoaddr:$src)),
3678*5ffd83dbSDimitry Andric                         (VSPLTBs 7, (LXSIBZX xoaddr:$src))>;
3679*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.ZELi8,
3680*5ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIBZX xoaddr:$src)),
3681*5ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIBZX xoaddr:$src))>;
3682*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi8,
3683*5ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIBZX xoaddr:$src), 1),
3684*5ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIBZX xoaddr:$src), 1)>;
3685*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi8i64,
3686*5ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIBZX xoaddr:$src), 0),
3687*5ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIBZX xoaddr:$src), 0)>;
3688*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.SELi8,
3689*5ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1),
3690*5ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1)>;
3691*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.SELi8i64,
3692*5ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0),
3693*5ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0)>;
3694*5ffd83dbSDimitry Andric
3695*5ffd83dbSDimitry Andric// Build vectors from i16 loads
3696*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v8i16, ScalarLoads.Li16,
3697*5ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIHZX xoaddr:$src)),
3698*5ffd83dbSDimitry Andric                         (VSPLTHs 3, (LXSIHZX xoaddr:$src))>;
3699*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi16,
3700*5ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIHZX xoaddr:$src), 1),
3701*5ffd83dbSDimitry Andric                         (XXSPLTWs (LXSIHZX xoaddr:$src), 1)>;
3702*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi16i64,
3703*5ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIHZX xoaddr:$src), 0),
3704*5ffd83dbSDimitry Andric                         (XXPERMDIs (LXSIHZX xoaddr:$src), 0)>;
3705*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, ScalarLoads.SELi16,
3706*5ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1),
3707*5ffd83dbSDimitry Andric                         (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1)>;
3708*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v2i64, ScalarLoads.SELi16i64,
3709*5ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0),
3710*5ffd83dbSDimitry Andric                         (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0)>;
3711*5ffd83dbSDimitry Andric
3712*5ffd83dbSDimitry Andric// Load/convert and convert/store patterns for f16.
3713*5ffd83dbSDimitry Andricdef : Pat<(f64 (extloadf16 xoaddr:$src)),
3714*5ffd83dbSDimitry Andric          (f64 (XSCVHPDP (LXSIHZX xoaddr:$src)))>;
3715*5ffd83dbSDimitry Andricdef : Pat<(truncstoref16 f64:$src, xoaddr:$dst),
3716*5ffd83dbSDimitry Andric          (STXSIHX (XSCVDPHP $src), xoaddr:$dst)>;
3717*5ffd83dbSDimitry Andricdef : Pat<(f32 (extloadf16 xoaddr:$src)),
3718*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX xoaddr:$src)), VSSRC))>;
3719*5ffd83dbSDimitry Andricdef : Pat<(truncstoref16 f32:$src, xoaddr:$dst),
3720*5ffd83dbSDimitry Andric          (STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), xoaddr:$dst)>;
3721*5ffd83dbSDimitry Andricdef : Pat<(f64 (f16_to_fp i32:$A)),
3722*5ffd83dbSDimitry Andric          (f64 (XSCVHPDP (MTVSRWZ $A)))>;
3723*5ffd83dbSDimitry Andricdef : Pat<(f32 (f16_to_fp i32:$A)),
3724*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSCVHPDP (MTVSRWZ $A)), VSSRC))>;
3725*5ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f32:$A)),
3726*5ffd83dbSDimitry Andric          (i32 (MFVSRWZ (XSCVDPHP (COPY_TO_REGCLASS $A, VSFRC))))>;
3727*5ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_f16 f64:$A)), (i32 (MFVSRWZ (XSCVDPHP $A)))>;
3728*5ffd83dbSDimitry Andric
3729*5ffd83dbSDimitry Andric// Vector sign extensions
3730*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 1)),
3731*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
3732*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCVexts f64:$A, 2)),
3733*5ffd83dbSDimitry Andric          (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
3734*5ffd83dbSDimitry Andric
3735*5ffd83dbSDimitry Andricdef : Pat<(f64 (extloadf32 iaddrX4:$src)),
3736*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>;
3737*5ffd83dbSDimitry Andricdef : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))),
3738*5ffd83dbSDimitry Andric          (f32 (DFLOADf32 iaddrX4:$src))>;
3739*5ffd83dbSDimitry Andric
3740*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh xaddr:$src)),
3741*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>;
3742*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)),
3743*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>;
3744*5ffd83dbSDimitry Andric
3745*5ffd83dbSDimitry Andric// Convert (Un)Signed DWord in memory -> QP
3746*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))),
3747*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>;
3748*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))),
3749*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>;
3750*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))),
3751*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>;
3752*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))),
3753*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>;
3754*5ffd83dbSDimitry Andric
3755*5ffd83dbSDimitry Andric// Convert Unsigned HWord in memory -> QP
3756*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
3757*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
3758*5ffd83dbSDimitry Andric
3759*5ffd83dbSDimitry Andric// Convert Unsigned Byte in memory -> QP
3760*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
3761*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
3762*5ffd83dbSDimitry Andric
3763*5ffd83dbSDimitry Andric// Truncate & Convert QP -> (Un)Signed (D)Word.
3764*5ffd83dbSDimitry Andricdef : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3765*5ffd83dbSDimitry Andricdef : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3766*5ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_sint f128:$src)),
3767*5ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
3768*5ffd83dbSDimitry Andricdef : Pat<(i32 (fp_to_uint f128:$src)),
3769*5ffd83dbSDimitry Andric          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
3770*5ffd83dbSDimitry Andric
3771*5ffd83dbSDimitry Andric// Instructions for store(fptosi).
3772*5ffd83dbSDimitry Andric// The 8-byte version is repeated here due to availability of D-Form STXSD.
3773*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3774*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8),
3775*5ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3776*5ffd83dbSDimitry Andric                  xaddrX4:$dst)>;
3777*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3778*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8),
3779*5ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3780*5ffd83dbSDimitry Andric                 iaddrX4:$dst)>;
3781*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3782*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
3783*5ffd83dbSDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3784*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3785*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
3786*5ffd83dbSDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3787*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3788*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
3789*5ffd83dbSDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3790*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3791*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8),
3792*5ffd83dbSDimitry Andric          (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>;
3793*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3794*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8),
3795*5ffd83dbSDimitry Andric          (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>;
3796*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3797*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
3798*5ffd83dbSDimitry Andric          (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3799*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3800*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
3801*5ffd83dbSDimitry Andric          (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3802*5ffd83dbSDimitry Andric
3803*5ffd83dbSDimitry Andric// Instructions for store(fptoui).
3804*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3805*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8),
3806*5ffd83dbSDimitry Andric          (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3807*5ffd83dbSDimitry Andric                  xaddrX4:$dst)>;
3808*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3809*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8),
3810*5ffd83dbSDimitry Andric          (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3811*5ffd83dbSDimitry Andric                 iaddrX4:$dst)>;
3812*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3813*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
3814*5ffd83dbSDimitry Andric          (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3815*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3816*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
3817*5ffd83dbSDimitry Andric          (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3818*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3819*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
3820*5ffd83dbSDimitry Andric          (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3821*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3822*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8),
3823*5ffd83dbSDimitry Andric          (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>;
3824*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3825*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8),
3826*5ffd83dbSDimitry Andric          (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>;
3827*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3828*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
3829*5ffd83dbSDimitry Andric          (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3830*5ffd83dbSDimitry Andricdef : Pat<(PPCstore_scal_int_from_vsr
3831*5ffd83dbSDimitry Andric            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
3832*5ffd83dbSDimitry Andric          (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3833*5ffd83dbSDimitry Andric
3834*5ffd83dbSDimitry Andric// Round & Convert QP -> DP/SP
3835*5ffd83dbSDimitry Andricdef : Pat<(f64 (any_fpround f128:$src)), (f64 (XSCVQPDP $src))>;
3836*5ffd83dbSDimitry Andricdef : Pat<(f32 (any_fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
3837*5ffd83dbSDimitry Andric
3838*5ffd83dbSDimitry Andric// Convert SP -> QP
3839*5ffd83dbSDimitry Andricdef : Pat<(f128 (any_fpextend f32:$src)),
3840*5ffd83dbSDimitry Andric          (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
3841*5ffd83dbSDimitry Andric
3842*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)),
3843*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC),
3844*5ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
3845*5ffd83dbSDimitry Andric                                 VSSRC))>;
3846*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)),
3847*5ffd83dbSDimitry Andric          (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC),
3848*5ffd83dbSDimitry Andric                                           (COPY_TO_REGCLASS $XB, VSSRC)),
3849*5ffd83dbSDimitry Andric                                 VSSRC))>;
3850*5ffd83dbSDimitry Andric
38510b57cec5SDimitry Andric// Endianness-neutral patterns for const splats with ISA 3.0 instructions.
3852*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, (i32 i32:$A), (MTVSRWS $A), (MTVSRWS $A)>;
38530b57cec5SDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
38540b57cec5SDimitry Andric          (v4i32 (MTVSRWS $A))>;
38558bcb0991SDimitry Andricdef : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38568bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38578bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38588bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38598bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38608bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38618bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
38628bcb0991SDimitry Andric                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
38630b57cec5SDimitry Andric          (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
3864*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, FltToIntLoad.A,
3865*5ffd83dbSDimitry Andric                         (XVCVSPSXWS (LXVWSX xoaddr:$A)),
3866*5ffd83dbSDimitry Andric                         (XVCVSPSXWS (LXVWSX xoaddr:$A))>;
3867*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<v4i32, FltToUIntLoad.A,
3868*5ffd83dbSDimitry Andric                         (XVCVSPUXWS (LXVWSX xoaddr:$A)),
3869*5ffd83dbSDimitry Andric                         (XVCVSPUXWS (LXVWSX xoaddr:$A))>;
3870*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3871*5ffd83dbSDimitry Andric  v4i32, DblToIntLoadP9.A,
3872*5ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1),
3873*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), sub_64)>;
3874*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3875*5ffd83dbSDimitry Andric  v4i32, DblToUIntLoadP9.A,
3876*5ffd83dbSDimitry Andric  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1),
3877*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), sub_64)>;
3878*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3879*5ffd83dbSDimitry Andric  v2i64, FltToLongLoadP9.A,
3880*5ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), 0),
3881*5ffd83dbSDimitry Andric  (SUBREG_TO_REG
3882*5ffd83dbSDimitry Andric     (i64 1),
3883*5ffd83dbSDimitry Andric     (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), sub_64)>;
3884*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
3885*5ffd83dbSDimitry Andric  v2i64, FltToULongLoadP9.A,
3886*5ffd83dbSDimitry Andric  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), 0),
3887*5ffd83dbSDimitry Andric  (SUBREG_TO_REG
3888*5ffd83dbSDimitry Andric     (i64 1),
3889*5ffd83dbSDimitry Andric     (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), sub_64)>;
38908bcb0991SDimitry Andricdef : Pat<(v4f32 (PPCldsplat xoaddr:$A)),
38918bcb0991SDimitry Andric          (v4f32 (LXVWSX xoaddr:$A))>;
38928bcb0991SDimitry Andricdef : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
38938bcb0991SDimitry Andric          (v4i32 (LXVWSX xoaddr:$A))>;
3894*5ffd83dbSDimitry Andric} // HasVSX, HasP9Vector
3895*5ffd83dbSDimitry Andric
3896*5ffd83dbSDimitry Andric// Big endian Power9 subtarget.
3897*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsBigEndian] in {
3898*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3899*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
3900*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3901*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
3902*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3903*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
3904*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3905*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
3906*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3907*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
3908*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3909*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
3910*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3911*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
3912*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3913*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
3914*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
3915*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
3916*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
3917*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
3918*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
3919*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
3920*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
3921*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
3922*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
3923*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3924*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
3925*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
3926*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
3927*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
3928*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3929*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
3930*5ffd83dbSDimitry Andric
3931*5ffd83dbSDimitry Andric// Scalar stores of i8
3932*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3933*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
3934*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3935*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3936*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3937*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
3938*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3939*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3940*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3941*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
3942*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3943*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3944*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3945*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
3946*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3947*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3948*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3949*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
3950*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3951*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3952*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3953*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
3954*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3955*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3956*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3957*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
3958*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3959*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3960*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3961*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
3962*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3963*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3964*5ffd83dbSDimitry Andric
3965*5ffd83dbSDimitry Andric// Scalar stores of i16
3966*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3967*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3968*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3969*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3970*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3971*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3972*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3973*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3974*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3975*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3976*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3977*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3978*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3979*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3980*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3981*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3982*5ffd83dbSDimitry Andric
3983*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
3984*5ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
3985*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
3986*5ffd83dbSDimitry Andric          (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
3987*5ffd83dbSDimitry Andric
3988*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
3989*5ffd83dbSDimitry Andric          (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
3990*5ffd83dbSDimitry Andricdef : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
3991*5ffd83dbSDimitry Andric          (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
3992*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
3993*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3994*5ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
3995*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
3996*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3997*5ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
3998*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
3999*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4000*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
4001*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4002*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
4003*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4004*5ffd83dbSDimitry Andric                       sub_64), iaddrX4:$src)>;
4005*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
4006*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4007*5ffd83dbSDimitry Andric                       sub_64), iaddrX4:$src)>;
4008*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
4009*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4010*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
4011*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4012*5ffd83dbSDimitry Andric
4013*5ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
4014*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4015*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4016*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4017*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP
4018*5ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4019*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4020*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4021*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4022*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP
4023*5ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4024*5ffd83dbSDimitry Andric
4025*5ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
4026*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
4027*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
4028*5ffd83dbSDimitry Andricforeach Idx = [0,2,3] in {
4029*5ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
4030*5ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
4031*5ffd83dbSDimitry Andric                            (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
4032*5ffd83dbSDimitry Andric}
4033*5ffd83dbSDimitry Andricforeach Idx = 0-3 in {
4034*5ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
4035*5ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
40360b57cec5SDimitry Andric}
40370b57cec5SDimitry Andric
4038*5ffd83dbSDimitry Andric// (Un)Signed HWord vector extract -> QP
4039*5ffd83dbSDimitry Andricforeach Idx = 0-7 in {
4040*5ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
4041*5ffd83dbSDimitry Andric                    (i32 (sext_inreg
4042*5ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, Idx), i16)))),
4043*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG
4044*5ffd83dbSDimitry Andric                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
4045*5ffd83dbSDimitry Andric                            sub_64)))>;
4046*5ffd83dbSDimitry Andric  // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
4047*5ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
4048*5ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
4049*5ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
4050*5ffd83dbSDimitry Andric                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
40510b57cec5SDimitry Andric}
40520b57cec5SDimitry Andric
4053*5ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP
4054*5ffd83dbSDimitry Andricforeach Idx = 0-15 in {
4055*5ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
4056*5ffd83dbSDimitry Andric                    (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
4057*5ffd83dbSDimitry Andric                                     i8)))),
4058*5ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
4059*5ffd83dbSDimitry Andric                              (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
4060*5ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
4061*5ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
4062*5ffd83dbSDimitry Andric            (f128 (XSCVUDQP
4063*5ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
40640b57cec5SDimitry Andric}
40650b57cec5SDimitry Andric
4066*5ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
4067*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
4068*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP
4069*5ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
4070*5ffd83dbSDimitry Andric} // HasVSX, HasP9Vector, IsBigEndian
4071*5ffd83dbSDimitry Andric
4072*5ffd83dbSDimitry Andric// Little endian Power9 subtarget.
4073*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in {
4074*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
4075*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
4076*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
4077*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
4078*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
4079*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
4080*5ffd83dbSDimitry Andricdef : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
4081*5ffd83dbSDimitry Andric          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
4082*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
4083*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
4084*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
4085*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
4086*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
4087*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
4088*5ffd83dbSDimitry Andricdef : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
4089*5ffd83dbSDimitry Andric          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
4090*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
4091*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
4092*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
4093*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
4094*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
4095*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
4096*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
4097*5ffd83dbSDimitry Andric          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
4098*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
4099*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
4100*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
4101*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
4102*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
4103*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
4104*5ffd83dbSDimitry Andricdef : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
4105*5ffd83dbSDimitry Andric          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
4106*5ffd83dbSDimitry Andric
4107*5ffd83dbSDimitry Andricdef : Pat<(v8i16 (PPCld_vec_be xoaddr:$src)),
4108*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXVH8X xoaddr:$src), VRRC)>;
4109*5ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v8i16:$rS, xoaddr:$dst),
4110*5ffd83dbSDimitry Andric          (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
4111*5ffd83dbSDimitry Andric
4112*5ffd83dbSDimitry Andricdef : Pat<(v16i8 (PPCld_vec_be xoaddr:$src)),
4113*5ffd83dbSDimitry Andric          (COPY_TO_REGCLASS (LXVB16X xoaddr:$src), VRRC)>;
4114*5ffd83dbSDimitry Andricdef : Pat<(PPCst_vec_be v16i8:$rS, xoaddr:$dst),
4115*5ffd83dbSDimitry Andric          (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
4116*5ffd83dbSDimitry Andric
4117*5ffd83dbSDimitry Andric// Scalar stores of i8
4118*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
4119*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
4120*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
4121*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
4122*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
4123*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
4124*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
4125*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
4126*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
4127*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
4128*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
4129*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
4130*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
4131*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
4132*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
4133*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
4134*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
4135*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
4136*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
4137*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
4138*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
4139*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
4140*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
4141*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
4142*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
4143*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
4144*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
4145*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
4146*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
4147*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
4148*5ffd83dbSDimitry Andricdef : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
4149*5ffd83dbSDimitry Andric          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
4150*5ffd83dbSDimitry Andric
4151*5ffd83dbSDimitry Andric// Scalar stores of i16
4152*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
4153*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
4154*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
4155*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
4156*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
4157*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
4158*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
4159*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
4160*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
4161*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
4162*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
4163*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
4164*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
4165*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
4166*5ffd83dbSDimitry Andricdef : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
4167*5ffd83dbSDimitry Andric          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
4168*5ffd83dbSDimitry Andric
4169*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4170*5ffd83dbSDimitry Andric  v2i64, (i64 (load iaddrX4:$src)),
4171*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSFRC), 2),
4172*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 iaddrX4:$src), sub_64)>;
4173*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4174*5ffd83dbSDimitry Andric  v2i64, (i64 (load xaddrX4:$src)),
4175*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSFRC), 2),
4176*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 xaddrX4:$src), sub_64)>;
4177*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4178*5ffd83dbSDimitry Andric  v2f64, (f64 (load iaddrX4:$src)),
4179*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSFRC), 2),
4180*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (DFLOADf64 iaddrX4:$src), sub_64)>;
4181*5ffd83dbSDimitry Andricdefm : ScalToVecWPermute<
4182*5ffd83dbSDimitry Andric  v2f64, (f64 (load xaddrX4:$src)),
4183*5ffd83dbSDimitry Andric  (XXPERMDIs (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSFRC), 2),
4184*5ffd83dbSDimitry Andric  (SUBREG_TO_REG (i64 1), (XFLOADf64 xaddrX4:$src), sub_64)>;
4185*5ffd83dbSDimitry Andric
4186*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
4187*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4188*5ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
4189*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
4190*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4191*5ffd83dbSDimitry Andric                       sub_64), xaddrX4:$src)>;
4192*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
4193*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4194*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
4195*5ffd83dbSDimitry Andric          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4196*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
4197*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4198*5ffd83dbSDimitry Andric                       sub_64), iaddrX4:$src)>;
4199*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
4200*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4201*5ffd83dbSDimitry Andric                      iaddrX4:$src)>;
4202*5ffd83dbSDimitry Andricdef : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
4203*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4204*5ffd83dbSDimitry Andricdef : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
4205*5ffd83dbSDimitry Andric          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4206*5ffd83dbSDimitry Andric
4207*5ffd83dbSDimitry Andric// (Un)Signed DWord vector extract -> QP
4208*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4209*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP
4210*5ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4211*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4212*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4213*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4214*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP
4215*5ffd83dbSDimitry Andric                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4216*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4217*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4218*5ffd83dbSDimitry Andric
4219*5ffd83dbSDimitry Andric// (Un)Signed Word vector extract -> QP
4220*5ffd83dbSDimitry Andricforeach Idx = [[0,3],[1,2],[3,0]] in {
4221*5ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
4222*5ffd83dbSDimitry Andric            (f128 (XSCVSDQP (EXTRACT_SUBREG
4223*5ffd83dbSDimitry Andric                              (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
4224*5ffd83dbSDimitry Andric                              sub_64)))>;
4225*5ffd83dbSDimitry Andric}
4226*5ffd83dbSDimitry Andricdef : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
4227*5ffd83dbSDimitry Andric          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
4228*5ffd83dbSDimitry Andric
4229*5ffd83dbSDimitry Andricforeach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
4230*5ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
4231*5ffd83dbSDimitry Andric            (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
42320b57cec5SDimitry Andric}
42330b57cec5SDimitry Andric
4234*5ffd83dbSDimitry Andric// (Un)Signed HWord vector extract -> QP
4235*5ffd83dbSDimitry Andric// The Nested foreach lists identifies the vector element and corresponding
4236*5ffd83dbSDimitry Andric// register byte location.
4237*5ffd83dbSDimitry Andricforeach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
4238*5ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
4239*5ffd83dbSDimitry Andric                    (i32 (sext_inreg
4240*5ffd83dbSDimitry Andric                           (vector_extract v8i16:$src, !head(Idx)), i16)))),
4241*5ffd83dbSDimitry Andric            (f128 (XSCVSDQP
4242*5ffd83dbSDimitry Andric                    (EXTRACT_SUBREG (VEXTSH2D
4243*5ffd83dbSDimitry Andric                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
4244*5ffd83dbSDimitry Andric                                    sub_64)))>;
4245*5ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
4246*5ffd83dbSDimitry Andric                    (and (i32 (vector_extract v8i16:$src, !head(Idx))),
4247*5ffd83dbSDimitry Andric                         65535))),
4248*5ffd83dbSDimitry Andric            (f128 (XSCVUDQP (EXTRACT_SUBREG
4249*5ffd83dbSDimitry Andric                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
42500b57cec5SDimitry Andric}
42510b57cec5SDimitry Andric
4252*5ffd83dbSDimitry Andric// (Un)Signed Byte vector extract -> QP
4253*5ffd83dbSDimitry Andricforeach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
4254*5ffd83dbSDimitry Andric               [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
4255*5ffd83dbSDimitry Andric  def : Pat<(f128 (sint_to_fp
4256*5ffd83dbSDimitry Andric                    (i32 (sext_inreg
4257*5ffd83dbSDimitry Andric                           (vector_extract v16i8:$src, !head(Idx)), i8)))),
4258*5ffd83dbSDimitry Andric            (f128 (XSCVSDQP
4259*5ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
4260*5ffd83dbSDimitry Andric                      (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
4261*5ffd83dbSDimitry Andric                      sub_64)))>;
4262*5ffd83dbSDimitry Andric  def : Pat<(f128 (uint_to_fp
4263*5ffd83dbSDimitry Andric                    (and (i32 (vector_extract v16i8:$src, !head(Idx))),
4264*5ffd83dbSDimitry Andric                         255))),
4265*5ffd83dbSDimitry Andric            (f128 (XSCVUDQP
4266*5ffd83dbSDimitry Andric                    (EXTRACT_SUBREG
4267*5ffd83dbSDimitry Andric                      (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4268*5ffd83dbSDimitry Andric}
4269*5ffd83dbSDimitry Andric
4270*5ffd83dbSDimitry Andric// Unsiged int in vsx register -> QP
4271*5ffd83dbSDimitry Andricdef : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
4272*5ffd83dbSDimitry Andric          (f128 (XSCVUDQP
4273*5ffd83dbSDimitry Andric                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
4274*5ffd83dbSDimitry Andric} // HasVSX, HasP9Vector, IsLittleEndian
4275*5ffd83dbSDimitry Andric
4276*5ffd83dbSDimitry Andric// Any Power9 VSX subtarget that supports Power9 Altivec.
4277*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec] in {
42780b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be
42790b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef.
42800b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
42810b57cec5SDimitry Andric          (v4i32 (VABSDUW $A, $B))>;
42820b57cec5SDimitry Andric
42830b57cec5SDimitry Andricdef : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
42840b57cec5SDimitry Andric          (v8i16 (VABSDUH $A, $B))>;
42850b57cec5SDimitry Andric
42860b57cec5SDimitry Andricdef : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
42870b57cec5SDimitry Andric          (v16i8 (VABSDUB $A, $B))>;
42880b57cec5SDimitry Andric
42890b57cec5SDimitry Andric// As PPCVABSD description, the last operand indicates whether do the
42900b57cec5SDimitry Andric// sign bit flip.
42910b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
42920b57cec5SDimitry Andric          (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
4293*5ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec
4294*5ffd83dbSDimitry Andric
4295*5ffd83dbSDimitry Andric// Big endian Power9 VSX subtargets with P9 Altivec support.
4296*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsBigEndian] in {
4297*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
4298*5ffd83dbSDimitry Andric          (VEXTUBLX $Idx, $S)>;
4299*5ffd83dbSDimitry Andric
4300*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
4301*5ffd83dbSDimitry Andric          (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
4302*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
4303*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 0), $S)>;
4304*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
4305*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 2), $S)>;
4306*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
4307*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 4), $S)>;
4308*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
4309*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 6), $S)>;
4310*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
4311*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 8), $S)>;
4312*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
4313*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 10), $S)>;
4314*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
4315*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 12), $S)>;
4316*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
4317*5ffd83dbSDimitry Andric          (VEXTUHLX (LI8 14), $S)>;
4318*5ffd83dbSDimitry Andric
4319*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4320*5ffd83dbSDimitry Andric          (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
4321*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
4322*5ffd83dbSDimitry Andric          (VEXTUWLX (LI8 0), $S)>;
4323*5ffd83dbSDimitry Andric
4324*5ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
4325*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
4326*5ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4327*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
4328*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
4329*5ffd83dbSDimitry Andric          (VEXTUWLX (LI8 8), $S)>;
4330*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
4331*5ffd83dbSDimitry Andric          (VEXTUWLX (LI8 12), $S)>;
4332*5ffd83dbSDimitry Andric
4333*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4334*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
4335*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
4336*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 0), $S))>;
4337*5ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
4338*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
4339*5ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4340*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
4341*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
4342*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 8), $S))>;
4343*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
4344*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWLX (LI8 12), $S))>;
4345*5ffd83dbSDimitry Andric
4346*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
4347*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
4348*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
4349*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
4350*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
4351*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
4352*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
4353*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
4354*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
4355*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
4356*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
4357*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
4358*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
4359*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
4360*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
4361*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
4362*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
4363*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
4364*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
4365*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
4366*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
4367*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
4368*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
4369*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
4370*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
4371*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
4372*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
4373*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
4374*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
4375*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
4376*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
4377*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
4378*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
4379*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
4380*5ffd83dbSDimitry Andric
4381*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
4382*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX
4383*5ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
4384*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
4385*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
4386*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
4387*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
4388*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
4389*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
4390*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
4391*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
4392*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
4393*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
4394*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
4395*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
4396*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
4397*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
4398*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
4399*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
4400*5ffd83dbSDimitry Andric
4401*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
4402*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX
4403*5ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
4404*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
4405*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
4406*5ffd83dbSDimitry Andric// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
4407*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
4408*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
4409*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
4410*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
4411*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
4412*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
4413*5ffd83dbSDimitry Andric
4414*5ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
4415*5ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
4416*5ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
4417*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
4418*5ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
4419*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
4420*5ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
4421*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
4422*5ffd83dbSDimitry Andric                  HWordToWord.BE_A2, HWordToWord.BE_A3)),
4423*5ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
4424*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
4425*5ffd83dbSDimitry Andric                  ByteToWord.BE_A2, ByteToWord.BE_A3)),
4426*5ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
4427*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
4428*5ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
4429*5ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec, IsBigEndian
4430*5ffd83dbSDimitry Andric
4431*5ffd83dbSDimitry Andric// Little endian Power9 VSX subtargets with P9 Altivec support.
4432*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in {
4433*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
4434*5ffd83dbSDimitry Andric          (VEXTUBRX $Idx, $S)>;
4435*5ffd83dbSDimitry Andric
4436*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
4437*5ffd83dbSDimitry Andric          (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
4438*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
4439*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 0), $S)>;
4440*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
4441*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 2), $S)>;
4442*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
4443*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 4), $S)>;
4444*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
4445*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 6), $S)>;
4446*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
4447*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 8), $S)>;
4448*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
4449*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 10), $S)>;
4450*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
4451*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 12), $S)>;
4452*5ffd83dbSDimitry Andricdef : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
4453*5ffd83dbSDimitry Andric          (VEXTUHRX (LI8 14), $S)>;
4454*5ffd83dbSDimitry Andric
4455*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4456*5ffd83dbSDimitry Andric          (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
4457*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
4458*5ffd83dbSDimitry Andric          (VEXTUWRX (LI8 0), $S)>;
4459*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
4460*5ffd83dbSDimitry Andric          (VEXTUWRX (LI8 4), $S)>;
4461*5ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
4462*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
4463*5ffd83dbSDimitry Andric          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4464*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
4465*5ffd83dbSDimitry Andricdef : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
4466*5ffd83dbSDimitry Andric          (VEXTUWRX (LI8 12), $S)>;
4467*5ffd83dbSDimitry Andric
4468*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4469*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
4470*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
4471*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 0), $S))>;
4472*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
4473*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 4), $S))>;
4474*5ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
4475*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
4476*5ffd83dbSDimitry Andric          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4477*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
4478*5ffd83dbSDimitry Andricdef : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
4479*5ffd83dbSDimitry Andric          (EXTSW (VEXTUWRX (LI8 12), $S))>;
4480*5ffd83dbSDimitry Andric
4481*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
4482*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
4483*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 0)),
4484*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
4485*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 1)),
4486*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
4487*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 2)),
4488*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
4489*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 3)),
4490*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
4491*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 4)),
4492*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
4493*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 5)),
4494*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
4495*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 6)),
4496*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
4497*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 7)),
4498*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
4499*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 8)),
4500*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
4501*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 9)),
4502*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
4503*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 10)),
4504*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
4505*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 11)),
4506*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
4507*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 12)),
4508*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
4509*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 13)),
4510*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
4511*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 14)),
4512*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
4513*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v16i8:$S, 15)),
4514*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
4515*5ffd83dbSDimitry Andric
4516*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
4517*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX
4518*5ffd83dbSDimitry Andric          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
4519*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 0)),
4520*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
4521*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 1)),
4522*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
4523*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 2)),
4524*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
4525*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 3)),
4526*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
4527*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 4)),
4528*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
4529*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 5)),
4530*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
4531*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
4532*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
4533*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v8i16:$S, 6)),
4534*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
4535*5ffd83dbSDimitry Andric
4536*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
4537*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX
4538*5ffd83dbSDimitry Andric          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
4539*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 0)),
4540*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
4541*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 1)),
4542*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
4543*5ffd83dbSDimitry Andric// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
4544*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 2)),
4545*5ffd83dbSDimitry Andric          (i32 VectorExtractions.LE_WORD_2)>;
4546*5ffd83dbSDimitry Andricdef : Pat<(i32 (vector_extract v4i32:$S, 3)),
4547*5ffd83dbSDimitry Andric          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
4548*5ffd83dbSDimitry Andric
4549*5ffd83dbSDimitry Andric// P9 Altivec instructions that can be used to build vectors.
4550*5ffd83dbSDimitry Andric// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
4551*5ffd83dbSDimitry Andric// with complexities of existing build vector patterns in this file.
4552*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
4553*5ffd83dbSDimitry Andric          (v2i64 (VEXTSW2D $A))>;
4554*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
4555*5ffd83dbSDimitry Andric          (v2i64 (VEXTSH2D $A))>;
4556*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
4557*5ffd83dbSDimitry Andric                  HWordToWord.LE_A2, HWordToWord.LE_A3)),
4558*5ffd83dbSDimitry Andric          (v4i32 (VEXTSH2W $A))>;
4559*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
4560*5ffd83dbSDimitry Andric                  ByteToWord.LE_A2, ByteToWord.LE_A3)),
4561*5ffd83dbSDimitry Andric          (v4i32 (VEXTSB2W $A))>;
4562*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
4563*5ffd83dbSDimitry Andric          (v2i64 (VEXTSB2D $A))>;
4564*5ffd83dbSDimitry Andric} // HasVSX, HasP9Altivec, IsLittleEndian
4565*5ffd83dbSDimitry Andric
4566*5ffd83dbSDimitry Andric// Big endian VSX subtarget that supports additional direct moves from ISA3.0.
4567*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian] in {
4568*5ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 1)),
4569*5ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
4570*5ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Big endian.
4571*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
4572*5ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
4573*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4574*5ffd83dbSDimitry Andric          (MTVSRDD
4575*5ffd83dbSDimitry Andric            (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
4576*5ffd83dbSDimitry Andric            (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
4577*5ffd83dbSDimitry Andric
4578*5ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
4579*5ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
4580*5ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian
4581*5ffd83dbSDimitry Andric
4582*5ffd83dbSDimitry Andric// Little endian VSX subtarget that supports direct moves from ISA3.0.
4583*5ffd83dbSDimitry Andriclet Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in {
4584*5ffd83dbSDimitry Andricdef : Pat<(i64 (extractelt v2i64:$A, 0)),
4585*5ffd83dbSDimitry Andric          (i64 (MFVSRLD $A))>;
4586*5ffd83dbSDimitry Andric// Better way to build integer vectors if we have MTVSRDD. Little endian.
4587*5ffd83dbSDimitry Andricdef : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
4588*5ffd83dbSDimitry Andric          (v2i64 (MTVSRDD $rB, $rA))>;
4589*5ffd83dbSDimitry Andricdef : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4590*5ffd83dbSDimitry Andric          (MTVSRDD
4591*5ffd83dbSDimitry Andric            (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
4592*5ffd83dbSDimitry Andric            (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
4593*5ffd83dbSDimitry Andric
4594*5ffd83dbSDimitry Andricdef : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
4595*5ffd83dbSDimitry Andric          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
4596*5ffd83dbSDimitry Andric} // HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian
4597*5ffd83dbSDimitry Andric} // AddedComplexity = 400
4598*5ffd83dbSDimitry Andric
4599*5ffd83dbSDimitry Andric//---------------------------- Instruction aliases ---------------------------//
4600*5ffd83dbSDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB",
4601*5ffd83dbSDimitry Andric                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
4602*5ffd83dbSDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB",
4603*5ffd83dbSDimitry Andric                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
4604*5ffd83dbSDimitry Andric
4605*5ffd83dbSDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 0",
4606*5ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
4607*5ffd83dbSDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 1",
4608*5ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
4609*5ffd83dbSDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB",
4610*5ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
4611*5ffd83dbSDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB",
4612*5ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
4613*5ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
4614*5ffd83dbSDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
4615*5ffd83dbSDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 0",
4616*5ffd83dbSDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
4617*5ffd83dbSDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 1",
4618*5ffd83dbSDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
4619*5ffd83dbSDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
4620*5ffd83dbSDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
4621*5ffd83dbSDimitry Andricdef : InstAlias<"mfvrd $rA, $XT",
4622*5ffd83dbSDimitry Andric                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
4623*5ffd83dbSDimitry Andricdef : InstAlias<"mffprd $rA, $src",
4624*5ffd83dbSDimitry Andric                (MFVSRD g8rc:$rA, f8rc:$src)>;
4625*5ffd83dbSDimitry Andricdef : InstAlias<"mtvrd $XT, $rA",
4626*5ffd83dbSDimitry Andric                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
4627*5ffd83dbSDimitry Andricdef : InstAlias<"mtfprd $dst, $rA",
4628*5ffd83dbSDimitry Andric                (MTVSRD f8rc:$dst, g8rc:$rA)>;
4629*5ffd83dbSDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT",
4630*5ffd83dbSDimitry Andric                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
4631*5ffd83dbSDimitry Andricdef : InstAlias<"mffprwz $rA, $src",
4632*5ffd83dbSDimitry Andric                (MFVSRWZ gprc:$rA, f8rc:$src)>;
4633*5ffd83dbSDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA",
4634*5ffd83dbSDimitry Andric                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
4635*5ffd83dbSDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA",
4636*5ffd83dbSDimitry Andric                (MTVSRWA f8rc:$dst, gprc:$rA)>;
4637*5ffd83dbSDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA",
4638*5ffd83dbSDimitry Andric                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
4639*5ffd83dbSDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA",
4640*5ffd83dbSDimitry Andric                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
4641