1//===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the VSX extension to the PowerPC instruction set.
10//
11//===----------------------------------------------------------------------===//
12
13// *********************************** NOTE ***********************************
14// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing  **
15// ** which VMX and VSX instructions are lane-sensitive and which are not.   **
16// ** A lane-sensitive instruction relies, implicitly or explicitly, on      **
17// ** whether lanes are numbered from left to right.  An instruction like    **
18// ** VADDFP is not lane-sensitive, because each lane of the result vector   **
19// ** relies only on the corresponding lane of the source vectors.  However, **
20// ** an instruction like VMULESB is lane-sensitive, because "even" and      **
21// ** "odd" lanes are different for big-endian and little-endian numbering.  **
22// **                                                                        **
23// ** When adding new VMX and VSX instructions, please consider whether they **
24// ** are lane-sensitive.  If so, they must be added to a switch statement   **
25// ** in PPCVSXSwapRemoval::gatherVectorInstructions().                      **
26// ****************************************************************************
27
28// *********************************** NOTE ***********************************
29// ** When adding new anonymous patterns to this file, please add them to    **
30// ** the section titled Anonymous Patterns. Chances are that the existing   **
31// ** predicate blocks already contain a combination of features that you    **
32// ** are after. There is a list of blocks at the top of the section. If     **
33// ** you definitely need a new combination of predicates, please add that   **
34// ** combination to the list.                                               **
35// ** File Structure:                                                        **
36// ** - Custom PPCISD node definitions                                       **
37// ** - Predicate definitions: predicates to specify the subtargets for      **
38// **   which an instruction or pattern can be emitted.                      **
39// ** - Instruction formats: classes instantiated by the instructions.       **
40// **   These generally correspond to instruction formats in section 1.6 of  **
41// **   the ISA document.                                                    **
42// ** - Instruction definitions: the actual definitions of the instructions  **
43// **   often including input patterns that they match.                      **
44// ** - Helper DAG definitions: We define a number of dag objects to use as  **
45// **   input or output patterns for consciseness of the code.               **
46// ** - Anonymous patterns: input patterns that an instruction matches can   **
47// **   often not be specified as part of the instruction definition, so an  **
48// **   anonymous pattern must be specified mapping an input pattern to an   **
49// **   output pattern. These are generally guarded by subtarget predicates. **
50// ** - Instruction aliases: used to define extended mnemonics for assembly  **
51// **   printing (for example: xxswapd for xxpermdi with 0x2 as the imm).    **
52// ****************************************************************************
53
54def PPCRegVSRCAsmOperand : AsmOperandClass {
55  let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
56}
57def vsrc : RegisterOperand<VSRC> {
58  let ParserMatchClass = PPCRegVSRCAsmOperand;
59}
60
61def PPCRegVSFRCAsmOperand : AsmOperandClass {
62  let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
63}
64def vsfrc : RegisterOperand<VSFRC> {
65  let ParserMatchClass = PPCRegVSFRCAsmOperand;
66}
67
68def PPCRegVSSRCAsmOperand : AsmOperandClass {
69  let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
70}
71def vssrc : RegisterOperand<VSSRC> {
72  let ParserMatchClass = PPCRegVSSRCAsmOperand;
73}
74
75def PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass {
76  let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber";
77}
78
79def spilltovsrrc : RegisterOperand<SPILLTOVSRRC> {
80  let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand;
81}
82
83def SDT_PPCldvsxlh : SDTypeProfile<1, 1, [
84  SDTCisVT<0, v4f32>, SDTCisPtrTy<1>
85]>;
86
87def SDT_PPCfpexth : SDTypeProfile<1, 2, [
88  SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>, SDTCisPtrTy<2>
89]>;
90
91def SDT_PPCldsplat : SDTypeProfile<1, 1, [
92  SDTCisVec<0>, SDTCisPtrTy<1>
93]>;
94
95// Little-endian-specific nodes.
96def SDT_PPClxvd2x : SDTypeProfile<1, 1, [
97  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
98]>;
99def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
100  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
101]>;
102def SDT_PPCxxswapd : SDTypeProfile<1, 1, [
103  SDTCisSameAs<0, 1>
104]>;
105def SDTVecConv : SDTypeProfile<1, 2, [
106  SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>
107]>;
108def SDTVabsd : SDTypeProfile<1, 3, [
109  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<3, i32>
110]>;
111def SDT_PPCld_vec_be : SDTypeProfile<1, 1, [
112  SDTCisVec<0>, SDTCisPtrTy<1>
113]>;
114def SDT_PPCst_vec_be : SDTypeProfile<0, 2, [
115  SDTCisVec<0>, SDTCisPtrTy<1>
116]>;
117
118//--------------------------- Custom PPC nodes -------------------------------//
119def PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
120                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
121def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
122                        [SDNPHasChain, SDNPMayStore]>;
123def PPCld_vec_be  : SDNode<"PPCISD::LOAD_VEC_BE", SDT_PPCld_vec_be,
124                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
125def PPCst_vec_be : SDNode<"PPCISD::STORE_VEC_BE", SDT_PPCst_vec_be,
126                        [SDNPHasChain, SDNPMayStore]>;
127def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
128def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
129def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
130def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
131def PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
132def PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
133def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
134def PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>;
135
136def PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>;
137def PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
138                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
139def PPCldsplat : SDNode<"PPCISD::LD_SPLAT", SDT_PPCldsplat,
140                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
141def PPCSToV : SDNode<"PPCISD::SCALAR_TO_VECTOR_PERMUTED",
142                     SDTypeProfile<1, 1, []>, []>;
143
144//-------------------------- Predicate definitions ---------------------------//
145def HasVSX : Predicate<"Subtarget->hasVSX()">;
146def IsLittleEndian : Predicate<"Subtarget->isLittleEndian()">;
147def IsBigEndian : Predicate<"!Subtarget->isLittleEndian()">;
148def HasOnlySwappingMemOps : Predicate<"!Subtarget->hasP9Vector()">;
149def HasP8Vector : Predicate<"Subtarget->hasP8Vector()">;
150def HasDirectMove : Predicate<"Subtarget->hasDirectMove()">;
151def NoP9Vector : Predicate<"!Subtarget->hasP9Vector()">;
152def HasP9Vector : Predicate<"Subtarget->hasP9Vector()">;
153def NoP9Altivec : Predicate<"!Subtarget->hasP9Altivec()">;
154
155//--------------------- VSX-specific instruction formats ---------------------//
156// By default, all VSX instructions are to be selected over their Altivec
157// counter parts and they do not have unmodeled sideeffects.
158let AddedComplexity = 400, hasSideEffects = 0 in {
159multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
160                    string asmstr, InstrItinClass itin, Intrinsic Int,
161                    ValueType OutTy, ValueType InTy> {
162  let BaseName = asmbase in {
163    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
164                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
165                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
166    let Defs = [CR6] in
167    def _rec    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
168                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
169                       [(set InTy:$XT,
170                                (InTy (PPCvcmp_rec InTy:$XA, InTy:$XB, xo)))]>,
171                       isRecordForm;
172  }
173}
174
175// Instruction form with a single input register for instructions such as
176// XXPERMDI. The reason for defining this is that specifying multiple chained
177// operands (such as loads) to an instruction will perform both chained
178// operations rather than coalescing them into a single register - even though
179// the source memory location is the same. This simply forces the instruction
180// to use the same register for both inputs.
181// For example, an output DAG such as this:
182//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
183// would result in two load instructions emitted and used as separate inputs
184// to the XXPERMDI instruction.
185class XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
186                 InstrItinClass itin, list<dag> pattern>
187  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
188    let XB = XA;
189}
190
191let Predicates = [HasVSX, HasP9Vector] in {
192class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
193                    list<dag> pattern>
194  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
195                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
196
197// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
198class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
199                       list<dag> pattern>
200  : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm;
201
202// [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
203// So we use different operand class for VRB
204class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
205                         RegisterOperand vbtype, list<dag> pattern>
206  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
207                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
208
209// [PO VRT XO VRB XO /]
210class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
211                    list<dag> pattern>
212  : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
213                  !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
214
215// [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
216class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
217                       list<dag> pattern>
218  : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm;
219
220// [PO T XO B XO BX /]
221class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
222                      list<dag> pattern>
223  : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
224                    !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
225
226// [PO T XO B XO BX TX]
227class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
228                      RegisterOperand vtype, list<dag> pattern>
229  : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
230                    !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
231
232// [PO T A B XO AX BX TX], src and dest register use different operand class
233class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
234                RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
235                InstrItinClass itin, list<dag> pattern>
236  : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
237            !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
238
239// [PO VRT VRA VRB XO /]
240class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
241                    list<dag> pattern>
242  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
243            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
244
245// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
246class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
247                       list<dag> pattern>
248  : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm;
249
250// [PO VRT VRA VRB XO /]
251class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
252                        list<dag> pattern>
253  : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
254            !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
255            RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
256
257// [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
258class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
259                        list<dag> pattern>
260  : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm;
261
262class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
263                              list<dag> pattern>
264  : Z23Form_8<opcode, xo,
265              (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
266              !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
267  let RC = ex;
268}
269
270// [PO BF // VRA VRB XO /]
271class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
272                    list<dag> pattern>
273  : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
274             !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
275  let Pattern = pattern;
276}
277
278// [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
279// "out" and "in" dag
280class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
281                    RegisterOperand vtype, list<dag> pattern>
282  : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
283            !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
284
285// [PO S RA RB XO SX]
286class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
287                    RegisterOperand vtype, list<dag> pattern>
288  : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
289            !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
290} // Predicates = HasP9Vector
291} // AddedComplexity = 400, hasSideEffects = 0
292
293multiclass ScalToVecWPermute<ValueType Ty, dag In, dag NonPermOut, dag PermOut> {
294  def : Pat<(Ty (scalar_to_vector In)), (Ty NonPermOut)>;
295  def : Pat<(Ty (PPCSToV In)), (Ty PermOut)>;
296}
297
298//-------------------------- Instruction definitions -------------------------//
299// VSX instructions require the VSX feature, they are to be selected over
300// equivalent Altivec patterns (as they address a larger register set) and
301// they do not have unmodeled side effects.
302let Predicates = [HasVSX], AddedComplexity = 400 in {
303let hasSideEffects = 0 in {
304
305  // Load indexed instructions
306  let mayLoad = 1, mayStore = 0 in {
307    let CodeSize = 3 in
308    def LXSDX : XX1Form_memOp<31, 588,
309                        (outs vsfrc:$XT), (ins memrr:$src),
310                        "lxsdx $XT, $src", IIC_LdStLFD,
311                        []>;
312
313    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
314    let CodeSize = 3 in
315      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
316                              "#XFLOADf64",
317                              [(set f64:$XT, (load xoaddr:$src))]>;
318
319    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
320    def LXVD2X : XX1Form_memOp<31, 844,
321                         (outs vsrc:$XT), (ins memrr:$src),
322                         "lxvd2x $XT, $src", IIC_LdStLFD,
323                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
324
325    def LXVDSX : XX1Form_memOp<31, 332,
326                         (outs vsrc:$XT), (ins memrr:$src),
327                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
328
329    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
330    def LXVW4X : XX1Form_memOp<31, 780,
331                         (outs vsrc:$XT), (ins memrr:$src),
332                         "lxvw4x $XT, $src", IIC_LdStLFD,
333                         []>;
334  } // mayLoad
335
336  // Store indexed instructions
337  let mayStore = 1, mayLoad = 0 in {
338    let CodeSize = 3 in
339    def STXSDX : XX1Form_memOp<31, 716,
340                        (outs), (ins vsfrc:$XT, memrr:$dst),
341                        "stxsdx $XT, $dst", IIC_LdStSTFD,
342                        []>;
343
344    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
345    let CodeSize = 3 in
346      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
347                              "#XFSTOREf64",
348                              [(store f64:$XT, xoaddr:$dst)]>;
349
350    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
351    // The behaviour of this instruction is endianness-specific so we provide no
352    // pattern to match it without considering endianness.
353    def STXVD2X : XX1Form_memOp<31, 972,
354                         (outs), (ins vsrc:$XT, memrr:$dst),
355                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
356                         []>;
357
358    def STXVW4X : XX1Form_memOp<31, 908,
359                         (outs), (ins vsrc:$XT, memrr:$dst),
360                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
361                         []>;
362    }
363  } // mayStore
364
365  let mayRaiseFPException = 1 in {
366  let Uses = [RM] in {
367  // Add/Mul Instructions
368  let isCommutable = 1 in {
369    def XSADDDP : XX3Form<60, 32,
370                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
371                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
372                          [(set f64:$XT, (any_fadd f64:$XA, f64:$XB))]>;
373    def XSMULDP : XX3Form<60, 48,
374                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
375                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
376                          [(set f64:$XT, (any_fmul f64:$XA, f64:$XB))]>;
377
378    def XVADDDP : XX3Form<60, 96,
379                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
380                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
381                          [(set v2f64:$XT, (any_fadd v2f64:$XA, v2f64:$XB))]>;
382
383    def XVADDSP : XX3Form<60, 64,
384                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
385                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
386                          [(set v4f32:$XT, (any_fadd v4f32:$XA, v4f32:$XB))]>;
387
388    def XVMULDP : XX3Form<60, 112,
389                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
390                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
391                          [(set v2f64:$XT, (any_fmul v2f64:$XA, v2f64:$XB))]>;
392
393    def XVMULSP : XX3Form<60, 80,
394                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
395                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
396                          [(set v4f32:$XT, (any_fmul v4f32:$XA, v4f32:$XB))]>;
397  }
398
399  // Subtract Instructions
400  def XSSUBDP : XX3Form<60, 40,
401                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
402                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
403                        [(set f64:$XT, (any_fsub f64:$XA, f64:$XB))]>;
404
405  def XVSUBDP : XX3Form<60, 104,
406                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
407                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
408                        [(set v2f64:$XT, (any_fsub v2f64:$XA, v2f64:$XB))]>;
409  def XVSUBSP : XX3Form<60, 72,
410                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
411                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
412                        [(set v4f32:$XT, (any_fsub v4f32:$XA, v4f32:$XB))]>;
413
414  // FMA Instructions
415  let BaseName = "XSMADDADP" in {
416  let isCommutable = 1 in
417  def XSMADDADP : XX3Form<60, 33,
418                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
419                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
420                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, f64:$XTi))]>,
421                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
422                          AltVSXFMARel;
423  let IsVSXFMAAlt = 1 in
424  def XSMADDMDP : XX3Form<60, 41,
425                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
426                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
427                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
428                          AltVSXFMARel;
429  }
430
431  let BaseName = "XSMSUBADP" in {
432  let isCommutable = 1 in
433  def XSMSUBADP : XX3Form<60, 49,
434                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
435                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
436                          [(set f64:$XT, (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
437                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
438                          AltVSXFMARel;
439  let IsVSXFMAAlt = 1 in
440  def XSMSUBMDP : XX3Form<60, 57,
441                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
442                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
443                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
444                          AltVSXFMARel;
445  }
446
447  let BaseName = "XSNMADDADP" in {
448  let isCommutable = 1 in
449  def XSNMADDADP : XX3Form<60, 161,
450                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
451                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
452                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, f64:$XTi)))]>,
453                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
454                          AltVSXFMARel;
455  let IsVSXFMAAlt = 1 in
456  def XSNMADDMDP : XX3Form<60, 169,
457                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
458                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
459                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
460                          AltVSXFMARel;
461  }
462
463  let BaseName = "XSNMSUBADP" in {
464  let isCommutable = 1 in
465  def XSNMSUBADP : XX3Form<60, 177,
466                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
467                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
468                          [(set f64:$XT, (fneg (any_fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
469                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
470                          AltVSXFMARel;
471  let IsVSXFMAAlt = 1 in
472  def XSNMSUBMDP : XX3Form<60, 185,
473                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
474                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
475                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
476                          AltVSXFMARel;
477  }
478
479  let BaseName = "XVMADDADP" in {
480  let isCommutable = 1 in
481  def XVMADDADP : XX3Form<60, 97,
482                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
483                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
484                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
485                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
486                          AltVSXFMARel;
487  let IsVSXFMAAlt = 1 in
488  def XVMADDMDP : XX3Form<60, 105,
489                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
490                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
491                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
492                          AltVSXFMARel;
493  }
494
495  let BaseName = "XVMADDASP" in {
496  let isCommutable = 1 in
497  def XVMADDASP : XX3Form<60, 65,
498                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
499                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
500                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
501                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
502                          AltVSXFMARel;
503  let IsVSXFMAAlt = 1 in
504  def XVMADDMSP : XX3Form<60, 73,
505                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
506                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
507                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
508                          AltVSXFMARel;
509  }
510
511  let BaseName = "XVMSUBADP" in {
512  let isCommutable = 1 in
513  def XVMSUBADP : XX3Form<60, 113,
514                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
515                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
516                          [(set v2f64:$XT, (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
517                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
518                          AltVSXFMARel;
519  let IsVSXFMAAlt = 1 in
520  def XVMSUBMDP : XX3Form<60, 121,
521                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
522                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
523                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
524                          AltVSXFMARel;
525  }
526
527  let BaseName = "XVMSUBASP" in {
528  let isCommutable = 1 in
529  def XVMSUBASP : XX3Form<60, 81,
530                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
531                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
532                          [(set v4f32:$XT, (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
533                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
534                          AltVSXFMARel;
535  let IsVSXFMAAlt = 1 in
536  def XVMSUBMSP : XX3Form<60, 89,
537                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
538                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
539                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
540                          AltVSXFMARel;
541  }
542
543  let BaseName = "XVNMADDADP" in {
544  let isCommutable = 1 in
545  def XVNMADDADP : XX3Form<60, 225,
546                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
547                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
548                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
549                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
550                          AltVSXFMARel;
551  let IsVSXFMAAlt = 1 in
552  def XVNMADDMDP : XX3Form<60, 233,
553                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
554                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
555                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
556                          AltVSXFMARel;
557  }
558
559  let BaseName = "XVNMADDASP" in {
560  let isCommutable = 1 in
561  def XVNMADDASP : XX3Form<60, 193,
562                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
563                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
564                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
565                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
566                          AltVSXFMARel;
567  let IsVSXFMAAlt = 1 in
568  def XVNMADDMSP : XX3Form<60, 201,
569                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
570                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
571                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
572                          AltVSXFMARel;
573  }
574
575  let BaseName = "XVNMSUBADP" in {
576  let isCommutable = 1 in
577  def XVNMSUBADP : XX3Form<60, 241,
578                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
579                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
580                          [(set v2f64:$XT, (fneg (any_fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
581                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
582                          AltVSXFMARel;
583  let IsVSXFMAAlt = 1 in
584  def XVNMSUBMDP : XX3Form<60, 249,
585                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
586                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
587                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
588                          AltVSXFMARel;
589  }
590
591  let BaseName = "XVNMSUBASP" in {
592  let isCommutable = 1 in
593  def XVNMSUBASP : XX3Form<60, 209,
594                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
595                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
596                          [(set v4f32:$XT, (fneg (any_fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
597                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
598                          AltVSXFMARel;
599  let IsVSXFMAAlt = 1 in
600  def XVNMSUBMSP : XX3Form<60, 217,
601                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
602                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
603                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
604                          AltVSXFMARel;
605  }
606
607  // Division Instructions
608  def XSDIVDP : XX3Form<60, 56,
609                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
610                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
611                        [(set f64:$XT, (any_fdiv f64:$XA, f64:$XB))]>;
612  def XSSQRTDP : XX2Form<60, 75,
613                        (outs vsfrc:$XT), (ins vsfrc:$XB),
614                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
615                        [(set f64:$XT, (any_fsqrt f64:$XB))]>;
616
617  def XSREDP : XX2Form<60, 90,
618                        (outs vsfrc:$XT), (ins vsfrc:$XB),
619                        "xsredp $XT, $XB", IIC_VecFP,
620                        [(set f64:$XT, (PPCfre f64:$XB))]>;
621  def XSRSQRTEDP : XX2Form<60, 74,
622                           (outs vsfrc:$XT), (ins vsfrc:$XB),
623                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
624                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
625
626  let mayRaiseFPException = 0 in {
627  def XSTDIVDP : XX3Form_1<60, 61,
628                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
629                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
630  def XSTSQRTDP : XX2Form_1<60, 106,
631                          (outs crrc:$crD), (ins vsfrc:$XB),
632                          "xstsqrtdp $crD, $XB", IIC_FPCompare,
633                          [(set i32:$crD, (PPCftsqrt f64:$XB))]>;
634  def XVTDIVDP : XX3Form_1<60, 125,
635                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
636                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
637  def XVTDIVSP : XX3Form_1<60, 93,
638                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
639                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
640
641  def XVTSQRTDP : XX2Form_1<60, 234,
642                          (outs crrc:$crD), (ins vsrc:$XB),
643                          "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
644  def XVTSQRTSP : XX2Form_1<60, 170,
645                          (outs crrc:$crD), (ins vsrc:$XB),
646                          "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
647  }
648
649  def XVDIVDP : XX3Form<60, 120,
650                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
651                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
652                        [(set v2f64:$XT, (any_fdiv v2f64:$XA, v2f64:$XB))]>;
653  def XVDIVSP : XX3Form<60, 88,
654                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
655                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
656                        [(set v4f32:$XT, (any_fdiv v4f32:$XA, v4f32:$XB))]>;
657
658  def XVSQRTDP : XX2Form<60, 203,
659                        (outs vsrc:$XT), (ins vsrc:$XB),
660                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
661                        [(set v2f64:$XT, (any_fsqrt v2f64:$XB))]>;
662  def XVSQRTSP : XX2Form<60, 139,
663                        (outs vsrc:$XT), (ins vsrc:$XB),
664                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
665                        [(set v4f32:$XT, (any_fsqrt v4f32:$XB))]>;
666
667  def XVREDP : XX2Form<60, 218,
668                        (outs vsrc:$XT), (ins vsrc:$XB),
669                        "xvredp $XT, $XB", IIC_VecFP,
670                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
671  def XVRESP : XX2Form<60, 154,
672                        (outs vsrc:$XT), (ins vsrc:$XB),
673                        "xvresp $XT, $XB", IIC_VecFP,
674                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
675
676  def XVRSQRTEDP : XX2Form<60, 202,
677                           (outs vsrc:$XT), (ins vsrc:$XB),
678                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
679                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
680  def XVRSQRTESP : XX2Form<60, 138,
681                           (outs vsrc:$XT), (ins vsrc:$XB),
682                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
683                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
684
685  // Compare Instructions
686  def XSCMPODP : XX3Form_1<60, 43,
687                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
688                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
689  def XSCMPUDP : XX3Form_1<60, 35,
690                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
691                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
692
693  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
694                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
695                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
696  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
697                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
698                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
699  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
700                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
701                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
702  defm XVCMPGESP : XX3Form_Rcr<60, 83,
703                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
704                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
705  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
706                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
707                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
708  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
709                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
710                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
711
712  // Move Instructions
713  let mayRaiseFPException = 0 in {
714  def XSABSDP : XX2Form<60, 345,
715                      (outs vsfrc:$XT), (ins vsfrc:$XB),
716                      "xsabsdp $XT, $XB", IIC_VecFP,
717                      [(set f64:$XT, (fabs f64:$XB))]>;
718  def XSNABSDP : XX2Form<60, 361,
719                      (outs vsfrc:$XT), (ins vsfrc:$XB),
720                      "xsnabsdp $XT, $XB", IIC_VecFP,
721                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
722  def XSNEGDP : XX2Form<60, 377,
723                      (outs vsfrc:$XT), (ins vsfrc:$XB),
724                      "xsnegdp $XT, $XB", IIC_VecFP,
725                      [(set f64:$XT, (fneg f64:$XB))]>;
726  def XSCPSGNDP : XX3Form<60, 176,
727                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
728                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
729                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
730
731  def XVABSDP : XX2Form<60, 473,
732                      (outs vsrc:$XT), (ins vsrc:$XB),
733                      "xvabsdp $XT, $XB", IIC_VecFP,
734                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
735
736  def XVABSSP : XX2Form<60, 409,
737                      (outs vsrc:$XT), (ins vsrc:$XB),
738                      "xvabssp $XT, $XB", IIC_VecFP,
739                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
740
741  def XVCPSGNDP : XX3Form<60, 240,
742                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
743                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
744                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
745  def XVCPSGNSP : XX3Form<60, 208,
746                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
747                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
748                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
749
750  def XVNABSDP : XX2Form<60, 489,
751                      (outs vsrc:$XT), (ins vsrc:$XB),
752                      "xvnabsdp $XT, $XB", IIC_VecFP,
753                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
754  def XVNABSSP : XX2Form<60, 425,
755                      (outs vsrc:$XT), (ins vsrc:$XB),
756                      "xvnabssp $XT, $XB", IIC_VecFP,
757                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
758
759  def XVNEGDP : XX2Form<60, 505,
760                      (outs vsrc:$XT), (ins vsrc:$XB),
761                      "xvnegdp $XT, $XB", IIC_VecFP,
762                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
763  def XVNEGSP : XX2Form<60, 441,
764                      (outs vsrc:$XT), (ins vsrc:$XB),
765                      "xvnegsp $XT, $XB", IIC_VecFP,
766                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
767  }
768
769  // Conversion Instructions
770  def XSCVDPSP : XX2Form<60, 265,
771                      (outs vsfrc:$XT), (ins vsfrc:$XB),
772                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
773  def XSCVDPSXDS : XX2Form<60, 344,
774                      (outs vsfrc:$XT), (ins vsfrc:$XB),
775                      "xscvdpsxds $XT, $XB", IIC_VecFP,
776                      [(set f64:$XT, (PPCany_fctidz f64:$XB))]>;
777  let isCodeGenOnly = 1 in
778  def XSCVDPSXDSs : XX2Form<60, 344,
779                      (outs vssrc:$XT), (ins vssrc:$XB),
780                      "xscvdpsxds $XT, $XB", IIC_VecFP,
781                      [(set f32:$XT, (PPCany_fctidz f32:$XB))]>;
782  def XSCVDPSXWS : XX2Form<60, 88,
783                      (outs vsfrc:$XT), (ins vsfrc:$XB),
784                      "xscvdpsxws $XT, $XB", IIC_VecFP,
785                      [(set f64:$XT, (PPCany_fctiwz f64:$XB))]>;
786  let isCodeGenOnly = 1 in
787  def XSCVDPSXWSs : XX2Form<60, 88,
788                      (outs vssrc:$XT), (ins vssrc:$XB),
789                      "xscvdpsxws $XT, $XB", IIC_VecFP,
790                      [(set f32:$XT, (PPCany_fctiwz f32:$XB))]>;
791  def XSCVDPUXDS : XX2Form<60, 328,
792                      (outs vsfrc:$XT), (ins vsfrc:$XB),
793                      "xscvdpuxds $XT, $XB", IIC_VecFP,
794                      [(set f64:$XT, (PPCany_fctiduz f64:$XB))]>;
795  let isCodeGenOnly = 1 in
796  def XSCVDPUXDSs : XX2Form<60, 328,
797                      (outs vssrc:$XT), (ins vssrc:$XB),
798                      "xscvdpuxds $XT, $XB", IIC_VecFP,
799                      [(set f32:$XT, (PPCany_fctiduz f32:$XB))]>;
800  def XSCVDPUXWS : XX2Form<60, 72,
801                      (outs vsfrc:$XT), (ins vsfrc:$XB),
802                      "xscvdpuxws $XT, $XB", IIC_VecFP,
803                      [(set f64:$XT, (PPCany_fctiwuz f64:$XB))]>;
804  let isCodeGenOnly = 1 in
805  def XSCVDPUXWSs : XX2Form<60, 72,
806                      (outs vssrc:$XT), (ins vssrc:$XB),
807                      "xscvdpuxws $XT, $XB", IIC_VecFP,
808                      [(set f32:$XT, (PPCany_fctiwuz f32:$XB))]>;
809  def XSCVSPDP : XX2Form<60, 329,
810                      (outs vsfrc:$XT), (ins vsfrc:$XB),
811                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
812  def XSCVSXDDP : XX2Form<60, 376,
813                      (outs vsfrc:$XT), (ins vsfrc:$XB),
814                      "xscvsxddp $XT, $XB", IIC_VecFP,
815                      [(set f64:$XT, (PPCany_fcfid f64:$XB))]>;
816  def XSCVUXDDP : XX2Form<60, 360,
817                      (outs vsfrc:$XT), (ins vsfrc:$XB),
818                      "xscvuxddp $XT, $XB", IIC_VecFP,
819                      [(set f64:$XT, (PPCany_fcfidu f64:$XB))]>;
820
821  def XVCVDPSP : XX2Form<60, 393,
822                      (outs vsrc:$XT), (ins vsrc:$XB),
823                      "xvcvdpsp $XT, $XB", IIC_VecFP,
824                      [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
825  def XVCVDPSXDS : XX2Form<60, 472,
826                      (outs vsrc:$XT), (ins vsrc:$XB),
827                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
828                      [(set v2i64:$XT, (any_fp_to_sint v2f64:$XB))]>;
829  def XVCVDPSXWS : XX2Form<60, 216,
830                      (outs vsrc:$XT), (ins vsrc:$XB),
831                      "xvcvdpsxws $XT, $XB", IIC_VecFP,
832                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
833  def XVCVDPUXDS : XX2Form<60, 456,
834                      (outs vsrc:$XT), (ins vsrc:$XB),
835                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
836                      [(set v2i64:$XT, (any_fp_to_uint v2f64:$XB))]>;
837  def XVCVDPUXWS : XX2Form<60, 200,
838                      (outs vsrc:$XT), (ins vsrc:$XB),
839                      "xvcvdpuxws $XT, $XB", IIC_VecFP,
840                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
841
842  def XVCVSPDP : XX2Form<60, 457,
843                      (outs vsrc:$XT), (ins vsrc:$XB),
844                      "xvcvspdp $XT, $XB", IIC_VecFP,
845                      [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
846  def XVCVSPSXDS : XX2Form<60, 408,
847                      (outs vsrc:$XT), (ins vsrc:$XB),
848                      "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
849  def XVCVSPSXWS : XX2Form<60, 152,
850                      (outs vsrc:$XT), (ins vsrc:$XB),
851                      "xvcvspsxws $XT, $XB", IIC_VecFP,
852                      [(set v4i32:$XT, (any_fp_to_sint v4f32:$XB))]>;
853  def XVCVSPUXDS : XX2Form<60, 392,
854                      (outs vsrc:$XT), (ins vsrc:$XB),
855                      "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
856  def XVCVSPUXWS : XX2Form<60, 136,
857                      (outs vsrc:$XT), (ins vsrc:$XB),
858                      "xvcvspuxws $XT, $XB", IIC_VecFP,
859                      [(set v4i32:$XT, (any_fp_to_uint v4f32:$XB))]>;
860  def XVCVSXDDP : XX2Form<60, 504,
861                      (outs vsrc:$XT), (ins vsrc:$XB),
862                      "xvcvsxddp $XT, $XB", IIC_VecFP,
863                      [(set v2f64:$XT, (any_sint_to_fp v2i64:$XB))]>;
864  def XVCVSXDSP : XX2Form<60, 440,
865                      (outs vsrc:$XT), (ins vsrc:$XB),
866                      "xvcvsxdsp $XT, $XB", IIC_VecFP,
867                      [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
868  def XVCVSXWSP : XX2Form<60, 184,
869                      (outs vsrc:$XT), (ins vsrc:$XB),
870                      "xvcvsxwsp $XT, $XB", IIC_VecFP,
871                      [(set v4f32:$XT, (any_sint_to_fp v4i32:$XB))]>;
872  def XVCVUXDDP : XX2Form<60, 488,
873                      (outs vsrc:$XT), (ins vsrc:$XB),
874                      "xvcvuxddp $XT, $XB", IIC_VecFP,
875                      [(set v2f64:$XT, (any_uint_to_fp v2i64:$XB))]>;
876  def XVCVUXDSP : XX2Form<60, 424,
877                      (outs vsrc:$XT), (ins vsrc:$XB),
878                      "xvcvuxdsp $XT, $XB", IIC_VecFP,
879                      [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
880  def XVCVUXWSP : XX2Form<60, 168,
881                      (outs vsrc:$XT), (ins vsrc:$XB),
882                      "xvcvuxwsp $XT, $XB", IIC_VecFP,
883                      [(set v4f32:$XT, (any_uint_to_fp v4i32:$XB))]>;
884
885  let mayRaiseFPException = 0 in {
886  def XVCVSXWDP : XX2Form<60, 248,
887                    (outs vsrc:$XT), (ins vsrc:$XB),
888                    "xvcvsxwdp $XT, $XB", IIC_VecFP,
889                    [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
890  def XVCVUXWDP : XX2Form<60, 232,
891                      (outs vsrc:$XT), (ins vsrc:$XB),
892                      "xvcvuxwdp $XT, $XB", IIC_VecFP,
893                      [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
894  }
895
896  // Rounding Instructions respecting current rounding mode
897  def XSRDPIC : XX2Form<60, 107,
898                      (outs vsfrc:$XT), (ins vsfrc:$XB),
899                      "xsrdpic $XT, $XB", IIC_VecFP,
900                      [(set f64:$XT, (fnearbyint f64:$XB))]>;
901  def XVRDPIC : XX2Form<60, 235,
902                      (outs vsrc:$XT), (ins vsrc:$XB),
903                      "xvrdpic $XT, $XB", IIC_VecFP,
904                      [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
905  def XVRSPIC : XX2Form<60, 171,
906                      (outs vsrc:$XT), (ins vsrc:$XB),
907                      "xvrspic $XT, $XB", IIC_VecFP,
908                      [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
909  // Max/Min Instructions
910  let isCommutable = 1 in {
911  def XSMAXDP : XX3Form<60, 160,
912                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
913                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
914                        [(set vsfrc:$XT,
915                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
916  def XSMINDP : XX3Form<60, 168,
917                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
918                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
919                        [(set vsfrc:$XT,
920                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
921
922  def XVMAXDP : XX3Form<60, 224,
923                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
924                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
925                        [(set vsrc:$XT,
926                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
927  def XVMINDP : XX3Form<60, 232,
928                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
929                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
930                        [(set vsrc:$XT,
931                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
932
933  def XVMAXSP : XX3Form<60, 192,
934                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
935                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
936                        [(set vsrc:$XT,
937                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
938  def XVMINSP : XX3Form<60, 200,
939                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
940                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
941                        [(set vsrc:$XT,
942                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
943  } // isCommutable
944  } // Uses = [RM]
945
946  // Rounding Instructions with static direction.
947  def XSRDPI : XX2Form<60, 73,
948                      (outs vsfrc:$XT), (ins vsfrc:$XB),
949                      "xsrdpi $XT, $XB", IIC_VecFP,
950                      [(set f64:$XT, (any_fround f64:$XB))]>;
951  def XSRDPIM : XX2Form<60, 121,
952                      (outs vsfrc:$XT), (ins vsfrc:$XB),
953                      "xsrdpim $XT, $XB", IIC_VecFP,
954                      [(set f64:$XT, (any_ffloor f64:$XB))]>;
955  def XSRDPIP : XX2Form<60, 105,
956                      (outs vsfrc:$XT), (ins vsfrc:$XB),
957                      "xsrdpip $XT, $XB", IIC_VecFP,
958                      [(set f64:$XT, (any_fceil f64:$XB))]>;
959  def XSRDPIZ : XX2Form<60, 89,
960                      (outs vsfrc:$XT), (ins vsfrc:$XB),
961                      "xsrdpiz $XT, $XB", IIC_VecFP,
962                      [(set f64:$XT, (any_ftrunc f64:$XB))]>;
963
964  def XVRDPI : XX2Form<60, 201,
965                      (outs vsrc:$XT), (ins vsrc:$XB),
966                      "xvrdpi $XT, $XB", IIC_VecFP,
967                      [(set v2f64:$XT, (any_fround v2f64:$XB))]>;
968  def XVRDPIM : XX2Form<60, 249,
969                      (outs vsrc:$XT), (ins vsrc:$XB),
970                      "xvrdpim $XT, $XB", IIC_VecFP,
971                      [(set v2f64:$XT, (any_ffloor v2f64:$XB))]>;
972  def XVRDPIP : XX2Form<60, 233,
973                      (outs vsrc:$XT), (ins vsrc:$XB),
974                      "xvrdpip $XT, $XB", IIC_VecFP,
975                      [(set v2f64:$XT, (any_fceil v2f64:$XB))]>;
976  def XVRDPIZ : XX2Form<60, 217,
977                      (outs vsrc:$XT), (ins vsrc:$XB),
978                      "xvrdpiz $XT, $XB", IIC_VecFP,
979                      [(set v2f64:$XT, (any_ftrunc v2f64:$XB))]>;
980
981  def XVRSPI : XX2Form<60, 137,
982                      (outs vsrc:$XT), (ins vsrc:$XB),
983                      "xvrspi $XT, $XB", IIC_VecFP,
984                      [(set v4f32:$XT, (any_fround v4f32:$XB))]>;
985  def XVRSPIM : XX2Form<60, 185,
986                      (outs vsrc:$XT), (ins vsrc:$XB),
987                      "xvrspim $XT, $XB", IIC_VecFP,
988                      [(set v4f32:$XT, (any_ffloor v4f32:$XB))]>;
989  def XVRSPIP : XX2Form<60, 169,
990                      (outs vsrc:$XT), (ins vsrc:$XB),
991                      "xvrspip $XT, $XB", IIC_VecFP,
992                      [(set v4f32:$XT, (any_fceil v4f32:$XB))]>;
993  def XVRSPIZ : XX2Form<60, 153,
994                      (outs vsrc:$XT), (ins vsrc:$XB),
995                      "xvrspiz $XT, $XB", IIC_VecFP,
996                      [(set v4f32:$XT, (any_ftrunc v4f32:$XB))]>;
997  } // mayRaiseFPException
998
999  // Logical Instructions
1000  let isCommutable = 1 in
1001  def XXLAND : XX3Form<60, 130,
1002                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1003                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
1004                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
1005  def XXLANDC : XX3Form<60, 138,
1006                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1007                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
1008                        [(set v4i32:$XT, (and v4i32:$XA,
1009                                              (vnot_ppc v4i32:$XB)))]>;
1010  let isCommutable = 1 in {
1011  def XXLNOR : XX3Form<60, 162,
1012                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1013                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
1014                       [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
1015                                                   v4i32:$XB)))]>;
1016  def XXLOR : XX3Form<60, 146,
1017                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1018                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
1019                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
1020  let isCodeGenOnly = 1 in
1021  def XXLORf: XX3Form<60, 146,
1022                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
1023                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
1024  def XXLXOR : XX3Form<60, 154,
1025                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1026                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
1027                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
1028  } // isCommutable
1029
1030  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
1031      isReMaterializable = 1 in {
1032    def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
1033                       "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
1034                       [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
1035    def XXLXORdpz : XX3Form_SameOp<60, 154,
1036                         (outs vsfrc:$XT), (ins),
1037                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
1038                         [(set f64:$XT, (fpimm0))]>;
1039    def XXLXORspz : XX3Form_SameOp<60, 154,
1040                         (outs vssrc:$XT), (ins),
1041                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
1042                         [(set f32:$XT, (fpimm0))]>;
1043  }
1044
1045  // Permutation Instructions
1046  def XXMRGHW : XX3Form<60, 18,
1047                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1048                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
1049  def XXMRGLW : XX3Form<60, 50,
1050                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1051                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
1052
1053  def XXPERMDI : XX3Form_2<60, 10,
1054                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
1055                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
1056                       [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
1057                         imm32SExt16:$DM))]>;
1058  let isCodeGenOnly = 1 in
1059  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
1060                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
1061  def XXSEL : XX4Form<60, 3,
1062                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
1063                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
1064
1065  def XXSLDWI : XX3Form_2<60, 2,
1066                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
1067                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
1068                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
1069                                                  imm32SExt16:$SHW))]>;
1070
1071  let isCodeGenOnly = 1 in
1072  def XXSLDWIs : XX3Form_2s<60, 2,
1073                       (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
1074                       "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
1075
1076  def XXSPLTW : XX2Form_2<60, 164,
1077                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
1078                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
1079                       [(set v4i32:$XT,
1080                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
1081  let isCodeGenOnly = 1 in
1082  def XXSPLTWs : XX2Form_2<60, 164,
1083                       (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
1084                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
1085
1086// The following VSX instructions were introduced in Power ISA 2.07
1087let Predicates = [HasVSX, HasP8Vector] in {
1088  let isCommutable = 1 in {
1089    def XXLEQV : XX3Form<60, 186,
1090                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1091                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1092                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1093    def XXLNAND : XX3Form<60, 178,
1094                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1095                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1096                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1097                                                    v4i32:$XB)))]>;
1098  } // isCommutable
1099
1100  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
1101      isReMaterializable = 1 in {
1102    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
1103                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
1104                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
1105  }
1106
1107  def XXLORC : XX3Form<60, 170,
1108                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1109                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1110                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1111
1112  // VSX scalar loads introduced in ISA 2.07
1113  let mayLoad = 1, mayStore = 0 in {
1114    let CodeSize = 3 in
1115    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1116                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
1117    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1118                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
1119    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1120                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
1121
1122    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
1123    let CodeSize = 3 in
1124    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
1125                            "#XFLOADf32",
1126                            [(set f32:$XT, (load xoaddr:$src))]>;
1127    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
1128    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1129                       "#LIWAX",
1130                       [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1131    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
1132    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1133                       "#LIWZX",
1134                       [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1135  } // mayLoad
1136
1137  // VSX scalar stores introduced in ISA 2.07
1138  let mayStore = 1, mayLoad = 0 in {
1139    let CodeSize = 3 in
1140    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1141                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
1142    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1143                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
1144
1145    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
1146    let CodeSize = 3 in
1147    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
1148                            "#XFSTOREf32",
1149                            [(store f32:$XT, xoaddr:$dst)]>;
1150    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
1151    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1152                       "#STIWX",
1153                      [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1154  } // mayStore
1155
1156  // VSX Elementary Scalar FP arithmetic (SP)
1157  let mayRaiseFPException = 1 in {
1158  let isCommutable = 1 in {
1159    def XSADDSP : XX3Form<60, 0,
1160                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1161                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1162                          [(set f32:$XT, (any_fadd f32:$XA, f32:$XB))]>;
1163    def XSMULSP : XX3Form<60, 16,
1164                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1165                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1166                          [(set f32:$XT, (any_fmul f32:$XA, f32:$XB))]>;
1167  } // isCommutable
1168
1169  def XSSUBSP : XX3Form<60, 8,
1170                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1171                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
1172                        [(set f32:$XT, (any_fsub f32:$XA, f32:$XB))]>;
1173  def XSDIVSP : XX3Form<60, 24,
1174                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1175                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1176                        [(set f32:$XT, (any_fdiv f32:$XA, f32:$XB))]>;
1177
1178  def XSRESP : XX2Form<60, 26,
1179                        (outs vssrc:$XT), (ins vssrc:$XB),
1180                        "xsresp $XT, $XB", IIC_VecFP,
1181                        [(set f32:$XT, (PPCfre f32:$XB))]>;
1182  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1183  let hasSideEffects = 1 in
1184  def XSRSP : XX2Form<60, 281,
1185                        (outs vssrc:$XT), (ins vsfrc:$XB),
1186                        "xsrsp $XT, $XB", IIC_VecFP,
1187                        [(set f32:$XT, (any_fpround f64:$XB))]>;
1188  def XSSQRTSP : XX2Form<60, 11,
1189                        (outs vssrc:$XT), (ins vssrc:$XB),
1190                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1191                        [(set f32:$XT, (any_fsqrt f32:$XB))]>;
1192  def XSRSQRTESP : XX2Form<60, 10,
1193                           (outs vssrc:$XT), (ins vssrc:$XB),
1194                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
1195                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1196
1197  // FMA Instructions
1198  let BaseName = "XSMADDASP" in {
1199  let isCommutable = 1 in
1200  def XSMADDASP : XX3Form<60, 1,
1201                          (outs vssrc:$XT),
1202                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1203                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1204                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB, f32:$XTi))]>,
1205                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1206                          AltVSXFMARel;
1207  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1208  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1209  def XSMADDMSP : XX3Form<60, 9,
1210                          (outs vssrc:$XT),
1211                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1212                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1213                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1214                          AltVSXFMARel;
1215  }
1216
1217  let BaseName = "XSMSUBASP" in {
1218  let isCommutable = 1 in
1219  def XSMSUBASP : XX3Form<60, 17,
1220                          (outs vssrc:$XT),
1221                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1222                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1223                          [(set f32:$XT, (any_fma f32:$XA, f32:$XB,
1224                                              (fneg f32:$XTi)))]>,
1225                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1226                          AltVSXFMARel;
1227  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1228  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1229  def XSMSUBMSP : XX3Form<60, 25,
1230                          (outs vssrc:$XT),
1231                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1232                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1233                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1234                          AltVSXFMARel;
1235  }
1236
1237  let BaseName = "XSNMADDASP" in {
1238  let isCommutable = 1 in
1239  def XSNMADDASP : XX3Form<60, 129,
1240                          (outs vssrc:$XT),
1241                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1242                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1243                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
1244                                                    f32:$XTi)))]>,
1245                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1246                          AltVSXFMARel;
1247  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1248  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1249  def XSNMADDMSP : XX3Form<60, 137,
1250                          (outs vssrc:$XT),
1251                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1252                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1253                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1254                          AltVSXFMARel;
1255  }
1256
1257  let BaseName = "XSNMSUBASP" in {
1258  let isCommutable = 1 in
1259  def XSNMSUBASP : XX3Form<60, 145,
1260                          (outs vssrc:$XT),
1261                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1262                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1263                          [(set f32:$XT, (fneg (any_fma f32:$XA, f32:$XB,
1264                                                    (fneg f32:$XTi))))]>,
1265                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1266                          AltVSXFMARel;
1267  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1268  let IsVSXFMAAlt = 1, hasSideEffects = 1 in
1269  def XSNMSUBMSP : XX3Form<60, 153,
1270                          (outs vssrc:$XT),
1271                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1272                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1273                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1274                          AltVSXFMARel;
1275  }
1276
1277  // Single Precision Conversions (FP <-> INT)
1278  def XSCVSXDSP : XX2Form<60, 312,
1279                      (outs vssrc:$XT), (ins vsfrc:$XB),
1280                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1281                      [(set f32:$XT, (PPCany_fcfids f64:$XB))]>;
1282  def XSCVUXDSP : XX2Form<60, 296,
1283                      (outs vssrc:$XT), (ins vsfrc:$XB),
1284                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1285                      [(set f32:$XT, (PPCany_fcfidus f64:$XB))]>;
1286  } // mayRaiseFPException
1287
1288  // Conversions between vector and scalar single precision
1289  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1290                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1291  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1292                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1293
1294  let Predicates = [HasVSX, HasDirectMove] in {
1295  // VSX direct move instructions
1296  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1297                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1298                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1299      Requires<[In64BitMode]>;
1300  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1301  let isCodeGenOnly = 1, hasSideEffects = 1 in
1302  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
1303                             "mfvsrd $rA, $XT", IIC_VecGeneral,
1304                             []>,
1305      Requires<[In64BitMode]>;
1306  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1307                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1308                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1309  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1310  let isCodeGenOnly = 1, hasSideEffects = 1 in
1311  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
1312                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1313                               []>;
1314  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1315                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1316                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1317      Requires<[In64BitMode]>;
1318  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1319  let isCodeGenOnly = 1, hasSideEffects = 1 in
1320  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
1321                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1322                              []>,
1323      Requires<[In64BitMode]>;
1324  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1325                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1326                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1327  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1328  let isCodeGenOnly = 1, hasSideEffects = 1 in
1329  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
1330                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1331                               []>;
1332  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1333                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1334                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1335  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1336  let isCodeGenOnly = 1, hasSideEffects = 1 in
1337  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
1338                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1339                               []>;
1340  } // HasDirectMove
1341
1342} // HasVSX, HasP8Vector
1343
1344let Predicates = [HasVSX, IsISA3_0, HasDirectMove] in {
1345def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1346                            "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1347
1348def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1349                     "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1350                     []>, Requires<[In64BitMode]>;
1351
1352def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1353                            "mfvsrld $rA, $XT", IIC_VecGeneral,
1354                            []>, Requires<[In64BitMode]>;
1355
1356} // HasVSX, IsISA3_0, HasDirectMove
1357
1358let Predicates = [HasVSX, HasP9Vector] in {
1359  // Quad-Precision Scalar Move Instructions:
1360  // Copy Sign
1361  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
1362                                [(set f128:$vT,
1363                                      (fcopysign f128:$vB, f128:$vA))]>;
1364
1365  // Absolute/Negative-Absolute/Negate
1366  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
1367                                [(set f128:$vT, (fabs f128:$vB))]>;
1368  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
1369                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
1370  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
1371                                [(set f128:$vT, (fneg f128:$vB))]>;
1372
1373  //===--------------------------------------------------------------------===//
1374  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
1375
1376  // Add/Divide/Multiply/Subtract
1377  let mayRaiseFPException = 1 in {
1378  let isCommutable = 1 in {
1379  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
1380                                   [(set f128:$vT, (any_fadd f128:$vA, f128:$vB))]>;
1381  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
1382                                   [(set f128:$vT, (any_fmul f128:$vA, f128:$vB))]>;
1383  }
1384  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
1385                                   [(set f128:$vT, (any_fsub f128:$vA, f128:$vB))]>;
1386  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
1387                                   [(set f128:$vT, (any_fdiv f128:$vA, f128:$vB))]>;
1388  // Square-Root
1389  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
1390                                   [(set f128:$vT, (any_fsqrt f128:$vB))]>;
1391  // (Negative) Multiply-{Add/Subtract}
1392  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
1393                                    [(set f128:$vT,
1394                                          (any_fma f128:$vA, f128:$vB, f128:$vTi))]>;
1395  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
1396                                       [(set f128:$vT,
1397                                             (any_fma f128:$vA, f128:$vB,
1398                                                      (fneg f128:$vTi)))]>;
1399  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
1400                                     [(set f128:$vT,
1401                                           (fneg (any_fma f128:$vA, f128:$vB,
1402                                                          f128:$vTi)))]>;
1403  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
1404                                     [(set f128:$vT,
1405                                           (fneg (any_fma f128:$vA, f128:$vB,
1406                                                          (fneg f128:$vTi))))]>;
1407
1408  let isCommutable = 1 in {
1409  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
1410                                  [(set f128:$vT,
1411                                  (int_ppc_addf128_round_to_odd
1412                                  f128:$vA, f128:$vB))]>;
1413  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
1414                                  [(set f128:$vT,
1415                                  (int_ppc_mulf128_round_to_odd
1416                                  f128:$vA, f128:$vB))]>;
1417  }
1418  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
1419                                  [(set f128:$vT,
1420                                  (int_ppc_subf128_round_to_odd
1421                                  f128:$vA, f128:$vB))]>;
1422  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
1423                                  [(set f128:$vT,
1424                                  (int_ppc_divf128_round_to_odd
1425                                  f128:$vA, f128:$vB))]>;
1426  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
1427                                  [(set f128:$vT,
1428                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
1429
1430
1431  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
1432                                      [(set f128:$vT,
1433                                      (int_ppc_fmaf128_round_to_odd
1434                                      f128:$vA,f128:$vB,f128:$vTi))]>;
1435
1436  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
1437                                      [(set f128:$vT,
1438                                      (int_ppc_fmaf128_round_to_odd
1439                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
1440  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
1441                                      [(set f128:$vT,
1442                                      (fneg (int_ppc_fmaf128_round_to_odd
1443                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
1444  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
1445                                      [(set f128:$vT,
1446                                      (fneg (int_ppc_fmaf128_round_to_odd
1447                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
1448  } // mayRaiseFPException
1449
1450  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1451  // QP Compare Ordered/Unordered
1452  let hasSideEffects = 1 in {
1453    // DP/QP Compare Exponents
1454    def XSCMPEXPDP : XX3Form_1<60, 59,
1455                               (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
1456                               "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
1457    def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
1458
1459    let mayRaiseFPException = 1 in {
1460    def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1461    def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1462
1463    // DP Compare ==, >=, >, !=
1464    // Use vsrc for XT, because the entire register of XT is set.
1465    // XT.dword[1] = 0x0000_0000_0000_0000
1466    def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
1467                                    IIC_FPCompare, []>;
1468    def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
1469                                    IIC_FPCompare, []>;
1470    def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
1471                                    IIC_FPCompare, []>;
1472    }
1473  }
1474
1475  //===--------------------------------------------------------------------===//
1476  // Quad-Precision Floating-Point Conversion Instructions:
1477
1478  let mayRaiseFPException = 1 in {
1479    // Convert DP -> QP
1480    def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
1481                                       [(set f128:$vT, (any_fpextend f64:$vB))]>;
1482
1483    // Round & Convert QP -> DP (dword[1] is set to zero)
1484    def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
1485    def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
1486                                          [(set f64:$vT,
1487                                          (int_ppc_truncf128_round_to_odd
1488                                          f128:$vB))]>;
1489  }
1490
1491  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
1492  let mayRaiseFPException = 1 in {
1493    def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
1494    def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
1495    def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
1496    def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
1497  }
1498
1499  // Convert (Un)Signed DWord -> QP.
1500  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
1501  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
1502
1503  // (Round &) Convert DP <-> HP
1504  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
1505  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
1506  // but we still use vsfrc for it.
1507  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1508  let hasSideEffects = 1, mayRaiseFPException = 1 in {
1509    def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
1510    def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
1511  }
1512
1513  let mayRaiseFPException = 1 in {
1514  // Vector HP -> SP
1515  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1516  let hasSideEffects = 1 in
1517  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
1518  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
1519                                 [(set v4f32:$XT,
1520                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
1521
1522  // Round to Quad-Precision Integer [with Inexact]
1523  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
1524  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
1525
1526  // Round Quad-Precision to Double-Extended Precision (fp80)
1527  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1528  let hasSideEffects = 1 in
1529  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
1530  }
1531
1532  //===--------------------------------------------------------------------===//
1533  // Insert/Extract Instructions
1534
1535  // Insert Exponent DP/QP
1536  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
1537  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1538  let hasSideEffects = 1 in {
1539    def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
1540                            "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
1541    // vB NOTE: only vB.dword[0] is used, that's why we don't use
1542    //          X_VT5_VA5_VB5 form
1543    def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
1544                            "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
1545  }
1546
1547  // Extract Exponent/Significand DP/QP
1548  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1549  let hasSideEffects = 1 in {
1550    def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
1551    def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
1552
1553    def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
1554    def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
1555  }
1556
1557  // Vector Insert Word
1558  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
1559  def XXINSERTW   :
1560    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
1561                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
1562                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
1563                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
1564                                                   imm32SExt16:$UIM))]>,
1565                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
1566
1567  // Vector Extract Unsigned Word
1568  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1569  let hasSideEffects = 1 in
1570  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
1571                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
1572                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
1573
1574  // Vector Insert Exponent DP/SP
1575  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
1576    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
1577  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
1578    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
1579
1580  // Vector Extract Exponent/Significand DP/SP
1581  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
1582                                 [(set v2i64: $XT,
1583                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
1584  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
1585                                 [(set v4i32: $XT,
1586                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
1587  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
1588                                 [(set v2i64: $XT,
1589                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
1590  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
1591                                 [(set v4i32: $XT,
1592                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
1593
1594  // Test Data Class SP/DP/QP
1595  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1596  let hasSideEffects = 1 in {
1597    def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
1598                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
1599                                "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
1600    def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
1601                                (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
1602                                "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
1603    def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
1604                                (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
1605                                "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
1606  }
1607
1608  // Vector Test Data Class SP/DP
1609  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
1610                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
1611                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
1612                              [(set v4i32: $XT,
1613                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
1614  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
1615                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
1616                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
1617                              [(set v2i64: $XT,
1618                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
1619
1620  // Maximum/Minimum Type-C/Type-J DP
1621  let mayRaiseFPException = 1 in {
1622  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
1623                                 IIC_VecFP,
1624                                 [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
1625  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc,
1626                                 IIC_VecFP,
1627                                 [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>;
1628
1629  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1630  let hasSideEffects = 1 in {
1631    def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
1632                                   IIC_VecFP, []>;
1633    def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
1634                                   IIC_VecFP, []>;
1635  }
1636  }
1637
1638  // Vector Byte-Reverse H/W/D/Q Word
1639  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1640  let hasSideEffects = 1 in
1641  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
1642  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc,
1643    [(set v4i32:$XT, (bswap v4i32:$XB))]>;
1644  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc,
1645    [(set v2i64:$XT, (bswap v2i64:$XB))]>;
1646  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1647  let hasSideEffects = 1 in
1648  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
1649
1650  // Vector Permute
1651  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1652  let hasSideEffects = 1 in {
1653    def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
1654                                  IIC_VecPerm, []>;
1655    def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
1656                                  IIC_VecPerm, []>;
1657  }
1658
1659  // Vector Splat Immediate Byte
1660  // FIXME: Setting the hasSideEffects flag here to match current behaviour.
1661  let hasSideEffects = 1 in
1662  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
1663                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
1664
1665  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
1666  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
1667  let mayLoad = 1, mayStore = 0 in {
1668  // Load Vector
1669  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
1670                            "lxv $XT, $src", IIC_LdStLFD, []>;
1671  // Load DWord
1672  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
1673                       "lxsd $vD, $src", IIC_LdStLFD, []>;
1674  // Load SP from src, convert it to DP, and place in dword[0]
1675  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
1676                       "lxssp $vD, $src", IIC_LdStLFD, []>;
1677
1678  // Load as Integer Byte/Halfword & Zero Indexed
1679  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
1680                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
1681  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
1682                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
1683
1684  // Load Vector Halfword*8/Byte*16 Indexed
1685  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
1686  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
1687
1688  // Load Vector Indexed
1689  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
1690                [(set v2f64:$XT, (load xaddrX16:$src))]>;
1691  // Load Vector (Left-justified) with Length
1692  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
1693                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
1694                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
1695  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
1696                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
1697                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
1698
1699  // Load Vector Word & Splat Indexed
1700  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
1701  } // mayLoad
1702
1703  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
1704  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
1705  let mayStore = 1, mayLoad = 0 in {
1706  // Store Vector
1707  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
1708                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
1709  // Store DWord
1710  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
1711                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
1712  // Convert DP of dword[0] to SP, and Store to dst
1713  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
1714                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
1715
1716  // Store as Integer Byte/Halfword Indexed
1717  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
1718                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
1719  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
1720                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
1721  let isCodeGenOnly = 1 in {
1722    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
1723    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
1724  }
1725
1726  // Store Vector Halfword*8/Byte*16 Indexed
1727  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
1728  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
1729
1730  // Store Vector Indexed
1731  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
1732                 [(store v2f64:$XT, xaddrX16:$dst)]>;
1733
1734  // Store Vector (Left-justified) with Length
1735  def STXVL : XX1Form_memOp<31, 397, (outs),
1736                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
1737                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
1738                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
1739                              i64:$rB)]>;
1740  def STXVLL : XX1Form_memOp<31, 429, (outs),
1741                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
1742                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
1743                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
1744                              i64:$rB)]>;
1745  } // mayStore
1746
1747  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
1748                          "#DFLOADf32",
1749                          [(set f32:$XT, (load iaddrX4:$src))]>;
1750  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
1751                          "#DFLOADf64",
1752                          [(set f64:$XT, (load iaddrX4:$src))]>;
1753  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
1754                          "#DFSTOREf32",
1755                          [(store f32:$XT, iaddrX4:$dst)]>;
1756  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
1757                          "#DFSTOREf64",
1758                          [(store f64:$XT, iaddrX4:$dst)]>;
1759
1760  let mayStore = 1 in {
1761    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
1762                                          (ins spilltovsrrc:$XT, memrr:$dst),
1763                                          "#SPILLTOVSR_STX", []>;
1764    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
1765                              "#SPILLTOVSR_ST", []>;
1766  }
1767  let mayLoad = 1 in {
1768    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
1769                                          (ins memrr:$src),
1770                                          "#SPILLTOVSR_LDX", []>;
1771    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
1772                              "#SPILLTOVSR_LD", []>;
1773
1774  }
1775  } // HasP9Vector
1776} // hasSideEffects = 0
1777
1778let PPC970_Single = 1, AddedComplexity = 400 in {
1779
1780  def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
1781                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
1782                             "#SELECT_CC_VSRC",
1783                             []>;
1784  def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
1785                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
1786                          "#SELECT_VSRC",
1787                          [(set v2f64:$dst,
1788                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
1789  def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
1790                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
1791                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
1792                              []>;
1793  def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
1794                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
1795                           "#SELECT_VSFRC",
1796                           [(set f64:$dst,
1797                                 (select i1:$cond, f64:$T, f64:$F))]>;
1798  def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
1799                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
1800                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
1801                              []>;
1802  def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
1803                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
1804                           "#SELECT_VSSRC",
1805                           [(set f32:$dst,
1806                                 (select i1:$cond, f32:$T, f32:$F))]>;
1807}
1808}
1809
1810//----------------------------- DAG Definitions ------------------------------//
1811def FpMinMax {
1812  dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC),
1813                                          (COPY_TO_REGCLASS $B, VSFRC)),
1814                                 VSSRC);
1815  dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC),
1816                                          (COPY_TO_REGCLASS $B, VSFRC)),
1817                                 VSSRC);
1818}
1819
1820def ScalarLoads {
1821  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
1822  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
1823  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
1824  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
1825  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
1826
1827  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
1828  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
1829  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
1830  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
1831  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
1832
1833  dag Li32 = (i32 (load xoaddr:$src));
1834}
1835
1836def DWToSPExtractConv {
1837  dag El0US1 = (f32 (PPCfcfidus
1838                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
1839  dag El1US1 = (f32 (PPCfcfidus
1840                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
1841  dag El0US2 = (f32 (PPCfcfidus
1842                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
1843  dag El1US2 = (f32 (PPCfcfidus
1844                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
1845  dag El0SS1 = (f32 (PPCfcfids
1846                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
1847  dag El1SS1 = (f32 (PPCfcfids
1848                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
1849  dag El0SS2 = (f32 (PPCfcfids
1850                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
1851  dag El1SS2 = (f32 (PPCfcfids
1852                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
1853  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
1854  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
1855}
1856
1857def WToDPExtractConv {
1858  dag El0S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 0))));
1859  dag El1S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 1))));
1860  dag El2S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 2))));
1861  dag El3S = (f64 (PPCfcfid (PPCmtvsra (extractelt v4i32:$A, 3))));
1862  dag El0U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 0))));
1863  dag El1U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 1))));
1864  dag El2U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 2))));
1865  dag El3U = (f64 (PPCfcfidu (PPCmtvsrz (extractelt v4i32:$A, 3))));
1866  dag BV02S = (v2f64 (build_vector El0S, El2S));
1867  dag BV13S = (v2f64 (build_vector El1S, El3S));
1868  dag BV02U = (v2f64 (build_vector El0U, El2U));
1869  dag BV13U = (v2f64 (build_vector El1U, El3U));
1870}
1871
1872/*  Direct moves of various widths from GPR's into VSR's. Each move lines
1873    the value up into element 0 (both BE and LE). Namely, entities smaller than
1874    a doubleword are shifted left and moved for BE. For LE, they're moved, then
1875    swapped to go into the least significant element of the VSR.
1876*/
1877def MovesToVSR {
1878  dag BE_BYTE_0 =
1879    (MTVSRD
1880      (RLDICR
1881        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1882  dag BE_HALF_0 =
1883    (MTVSRD
1884      (RLDICR
1885        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1886  dag BE_WORD_0 =
1887    (MTVSRD
1888      (RLDICR
1889        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1890  dag BE_DWORD_0 = (MTVSRD $A);
1891
1892  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1893  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1894                                        LE_MTVSRW, sub_64));
1895  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1896  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1897                                         BE_DWORD_0, sub_64));
1898  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1899}
1900
1901/*  Patterns for extracting elements out of vectors. Integer elements are
1902    extracted using direct move operations. Patterns for extracting elements
1903    whose indices are not available at compile time are also provided with
1904    various _VARIABLE_ patterns.
1905    The numbering for the DAG's is for LE, but when used on BE, the correct
1906    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1907*/
1908def VectorExtractions {
1909  // Doubleword extraction
1910  dag LE_DWORD_0 =
1911    (MFVSRD
1912      (EXTRACT_SUBREG
1913        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1914                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1915  dag LE_DWORD_1 = (MFVSRD
1916                     (EXTRACT_SUBREG
1917                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1918
1919  // Word extraction
1920  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1921  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1922  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1923                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1924  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1925
1926  // Halfword extraction
1927  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1928  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1929  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1930  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1931  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1932  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1933  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1934  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1935
1936  // Byte extraction
1937  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1938  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1939  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1940  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1941  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1942  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1943  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1944  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1945  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1946  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1947  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1948  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1949  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1950  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1951  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1952  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1953
1954  /* Variable element number (BE and LE patterns must be specified separately)
1955     This is a rather involved process.
1956
1957     Conceptually, this is how the move is accomplished:
1958     1. Identify which doubleword contains the element
1959     2. Shift in the VMX register so that the correct doubleword is correctly
1960        lined up for the MFVSRD
1961     3. Perform the move so that the element (along with some extra stuff)
1962        is in the GPR
1963     4. Right shift within the GPR so that the element is right-justified
1964
1965     Of course, the index is an element number which has a different meaning
1966     on LE/BE so the patterns have to be specified separately.
1967
1968     Note: The final result will be the element right-justified with high
1969           order bits being arbitrarily defined (namely, whatever was in the
1970           vector register to the left of the value originally).
1971  */
1972
1973  /*  LE variable byte
1974      Number 1. above:
1975      - For elements 0-7, we shift left by 8 bytes since they're on the right
1976      - For elements 8-15, we need not shift (shift left by zero bytes)
1977      This is accomplished by inverting the bits of the index and AND-ing
1978      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1979  */
1980  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
1981
1982  //  Number 2. above:
1983  //  - Now that we set up the shift amount, we shift in the VMX register
1984  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
1985
1986  //  Number 3. above:
1987  //  - The doubleword containing our element is moved to a GPR
1988  dag LE_MV_VBYTE = (MFVSRD
1989                      (EXTRACT_SUBREG
1990                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1991                        sub_64));
1992
1993  /*  Number 4. above:
1994      - Truncate the element number to the range 0-7 (8-15 are symmetrical
1995        and out of range values are truncated accordingly)
1996      - Multiply by 8 as we need to shift right by the number of bits, not bytes
1997      - Shift right in the GPR by the calculated value
1998  */
1999  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
2000                                       sub_32);
2001  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
2002                                         sub_32);
2003
2004  /*  LE variable halfword
2005      Number 1. above:
2006      - For elements 0-3, we shift left by 8 since they're on the right
2007      - For elements 4-7, we need not shift (shift left by zero bytes)
2008      Similarly to the byte pattern, we invert the bits of the index, but we
2009      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
2010      Of course, the shift is still by 8 bytes, so we must multiply by 2.
2011  */
2012  dag LE_VHALF_PERM_VEC =
2013    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
2014
2015  //  Number 2. above:
2016  //  - Now that we set up the shift amount, we shift in the VMX register
2017  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
2018
2019  //  Number 3. above:
2020  //  - The doubleword containing our element is moved to a GPR
2021  dag LE_MV_VHALF = (MFVSRD
2022                      (EXTRACT_SUBREG
2023                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
2024                        sub_64));
2025
2026  /*  Number 4. above:
2027      - Truncate the element number to the range 0-3 (4-7 are symmetrical
2028        and out of range values are truncated accordingly)
2029      - Multiply by 16 as we need to shift right by the number of bits
2030      - Shift right in the GPR by the calculated value
2031  */
2032  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
2033                                       sub_32);
2034  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
2035                                         sub_32);
2036
2037  /*  LE variable word
2038      Number 1. above:
2039      - For elements 0-1, we shift left by 8 since they're on the right
2040      - For elements 2-3, we need not shift
2041  */
2042  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2043                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
2044
2045  //  Number 2. above:
2046  //  - Now that we set up the shift amount, we shift in the VMX register
2047  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
2048
2049  //  Number 3. above:
2050  //  - The doubleword containing our element is moved to a GPR
2051  dag LE_MV_VWORD = (MFVSRD
2052                      (EXTRACT_SUBREG
2053                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
2054                        sub_64));
2055
2056  /*  Number 4. above:
2057      - Truncate the element number to the range 0-1 (2-3 are symmetrical
2058        and out of range values are truncated accordingly)
2059      - Multiply by 32 as we need to shift right by the number of bits
2060      - Shift right in the GPR by the calculated value
2061  */
2062  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
2063                                       sub_32);
2064  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
2065                                         sub_32);
2066
2067  /*  LE variable doubleword
2068      Number 1. above:
2069      - For element 0, we shift left by 8 since it's on the right
2070      - For element 1, we need not shift
2071  */
2072  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2073                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
2074
2075  //  Number 2. above:
2076  //  - Now that we set up the shift amount, we shift in the VMX register
2077  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
2078
2079  // Number 3. above:
2080  //  - The doubleword containing our element is moved to a GPR
2081  //  - Number 4. is not needed for the doubleword as the value is 64-bits
2082  dag LE_VARIABLE_DWORD =
2083        (MFVSRD (EXTRACT_SUBREG
2084                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
2085                  sub_64));
2086
2087  /*  LE variable float
2088      - Shift the vector to line up the desired element to BE Word 0
2089      - Convert 32-bit float to a 64-bit single precision float
2090  */
2091  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
2092                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
2093  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
2094  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
2095
2096  /*  LE variable double
2097      Same as the LE doubleword except there is no move.
2098  */
2099  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2100                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2101                                         LE_VDWORD_PERM_VEC));
2102  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
2103
2104  /*  BE variable byte
2105      The algorithm here is the same as the LE variable byte except:
2106      - The shift in the VMX register is by 0/8 for opposite element numbers so
2107        we simply AND the element number with 0x8
2108      - The order of elements after the move to GPR is reversed, so we invert
2109        the bits of the index prior to truncating to the range 0-7
2110  */
2111  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8)));
2112  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
2113  dag BE_MV_VBYTE = (MFVSRD
2114                      (EXTRACT_SUBREG
2115                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
2116                        sub_64));
2117  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
2118                                       sub_32);
2119  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
2120                                         sub_32);
2121
2122  /*  BE variable halfword
2123      The algorithm here is the same as the LE variable halfword except:
2124      - The shift in the VMX register is by 0/8 for opposite element numbers so
2125        we simply AND the element number with 0x4 and multiply by 2
2126      - The order of elements after the move to GPR is reversed, so we invert
2127        the bits of the index prior to truncating to the range 0-3
2128  */
2129  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
2130                                       (RLDICR (ANDI8_rec $Idx, 4), 1, 62)));
2131  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
2132  dag BE_MV_VHALF = (MFVSRD
2133                      (EXTRACT_SUBREG
2134                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
2135                        sub_64));
2136  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
2137                                       sub_32);
2138  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
2139                                         sub_32);
2140
2141  /*  BE variable word
2142      The algorithm is the same as the LE variable word except:
2143      - The shift in the VMX register happens for opposite element numbers
2144      - The order of elements after the move to GPR is reversed, so we invert
2145        the bits of the index prior to truncating to the range 0-1
2146  */
2147  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2148                                       (RLDICR (ANDI8_rec $Idx, 2), 2, 61)));
2149  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
2150  dag BE_MV_VWORD = (MFVSRD
2151                      (EXTRACT_SUBREG
2152                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
2153                        sub_64));
2154  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
2155                                       sub_32);
2156  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
2157                                         sub_32);
2158
2159  /*  BE variable doubleword
2160      Same as the LE doubleword except we shift in the VMX register for opposite
2161      element indices.
2162  */
2163  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2164                                        (RLDICR (ANDI8_rec $Idx, 1), 3, 60)));
2165  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
2166  dag BE_VARIABLE_DWORD =
2167        (MFVSRD (EXTRACT_SUBREG
2168                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
2169                  sub_64));
2170
2171  /*  BE variable float
2172      - Shift the vector to line up the desired element to BE Word 0
2173      - Convert 32-bit float to a 64-bit single precision float
2174  */
2175  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
2176  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
2177  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
2178
2179  /* BE variable double
2180      Same as the BE doubleword except there is no move.
2181  */
2182  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2183                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
2184                                         BE_VDWORD_PERM_VEC));
2185  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
2186}
2187
2188def AlignValues {
2189  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2190  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2191}
2192
2193// Integer extend helper dags 32 -> 64
2194def AnyExts {
2195  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
2196  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
2197  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
2198  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
2199}
2200
2201def DblToFlt {
2202  dag A0 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 0))));
2203  dag A1 = (f32 (any_fpround (f64 (extractelt v2f64:$A, 1))));
2204  dag B0 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 0))));
2205  dag B1 = (f32 (any_fpround (f64 (extractelt v2f64:$B, 1))));
2206}
2207
2208def ExtDbl {
2209  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
2210  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
2211  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
2212  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
2213  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
2214  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
2215  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
2216  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
2217}
2218
2219def ByteToWord {
2220  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
2221  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
2222  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
2223  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
2224  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
2225  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
2226  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
2227  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
2228}
2229
2230def ByteToDWord {
2231  dag LE_A0 = (i64 (sext_inreg
2232              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
2233  dag LE_A1 = (i64 (sext_inreg
2234              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
2235  dag BE_A0 = (i64 (sext_inreg
2236              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
2237  dag BE_A1 = (i64 (sext_inreg
2238              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
2239}
2240
2241def HWordToWord {
2242  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
2243  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
2244  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
2245  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
2246  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
2247  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
2248  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
2249  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
2250}
2251
2252def HWordToDWord {
2253  dag LE_A0 = (i64 (sext_inreg
2254              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
2255  dag LE_A1 = (i64 (sext_inreg
2256              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
2257  dag BE_A0 = (i64 (sext_inreg
2258              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
2259  dag BE_A1 = (i64 (sext_inreg
2260              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
2261}
2262
2263def WordToDWord {
2264  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
2265  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
2266  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
2267  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
2268}
2269
2270def FltToIntLoad {
2271  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
2272}
2273def FltToUIntLoad {
2274  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
2275}
2276def FltToLongLoad {
2277  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
2278}
2279def FltToLongLoadP9 {
2280  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A)))));
2281}
2282def FltToULongLoad {
2283  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
2284}
2285def FltToULongLoadP9 {
2286  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A)))));
2287}
2288def FltToLong {
2289  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
2290}
2291def FltToULong {
2292  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
2293}
2294def DblToInt {
2295  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
2296  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
2297  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
2298  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
2299}
2300def DblToUInt {
2301  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
2302  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
2303  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
2304  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
2305}
2306def DblToLong {
2307  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
2308}
2309def DblToULong {
2310  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
2311}
2312def DblToIntLoad {
2313  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
2314}
2315def DblToIntLoadP9 {
2316  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A)))));
2317}
2318def DblToUIntLoad {
2319  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
2320}
2321def DblToUIntLoadP9 {
2322  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A)))));
2323}
2324def DblToLongLoad {
2325  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
2326}
2327def DblToULongLoad {
2328  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
2329}
2330
2331// FP load dags (for f32 -> v4f32)
2332def LoadFP {
2333  dag A = (f32 (load xoaddr:$A));
2334  dag B = (f32 (load xoaddr:$B));
2335  dag C = (f32 (load xoaddr:$C));
2336  dag D = (f32 (load xoaddr:$D));
2337}
2338
2339// FP merge dags (for f32 -> v4f32)
2340def MrgFP {
2341  dag LD32A = (COPY_TO_REGCLASS (LIWZX xoaddr:$A), VSRC);
2342  dag LD32B = (COPY_TO_REGCLASS (LIWZX xoaddr:$B), VSRC);
2343  dag LD32C = (COPY_TO_REGCLASS (LIWZX xoaddr:$C), VSRC);
2344  dag LD32D = (COPY_TO_REGCLASS (LIWZX xoaddr:$D), VSRC);
2345  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
2346                               (COPY_TO_REGCLASS $C, VSRC), 0));
2347  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
2348                               (COPY_TO_REGCLASS $D, VSRC), 0));
2349  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
2350  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
2351  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
2352  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
2353}
2354
2355// Word-element merge dags - conversions from f64 to i32 merged into vectors.
2356def MrgWords {
2357  // For big endian, we merge low and hi doublewords (A, B).
2358  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
2359  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
2360  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
2361  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
2362  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
2363  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
2364
2365  // For little endian, we merge low and hi doublewords (B, A).
2366  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
2367  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
2368  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
2369  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
2370  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
2371  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
2372
2373  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
2374  // then merge.
2375  dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
2376                            (COPY_TO_REGCLASS f64:$C, VSRC), 0));
2377  dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
2378                            (COPY_TO_REGCLASS f64:$D, VSRC), 0));
2379  dag CVACS = (v4i32 (XVCVDPSXWS AC));
2380  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
2381  dag CVACU = (v4i32 (XVCVDPUXWS AC));
2382  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
2383
2384  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
2385  // then merge.
2386  dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
2387                            (COPY_TO_REGCLASS f64:$B, VSRC), 0));
2388  dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
2389                            (COPY_TO_REGCLASS f64:$A, VSRC), 0));
2390  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
2391  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
2392  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
2393  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
2394}
2395
2396//---------------------------- Anonymous Patterns ----------------------------//
2397// Predicate combinations are kept in roughly chronological order in terms of
2398// instruction availability in the architecture. For example, VSX came in with
2399// ISA 2.06 (Power7). There have since been additions in ISA 2.07 (Power8) and
2400// ISA 3.0 (Power9). However, the granularity of features on later subtargets
2401// is finer for various reasons. For example, we have Power8Vector,
2402// Power8Altivec, DirectMove that all came in with ISA 2.07. The situation is
2403// similar with ISA 3.0 with Power9Vector, Power9Altivec, IsISA3_0. Then there
2404// are orthogonal predicates such as endianness for which the order was
2405// arbitrarily chosen to be Big, Little.
2406//
2407// Predicate combinations available:
2408// [HasVSX]
2409// [HasVSX, IsBigEndian]
2410// [HasVSX, IsLittleEndian]
2411// [HasVSX, NoP9Vector]
2412// [HasVSX, HasOnlySwappingMemOps]
2413// [HasVSX, HasOnlySwappingMemOps, IsBigEndian]
2414// [HasVSX, HasP8Vector]
2415// [HasVSX, HasP8Vector, IsBigEndian]
2416// [HasVSX, HasP8Vector, IsLittleEndian]
2417// [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian]
2418// [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian]
2419// [HasVSX, HasDirectMove]
2420// [HasVSX, HasDirectMove, IsBigEndian]
2421// [HasVSX, HasDirectMove, IsLittleEndian]
2422// [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian]
2423// [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian]
2424// [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian]
2425// [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian]
2426// [HasVSX, HasP9Vector]
2427// [HasVSX, HasP9Vector, IsBigEndian]
2428// [HasVSX, HasP9Vector, IsLittleEndian]
2429// [HasVSX, HasP9Altivec]
2430// [HasVSX, HasP9Altivec, IsBigEndian]
2431// [HasVSX, HasP9Altivec, IsLittleEndian]
2432// [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian]
2433// [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian]
2434
2435let AddedComplexity = 400 in {
2436// Valid for any VSX subtarget, regardless of endianness.
2437let Predicates = [HasVSX] in {
2438def : Pat<(v4i32 (vnot_ppc v4i32:$A)),
2439          (v4i32 (XXLNOR $A, $A))>;
2440def : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A),
2441                     (and v4i32:$B, v4i32:$C))),
2442          (v4i32 (XXSEL $A, $B, $C))>;
2443
2444// Additional fnmsub pattern for PPC specific ISD opcode
2445def : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
2446          (XSNMSUBADP $C, $A, $B)>;
2447def : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
2448          (XSMSUBADP $C, $A, $B)>;
2449def : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
2450          (XSNMADDADP $C, $A, $B)>;
2451
2452def : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C),
2453          (XVNMSUBADP $C, $A, $B)>;
2454def : Pat<(fneg (PPCfnmsub v2f64:$A, v2f64:$B, v2f64:$C)),
2455          (XVMSUBADP $C, $A, $B)>;
2456def : Pat<(PPCfnmsub v2f64:$A, v2f64:$B, (fneg v2f64:$C)),
2457          (XVNMADDADP $C, $A, $B)>;
2458
2459def : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C),
2460          (XVNMSUBASP $C, $A, $B)>;
2461def : Pat<(fneg (PPCfnmsub v4f32:$A, v4f32:$B, v4f32:$C)),
2462          (XVMSUBASP $C, $A, $B)>;
2463def : Pat<(PPCfnmsub v4f32:$A, v4f32:$B, (fneg v4f32:$C)),
2464          (XVNMADDASP $C, $A, $B)>;
2465
2466def : Pat<(v2f64 (bitconvert v4f32:$A)),
2467          (COPY_TO_REGCLASS $A, VSRC)>;
2468def : Pat<(v2f64 (bitconvert v4i32:$A)),
2469          (COPY_TO_REGCLASS $A, VSRC)>;
2470def : Pat<(v2f64 (bitconvert v8i16:$A)),
2471          (COPY_TO_REGCLASS $A, VSRC)>;
2472def : Pat<(v2f64 (bitconvert v16i8:$A)),
2473          (COPY_TO_REGCLASS $A, VSRC)>;
2474
2475def : Pat<(v4f32 (bitconvert v2f64:$A)),
2476          (COPY_TO_REGCLASS $A, VRRC)>;
2477def : Pat<(v4i32 (bitconvert v2f64:$A)),
2478          (COPY_TO_REGCLASS $A, VRRC)>;
2479def : Pat<(v8i16 (bitconvert v2f64:$A)),
2480          (COPY_TO_REGCLASS $A, VRRC)>;
2481def : Pat<(v16i8 (bitconvert v2f64:$A)),
2482          (COPY_TO_REGCLASS $A, VRRC)>;
2483
2484def : Pat<(v2i64 (bitconvert v4f32:$A)),
2485          (COPY_TO_REGCLASS $A, VSRC)>;
2486def : Pat<(v2i64 (bitconvert v4i32:$A)),
2487          (COPY_TO_REGCLASS $A, VSRC)>;
2488def : Pat<(v2i64 (bitconvert v8i16:$A)),
2489          (COPY_TO_REGCLASS $A, VSRC)>;
2490def : Pat<(v2i64 (bitconvert v16i8:$A)),
2491          (COPY_TO_REGCLASS $A, VSRC)>;
2492
2493def : Pat<(v4f32 (bitconvert v2i64:$A)),
2494          (COPY_TO_REGCLASS $A, VRRC)>;
2495def : Pat<(v4i32 (bitconvert v2i64:$A)),
2496          (COPY_TO_REGCLASS $A, VRRC)>;
2497def : Pat<(v8i16 (bitconvert v2i64:$A)),
2498          (COPY_TO_REGCLASS $A, VRRC)>;
2499def : Pat<(v16i8 (bitconvert v2i64:$A)),
2500          (COPY_TO_REGCLASS $A, VRRC)>;
2501
2502def : Pat<(v2f64 (bitconvert v2i64:$A)),
2503          (COPY_TO_REGCLASS $A, VRRC)>;
2504def : Pat<(v2i64 (bitconvert v2f64:$A)),
2505          (COPY_TO_REGCLASS $A, VRRC)>;
2506
2507def : Pat<(v2f64 (bitconvert v1i128:$A)),
2508          (COPY_TO_REGCLASS $A, VRRC)>;
2509def : Pat<(v1i128 (bitconvert v2f64:$A)),
2510          (COPY_TO_REGCLASS $A, VRRC)>;
2511
2512def : Pat<(v2i64 (bitconvert f128:$A)),
2513          (COPY_TO_REGCLASS $A, VRRC)>;
2514def : Pat<(v4i32 (bitconvert f128:$A)),
2515          (COPY_TO_REGCLASS $A, VRRC)>;
2516def : Pat<(v8i16 (bitconvert f128:$A)),
2517          (COPY_TO_REGCLASS $A, VRRC)>;
2518def : Pat<(v16i8 (bitconvert f128:$A)),
2519          (COPY_TO_REGCLASS $A, VRRC)>;
2520
2521def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
2522          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
2523def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
2524          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
2525
2526def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
2527          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
2528def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
2529          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
2530
2531def : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
2532def : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
2533
2534// Permutes.
2535def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
2536def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
2537def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
2538def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
2539def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
2540
2541// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
2542// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
2543def : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)),
2544          (XXPERMDI $src, $src, 2)>;
2545
2546// Selects.
2547def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
2548          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2549def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
2550          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2551def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
2552          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2553def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
2554          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2555def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
2556          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
2557def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
2558          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2559def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
2560          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2561def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
2562          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2563def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
2564          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2565def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
2566          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
2567
2568def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
2569          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2570def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
2571          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2572def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
2573          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2574def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
2575          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2576def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
2577          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
2578def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
2579          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
2580def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
2581          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
2582def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
2583          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
2584def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
2585          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
2586def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
2587          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
2588
2589// Divides.
2590def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
2591          (XVDIVSP $A, $B)>;
2592def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
2593          (XVDIVDP $A, $B)>;
2594
2595// Vector test for software divide and sqrt.
2596def : Pat<(i32 (int_ppc_vsx_xvtdivdp v2f64:$A, v2f64:$B)),
2597          (COPY_TO_REGCLASS (XVTDIVDP $A, $B), GPRC)>;
2598def : Pat<(i32 (int_ppc_vsx_xvtdivsp v4f32:$A, v4f32:$B)),
2599          (COPY_TO_REGCLASS (XVTDIVSP $A, $B), GPRC)>;
2600def : Pat<(i32 (int_ppc_vsx_xvtsqrtdp v2f64:$A)),
2601          (COPY_TO_REGCLASS (XVTSQRTDP $A), GPRC)>;
2602def : Pat<(i32 (int_ppc_vsx_xvtsqrtsp v4f32:$A)),
2603          (COPY_TO_REGCLASS (XVTSQRTSP $A), GPRC)>;
2604
2605// Reciprocal estimate
2606def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
2607          (XVRESP $A)>;
2608def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
2609          (XVREDP $A)>;
2610
2611// Recip. square root estimate
2612def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
2613          (XVRSQRTESP $A)>;
2614def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
2615          (XVRSQRTEDP $A)>;
2616
2617// Vector selection
2618def : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
2619          (COPY_TO_REGCLASS
2620                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
2621                        (COPY_TO_REGCLASS $vB, VSRC),
2622                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
2623def : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
2624          (COPY_TO_REGCLASS
2625                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
2626                        (COPY_TO_REGCLASS $vB, VSRC),
2627                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
2628def : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
2629          (XXSEL $vC, $vB, $vA)>;
2630def : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
2631          (XXSEL $vC, $vB, $vA)>;
2632def : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
2633          (XXSEL $vC, $vB, $vA)>;
2634def : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
2635          (XXSEL $vC, $vB, $vA)>;
2636
2637def : Pat<(v4f32 (any_fmaxnum v4f32:$src1, v4f32:$src2)),
2638          (v4f32 (XVMAXSP $src1, $src2))>;
2639def : Pat<(v4f32 (any_fminnum v4f32:$src1, v4f32:$src2)),
2640          (v4f32 (XVMINSP $src1, $src2))>;
2641def : Pat<(v2f64 (any_fmaxnum v2f64:$src1, v2f64:$src2)),
2642          (v2f64 (XVMAXDP $src1, $src2))>;
2643def : Pat<(v2f64 (any_fminnum v2f64:$src1, v2f64:$src2)),
2644          (v2f64 (XVMINDP $src1, $src2))>;
2645
2646// f32 abs
2647def : Pat<(f32 (fabs f32:$S)),
2648          (f32 (COPY_TO_REGCLASS (XSABSDP
2649               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2650
2651// f32 nabs
2652def : Pat<(f32 (fneg (fabs f32:$S))),
2653          (f32 (COPY_TO_REGCLASS (XSNABSDP
2654               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2655
2656// f32 Min.
2657def : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)),
2658          (f32 FpMinMax.F32Min)>;
2659def : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)),
2660          (f32 FpMinMax.F32Min)>;
2661def : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))),
2662          (f32 FpMinMax.F32Min)>;
2663def : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
2664          (f32 FpMinMax.F32Min)>;
2665// F32 Max.
2666def : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)),
2667          (f32 FpMinMax.F32Max)>;
2668def : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)),
2669          (f32 FpMinMax.F32Max)>;
2670def : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))),
2671          (f32 FpMinMax.F32Max)>;
2672def : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
2673          (f32 FpMinMax.F32Max)>;
2674
2675// f64 Min.
2676def : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)),
2677          (f64 (XSMINDP $A, $B))>;
2678def : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)),
2679          (f64 (XSMINDP $A, $B))>;
2680def : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))),
2681          (f64 (XSMINDP $A, $B))>;
2682def : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
2683          (f64 (XSMINDP $A, $B))>;
2684// f64 Max.
2685def : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)),
2686          (f64 (XSMAXDP $A, $B))>;
2687def : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)),
2688          (f64 (XSMAXDP $A, $B))>;
2689def : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))),
2690          (f64 (XSMAXDP $A, $B))>;
2691def : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
2692          (f64 (XSMAXDP $A, $B))>;
2693
2694def : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
2695            (STXVD2X $rS, xoaddr:$dst)>;
2696def : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
2697            (STXVW4X $rS, xoaddr:$dst)>;
2698def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2699def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2700
2701// Rounding for single precision.
2702def : Pat<(f32 (any_fround f32:$S)),
2703          (f32 (COPY_TO_REGCLASS (XSRDPI
2704                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2705def : Pat<(f32 (fnearbyint f32:$S)),
2706          (f32 (COPY_TO_REGCLASS (XSRDPIC
2707                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2708def : Pat<(f32 (any_ffloor f32:$S)),
2709          (f32 (COPY_TO_REGCLASS (XSRDPIM
2710                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2711def : Pat<(f32 (any_fceil f32:$S)),
2712          (f32 (COPY_TO_REGCLASS (XSRDPIP
2713                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2714def : Pat<(f32 (any_ftrunc f32:$S)),
2715          (f32 (COPY_TO_REGCLASS (XSRDPIZ
2716                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2717def : Pat<(f32 (any_frint f32:$S)),
2718          (f32 (COPY_TO_REGCLASS (XSRDPIC
2719                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2720def : Pat<(v4f32 (any_frint v4f32:$S)), (v4f32 (XVRSPIC $S))>;
2721
2722// Rounding for double precision.
2723def : Pat<(f64 (any_frint f64:$S)), (f64 (XSRDPIC $S))>;
2724def : Pat<(v2f64 (any_frint v2f64:$S)), (v2f64 (XVRDPIC $S))>;
2725
2726// Materialize a zero-vector of long long
2727def : Pat<(v2i64 immAllZerosV),
2728          (v2i64 (XXLXORz))>;
2729
2730// Build vectors of floating point converted to i32.
2731def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
2732                               DblToInt.A, DblToInt.A)),
2733          (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
2734def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
2735                               DblToUInt.A, DblToUInt.A)),
2736          (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
2737def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
2738          (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
2739                           (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
2740def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
2741          (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
2742                           (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
2743defm : ScalToVecWPermute<
2744  v4i32, FltToIntLoad.A,
2745  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1),
2746  (COPY_TO_REGCLASS (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC)>;
2747defm : ScalToVecWPermute<
2748  v4i32, FltToUIntLoad.A,
2749  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1),
2750  (COPY_TO_REGCLASS (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC)>;
2751def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
2752          (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
2753def : Pat<(v2f64 (PPCldsplat xoaddr:$A)),
2754          (v2f64 (LXVDSX xoaddr:$A))>;
2755def : Pat<(v2i64 (PPCldsplat xoaddr:$A)),
2756          (v2i64 (LXVDSX xoaddr:$A))>;
2757
2758// Build vectors of floating point converted to i64.
2759def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
2760          (v2i64 (XXPERMDIs
2761                   (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
2762def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
2763          (v2i64 (XXPERMDIs
2764                   (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
2765defm : ScalToVecWPermute<
2766  v2i64, DblToLongLoad.A,
2767  (XVCVDPSXDS (LXVDSX xoaddr:$A)), (XVCVDPSXDS (LXVDSX xoaddr:$A))>;
2768defm : ScalToVecWPermute<
2769  v2i64, DblToULongLoad.A,
2770  (XVCVDPUXDS (LXVDSX xoaddr:$A)), (XVCVDPUXDS (LXVDSX xoaddr:$A))>;
2771} // HasVSX
2772
2773// Any big endian VSX subtarget.
2774let Predicates = [HasVSX, IsBigEndian] in {
2775def : Pat<(v2f64 (scalar_to_vector f64:$A)),
2776          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
2777
2778def : Pat<(f64 (extractelt v2f64:$S, 0)),
2779          (f64 (EXTRACT_SUBREG $S, sub_64))>;
2780def : Pat<(f64 (extractelt v2f64:$S, 1)),
2781          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
2782def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2783          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
2784def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2785          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2786def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2787          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
2788def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2789          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2790
2791def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2792          (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
2793
2794def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2795          (v2f64 (XXPERMDI
2796                    (COPY_TO_REGCLASS $A, VSRC),
2797                    (COPY_TO_REGCLASS $B, VSRC), 0))>;
2798// Using VMRGEW to assemble the final vector would be a lower latency
2799// solution. However, we choose to go with the slightly higher latency
2800// XXPERMDI for 2 reasons:
2801// 1. This is likely to occur in unrolled loops where regpressure is high,
2802//    so we want to use the latter as it has access to all 64 VSX registers.
2803// 2. Using Altivec instructions in this sequence would likely cause the
2804//    allocation of Altivec registers even for the loads which in turn would
2805//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2806//    each of the loads which would otherwise be able to use LFIWZX.
2807def : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2808          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B),
2809                           (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>;
2810def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
2811          (VMRGEW MrgFP.AC, MrgFP.BD)>;
2812def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2813                               DblToFlt.B0, DblToFlt.B1)),
2814          (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
2815
2816// Convert 4 doubles to a vector of ints.
2817def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
2818                               DblToInt.C, DblToInt.D)),
2819          (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
2820def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
2821                               DblToUInt.C, DblToUInt.D)),
2822          (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
2823def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
2824                               ExtDbl.B0S, ExtDbl.B1S)),
2825          (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
2826def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
2827                               ExtDbl.B0U, ExtDbl.B1U)),
2828          (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
2829def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2830                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
2831          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
2832def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2833                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
2834          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
2835                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
2836def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2837                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2838          (v2f64 (XVCVSPDP $A))>;
2839def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2840                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2841          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 3)))>;
2842def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
2843                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2844          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
2845def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2846                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2847          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
2848                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
2849def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2850                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
2851          (v2f64 (XVCVSPDP (XXPERMDI $A, $B, 0)))>;
2852def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2853                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
2854          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $A, $B, 3),
2855                                    (XXPERMDI $A, $B, 3), 1)))>;
2856def : Pat<WToDPExtractConv.BV02S,
2857          (v2f64 (XVCVSXWDP $A))>;
2858def : Pat<WToDPExtractConv.BV13S,
2859          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 3)))>;
2860def : Pat<WToDPExtractConv.BV02U,
2861          (v2f64 (XVCVUXWDP $A))>;
2862def : Pat<WToDPExtractConv.BV13U,
2863          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 3)))>;
2864} // HasVSX, IsBigEndian
2865
2866// Any little endian VSX subtarget.
2867let Predicates = [HasVSX, IsLittleEndian] in {
2868defm : ScalToVecWPermute<v2f64, (f64 f64:$A),
2869                         (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
2870                                   (SUBREG_TO_REG (i64 1), $A, sub_64), 0),
2871                         (SUBREG_TO_REG (i64 1), $A, sub_64)>;
2872
2873def : Pat<(f64 (extractelt v2f64:$S, 0)),
2874          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
2875def : Pat<(f64 (extractelt v2f64:$S, 1)),
2876          (f64 (EXTRACT_SUBREG $S, sub_64))>;
2877
2878def : Pat<(v2f64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2879def : Pat<(PPCst_vec_be v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2880def : Pat<(v4f32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2881def : Pat<(PPCst_vec_be v4f32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
2882def : Pat<(v2i64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2883def : Pat<(PPCst_vec_be v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
2884def : Pat<(v4i32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2885def : Pat<(PPCst_vec_be v4i32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
2886def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2887          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2888def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2889          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
2890def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
2891          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
2892def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
2893          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
2894
2895def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2896          (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
2897
2898// Little endian, available on all targets with VSX
2899def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2900          (v2f64 (XXPERMDI
2901                    (COPY_TO_REGCLASS $B, VSRC),
2902                    (COPY_TO_REGCLASS $A, VSRC), 0))>;
2903// Using VMRGEW to assemble the final vector would be a lower latency
2904// solution. However, we choose to go with the slightly higher latency
2905// XXPERMDI for 2 reasons:
2906// 1. This is likely to occur in unrolled loops where regpressure is high,
2907//    so we want to use the latter as it has access to all 64 VSX registers.
2908// 2. Using Altivec instructions in this sequence would likely cause the
2909//    allocation of Altivec registers even for the loads which in turn would
2910//    force the use of LXSIWZX for the loads, adding a cycle of latency to
2911//    each of the loads which would otherwise be able to use LFIWZX.
2912def : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
2913          (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C),
2914                           (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>;
2915def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
2916          (VMRGEW MrgFP.AC, MrgFP.BD)>;
2917def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2918                               DblToFlt.B0, DblToFlt.B1)),
2919          (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
2920
2921// Convert 4 doubles to a vector of ints.
2922def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
2923                               DblToInt.C, DblToInt.D)),
2924          (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
2925def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
2926                               DblToUInt.C, DblToUInt.D)),
2927          (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
2928def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
2929                               ExtDbl.B0S, ExtDbl.B1S)),
2930          (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
2931def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
2932                               ExtDbl.B0U, ExtDbl.B1U)),
2933          (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
2934def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2935                               (f64 (fpextend (extractelt v4f32:$A, 1))))),
2936          (v2f64 (XVCVSPDP (XXMRGLW $A, $A)))>;
2937def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2938                               (f64 (fpextend (extractelt v4f32:$A, 0))))),
2939          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGLW $A, $A)),
2940                           (XVCVSPDP (XXMRGLW $A, $A)), 2))>;
2941def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2942                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2943          (v2f64 (XVCVSPDP (XXSLDWI $A, $A, 1)))>;
2944def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 1))),
2945                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2946          (v2f64 (XVCVSPDP $A))>;
2947def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 2))),
2948                               (f64 (fpextend (extractelt v4f32:$A, 3))))),
2949          (v2f64 (XVCVSPDP (XXMRGHW $A, $A)))>;
2950def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2951                               (f64 (fpextend (extractelt v4f32:$A, 2))))),
2952          (v2f64 (XXPERMDI (XVCVSPDP (XXMRGHW $A, $A)),
2953                           (XVCVSPDP (XXMRGHW $A, $A)), 2))>;
2954def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 0))),
2955                               (f64 (fpextend (extractelt v4f32:$B, 0))))),
2956          (v2f64 (XVCVSPDP (XXSLDWI (XXPERMDI $B, $A, 3),
2957                                    (XXPERMDI $B, $A, 3), 1)))>;
2958def : Pat<(v2f64 (build_vector (f64 (fpextend (extractelt v4f32:$A, 3))),
2959                               (f64 (fpextend (extractelt v4f32:$B, 3))))),
2960          (v2f64 (XVCVSPDP (XXPERMDI $B, $A, 0)))>;
2961def : Pat<WToDPExtractConv.BV02S,
2962          (v2f64 (XVCVSXWDP (XXSLDWI $A, $A, 1)))>;
2963def : Pat<WToDPExtractConv.BV13S,
2964          (v2f64 (XVCVSXWDP $A))>;
2965def : Pat<WToDPExtractConv.BV02U,
2966          (v2f64 (XVCVUXWDP (XXSLDWI $A, $A, 1)))>;
2967def : Pat<WToDPExtractConv.BV13U,
2968          (v2f64 (XVCVUXWDP $A))>;
2969} // HasVSX, IsLittleEndian
2970
2971// Any pre-Power9 VSX subtarget.
2972let Predicates = [HasVSX, NoP9Vector] in {
2973def : Pat<(PPCstore_scal_int_from_vsr
2974            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
2975          (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
2976def : Pat<(PPCstore_scal_int_from_vsr
2977            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
2978          (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
2979
2980// Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
2981defm : ScalToVecWPermute<
2982  v4i32, DblToIntLoad.A,
2983  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1),
2984  (COPY_TO_REGCLASS (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC)>;
2985defm : ScalToVecWPermute<
2986  v4i32, DblToUIntLoad.A,
2987  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1),
2988  (COPY_TO_REGCLASS (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC)>;
2989defm : ScalToVecWPermute<
2990  v2i64, FltToLongLoad.A,
2991  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A), VSFRC)), 0),
2992  (SUBREG_TO_REG (i64 1), (XSCVDPSXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A),
2993                                                        VSFRC)), sub_64)>;
2994defm : ScalToVecWPermute<
2995  v2i64, FltToULongLoad.A,
2996  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A), VSFRC)), 0),
2997  (SUBREG_TO_REG (i64 1), (XSCVDPUXDS (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$A),
2998                                                        VSFRC)), sub_64)>;
2999} // HasVSX, NoP9Vector
3000
3001// Any VSX subtarget that only has loads and stores that load in big endian
3002// order regardless of endianness. This is really pre-Power9 subtargets.
3003let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
3004  def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
3005
3006  // Stores.
3007  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
3008            (STXVD2X $rS, xoaddr:$dst)>;
3009  def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
3010} // HasVSX, HasOnlySwappingMemOps
3011
3012// Big endian VSX subtarget that only has loads and stores that always load
3013// in big endian order. Really big endian pre-Power9 subtargets.
3014let Predicates = [HasVSX, HasOnlySwappingMemOps, IsBigEndian] in {
3015  def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
3016  def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
3017  def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
3018  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
3019  def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
3020  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
3021  def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
3022  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3023            (STXVW4X $rS, xoaddr:$dst)>;
3024} // HasVSX, HasOnlySwappingMemOps, IsBigEndian
3025
3026// Any Power8 VSX subtarget.
3027let Predicates = [HasVSX, HasP8Vector] in {
3028def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
3029          (XXLEQV $A, $B)>;
3030def : Pat<(f64 (extloadf32 xoaddr:$src)),
3031          (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
3032def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
3033          (f32 (XFLOADf32 xoaddr:$src))>;
3034def : Pat<(f64 (any_fpextend f32:$src)),
3035          (COPY_TO_REGCLASS $src, VSFRC)>;
3036
3037def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
3038          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
3039def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
3040          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
3041def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
3042          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
3043def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
3044          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
3045def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
3046          (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
3047def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
3048          (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
3049def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
3050          (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
3051def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
3052          (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
3053def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
3054          (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
3055def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
3056          (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
3057
3058// Additional fnmsub pattern for PPC specific ISD opcode
3059def : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
3060          (XSNMSUBASP $C, $A, $B)>;
3061def : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
3062          (XSMSUBASP $C, $A, $B)>;
3063def : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
3064          (XSNMADDASP $C, $A, $B)>;
3065
3066// f32 neg
3067// Although XSNEGDP is available in P7, we want to select it starting from P8,
3068// so that FNMSUBS can be selected for fneg-fmsub pattern on P7. (VSX version,
3069// XSNMSUBASP, is available since P8)
3070def : Pat<(f32 (fneg f32:$S)),
3071          (f32 (COPY_TO_REGCLASS (XSNEGDP
3072               (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
3073
3074// Instructions for converting float to i32 feeding a store.
3075def : Pat<(PPCstore_scal_int_from_vsr
3076            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
3077          (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3078def : Pat<(PPCstore_scal_int_from_vsr
3079            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
3080          (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3081
3082def : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
3083          (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
3084                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3085def : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
3086          (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
3087                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3088def : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
3089          (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
3090                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3091def : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
3092          (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
3093                         (COPY_TO_REGCLASS $src2, VRRC)))>;
3094
3095def : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
3096          (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3097def : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
3098          (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3099def : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
3100          (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3101def : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
3102          (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
3103} // HasVSX, HasP8Vector
3104
3105// Big endian Power8 VSX subtarget.
3106let Predicates = [HasVSX, HasP8Vector, IsBigEndian] in {
3107def : Pat<DWToSPExtractConv.El0SS1,
3108          (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
3109def : Pat<DWToSPExtractConv.El1SS1,
3110          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3111def : Pat<DWToSPExtractConv.El0US1,
3112          (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
3113def : Pat<DWToSPExtractConv.El1US1,
3114          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3115
3116// v4f32 scalar <-> vector conversions (BE)
3117def : Pat<(v4f32 (scalar_to_vector f32:$A)),
3118          (v4f32 (XSCVDPSPN $A))>;
3119def : Pat<(f32 (vector_extract v4f32:$S, 0)),
3120          (f32 (XSCVSPDPN $S))>;
3121def : Pat<(f32 (vector_extract v4f32:$S, 1)),
3122          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
3123def : Pat<(f32 (vector_extract v4f32:$S, 2)),
3124          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
3125def : Pat<(f32 (vector_extract v4f32:$S, 3)),
3126          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
3127def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
3128          (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
3129
3130def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3131          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
3132def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3133          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
3134def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3135          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
3136def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3137          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
3138def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3139          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
3140def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3141          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
3142def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3143          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
3144def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3145          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
3146
3147// LIWAX - This instruction is used for sign extending i32 -> i64.
3148// LIWZX - This instruction will be emitted for i32, f32, and when
3149//         zero-extending i32 to i64 (zext i32 -> i64).
3150def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
3151          (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
3152def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
3153          (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
3154def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3155          (v4i32 (XXSLDWIs
3156          (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3157def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3158          (v4f32 (XXSLDWIs
3159          (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3160
3161def : Pat<DWToSPExtractConv.BVU,
3162          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
3163                          (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
3164def : Pat<DWToSPExtractConv.BVS,
3165          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
3166                          (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
3167def : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src),
3168          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3169def : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src),
3170          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3171
3172// Elements in a register on a BE system are in order <0, 1, 2, 3>.
3173// The store instructions store the second word from the left.
3174// So to align element zero, we need to modulo-left-shift by 3 words.
3175// Similar logic applies for elements 2 and 3.
3176foreach Idx = [ [0,3], [2,1], [3,2] ] in {
3177  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
3178            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3179                                   sub_64), xoaddr:$src)>;
3180  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
3181            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3182                                   sub_64), xoaddr:$src)>;
3183}
3184} // HasVSX, HasP8Vector, IsBigEndian
3185
3186// Little endian Power8 VSX subtarget.
3187let Predicates = [HasVSX, HasP8Vector, IsLittleEndian] in {
3188def : Pat<DWToSPExtractConv.El0SS1,
3189          (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3190def : Pat<DWToSPExtractConv.El1SS1,
3191          (f32 (XSCVSXDSP (COPY_TO_REGCLASS
3192                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
3193def : Pat<DWToSPExtractConv.El0US1,
3194          (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
3195def : Pat<DWToSPExtractConv.El1US1,
3196          (f32 (XSCVUXDSP (COPY_TO_REGCLASS
3197                            (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
3198
3199// v4f32 scalar <-> vector conversions (LE)
3200  // The permuted version is no better than the version that puts the value
3201  // into the right element because XSCVDPSPN is different from all the other
3202  // instructions used for PPCSToV.
3203  defm : ScalToVecWPermute<v4f32, (f32 f32:$A),
3204                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1),
3205                           (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 3)>;
3206def : Pat<(f32 (vector_extract v4f32:$S, 0)),
3207          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
3208def : Pat<(f32 (vector_extract v4f32:$S, 1)),
3209          (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
3210def : Pat<(f32 (vector_extract v4f32:$S, 2)),
3211          (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
3212def : Pat<(f32 (vector_extract v4f32:$S, 3)),
3213          (f32 (XSCVSPDPN $S))>;
3214def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
3215          (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
3216
3217def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3218          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
3219def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3220          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
3221def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3222          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
3223def : Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3224          (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
3225def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3226          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
3227def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3228          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
3229def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3230          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
3231def : Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3232          (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
3233
3234// LIWAX - This instruction is used for sign extending i32 -> i64.
3235// LIWZX - This instruction will be emitted for i32, f32, and when
3236//         zero-extending i32 to i64 (zext i32 -> i64).
3237defm : ScalToVecWPermute<
3238  v2i64, (i64 (sextloadi32 xoaddr:$src)),
3239  (XXPERMDIs (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSFRC), 2),
3240  (SUBREG_TO_REG (i64 1), (LIWAX xoaddr:$src), sub_64)>;
3241
3242defm : ScalToVecWPermute<
3243  v2i64, (i64 (zextloadi32 xoaddr:$src)),
3244  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
3245  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
3246
3247defm : ScalToVecWPermute<
3248  v4i32, (i32 (load xoaddr:$src)),
3249  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
3250  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
3251
3252defm : ScalToVecWPermute<
3253  v4f32, (f32 (load xoaddr:$src)),
3254  (XXPERMDIs (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSFRC), 2),
3255  (SUBREG_TO_REG (i64 1), (LIWZX xoaddr:$src), sub_64)>;
3256
3257def : Pat<DWToSPExtractConv.BVU,
3258          (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
3259                          (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
3260def : Pat<DWToSPExtractConv.BVS,
3261          (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
3262                          (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
3263def : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src),
3264          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3265def : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src),
3266          (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3267
3268// Elements in a register on a LE system are in order <3, 2, 1, 0>.
3269// The store instructions store the second word from the left.
3270// So to align element 3, we need to modulo-left-shift by 3 words.
3271// Similar logic applies for elements 0 and 1.
3272foreach Idx = [ [0,2], [1,1], [3,3] ] in {
3273  def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
3274            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3275                                   sub_64), xoaddr:$src)>;
3276  def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
3277            (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3278                                   sub_64), xoaddr:$src)>;
3279}
3280} // HasVSX, HasP8Vector, IsLittleEndian
3281
3282// Big endian pre-Power9 VSX subtarget.
3283let Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsBigEndian] in {
3284def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
3285          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3286def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
3287          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3288def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
3289          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3290                      xoaddr:$src)>;
3291def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
3292          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3293                      xoaddr:$src)>;
3294} // HasVSX, HasP8Vector, NoP9Vector, IsBigEndian
3295
3296// Little endian pre-Power9 VSX subtarget.
3297let Predicates = [HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian] in {
3298def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
3299          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3300                      xoaddr:$src)>;
3301def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
3302          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3303                      xoaddr:$src)>;
3304def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
3305          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3306def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
3307          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3308} // HasVSX, HasP8Vector, NoP9Vector, IsLittleEndian
3309
3310// Any VSX target with direct moves.
3311let Predicates = [HasVSX, HasDirectMove] in {
3312// bitconvert f32 -> i32
3313// (convert to 32-bit fp single, shift right 1 word, move to GPR)
3314def : Pat<(i32 (bitconvert f32:$S)),
3315          (i32 (MFVSRWZ (EXTRACT_SUBREG
3316                          (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
3317                          sub_64)))>;
3318// bitconvert i32 -> f32
3319// (move to FPR, shift left 1 word, convert to 64-bit fp single)
3320def : Pat<(f32 (bitconvert i32:$A)),
3321          (f32 (XSCVSPDPN
3322                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
3323
3324// bitconvert f64 -> i64
3325// (move to GPR, nothing else needed)
3326def : Pat<(i64 (bitconvert f64:$S)),
3327          (i64 (MFVSRD $S))>;
3328
3329// bitconvert i64 -> f64
3330// (move to FPR, nothing else needed)
3331def : Pat<(f64 (bitconvert i64:$S)),
3332          (f64 (MTVSRD $S))>;
3333
3334// Rounding to integer.
3335def : Pat<(i64 (lrint f64:$S)),
3336          (i64 (MFVSRD (FCTID $S)))>;
3337def : Pat<(i64 (lrint f32:$S)),
3338          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
3339def : Pat<(i64 (llrint f64:$S)),
3340          (i64 (MFVSRD (FCTID $S)))>;
3341def : Pat<(i64 (llrint f32:$S)),
3342          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
3343def : Pat<(i64 (lround f64:$S)),
3344          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
3345def : Pat<(i64 (lround f32:$S)),
3346          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
3347def : Pat<(i64 (llround f64:$S)),
3348          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
3349def : Pat<(i64 (llround f32:$S)),
3350          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
3351
3352// Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
3353// of f64
3354def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
3355          (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
3356def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
3357          (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
3358
3359// Endianness-neutral constant splat on P8 and newer targets. The reason
3360// for this pattern is that on targets with direct moves, we don't expand
3361// BUILD_VECTOR nodes for v4i32.
3362def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
3363                               immSExt5NonZero:$A, immSExt5NonZero:$A)),
3364          (v4i32 (VSPLTISW imm:$A))>;
3365} // HasVSX, HasDirectMove
3366
3367// Big endian VSX subtarget with direct moves.
3368let Predicates = [HasVSX, HasDirectMove, IsBigEndian] in {
3369// v16i8 scalar <-> vector conversions (BE)
3370def : Pat<(v16i8 (scalar_to_vector i32:$A)),
3371          (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
3372def : Pat<(v8i16 (scalar_to_vector i32:$A)),
3373          (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
3374def : Pat<(v4i32 (scalar_to_vector i32:$A)),
3375          (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
3376def : Pat<(v2i64 (scalar_to_vector i64:$A)),
3377          (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
3378
3379// v2i64 scalar <-> vector conversions (BE)
3380def : Pat<(i64 (vector_extract v2i64:$S, 0)),
3381          (i64 VectorExtractions.LE_DWORD_1)>;
3382def : Pat<(i64 (vector_extract v2i64:$S, 1)),
3383          (i64 VectorExtractions.LE_DWORD_0)>;
3384def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
3385          (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
3386} // HasVSX, HasDirectMove, IsBigEndian
3387
3388// Little endian VSX subtarget with direct moves.
3389let Predicates = [HasVSX, HasDirectMove, IsLittleEndian] in {
3390  // v16i8 scalar <-> vector conversions (LE)
3391  defm : ScalToVecWPermute<v16i8, (i32 i32:$A),
3392                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
3393                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
3394  defm : ScalToVecWPermute<v8i16, (i32 i32:$A),
3395                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC),
3396                           (COPY_TO_REGCLASS MovesToVSR.LE_WORD_1, VSRC)>;
3397  defm : ScalToVecWPermute<v4i32, (i32 i32:$A), MovesToVSR.LE_WORD_0,
3398                           (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64)>;
3399  defm : ScalToVecWPermute<v2i64, (i64 i64:$A), MovesToVSR.LE_DWORD_0,
3400                           MovesToVSR.LE_DWORD_1>;
3401
3402  // v2i64 scalar <-> vector conversions (LE)
3403  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
3404            (i64 VectorExtractions.LE_DWORD_0)>;
3405  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
3406            (i64 VectorExtractions.LE_DWORD_1)>;
3407  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
3408            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
3409} // HasVSX, HasDirectMove, IsLittleEndian
3410
3411// Big endian pre-P9 VSX subtarget with direct moves.
3412let Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian] in {
3413def : Pat<(i32 (vector_extract v16i8:$S, 0)),
3414          (i32 VectorExtractions.LE_BYTE_15)>;
3415def : Pat<(i32 (vector_extract v16i8:$S, 1)),
3416          (i32 VectorExtractions.LE_BYTE_14)>;
3417def : Pat<(i32 (vector_extract v16i8:$S, 2)),
3418          (i32 VectorExtractions.LE_BYTE_13)>;
3419def : Pat<(i32 (vector_extract v16i8:$S, 3)),
3420          (i32 VectorExtractions.LE_BYTE_12)>;
3421def : Pat<(i32 (vector_extract v16i8:$S, 4)),
3422          (i32 VectorExtractions.LE_BYTE_11)>;
3423def : Pat<(i32 (vector_extract v16i8:$S, 5)),
3424          (i32 VectorExtractions.LE_BYTE_10)>;
3425def : Pat<(i32 (vector_extract v16i8:$S, 6)),
3426          (i32 VectorExtractions.LE_BYTE_9)>;
3427def : Pat<(i32 (vector_extract v16i8:$S, 7)),
3428          (i32 VectorExtractions.LE_BYTE_8)>;
3429def : Pat<(i32 (vector_extract v16i8:$S, 8)),
3430          (i32 VectorExtractions.LE_BYTE_7)>;
3431def : Pat<(i32 (vector_extract v16i8:$S, 9)),
3432          (i32 VectorExtractions.LE_BYTE_6)>;
3433def : Pat<(i32 (vector_extract v16i8:$S, 10)),
3434          (i32 VectorExtractions.LE_BYTE_5)>;
3435def : Pat<(i32 (vector_extract v16i8:$S, 11)),
3436          (i32 VectorExtractions.LE_BYTE_4)>;
3437def : Pat<(i32 (vector_extract v16i8:$S, 12)),
3438          (i32 VectorExtractions.LE_BYTE_3)>;
3439def : Pat<(i32 (vector_extract v16i8:$S, 13)),
3440          (i32 VectorExtractions.LE_BYTE_2)>;
3441def : Pat<(i32 (vector_extract v16i8:$S, 14)),
3442          (i32 VectorExtractions.LE_BYTE_1)>;
3443def : Pat<(i32 (vector_extract v16i8:$S, 15)),
3444          (i32 VectorExtractions.LE_BYTE_0)>;
3445def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
3446          (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
3447
3448// v8i16 scalar <-> vector conversions (BE)
3449def : Pat<(i32 (vector_extract v8i16:$S, 0)),
3450          (i32 VectorExtractions.LE_HALF_7)>;
3451def : Pat<(i32 (vector_extract v8i16:$S, 1)),
3452          (i32 VectorExtractions.LE_HALF_6)>;
3453def : Pat<(i32 (vector_extract v8i16:$S, 2)),
3454          (i32 VectorExtractions.LE_HALF_5)>;
3455def : Pat<(i32 (vector_extract v8i16:$S, 3)),
3456          (i32 VectorExtractions.LE_HALF_4)>;
3457def : Pat<(i32 (vector_extract v8i16:$S, 4)),
3458          (i32 VectorExtractions.LE_HALF_3)>;
3459def : Pat<(i32 (vector_extract v8i16:$S, 5)),
3460          (i32 VectorExtractions.LE_HALF_2)>;
3461def : Pat<(i32 (vector_extract v8i16:$S, 6)),
3462          (i32 VectorExtractions.LE_HALF_1)>;
3463def : Pat<(i32 (vector_extract v8i16:$S, 7)),
3464          (i32 VectorExtractions.LE_HALF_0)>;
3465def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
3466          (i32 VectorExtractions.BE_VARIABLE_HALF)>;
3467
3468// v4i32 scalar <-> vector conversions (BE)
3469def : Pat<(i32 (vector_extract v4i32:$S, 0)),
3470          (i32 VectorExtractions.LE_WORD_3)>;
3471def : Pat<(i32 (vector_extract v4i32:$S, 1)),
3472          (i32 VectorExtractions.LE_WORD_2)>;
3473def : Pat<(i32 (vector_extract v4i32:$S, 2)),
3474          (i32 VectorExtractions.LE_WORD_1)>;
3475def : Pat<(i32 (vector_extract v4i32:$S, 3)),
3476          (i32 VectorExtractions.LE_WORD_0)>;
3477def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
3478          (i32 VectorExtractions.BE_VARIABLE_WORD)>;
3479} // HasVSX, HasDirectMove, NoP9Altivec, IsBigEndian
3480
3481// Little endian pre-P9 VSX subtarget with direct moves.
3482let Predicates = [HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian] in {
3483def : Pat<(i32 (vector_extract v16i8:$S, 0)),
3484          (i32 VectorExtractions.LE_BYTE_0)>;
3485def : Pat<(i32 (vector_extract v16i8:$S, 1)),
3486          (i32 VectorExtractions.LE_BYTE_1)>;
3487def : Pat<(i32 (vector_extract v16i8:$S, 2)),
3488          (i32 VectorExtractions.LE_BYTE_2)>;
3489def : Pat<(i32 (vector_extract v16i8:$S, 3)),
3490          (i32 VectorExtractions.LE_BYTE_3)>;
3491def : Pat<(i32 (vector_extract v16i8:$S, 4)),
3492          (i32 VectorExtractions.LE_BYTE_4)>;
3493def : Pat<(i32 (vector_extract v16i8:$S, 5)),
3494          (i32 VectorExtractions.LE_BYTE_5)>;
3495def : Pat<(i32 (vector_extract v16i8:$S, 6)),
3496          (i32 VectorExtractions.LE_BYTE_6)>;
3497def : Pat<(i32 (vector_extract v16i8:$S, 7)),
3498          (i32 VectorExtractions.LE_BYTE_7)>;
3499def : Pat<(i32 (vector_extract v16i8:$S, 8)),
3500          (i32 VectorExtractions.LE_BYTE_8)>;
3501def : Pat<(i32 (vector_extract v16i8:$S, 9)),
3502          (i32 VectorExtractions.LE_BYTE_9)>;
3503def : Pat<(i32 (vector_extract v16i8:$S, 10)),
3504          (i32 VectorExtractions.LE_BYTE_10)>;
3505def : Pat<(i32 (vector_extract v16i8:$S, 11)),
3506          (i32 VectorExtractions.LE_BYTE_11)>;
3507def : Pat<(i32 (vector_extract v16i8:$S, 12)),
3508          (i32 VectorExtractions.LE_BYTE_12)>;
3509def : Pat<(i32 (vector_extract v16i8:$S, 13)),
3510          (i32 VectorExtractions.LE_BYTE_13)>;
3511def : Pat<(i32 (vector_extract v16i8:$S, 14)),
3512          (i32 VectorExtractions.LE_BYTE_14)>;
3513def : Pat<(i32 (vector_extract v16i8:$S, 15)),
3514          (i32 VectorExtractions.LE_BYTE_15)>;
3515def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
3516          (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
3517
3518// v8i16 scalar <-> vector conversions (LE)
3519def : Pat<(i32 (vector_extract v8i16:$S, 0)),
3520          (i32 VectorExtractions.LE_HALF_0)>;
3521def : Pat<(i32 (vector_extract v8i16:$S, 1)),
3522          (i32 VectorExtractions.LE_HALF_1)>;
3523def : Pat<(i32 (vector_extract v8i16:$S, 2)),
3524          (i32 VectorExtractions.LE_HALF_2)>;
3525def : Pat<(i32 (vector_extract v8i16:$S, 3)),
3526          (i32 VectorExtractions.LE_HALF_3)>;
3527def : Pat<(i32 (vector_extract v8i16:$S, 4)),
3528          (i32 VectorExtractions.LE_HALF_4)>;
3529def : Pat<(i32 (vector_extract v8i16:$S, 5)),
3530          (i32 VectorExtractions.LE_HALF_5)>;
3531def : Pat<(i32 (vector_extract v8i16:$S, 6)),
3532          (i32 VectorExtractions.LE_HALF_6)>;
3533def : Pat<(i32 (vector_extract v8i16:$S, 7)),
3534          (i32 VectorExtractions.LE_HALF_7)>;
3535def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
3536          (i32 VectorExtractions.LE_VARIABLE_HALF)>;
3537
3538// v4i32 scalar <-> vector conversions (LE)
3539def : Pat<(i32 (vector_extract v4i32:$S, 0)),
3540          (i32 VectorExtractions.LE_WORD_0)>;
3541def : Pat<(i32 (vector_extract v4i32:$S, 1)),
3542          (i32 VectorExtractions.LE_WORD_1)>;
3543def : Pat<(i32 (vector_extract v4i32:$S, 2)),
3544          (i32 VectorExtractions.LE_WORD_2)>;
3545def : Pat<(i32 (vector_extract v4i32:$S, 3)),
3546          (i32 VectorExtractions.LE_WORD_3)>;
3547def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
3548          (i32 VectorExtractions.LE_VARIABLE_WORD)>;
3549} // HasVSX, HasDirectMove, NoP9Altivec, IsLittleEndian
3550
3551// Big endian pre-Power9 VSX subtarget that has direct moves.
3552let Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsBigEndian] in {
3553// Big endian integer vectors using direct moves.
3554def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3555          (v2i64 (XXPERMDI
3556                    (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
3557                    (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
3558def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3559          (XXPERMDI
3560            (COPY_TO_REGCLASS
3561              (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
3562            (COPY_TO_REGCLASS
3563              (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
3564def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3565          (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3566} // HasVSX, HasDirectMove, NoP9Vector, IsBigEndian
3567
3568// Little endian pre-Power9 VSX subtarget that has direct moves.
3569let Predicates = [HasVSX, HasDirectMove, NoP9Vector, IsLittleEndian] in {
3570// Little endian integer vectors using direct moves.
3571def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3572          (v2i64 (XXPERMDI
3573                    (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
3574                    (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
3575def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3576          (XXPERMDI
3577            (COPY_TO_REGCLASS
3578              (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
3579            (COPY_TO_REGCLASS
3580              (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
3581def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3582          (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3583}
3584
3585// Any Power9 VSX subtarget.
3586let Predicates = [HasVSX, HasP9Vector] in {
3587// Additional fnmsub pattern for PPC specific ISD opcode
3588def : Pat<(PPCfnmsub f128:$A, f128:$B, f128:$C),
3589          (XSNMSUBQP $C, $A, $B)>;
3590def : Pat<(fneg (PPCfnmsub f128:$A, f128:$B, f128:$C)),
3591          (XSMSUBQP $C, $A, $B)>;
3592def : Pat<(PPCfnmsub f128:$A, f128:$B, (fneg f128:$C)),
3593          (XSNMADDQP $C, $A, $B)>;
3594
3595def : Pat<(f128 (any_sint_to_fp i64:$src)),
3596          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3597def : Pat<(f128 (any_sint_to_fp (i64 (PPCmfvsr f64:$src)))),
3598          (f128 (XSCVSDQP $src))>;
3599def : Pat<(f128 (any_sint_to_fp (i32 (PPCmfvsr f64:$src)))),
3600          (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
3601def : Pat<(f128 (any_uint_to_fp i64:$src)),
3602          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3603def : Pat<(f128 (any_uint_to_fp (i64 (PPCmfvsr f64:$src)))),
3604          (f128 (XSCVUDQP $src))>;
3605
3606// Convert (Un)Signed Word -> QP.
3607def : Pat<(f128 (any_sint_to_fp i32:$src)),
3608          (f128 (XSCVSDQP (MTVSRWA $src)))>;
3609def : Pat<(f128 (any_sint_to_fp (i32 (load xoaddr:$src)))),
3610          (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
3611def : Pat<(f128 (any_uint_to_fp i32:$src)),
3612          (f128 (XSCVUDQP (MTVSRWZ $src)))>;
3613def : Pat<(f128 (any_uint_to_fp (i32 (load xoaddr:$src)))),
3614          (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
3615
3616// Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
3617// separate pattern so that it can convert the input register class from
3618// VRRC(v8i16) to VSRC.
3619def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
3620          (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
3621
3622// Use current rounding mode
3623def : Pat<(f128 (any_fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
3624// Round to nearest, ties away from zero
3625def : Pat<(f128 (any_fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
3626// Round towards Zero
3627def : Pat<(f128 (any_ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
3628// Round towards +Inf
3629def : Pat<(f128 (any_fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
3630// Round towards -Inf
3631def : Pat<(f128 (any_ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
3632// Use current rounding mode, [with Inexact]
3633def : Pat<(f128 (any_frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
3634
3635def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
3636          (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
3637
3638def : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
3639          (i64 (MFVSRD (EXTRACT_SUBREG
3640                          (v2i64 (XSXEXPQP $vA)), sub_64)))>;
3641
3642// Extra patterns expanding to vector Extract Word/Insert Word
3643def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
3644          (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
3645def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
3646          (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
3647
3648// Vector Reverse
3649def : Pat<(v8i16 (bswap v8i16 :$A)),
3650          (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
3651def : Pat<(v1i128 (bswap v1i128 :$A)),
3652          (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
3653
3654// D-Form Load/Store
3655def : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3656def : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3657def : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3658def : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3659def : Pat<(f128  (quadwOffsetLoad iaddrX16:$src)),
3660          (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3661def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>;
3662def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>;
3663
3664def : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3665def : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3666def : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3667def : Pat<(quadwOffsetStore  f128:$rS, iaddrX16:$dst),
3668          (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3669def : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3670def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst),
3671          (STXV $rS, memrix16:$dst)>;
3672def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst),
3673          (STXV $rS, memrix16:$dst)>;
3674
3675def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3676def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3677def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3678def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3679def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
3680def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
3681def : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
3682          (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
3683def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
3684          (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3685def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
3686          (STXVX $rS, xoaddr:$dst)>;
3687def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
3688          (STXVX $rS, xoaddr:$dst)>;
3689def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
3690          (STXVX $rS, xoaddr:$dst)>;
3691def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
3692          (STXVX $rS, xoaddr:$dst)>;
3693def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3694          (STXVX $rS, xoaddr:$dst)>;
3695def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
3696          (STXVX $rS, xoaddr:$dst)>;
3697
3698// Build vectors from i8 loads
3699defm : ScalToVecWPermute<v16i8, ScalarLoads.Li8,
3700                         (VSPLTBs 7, (LXSIBZX xoaddr:$src)),
3701                         (VSPLTBs 7, (LXSIBZX xoaddr:$src))>;
3702defm : ScalToVecWPermute<v8i16, ScalarLoads.ZELi8,
3703                         (VSPLTHs 3, (LXSIBZX xoaddr:$src)),
3704                         (VSPLTHs 3, (LXSIBZX xoaddr:$src))>;
3705defm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi8,
3706                         (XXSPLTWs (LXSIBZX xoaddr:$src), 1),
3707                         (XXSPLTWs (LXSIBZX xoaddr:$src), 1)>;
3708defm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi8i64,
3709                         (XXPERMDIs (LXSIBZX xoaddr:$src), 0),
3710                         (XXPERMDIs (LXSIBZX xoaddr:$src), 0)>;
3711defm : ScalToVecWPermute<v4i32, ScalarLoads.SELi8,
3712                         (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1),
3713                         (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1)>;
3714defm : ScalToVecWPermute<v2i64, ScalarLoads.SELi8i64,
3715                         (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0),
3716                         (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0)>;
3717
3718// Build vectors from i16 loads
3719defm : ScalToVecWPermute<v8i16, ScalarLoads.Li16,
3720                         (VSPLTHs 3, (LXSIHZX xoaddr:$src)),
3721                         (VSPLTHs 3, (LXSIHZX xoaddr:$src))>;
3722defm : ScalToVecWPermute<v4i32, ScalarLoads.ZELi16,
3723                         (XXSPLTWs (LXSIHZX xoaddr:$src), 1),
3724                         (XXSPLTWs (LXSIHZX xoaddr:$src), 1)>;
3725defm : ScalToVecWPermute<v2i64, ScalarLoads.ZELi16i64,
3726                         (XXPERMDIs (LXSIHZX xoaddr:$src), 0),
3727                         (XXPERMDIs (LXSIHZX xoaddr:$src), 0)>;
3728defm : ScalToVecWPermute<v4i32, ScalarLoads.SELi16,
3729                         (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1),
3730                         (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1)>;
3731defm : ScalToVecWPermute<v2i64, ScalarLoads.SELi16i64,
3732                         (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0),
3733                         (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0)>;
3734
3735// Load/convert and convert/store patterns for f16.
3736def : Pat<(f64 (extloadf16 xoaddr:$src)),
3737          (f64 (XSCVHPDP (LXSIHZX xoaddr:$src)))>;
3738def : Pat<(truncstoref16 f64:$src, xoaddr:$dst),
3739          (STXSIHX (XSCVDPHP $src), xoaddr:$dst)>;
3740def : Pat<(f32 (extloadf16 xoaddr:$src)),
3741          (f32 (COPY_TO_REGCLASS (XSCVHPDP (LXSIHZX xoaddr:$src)), VSSRC))>;
3742def : Pat<(truncstoref16 f32:$src, xoaddr:$dst),
3743          (STXSIHX (XSCVDPHP (COPY_TO_REGCLASS $src, VSFRC)), xoaddr:$dst)>;
3744def : Pat<(f64 (f16_to_fp i32:$A)),
3745          (f64 (XSCVHPDP (MTVSRWZ $A)))>;
3746def : Pat<(f32 (f16_to_fp i32:$A)),
3747          (f32 (COPY_TO_REGCLASS (XSCVHPDP (MTVSRWZ $A)), VSSRC))>;
3748def : Pat<(i32 (fp_to_f16 f32:$A)),
3749          (i32 (MFVSRWZ (XSCVDPHP (COPY_TO_REGCLASS $A, VSFRC))))>;
3750def : Pat<(i32 (fp_to_f16 f64:$A)), (i32 (MFVSRWZ (XSCVDPHP $A)))>;
3751
3752// Vector sign extensions
3753def : Pat<(f64 (PPCVexts f64:$A, 1)),
3754          (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
3755def : Pat<(f64 (PPCVexts f64:$A, 2)),
3756          (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
3757
3758def : Pat<(f64 (extloadf32 iaddrX4:$src)),
3759          (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>;
3760def : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))),
3761          (f32 (DFLOADf32 iaddrX4:$src))>;
3762
3763def : Pat<(v4f32 (PPCldvsxlh xaddr:$src)),
3764          (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>;
3765def : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)),
3766          (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>;
3767
3768// Convert (Un)Signed DWord in memory -> QP
3769def : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))),
3770          (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>;
3771def : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))),
3772          (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>;
3773def : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))),
3774          (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>;
3775def : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))),
3776          (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>;
3777
3778// Convert Unsigned HWord in memory -> QP
3779def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
3780          (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
3781
3782// Convert Unsigned Byte in memory -> QP
3783def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
3784          (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
3785
3786// Truncate & Convert QP -> (Un)Signed (D)Word.
3787def : Pat<(i64 (any_fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3788def : Pat<(i64 (any_fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3789def : Pat<(i32 (any_fp_to_sint f128:$src)),
3790          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
3791def : Pat<(i32 (any_fp_to_uint f128:$src)),
3792          (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
3793
3794// Instructions for store(fptosi).
3795// The 8-byte version is repeated here due to availability of D-Form STXSD.
3796def : Pat<(PPCstore_scal_int_from_vsr
3797            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8),
3798          (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3799                  xaddrX4:$dst)>;
3800def : Pat<(PPCstore_scal_int_from_vsr
3801            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8),
3802          (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3803                 iaddrX4:$dst)>;
3804def : Pat<(PPCstore_scal_int_from_vsr
3805            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
3806          (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3807def : Pat<(PPCstore_scal_int_from_vsr
3808            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
3809          (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3810def : Pat<(PPCstore_scal_int_from_vsr
3811            (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
3812          (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3813def : Pat<(PPCstore_scal_int_from_vsr
3814            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8),
3815          (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>;
3816def : Pat<(PPCstore_scal_int_from_vsr
3817            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8),
3818          (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>;
3819def : Pat<(PPCstore_scal_int_from_vsr
3820            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
3821          (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3822def : Pat<(PPCstore_scal_int_from_vsr
3823            (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
3824          (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3825
3826// Instructions for store(fptoui).
3827def : Pat<(PPCstore_scal_int_from_vsr
3828            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8),
3829          (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3830                  xaddrX4:$dst)>;
3831def : Pat<(PPCstore_scal_int_from_vsr
3832            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8),
3833          (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3834                 iaddrX4:$dst)>;
3835def : Pat<(PPCstore_scal_int_from_vsr
3836            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
3837          (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3838def : Pat<(PPCstore_scal_int_from_vsr
3839            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
3840          (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3841def : Pat<(PPCstore_scal_int_from_vsr
3842            (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
3843          (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3844def : Pat<(PPCstore_scal_int_from_vsr
3845            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8),
3846          (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>;
3847def : Pat<(PPCstore_scal_int_from_vsr
3848            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8),
3849          (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>;
3850def : Pat<(PPCstore_scal_int_from_vsr
3851            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
3852          (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3853def : Pat<(PPCstore_scal_int_from_vsr
3854            (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
3855          (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3856
3857// Round & Convert QP -> DP/SP
3858def : Pat<(f64 (any_fpround f128:$src)), (f64 (XSCVQPDP $src))>;
3859def : Pat<(f32 (any_fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
3860
3861// Convert SP -> QP
3862def : Pat<(f128 (any_fpextend f32:$src)),
3863          (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
3864
3865def : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)),
3866          (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC),
3867                                           (COPY_TO_REGCLASS $XB, VSSRC)),
3868                                 VSSRC))>;
3869def : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)),
3870          (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC),
3871                                           (COPY_TO_REGCLASS $XB, VSSRC)),
3872                                 VSSRC))>;
3873
3874// Endianness-neutral patterns for const splats with ISA 3.0 instructions.
3875defm : ScalToVecWPermute<v4i32, (i32 i32:$A), (MTVSRWS $A), (MTVSRWS $A)>;
3876def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3877          (v4i32 (MTVSRWS $A))>;
3878def : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3879                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3880                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3881                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3882                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3883                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3884                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
3885                               immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
3886          (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
3887defm : ScalToVecWPermute<v4i32, FltToIntLoad.A,
3888                         (XVCVSPSXWS (LXVWSX xoaddr:$A)),
3889                         (XVCVSPSXWS (LXVWSX xoaddr:$A))>;
3890defm : ScalToVecWPermute<v4i32, FltToUIntLoad.A,
3891                         (XVCVSPUXWS (LXVWSX xoaddr:$A)),
3892                         (XVCVSPUXWS (LXVWSX xoaddr:$A))>;
3893defm : ScalToVecWPermute<
3894  v4i32, DblToIntLoadP9.A,
3895  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1),
3896  (SUBREG_TO_REG (i64 1), (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), sub_64)>;
3897defm : ScalToVecWPermute<
3898  v4i32, DblToUIntLoadP9.A,
3899  (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1),
3900  (SUBREG_TO_REG (i64 1), (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), sub_64)>;
3901defm : ScalToVecWPermute<
3902  v2i64, FltToLongLoadP9.A,
3903  (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), 0),
3904  (SUBREG_TO_REG
3905     (i64 1),
3906     (XSCVDPSXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), sub_64)>;
3907defm : ScalToVecWPermute<
3908  v2i64, FltToULongLoadP9.A,
3909  (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), 0),
3910  (SUBREG_TO_REG
3911     (i64 1),
3912     (XSCVDPUXDS (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$A), VSFRC)), sub_64)>;
3913def : Pat<(v4f32 (PPCldsplat xoaddr:$A)),
3914          (v4f32 (LXVWSX xoaddr:$A))>;
3915def : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
3916          (v4i32 (LXVWSX xoaddr:$A))>;
3917} // HasVSX, HasP9Vector
3918
3919// Big endian Power9 subtarget.
3920let Predicates = [HasVSX, HasP9Vector, IsBigEndian] in {
3921def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3922          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
3923def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3924          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
3925def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3926          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
3927def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3928          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
3929def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3930          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
3931def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3932          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
3933def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3934          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
3935def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3936          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
3937def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
3938          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
3939def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
3940          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
3941def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
3942          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
3943def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
3944          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
3945def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
3946          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3947def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
3948          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
3949def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
3950          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
3951def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3952          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
3953
3954// Scalar stores of i8
3955def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3956          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
3957def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3958          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3959def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3960          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
3961def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3962          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3963def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3964          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
3965def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3966          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3967def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3968          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
3969def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3970          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3971def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3972          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
3973def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3974          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3975def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3976          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
3977def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3978          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3979def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3980          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
3981def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3982          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3983def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3984          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
3985def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3986          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3987
3988// Scalar stores of i16
3989def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3990          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3991def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3992          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3993def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3994          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3995def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3996          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3997def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3998          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3999def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
4000          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
4001def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
4002          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
4003def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
4004          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
4005
4006def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
4007          (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
4008def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
4009          (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
4010
4011def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
4012          (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
4013def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
4014          (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
4015def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
4016          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4017                       sub_64), xaddrX4:$src)>;
4018def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
4019          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4020                       sub_64), xaddrX4:$src)>;
4021def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
4022          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4023def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
4024          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4025def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
4026          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4027                       sub_64), iaddrX4:$src)>;
4028def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
4029          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4030                       sub_64), iaddrX4:$src)>;
4031def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
4032          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4033def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
4034          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4035
4036// (Un)Signed DWord vector extract -> QP
4037def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4038          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4039def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4040          (f128 (XSCVSDQP
4041                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4042def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4043          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4044def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4045          (f128 (XSCVUDQP
4046                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4047
4048// (Un)Signed Word vector extract -> QP
4049def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
4050          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
4051foreach Idx = [0,2,3] in {
4052  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
4053            (f128 (XSCVSDQP (EXTRACT_SUBREG
4054                            (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
4055}
4056foreach Idx = 0-3 in {
4057  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
4058            (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
4059}
4060
4061// (Un)Signed HWord vector extract -> QP
4062foreach Idx = 0-7 in {
4063  def : Pat<(f128 (sint_to_fp
4064                    (i32 (sext_inreg
4065                           (vector_extract v8i16:$src, Idx), i16)))),
4066          (f128 (XSCVSDQP (EXTRACT_SUBREG
4067                            (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
4068                            sub_64)))>;
4069  // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
4070  def : Pat<(f128 (uint_to_fp
4071                    (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
4072            (f128 (XSCVUDQP (EXTRACT_SUBREG
4073                              (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
4074}
4075
4076// (Un)Signed Byte vector extract -> QP
4077foreach Idx = 0-15 in {
4078  def : Pat<(f128 (sint_to_fp
4079                    (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
4080                                     i8)))),
4081            (f128 (XSCVSDQP (EXTRACT_SUBREG
4082                              (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
4083  def : Pat<(f128 (uint_to_fp
4084                    (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
4085            (f128 (XSCVUDQP
4086                    (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
4087}
4088
4089// Unsiged int in vsx register -> QP
4090def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
4091          (f128 (XSCVUDQP
4092                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
4093} // HasVSX, HasP9Vector, IsBigEndian
4094
4095// Little endian Power9 subtarget.
4096let Predicates = [HasVSX, HasP9Vector, IsLittleEndian] in {
4097def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
4098          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
4099def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
4100          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
4101def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
4102          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
4103def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
4104          (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
4105def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
4106          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
4107def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
4108          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
4109def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
4110          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
4111def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
4112          (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
4113def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
4114          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
4115def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
4116          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
4117def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
4118          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
4119def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
4120          (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
4121def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
4122          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
4123def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
4124          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
4125def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
4126          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
4127def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
4128          (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
4129
4130def : Pat<(v8i16 (PPCld_vec_be xoaddr:$src)),
4131          (COPY_TO_REGCLASS (LXVH8X xoaddr:$src), VRRC)>;
4132def : Pat<(PPCst_vec_be v8i16:$rS, xoaddr:$dst),
4133          (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
4134
4135def : Pat<(v16i8 (PPCld_vec_be xoaddr:$src)),
4136          (COPY_TO_REGCLASS (LXVB16X xoaddr:$src), VRRC)>;
4137def : Pat<(PPCst_vec_be v16i8:$rS, xoaddr:$dst),
4138          (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
4139
4140// Scalar stores of i8
4141def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
4142          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
4143def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
4144          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
4145def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
4146          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
4147def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
4148          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
4149def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
4150          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
4151def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
4152          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
4153def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
4154          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
4155def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
4156          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
4157def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
4158          (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
4159def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
4160          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
4161def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
4162          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
4163def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
4164          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
4165def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
4166          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
4167def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
4168          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
4169def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
4170          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
4171def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
4172          (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
4173
4174// Scalar stores of i16
4175def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
4176          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
4177def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
4178          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
4179def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
4180          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
4181def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
4182          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
4183def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
4184          (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
4185def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
4186          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
4187def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
4188          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
4189def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
4190          (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
4191
4192defm : ScalToVecWPermute<
4193  v2i64, (i64 (load iaddrX4:$src)),
4194  (XXPERMDIs (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSFRC), 2),
4195  (SUBREG_TO_REG (i64 1), (DFLOADf64 iaddrX4:$src), sub_64)>;
4196defm : ScalToVecWPermute<
4197  v2i64, (i64 (load xaddrX4:$src)),
4198  (XXPERMDIs (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSFRC), 2),
4199  (SUBREG_TO_REG (i64 1), (XFLOADf64 xaddrX4:$src), sub_64)>;
4200defm : ScalToVecWPermute<
4201  v2f64, (f64 (load iaddrX4:$src)),
4202  (XXPERMDIs (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSFRC), 2),
4203  (SUBREG_TO_REG (i64 1), (DFLOADf64 iaddrX4:$src), sub_64)>;
4204defm : ScalToVecWPermute<
4205  v2f64, (f64 (load xaddrX4:$src)),
4206  (XXPERMDIs (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSFRC), 2),
4207  (SUBREG_TO_REG (i64 1), (XFLOADf64 xaddrX4:$src), sub_64)>;
4208
4209def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
4210          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4211                       sub_64), xaddrX4:$src)>;
4212def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
4213          (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4214                       sub_64), xaddrX4:$src)>;
4215def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
4216          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4217def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
4218          (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
4219def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
4220          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
4221                       sub_64), iaddrX4:$src)>;
4222def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
4223          (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4224                      iaddrX4:$src)>;
4225def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
4226          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4227def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
4228          (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
4229
4230// (Un)Signed DWord vector extract -> QP
4231def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4232          (f128 (XSCVSDQP
4233                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4234def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4235          (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4236def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
4237          (f128 (XSCVUDQP
4238                  (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
4239def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
4240          (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
4241
4242// (Un)Signed Word vector extract -> QP
4243foreach Idx = [[0,3],[1,2],[3,0]] in {
4244  def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
4245            (f128 (XSCVSDQP (EXTRACT_SUBREG
4246                              (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
4247                              sub_64)))>;
4248}
4249def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
4250          (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
4251
4252foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
4253  def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
4254            (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
4255}
4256
4257// (Un)Signed HWord vector extract -> QP
4258// The Nested foreach lists identifies the vector element and corresponding
4259// register byte location.
4260foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
4261  def : Pat<(f128 (sint_to_fp
4262                    (i32 (sext_inreg
4263                           (vector_extract v8i16:$src, !head(Idx)), i16)))),
4264            (f128 (XSCVSDQP
4265                    (EXTRACT_SUBREG (VEXTSH2D
4266                                      (VEXTRACTUH !head(!tail(Idx)), $src)),
4267                                    sub_64)))>;
4268  def : Pat<(f128 (uint_to_fp
4269                    (and (i32 (vector_extract v8i16:$src, !head(Idx))),
4270                         65535))),
4271            (f128 (XSCVUDQP (EXTRACT_SUBREG
4272                              (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
4273}
4274
4275// (Un)Signed Byte vector extract -> QP
4276foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
4277               [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
4278  def : Pat<(f128 (sint_to_fp
4279                    (i32 (sext_inreg
4280                           (vector_extract v16i8:$src, !head(Idx)), i8)))),
4281            (f128 (XSCVSDQP
4282                    (EXTRACT_SUBREG
4283                      (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
4284                      sub_64)))>;
4285  def : Pat<(f128 (uint_to_fp
4286                    (and (i32 (vector_extract v16i8:$src, !head(Idx))),
4287                         255))),
4288            (f128 (XSCVUDQP
4289                    (EXTRACT_SUBREG
4290                      (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
4291}
4292
4293// Unsiged int in vsx register -> QP
4294def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
4295          (f128 (XSCVUDQP
4296                  (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
4297} // HasVSX, HasP9Vector, IsLittleEndian
4298
4299// Any Power9 VSX subtarget that supports Power9 Altivec.
4300let Predicates = [HasVSX, HasP9Altivec] in {
4301// Put this P9Altivec related definition here since it's possible to be
4302// selected to VSX instruction xvnegsp, avoid possible undef.
4303def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
4304          (v4i32 (VABSDUW $A, $B))>;
4305
4306def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
4307          (v8i16 (VABSDUH $A, $B))>;
4308
4309def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
4310          (v16i8 (VABSDUB $A, $B))>;
4311
4312// As PPCVABSD description, the last operand indicates whether do the
4313// sign bit flip.
4314def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
4315          (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
4316} // HasVSX, HasP9Altivec
4317
4318// Big endian Power9 VSX subtargets with P9 Altivec support.
4319let Predicates = [HasVSX, HasP9Altivec, IsBigEndian] in {
4320def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
4321          (VEXTUBLX $Idx, $S)>;
4322
4323def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
4324          (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
4325def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
4326          (VEXTUHLX (LI8 0), $S)>;
4327def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
4328          (VEXTUHLX (LI8 2), $S)>;
4329def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
4330          (VEXTUHLX (LI8 4), $S)>;
4331def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
4332          (VEXTUHLX (LI8 6), $S)>;
4333def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
4334          (VEXTUHLX (LI8 8), $S)>;
4335def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
4336          (VEXTUHLX (LI8 10), $S)>;
4337def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
4338          (VEXTUHLX (LI8 12), $S)>;
4339def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
4340          (VEXTUHLX (LI8 14), $S)>;
4341
4342def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4343          (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
4344def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
4345          (VEXTUWLX (LI8 0), $S)>;
4346
4347// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
4348def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
4349          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4350          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
4351def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
4352          (VEXTUWLX (LI8 8), $S)>;
4353def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
4354          (VEXTUWLX (LI8 12), $S)>;
4355
4356def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4357          (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
4358def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
4359          (EXTSW (VEXTUWLX (LI8 0), $S))>;
4360// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
4361def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
4362          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4363          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
4364def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
4365          (EXTSW (VEXTUWLX (LI8 8), $S))>;
4366def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
4367          (EXTSW (VEXTUWLX (LI8 12), $S))>;
4368
4369def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
4370          (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
4371def : Pat<(i32 (vector_extract v16i8:$S, 0)),
4372          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
4373def : Pat<(i32 (vector_extract v16i8:$S, 1)),
4374          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
4375def : Pat<(i32 (vector_extract v16i8:$S, 2)),
4376          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
4377def : Pat<(i32 (vector_extract v16i8:$S, 3)),
4378          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
4379def : Pat<(i32 (vector_extract v16i8:$S, 4)),
4380          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
4381def : Pat<(i32 (vector_extract v16i8:$S, 5)),
4382          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
4383def : Pat<(i32 (vector_extract v16i8:$S, 6)),
4384          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
4385def : Pat<(i32 (vector_extract v16i8:$S, 7)),
4386          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
4387def : Pat<(i32 (vector_extract v16i8:$S, 8)),
4388          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
4389def : Pat<(i32 (vector_extract v16i8:$S, 9)),
4390          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
4391def : Pat<(i32 (vector_extract v16i8:$S, 10)),
4392          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
4393def : Pat<(i32 (vector_extract v16i8:$S, 11)),
4394          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
4395def : Pat<(i32 (vector_extract v16i8:$S, 12)),
4396          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
4397def : Pat<(i32 (vector_extract v16i8:$S, 13)),
4398          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
4399def : Pat<(i32 (vector_extract v16i8:$S, 14)),
4400          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
4401def : Pat<(i32 (vector_extract v16i8:$S, 15)),
4402          (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
4403
4404def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
4405          (i32 (EXTRACT_SUBREG (VEXTUHLX
4406          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
4407def : Pat<(i32 (vector_extract v8i16:$S, 0)),
4408          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
4409def : Pat<(i32 (vector_extract v8i16:$S, 1)),
4410          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
4411def : Pat<(i32 (vector_extract v8i16:$S, 2)),
4412          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
4413def : Pat<(i32 (vector_extract v8i16:$S, 3)),
4414          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
4415def : Pat<(i32 (vector_extract v8i16:$S, 4)),
4416          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
4417def : Pat<(i32 (vector_extract v8i16:$S, 5)),
4418          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
4419def : Pat<(i32 (vector_extract v8i16:$S, 6)),
4420          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
4421def : Pat<(i32 (vector_extract v8i16:$S, 6)),
4422          (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
4423
4424def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
4425          (i32 (EXTRACT_SUBREG (VEXTUWLX
4426          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
4427def : Pat<(i32 (vector_extract v4i32:$S, 0)),
4428          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
4429// For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
4430def : Pat<(i32 (vector_extract v4i32:$S, 1)),
4431          (i32 VectorExtractions.LE_WORD_2)>;
4432def : Pat<(i32 (vector_extract v4i32:$S, 2)),
4433          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
4434def : Pat<(i32 (vector_extract v4i32:$S, 3)),
4435          (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
4436
4437// P9 Altivec instructions that can be used to build vectors.
4438// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
4439// with complexities of existing build vector patterns in this file.
4440def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
4441          (v2i64 (VEXTSW2D $A))>;
4442def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
4443          (v2i64 (VEXTSH2D $A))>;
4444def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
4445                  HWordToWord.BE_A2, HWordToWord.BE_A3)),
4446          (v4i32 (VEXTSH2W $A))>;
4447def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
4448                  ByteToWord.BE_A2, ByteToWord.BE_A3)),
4449          (v4i32 (VEXTSB2W $A))>;
4450def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
4451          (v2i64 (VEXTSB2D $A))>;
4452} // HasVSX, HasP9Altivec, IsBigEndian
4453
4454// Little endian Power9 VSX subtargets with P9 Altivec support.
4455let Predicates = [HasVSX, HasP9Altivec, IsLittleEndian] in {
4456def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
4457          (VEXTUBRX $Idx, $S)>;
4458
4459def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
4460          (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
4461def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
4462          (VEXTUHRX (LI8 0), $S)>;
4463def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
4464          (VEXTUHRX (LI8 2), $S)>;
4465def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
4466          (VEXTUHRX (LI8 4), $S)>;
4467def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
4468          (VEXTUHRX (LI8 6), $S)>;
4469def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
4470          (VEXTUHRX (LI8 8), $S)>;
4471def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
4472          (VEXTUHRX (LI8 10), $S)>;
4473def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
4474          (VEXTUHRX (LI8 12), $S)>;
4475def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
4476          (VEXTUHRX (LI8 14), $S)>;
4477
4478def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4479          (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
4480def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
4481          (VEXTUWRX (LI8 0), $S)>;
4482def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
4483          (VEXTUWRX (LI8 4), $S)>;
4484// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
4485def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
4486          (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4487          (i32 VectorExtractions.LE_WORD_2), sub_32)>;
4488def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
4489          (VEXTUWRX (LI8 12), $S)>;
4490
4491def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
4492          (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
4493def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
4494          (EXTSW (VEXTUWRX (LI8 0), $S))>;
4495def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
4496          (EXTSW (VEXTUWRX (LI8 4), $S))>;
4497// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
4498def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
4499          (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
4500          (i32 VectorExtractions.LE_WORD_2), sub_32))>;
4501def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
4502          (EXTSW (VEXTUWRX (LI8 12), $S))>;
4503
4504def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
4505          (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
4506def : Pat<(i32 (vector_extract v16i8:$S, 0)),
4507          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
4508def : Pat<(i32 (vector_extract v16i8:$S, 1)),
4509          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
4510def : Pat<(i32 (vector_extract v16i8:$S, 2)),
4511          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
4512def : Pat<(i32 (vector_extract v16i8:$S, 3)),
4513          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
4514def : Pat<(i32 (vector_extract v16i8:$S, 4)),
4515          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
4516def : Pat<(i32 (vector_extract v16i8:$S, 5)),
4517          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
4518def : Pat<(i32 (vector_extract v16i8:$S, 6)),
4519          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
4520def : Pat<(i32 (vector_extract v16i8:$S, 7)),
4521          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
4522def : Pat<(i32 (vector_extract v16i8:$S, 8)),
4523          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
4524def : Pat<(i32 (vector_extract v16i8:$S, 9)),
4525          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
4526def : Pat<(i32 (vector_extract v16i8:$S, 10)),
4527          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
4528def : Pat<(i32 (vector_extract v16i8:$S, 11)),
4529          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
4530def : Pat<(i32 (vector_extract v16i8:$S, 12)),
4531          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
4532def : Pat<(i32 (vector_extract v16i8:$S, 13)),
4533          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
4534def : Pat<(i32 (vector_extract v16i8:$S, 14)),
4535          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
4536def : Pat<(i32 (vector_extract v16i8:$S, 15)),
4537          (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
4538
4539def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
4540          (i32 (EXTRACT_SUBREG (VEXTUHRX
4541          (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
4542def : Pat<(i32 (vector_extract v8i16:$S, 0)),
4543          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
4544def : Pat<(i32 (vector_extract v8i16:$S, 1)),
4545          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
4546def : Pat<(i32 (vector_extract v8i16:$S, 2)),
4547          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
4548def : Pat<(i32 (vector_extract v8i16:$S, 3)),
4549          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
4550def : Pat<(i32 (vector_extract v8i16:$S, 4)),
4551          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
4552def : Pat<(i32 (vector_extract v8i16:$S, 5)),
4553          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
4554def : Pat<(i32 (vector_extract v8i16:$S, 6)),
4555          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
4556def : Pat<(i32 (vector_extract v8i16:$S, 6)),
4557          (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
4558
4559def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
4560          (i32 (EXTRACT_SUBREG (VEXTUWRX
4561          (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
4562def : Pat<(i32 (vector_extract v4i32:$S, 0)),
4563          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
4564def : Pat<(i32 (vector_extract v4i32:$S, 1)),
4565          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
4566// For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
4567def : Pat<(i32 (vector_extract v4i32:$S, 2)),
4568          (i32 VectorExtractions.LE_WORD_2)>;
4569def : Pat<(i32 (vector_extract v4i32:$S, 3)),
4570          (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
4571
4572// P9 Altivec instructions that can be used to build vectors.
4573// Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
4574// with complexities of existing build vector patterns in this file.
4575def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
4576          (v2i64 (VEXTSW2D $A))>;
4577def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
4578          (v2i64 (VEXTSH2D $A))>;
4579def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
4580                  HWordToWord.LE_A2, HWordToWord.LE_A3)),
4581          (v4i32 (VEXTSH2W $A))>;
4582def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
4583                  ByteToWord.LE_A2, ByteToWord.LE_A3)),
4584          (v4i32 (VEXTSB2W $A))>;
4585def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
4586          (v2i64 (VEXTSB2D $A))>;
4587} // HasVSX, HasP9Altivec, IsLittleEndian
4588
4589// Big endian VSX subtarget that supports additional direct moves from ISA3.0.
4590let Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsBigEndian] in {
4591def : Pat<(i64 (extractelt v2i64:$A, 1)),
4592          (i64 (MFVSRLD $A))>;
4593// Better way to build integer vectors if we have MTVSRDD. Big endian.
4594def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
4595          (v2i64 (MTVSRDD $rB, $rA))>;
4596def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4597          (MTVSRDD
4598            (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
4599            (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
4600
4601def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
4602          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
4603} // HasVSX, IsISA3_0, HasDirectMove, IsBigEndian
4604
4605// Little endian VSX subtarget that supports direct moves from ISA3.0.
4606let Predicates = [HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian] in {
4607def : Pat<(i64 (extractelt v2i64:$A, 0)),
4608          (i64 (MFVSRLD $A))>;
4609// Better way to build integer vectors if we have MTVSRDD. Little endian.
4610def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
4611          (v2i64 (MTVSRDD $rB, $rA))>;
4612def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4613          (MTVSRDD
4614            (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
4615            (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
4616
4617def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
4618          (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
4619} // HasVSX, IsISA3_0, HasDirectMove, IsLittleEndian
4620} // AddedComplexity = 400
4621
4622//---------------------------- Instruction aliases ---------------------------//
4623def : InstAlias<"xvmovdp $XT, $XB",
4624                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
4625def : InstAlias<"xvmovsp $XT, $XB",
4626                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
4627
4628def : InstAlias<"xxspltd $XT, $XB, 0",
4629                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
4630def : InstAlias<"xxspltd $XT, $XB, 1",
4631                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
4632def : InstAlias<"xxmrghd $XT, $XA, $XB",
4633                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
4634def : InstAlias<"xxmrgld $XT, $XA, $XB",
4635                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
4636def : InstAlias<"xxswapd $XT, $XB",
4637                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
4638def : InstAlias<"xxspltd $XT, $XB, 0",
4639                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
4640def : InstAlias<"xxspltd $XT, $XB, 1",
4641                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
4642def : InstAlias<"xxswapd $XT, $XB",
4643                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
4644def : InstAlias<"mfvrd $rA, $XT",
4645                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
4646def : InstAlias<"mffprd $rA, $src",
4647                (MFVSRD g8rc:$rA, f8rc:$src)>;
4648def : InstAlias<"mtvrd $XT, $rA",
4649                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
4650def : InstAlias<"mtfprd $dst, $rA",
4651                (MTVSRD f8rc:$dst, g8rc:$rA)>;
4652def : InstAlias<"mfvrwz $rA, $XT",
4653                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
4654def : InstAlias<"mffprwz $rA, $src",
4655                (MFVSRWZ gprc:$rA, f8rc:$src)>;
4656def : InstAlias<"mtvrwa $XT, $rA",
4657                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
4658def : InstAlias<"mtfprwa $dst, $rA",
4659                (MTVSRWA f8rc:$dst, gprc:$rA)>;
4660def : InstAlias<"mtvrwz $XT, $rA",
4661                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
4662def : InstAlias<"mtfprwz $dst, $rA",
4663                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
4664