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