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