]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302069, and update
[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 // Little-endian-specific nodes.
51 def SDT_PPClxvd2x : SDTypeProfile<1, 1, [
52   SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
53 ]>;
54 def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
55   SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
56 ]>;
57 def SDT_PPCxxswapd : SDTypeProfile<1, 1, [
58   SDTCisSameAs<0, 1>
59 ]>;
60 def SDTVecConv : SDTypeProfile<1, 2, [
61   SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>
62 ]>;
63
64 def PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
65                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
66 def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
67                         [SDNPHasChain, SDNPMayStore]>;
68 def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
69 def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
70 def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
71 def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
72 def PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
73 def PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
74 def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
75
76 multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
77                     string asmstr, InstrItinClass itin, Intrinsic Int,
78                     ValueType OutTy, ValueType InTy> {
79   let BaseName = asmbase in {
80     def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
81                        !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
82                        [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
83     let Defs = [CR6] in
84     def o    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
85                        !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
86                        [(set InTy:$XT,
87                                 (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>,
88                        isDOT;
89   }
90 }
91
92 // Instruction form with a single input register for instructions such as
93 // XXPERMDI. The reason for defining this is that specifying multiple chained
94 // operands (such as loads) to an instruction will perform both chained
95 // operations rather than coalescing them into a single register - even though
96 // the source memory location is the same. This simply forces the instruction
97 // to use the same register for both inputs.
98 // For example, an output DAG such as this:
99 //   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
100 // would result in two load instructions emitted and used as separate inputs
101 // to the XXPERMDI instruction.
102 class XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
103                  InstrItinClass itin, list<dag> pattern>
104   : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
105     let XB = XA;
106 }
107
108 def HasVSX : Predicate<"PPCSubTarget->hasVSX()">;
109 def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">;
110 def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">;
111 def HasOnlySwappingMemOps : Predicate<"!PPCSubTarget->hasP9Vector()">;
112
113 let Predicates = [HasVSX] in {
114 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
115 let UseVSXReg = 1 in {
116 let hasSideEffects = 0 in { // VSX instructions don't have side effects.
117 let Uses = [RM] in {
118
119   // Load indexed instructions
120   let mayLoad = 1, mayStore = 0 in {
121     let CodeSize = 3 in
122     def LXSDX : XX1Form<31, 588,
123                         (outs vsfrc:$XT), (ins memrr:$src),
124                         "lxsdx $XT, $src", IIC_LdStLFD,
125                         [(set f64:$XT, (load xoaddr:$src))]>;
126
127     let Predicates = [HasVSX, HasOnlySwappingMemOps] in
128     def LXVD2X : XX1Form<31, 844,
129                          (outs vsrc:$XT), (ins memrr:$src),
130                          "lxvd2x $XT, $src", IIC_LdStLFD,
131                          [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
132
133     def LXVDSX : XX1Form<31, 332,
134                          (outs vsrc:$XT), (ins memrr:$src),
135                          "lxvdsx $XT, $src", IIC_LdStLFD, []>;
136
137     let Predicates = [HasVSX, HasOnlySwappingMemOps] in
138     def LXVW4X : XX1Form<31, 780,
139                          (outs vsrc:$XT), (ins memrr:$src),
140                          "lxvw4x $XT, $src", IIC_LdStLFD,
141                          []>;
142   } // mayLoad
143
144   // Store indexed instructions
145   let mayStore = 1, mayLoad = 0 in {
146     let CodeSize = 3 in
147     def STXSDX : XX1Form<31, 716,
148                         (outs), (ins vsfrc:$XT, memrr:$dst),
149                         "stxsdx $XT, $dst", IIC_LdStSTFD,
150                         [(store f64:$XT, xoaddr:$dst)]>;
151
152     let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
153     // The behaviour of this instruction is endianness-specific so we provide no
154     // pattern to match it without considering endianness.
155     def STXVD2X : XX1Form<31, 972,
156                          (outs), (ins vsrc:$XT, memrr:$dst),
157                          "stxvd2x $XT, $dst", IIC_LdStSTFD,
158                          []>;
159
160     def STXVW4X : XX1Form<31, 908,
161                          (outs), (ins vsrc:$XT, memrr:$dst),
162                          "stxvw4x $XT, $dst", IIC_LdStSTFD,
163                          []>;
164     }
165   } // mayStore
166
167   // Add/Mul Instructions
168   let isCommutable = 1 in {
169     def XSADDDP : XX3Form<60, 32,
170                           (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
171                           "xsadddp $XT, $XA, $XB", IIC_VecFP,
172                           [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>;
173     def XSMULDP : XX3Form<60, 48,
174                           (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
175                           "xsmuldp $XT, $XA, $XB", IIC_VecFP,
176                           [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>;
177
178     def XVADDDP : XX3Form<60, 96,
179                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
180                           "xvadddp $XT, $XA, $XB", IIC_VecFP,
181                           [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>;
182
183     def XVADDSP : XX3Form<60, 64,
184                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
185                           "xvaddsp $XT, $XA, $XB", IIC_VecFP,
186                           [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>;
187
188     def XVMULDP : XX3Form<60, 112,
189                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
190                           "xvmuldp $XT, $XA, $XB", IIC_VecFP,
191                           [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>;
192
193     def XVMULSP : XX3Form<60, 80,
194                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
195                           "xvmulsp $XT, $XA, $XB", IIC_VecFP,
196                           [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>;
197   }
198
199   // Subtract Instructions
200   def XSSUBDP : XX3Form<60, 40,
201                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
202                         "xssubdp $XT, $XA, $XB", IIC_VecFP,
203                         [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>;
204
205   def XVSUBDP : XX3Form<60, 104,
206                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
207                         "xvsubdp $XT, $XA, $XB", IIC_VecFP,
208                         [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>;
209   def XVSUBSP : XX3Form<60, 72,
210                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
211                         "xvsubsp $XT, $XA, $XB", IIC_VecFP,
212                         [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>;
213
214   // FMA Instructions
215   let BaseName = "XSMADDADP" in {
216   let isCommutable = 1 in
217   def XSMADDADP : XX3Form<60, 33,
218                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
219                           "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
220                           [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>,
221                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
222                           AltVSXFMARel;
223   let IsVSXFMAAlt = 1 in
224   def XSMADDMDP : XX3Form<60, 41,
225                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
226                           "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
227                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
228                           AltVSXFMARel;
229   }
230
231   let BaseName = "XSMSUBADP" in {
232   let isCommutable = 1 in
233   def XSMSUBADP : XX3Form<60, 49,
234                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
235                           "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
236                           [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
237                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
238                           AltVSXFMARel;
239   let IsVSXFMAAlt = 1 in
240   def XSMSUBMDP : XX3Form<60, 57,
241                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
242                           "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
243                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
244                           AltVSXFMARel;
245   }
246
247   let BaseName = "XSNMADDADP" in {
248   let isCommutable = 1 in
249   def XSNMADDADP : XX3Form<60, 161,
250                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
251                           "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
252                           [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>,
253                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
254                           AltVSXFMARel;
255   let IsVSXFMAAlt = 1 in
256   def XSNMADDMDP : XX3Form<60, 169,
257                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
258                           "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
259                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
260                           AltVSXFMARel;
261   }
262
263   let BaseName = "XSNMSUBADP" in {
264   let isCommutable = 1 in
265   def XSNMSUBADP : XX3Form<60, 177,
266                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
267                           "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
268                           [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
269                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
270                           AltVSXFMARel;
271   let IsVSXFMAAlt = 1 in
272   def XSNMSUBMDP : XX3Form<60, 185,
273                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
274                           "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
275                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
276                           AltVSXFMARel;
277   }
278
279   let BaseName = "XVMADDADP" in {
280   let isCommutable = 1 in
281   def XVMADDADP : XX3Form<60, 97,
282                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
283                           "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
284                           [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
285                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
286                           AltVSXFMARel;
287   let IsVSXFMAAlt = 1 in
288   def XVMADDMDP : XX3Form<60, 105,
289                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
290                           "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
291                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
292                           AltVSXFMARel;
293   }
294
295   let BaseName = "XVMADDASP" in {
296   let isCommutable = 1 in
297   def XVMADDASP : XX3Form<60, 65,
298                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
299                           "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
300                           [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
301                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
302                           AltVSXFMARel;
303   let IsVSXFMAAlt = 1 in
304   def XVMADDMSP : XX3Form<60, 73,
305                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
306                           "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
307                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
308                           AltVSXFMARel;
309   }
310
311   let BaseName = "XVMSUBADP" in {
312   let isCommutable = 1 in
313   def XVMSUBADP : XX3Form<60, 113,
314                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
315                           "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
316                           [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
317                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
318                           AltVSXFMARel;
319   let IsVSXFMAAlt = 1 in
320   def XVMSUBMDP : XX3Form<60, 121,
321                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
322                           "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
323                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
324                           AltVSXFMARel;
325   }
326
327   let BaseName = "XVMSUBASP" in {
328   let isCommutable = 1 in
329   def XVMSUBASP : XX3Form<60, 81,
330                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
331                           "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
332                           [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
333                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
334                           AltVSXFMARel;
335   let IsVSXFMAAlt = 1 in
336   def XVMSUBMSP : XX3Form<60, 89,
337                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
338                           "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
339                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
340                           AltVSXFMARel;
341   }
342
343   let BaseName = "XVNMADDADP" in {
344   let isCommutable = 1 in
345   def XVNMADDADP : XX3Form<60, 225,
346                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
347                           "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
348                           [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
349                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
350                           AltVSXFMARel;
351   let IsVSXFMAAlt = 1 in
352   def XVNMADDMDP : XX3Form<60, 233,
353                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
354                           "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
355                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
356                           AltVSXFMARel;
357   }
358
359   let BaseName = "XVNMADDASP" in {
360   let isCommutable = 1 in
361   def XVNMADDASP : XX3Form<60, 193,
362                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
363                           "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
364                           [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
365                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
366                           AltVSXFMARel;
367   let IsVSXFMAAlt = 1 in
368   def XVNMADDMSP : XX3Form<60, 201,
369                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
370                           "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
371                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
372                           AltVSXFMARel;
373   }
374
375   let BaseName = "XVNMSUBADP" in {
376   let isCommutable = 1 in
377   def XVNMSUBADP : XX3Form<60, 241,
378                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
379                           "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
380                           [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
381                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
382                           AltVSXFMARel;
383   let IsVSXFMAAlt = 1 in
384   def XVNMSUBMDP : XX3Form<60, 249,
385                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
386                           "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
387                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
388                           AltVSXFMARel;
389   }
390
391   let BaseName = "XVNMSUBASP" in {
392   let isCommutable = 1 in
393   def XVNMSUBASP : XX3Form<60, 209,
394                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
395                           "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
396                           [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
397                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
398                           AltVSXFMARel;
399   let IsVSXFMAAlt = 1 in
400   def XVNMSUBMSP : XX3Form<60, 217,
401                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
402                           "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
403                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
404                           AltVSXFMARel;
405   }
406
407   // Division Instructions
408   def XSDIVDP : XX3Form<60, 56,
409                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
410                         "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
411                         [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>;
412   def XSSQRTDP : XX2Form<60, 75,
413                         (outs vsfrc:$XT), (ins vsfrc:$XB),
414                         "xssqrtdp $XT, $XB", IIC_FPSqrtD,
415                         [(set f64:$XT, (fsqrt f64:$XB))]>;
416
417   def XSREDP : XX2Form<60, 90,
418                         (outs vsfrc:$XT), (ins vsfrc:$XB),
419                         "xsredp $XT, $XB", IIC_VecFP,
420                         [(set f64:$XT, (PPCfre f64:$XB))]>;
421   def XSRSQRTEDP : XX2Form<60, 74,
422                            (outs vsfrc:$XT), (ins vsfrc:$XB),
423                            "xsrsqrtedp $XT, $XB", IIC_VecFP,
424                            [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
425
426   def XSTDIVDP : XX3Form_1<60, 61,
427                          (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
428                          "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
429   def XSTSQRTDP : XX2Form_1<60, 106,
430                           (outs crrc:$crD), (ins vsfrc:$XB),
431                           "xstsqrtdp $crD, $XB", IIC_FPCompare, []>;
432
433   def XVDIVDP : XX3Form<60, 120,
434                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
435                         "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
436                         [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>;
437   def XVDIVSP : XX3Form<60, 88,
438                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
439                         "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
440                         [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>;
441
442   def XVSQRTDP : XX2Form<60, 203,
443                         (outs vsrc:$XT), (ins vsrc:$XB),
444                         "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
445                         [(set v2f64:$XT, (fsqrt v2f64:$XB))]>;
446   def XVSQRTSP : XX2Form<60, 139,
447                         (outs vsrc:$XT), (ins vsrc:$XB),
448                         "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
449                         [(set v4f32:$XT, (fsqrt v4f32:$XB))]>;
450
451   def XVTDIVDP : XX3Form_1<60, 125,
452                          (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
453                          "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
454   def XVTDIVSP : XX3Form_1<60, 93,
455                          (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
456                          "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
457
458   def XVTSQRTDP : XX2Form_1<60, 234,
459                           (outs crrc:$crD), (ins vsrc:$XB),
460                           "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
461   def XVTSQRTSP : XX2Form_1<60, 170,
462                           (outs crrc:$crD), (ins vsrc:$XB),
463                           "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
464
465   def XVREDP : XX2Form<60, 218,
466                         (outs vsrc:$XT), (ins vsrc:$XB),
467                         "xvredp $XT, $XB", IIC_VecFP,
468                         [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
469   def XVRESP : XX2Form<60, 154,
470                         (outs vsrc:$XT), (ins vsrc:$XB),
471                         "xvresp $XT, $XB", IIC_VecFP,
472                         [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
473
474   def XVRSQRTEDP : XX2Form<60, 202,
475                            (outs vsrc:$XT), (ins vsrc:$XB),
476                            "xvrsqrtedp $XT, $XB", IIC_VecFP,
477                            [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
478   def XVRSQRTESP : XX2Form<60, 138,
479                            (outs vsrc:$XT), (ins vsrc:$XB),
480                            "xvrsqrtesp $XT, $XB", IIC_VecFP,
481                            [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
482
483   // Compare Instructions
484   def XSCMPODP : XX3Form_1<60, 43,
485                            (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
486                            "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
487   def XSCMPUDP : XX3Form_1<60, 35,
488                            (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
489                            "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
490
491   defm XVCMPEQDP : XX3Form_Rcr<60, 99,
492                              "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
493                              int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
494   defm XVCMPEQSP : XX3Form_Rcr<60, 67,
495                              "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
496                              int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
497   defm XVCMPGEDP : XX3Form_Rcr<60, 115,
498                              "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
499                              int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
500   defm XVCMPGESP : XX3Form_Rcr<60, 83,
501                              "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
502                              int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
503   defm XVCMPGTDP : XX3Form_Rcr<60, 107,
504                              "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
505                              int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
506   defm XVCMPGTSP : XX3Form_Rcr<60, 75,
507                              "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
508                              int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
509
510   // Move Instructions
511   def XSABSDP : XX2Form<60, 345,
512                       (outs vsfrc:$XT), (ins vsfrc:$XB),
513                       "xsabsdp $XT, $XB", IIC_VecFP,
514                       [(set f64:$XT, (fabs f64:$XB))]>;
515   def XSNABSDP : XX2Form<60, 361,
516                       (outs vsfrc:$XT), (ins vsfrc:$XB),
517                       "xsnabsdp $XT, $XB", IIC_VecFP,
518                       [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
519   def XSNEGDP : XX2Form<60, 377,
520                       (outs vsfrc:$XT), (ins vsfrc:$XB),
521                       "xsnegdp $XT, $XB", IIC_VecFP,
522                       [(set f64:$XT, (fneg f64:$XB))]>;
523   def XSCPSGNDP : XX3Form<60, 176,
524                       (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
525                       "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
526                       [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
527
528   def XVABSDP : XX2Form<60, 473,
529                       (outs vsrc:$XT), (ins vsrc:$XB),
530                       "xvabsdp $XT, $XB", IIC_VecFP,
531                       [(set v2f64:$XT, (fabs v2f64:$XB))]>;
532
533   def XVABSSP : XX2Form<60, 409,
534                       (outs vsrc:$XT), (ins vsrc:$XB),
535                       "xvabssp $XT, $XB", IIC_VecFP,
536                       [(set v4f32:$XT, (fabs v4f32:$XB))]>;
537
538   def XVCPSGNDP : XX3Form<60, 240,
539                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
540                       "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
541                       [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
542   def XVCPSGNSP : XX3Form<60, 208,
543                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
544                       "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
545                       [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
546
547   def XVNABSDP : XX2Form<60, 489,
548                       (outs vsrc:$XT), (ins vsrc:$XB),
549                       "xvnabsdp $XT, $XB", IIC_VecFP,
550                       [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
551   def XVNABSSP : XX2Form<60, 425,
552                       (outs vsrc:$XT), (ins vsrc:$XB),
553                       "xvnabssp $XT, $XB", IIC_VecFP,
554                       [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
555
556   def XVNEGDP : XX2Form<60, 505,
557                       (outs vsrc:$XT), (ins vsrc:$XB),
558                       "xvnegdp $XT, $XB", IIC_VecFP,
559                       [(set v2f64:$XT, (fneg v2f64:$XB))]>;
560   def XVNEGSP : XX2Form<60, 441,
561                       (outs vsrc:$XT), (ins vsrc:$XB),
562                       "xvnegsp $XT, $XB", IIC_VecFP,
563                       [(set v4f32:$XT, (fneg v4f32:$XB))]>;
564
565   // Conversion Instructions
566   def XSCVDPSP : XX2Form<60, 265,
567                       (outs vsfrc:$XT), (ins vsfrc:$XB),
568                       "xscvdpsp $XT, $XB", IIC_VecFP, []>;
569   def XSCVDPSXDS : XX2Form<60, 344,
570                       (outs vsfrc:$XT), (ins vsfrc:$XB),
571                       "xscvdpsxds $XT, $XB", IIC_VecFP,
572                       [(set f64:$XT, (PPCfctidz f64:$XB))]>;
573   let isCodeGenOnly = 1 in
574   def XSCVDPSXDSs : XX2Form<60, 344,
575                       (outs vssrc:$XT), (ins vssrc:$XB),
576                       "xscvdpsxds $XT, $XB", IIC_VecFP,
577                       [(set f32:$XT, (PPCfctidz f32:$XB))]>;
578   def XSCVDPSXWS : XX2Form<60, 88,
579                       (outs vsfrc:$XT), (ins vsfrc:$XB),
580                       "xscvdpsxws $XT, $XB", IIC_VecFP,
581                       [(set f64:$XT, (PPCfctiwz f64:$XB))]>;
582   let isCodeGenOnly = 1 in
583   def XSCVDPSXWSs : XX2Form<60, 88,
584                       (outs vssrc:$XT), (ins vssrc:$XB),
585                       "xscvdpsxws $XT, $XB", IIC_VecFP,
586                       [(set f32:$XT, (PPCfctiwz f32:$XB))]>;
587   def XSCVDPUXDS : XX2Form<60, 328,
588                       (outs vsfrc:$XT), (ins vsfrc:$XB),
589                       "xscvdpuxds $XT, $XB", IIC_VecFP,
590                       [(set f64:$XT, (PPCfctiduz f64:$XB))]>;
591   let isCodeGenOnly = 1 in
592   def XSCVDPUXDSs : XX2Form<60, 328,
593                       (outs vssrc:$XT), (ins vssrc:$XB),
594                       "xscvdpuxds $XT, $XB", IIC_VecFP,
595                       [(set f32:$XT, (PPCfctiduz f32:$XB))]>;
596   def XSCVDPUXWS : XX2Form<60, 72,
597                       (outs vsfrc:$XT), (ins vsfrc:$XB),
598                       "xscvdpuxws $XT, $XB", IIC_VecFP,
599                       [(set f64:$XT, (PPCfctiwuz f64:$XB))]>;
600   let isCodeGenOnly = 1 in
601   def XSCVDPUXWSs : XX2Form<60, 72,
602                       (outs vssrc:$XT), (ins vssrc:$XB),
603                       "xscvdpuxws $XT, $XB", IIC_VecFP,
604                       [(set f32:$XT, (PPCfctiwuz f32:$XB))]>;
605   def XSCVSPDP : XX2Form<60, 329,
606                       (outs vsfrc:$XT), (ins vsfrc:$XB),
607                       "xscvspdp $XT, $XB", IIC_VecFP, []>;
608   def XSCVSXDDP : XX2Form<60, 376,
609                       (outs vsfrc:$XT), (ins vsfrc:$XB),
610                       "xscvsxddp $XT, $XB", IIC_VecFP,
611                       [(set f64:$XT, (PPCfcfid f64:$XB))]>;
612   def XSCVUXDDP : XX2Form<60, 360,
613                       (outs vsfrc:$XT), (ins vsfrc:$XB),
614                       "xscvuxddp $XT, $XB", IIC_VecFP,
615                       [(set f64:$XT, (PPCfcfidu f64:$XB))]>;
616
617   def XVCVDPSP : XX2Form<60, 393,
618                       (outs vsrc:$XT), (ins vsrc:$XB),
619                       "xvcvdpsp $XT, $XB", IIC_VecFP,
620                       [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
621   def XVCVDPSXDS : XX2Form<60, 472,
622                       (outs vsrc:$XT), (ins vsrc:$XB),
623                       "xvcvdpsxds $XT, $XB", IIC_VecFP,
624                       [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>;
625   def XVCVDPSXWS : XX2Form<60, 216,
626                       (outs vsrc:$XT), (ins vsrc:$XB),
627                       "xvcvdpsxws $XT, $XB", IIC_VecFP,
628                       [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
629   def XVCVDPUXDS : XX2Form<60, 456,
630                       (outs vsrc:$XT), (ins vsrc:$XB),
631                       "xvcvdpuxds $XT, $XB", IIC_VecFP,
632                       [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>;
633   def XVCVDPUXWS : XX2Form<60, 200,
634                       (outs vsrc:$XT), (ins vsrc:$XB),
635                       "xvcvdpuxws $XT, $XB", IIC_VecFP,
636                       [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
637
638   def XVCVSPDP : XX2Form<60, 457,
639                       (outs vsrc:$XT), (ins vsrc:$XB),
640                       "xvcvspdp $XT, $XB", IIC_VecFP,
641                       [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
642   def XVCVSPSXDS : XX2Form<60, 408,
643                       (outs vsrc:$XT), (ins vsrc:$XB),
644                       "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
645   def XVCVSPSXWS : XX2Form<60, 152,
646                       (outs vsrc:$XT), (ins vsrc:$XB),
647                       "xvcvspsxws $XT, $XB", IIC_VecFP,
648                       [(set v4i32:$XT, (fp_to_sint v4f32:$XB))]>;
649   def XVCVSPUXDS : XX2Form<60, 392,
650                       (outs vsrc:$XT), (ins vsrc:$XB),
651                       "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
652   def XVCVSPUXWS : XX2Form<60, 136,
653                       (outs vsrc:$XT), (ins vsrc:$XB),
654                       "xvcvspuxws $XT, $XB", IIC_VecFP,
655                       [(set v4i32:$XT, (fp_to_uint v4f32:$XB))]>;
656   def XVCVSXDDP : XX2Form<60, 504,
657                       (outs vsrc:$XT), (ins vsrc:$XB),
658                       "xvcvsxddp $XT, $XB", IIC_VecFP,
659                       [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>;
660   def XVCVSXDSP : XX2Form<60, 440,
661                       (outs vsrc:$XT), (ins vsrc:$XB),
662                       "xvcvsxdsp $XT, $XB", IIC_VecFP,
663                       [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
664   def XVCVSXWDP : XX2Form<60, 248,
665                       (outs vsrc:$XT), (ins vsrc:$XB),
666                       "xvcvsxwdp $XT, $XB", IIC_VecFP,
667                       [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
668   def XVCVSXWSP : XX2Form<60, 184,
669                       (outs vsrc:$XT), (ins vsrc:$XB),
670                       "xvcvsxwsp $XT, $XB", IIC_VecFP,
671                       [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>;
672   def XVCVUXDDP : XX2Form<60, 488,
673                       (outs vsrc:$XT), (ins vsrc:$XB),
674                       "xvcvuxddp $XT, $XB", IIC_VecFP,
675                       [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>;
676   def XVCVUXDSP : XX2Form<60, 424,
677                       (outs vsrc:$XT), (ins vsrc:$XB),
678                       "xvcvuxdsp $XT, $XB", IIC_VecFP,
679                       [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
680   def XVCVUXWDP : XX2Form<60, 232,
681                       (outs vsrc:$XT), (ins vsrc:$XB),
682                       "xvcvuxwdp $XT, $XB", IIC_VecFP,
683                       [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
684   def XVCVUXWSP : XX2Form<60, 168,
685                       (outs vsrc:$XT), (ins vsrc:$XB),
686                       "xvcvuxwsp $XT, $XB", IIC_VecFP,
687                       [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>;
688
689   // Rounding Instructions
690   def XSRDPI : XX2Form<60, 73,
691                       (outs vsfrc:$XT), (ins vsfrc:$XB),
692                       "xsrdpi $XT, $XB", IIC_VecFP,
693                       [(set f64:$XT, (fround f64:$XB))]>;
694   def XSRDPIC : XX2Form<60, 107,
695                       (outs vsfrc:$XT), (ins vsfrc:$XB),
696                       "xsrdpic $XT, $XB", IIC_VecFP,
697                       [(set f64:$XT, (fnearbyint f64:$XB))]>;
698   def XSRDPIM : XX2Form<60, 121,
699                       (outs vsfrc:$XT), (ins vsfrc:$XB),
700                       "xsrdpim $XT, $XB", IIC_VecFP,
701                       [(set f64:$XT, (ffloor f64:$XB))]>;
702   def XSRDPIP : XX2Form<60, 105,
703                       (outs vsfrc:$XT), (ins vsfrc:$XB),
704                       "xsrdpip $XT, $XB", IIC_VecFP,
705                       [(set f64:$XT, (fceil f64:$XB))]>;
706   def XSRDPIZ : XX2Form<60, 89,
707                       (outs vsfrc:$XT), (ins vsfrc:$XB),
708                       "xsrdpiz $XT, $XB", IIC_VecFP,
709                       [(set f64:$XT, (ftrunc f64:$XB))]>;
710
711   def XVRDPI : XX2Form<60, 201,
712                       (outs vsrc:$XT), (ins vsrc:$XB),
713                       "xvrdpi $XT, $XB", IIC_VecFP,
714                       [(set v2f64:$XT, (fround v2f64:$XB))]>;
715   def XVRDPIC : XX2Form<60, 235,
716                       (outs vsrc:$XT), (ins vsrc:$XB),
717                       "xvrdpic $XT, $XB", IIC_VecFP,
718                       [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
719   def XVRDPIM : XX2Form<60, 249,
720                       (outs vsrc:$XT), (ins vsrc:$XB),
721                       "xvrdpim $XT, $XB", IIC_VecFP,
722                       [(set v2f64:$XT, (ffloor v2f64:$XB))]>;
723   def XVRDPIP : XX2Form<60, 233,
724                       (outs vsrc:$XT), (ins vsrc:$XB),
725                       "xvrdpip $XT, $XB", IIC_VecFP,
726                       [(set v2f64:$XT, (fceil v2f64:$XB))]>;
727   def XVRDPIZ : XX2Form<60, 217,
728                       (outs vsrc:$XT), (ins vsrc:$XB),
729                       "xvrdpiz $XT, $XB", IIC_VecFP,
730                       [(set v2f64:$XT, (ftrunc v2f64:$XB))]>;
731
732   def XVRSPI : XX2Form<60, 137,
733                       (outs vsrc:$XT), (ins vsrc:$XB),
734                       "xvrspi $XT, $XB", IIC_VecFP,
735                       [(set v4f32:$XT, (fround v4f32:$XB))]>;
736   def XVRSPIC : XX2Form<60, 171,
737                       (outs vsrc:$XT), (ins vsrc:$XB),
738                       "xvrspic $XT, $XB", IIC_VecFP,
739                       [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
740   def XVRSPIM : XX2Form<60, 185,
741                       (outs vsrc:$XT), (ins vsrc:$XB),
742                       "xvrspim $XT, $XB", IIC_VecFP,
743                       [(set v4f32:$XT, (ffloor v4f32:$XB))]>;
744   def XVRSPIP : XX2Form<60, 169,
745                       (outs vsrc:$XT), (ins vsrc:$XB),
746                       "xvrspip $XT, $XB", IIC_VecFP,
747                       [(set v4f32:$XT, (fceil v4f32:$XB))]>;
748   def XVRSPIZ : XX2Form<60, 153,
749                       (outs vsrc:$XT), (ins vsrc:$XB),
750                       "xvrspiz $XT, $XB", IIC_VecFP,
751                       [(set v4f32:$XT, (ftrunc v4f32:$XB))]>;
752
753   // Max/Min Instructions
754   let isCommutable = 1 in {
755   def XSMAXDP : XX3Form<60, 160,
756                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
757                         "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
758                         [(set vsfrc:$XT,
759                               (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
760   def XSMINDP : XX3Form<60, 168,
761                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
762                         "xsmindp $XT, $XA, $XB", IIC_VecFP,
763                         [(set vsfrc:$XT,
764                               (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
765
766   def XVMAXDP : XX3Form<60, 224,
767                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
768                         "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
769                         [(set vsrc:$XT,
770                               (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
771   def XVMINDP : XX3Form<60, 232,
772                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
773                         "xvmindp $XT, $XA, $XB", IIC_VecFP,
774                         [(set vsrc:$XT,
775                               (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
776
777   def XVMAXSP : XX3Form<60, 192,
778                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
779                         "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
780                         [(set vsrc:$XT,
781                               (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
782   def XVMINSP : XX3Form<60, 200,
783                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
784                         "xvminsp $XT, $XA, $XB", IIC_VecFP,
785                         [(set vsrc:$XT,
786                               (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
787   } // isCommutable
788 } // Uses = [RM]
789
790   // Logical Instructions
791   let isCommutable = 1 in
792   def XXLAND : XX3Form<60, 130,
793                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
794                        "xxland $XT, $XA, $XB", IIC_VecGeneral,
795                        [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
796   def XXLANDC : XX3Form<60, 138,
797                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
798                         "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
799                         [(set v4i32:$XT, (and v4i32:$XA,
800                                               (vnot_ppc v4i32:$XB)))]>;
801   let isCommutable = 1 in {
802   def XXLNOR : XX3Form<60, 162,
803                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
804                        "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
805                        [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
806                                                    v4i32:$XB)))]>;
807   def XXLOR : XX3Form<60, 146,
808                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
809                       "xxlor $XT, $XA, $XB", IIC_VecGeneral,
810                       [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
811   let isCodeGenOnly = 1 in
812   def XXLORf: XX3Form<60, 146,
813                       (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
814                       "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
815   def XXLXOR : XX3Form<60, 154,
816                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
817                        "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
818                        [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
819   } // isCommutable
820   let isCodeGenOnly = 1 in
821   def XXLXORz : XX3Form_Zero<60, 154, (outs vsrc:$XT), (ins),
822                        "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
823                        [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
824
825   let isCodeGenOnly = 1 in {
826     def XXLXORdpz : XX3Form_SetZero<60, 154,
827                          (outs vsfrc:$XT), (ins),
828                          "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
829                          [(set f64:$XT, (fpimm0))]>;
830     def XXLXORspz : XX3Form_SetZero<60, 154,
831                          (outs vssrc:$XT), (ins),
832                          "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
833                          [(set f32:$XT, (fpimm0))]>;
834   }
835
836   // Permutation Instructions
837   def XXMRGHW : XX3Form<60, 18,
838                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
839                        "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
840   def XXMRGLW : XX3Form<60, 50,
841                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
842                        "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
843
844   def XXPERMDI : XX3Form_2<60, 10,
845                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
846                        "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, []>;
847   let isCodeGenOnly = 1 in
848   def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
849                              "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
850   def XXSEL : XX4Form<60, 3,
851                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
852                       "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
853
854   def XXSLDWI : XX3Form_2<60, 2,
855                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
856                        "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
857                        [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
858                                                   imm32SExt16:$SHW))]>;
859   def XXSPLTW : XX2Form_2<60, 164,
860                        (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
861                        "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
862                        [(set v4i32:$XT,
863                              (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
864   let isCodeGenOnly = 1 in
865   def XXSPLTWs : XX2Form_2<60, 164,
866                        (outs vsrc:$XT), (ins vfrc:$XB, u2imm:$UIM),
867                        "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
868 } // hasSideEffects
869 } // UseVSXReg = 1
870
871 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
872 // instruction selection into a branch sequence.
873 let usesCustomInserter = 1,    // Expanded after instruction selection.
874     PPC970_Single = 1 in {
875
876   def SELECT_CC_VSRC: Pseudo<(outs vsrc:$dst),
877                              (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
878                              "#SELECT_CC_VSRC",
879                              []>;
880   def SELECT_VSRC: Pseudo<(outs vsrc:$dst),
881                           (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
882                           "#SELECT_VSRC",
883                           [(set v2f64:$dst,
884                                 (select i1:$cond, v2f64:$T, v2f64:$F))]>;
885   def SELECT_CC_VSFRC: Pseudo<(outs f8rc:$dst),
886                               (ins crrc:$cond, f8rc:$T, f8rc:$F,
887                                i32imm:$BROPC), "#SELECT_CC_VSFRC",
888                               []>;
889   def SELECT_VSFRC: Pseudo<(outs f8rc:$dst),
890                            (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
891                            "#SELECT_VSFRC",
892                            [(set f64:$dst,
893                                  (select i1:$cond, f64:$T, f64:$F))]>;
894   def SELECT_CC_VSSRC: Pseudo<(outs f4rc:$dst),
895                               (ins crrc:$cond, f4rc:$T, f4rc:$F,
896                                i32imm:$BROPC), "#SELECT_CC_VSSRC",
897                               []>;
898   def SELECT_VSSRC: Pseudo<(outs f4rc:$dst),
899                            (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
900                            "#SELECT_VSSRC",
901                            [(set f32:$dst,
902                                  (select i1:$cond, f32:$T, f32:$F))]>;
903 } // usesCustomInserter
904 } // AddedComplexity
905
906 def : InstAlias<"xvmovdp $XT, $XB",
907                 (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
908 def : InstAlias<"xvmovsp $XT, $XB",
909                 (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
910
911 def : InstAlias<"xxspltd $XT, $XB, 0",
912                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
913 def : InstAlias<"xxspltd $XT, $XB, 1",
914                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
915 def : InstAlias<"xxmrghd $XT, $XA, $XB",
916                 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
917 def : InstAlias<"xxmrgld $XT, $XA, $XB",
918                 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
919 def : InstAlias<"xxswapd $XT, $XB",
920                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
921 def : InstAlias<"xxspltd $XT, $XB, 0",
922                 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
923 def : InstAlias<"xxspltd $XT, $XB, 1",
924                 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
925 def : InstAlias<"xxswapd $XT, $XB",
926                 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
927
928 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
929
930 def : Pat<(v4i32 (vnot_ppc v4i32:$A)),
931           (v4i32 (XXLNOR $A, $A))>;
932 let Predicates = [IsBigEndian] in {
933 def : Pat<(v2f64 (scalar_to_vector f64:$A)),
934           (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
935
936 def : Pat<(f64 (extractelt v2f64:$S, 0)),
937           (f64 (EXTRACT_SUBREG $S, sub_64))>;
938 def : Pat<(f64 (extractelt v2f64:$S, 1)),
939           (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
940 }
941
942 let Predicates = [IsLittleEndian] in {
943 def : Pat<(v2f64 (scalar_to_vector f64:$A)),
944           (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
945                            (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
946
947 def : Pat<(f64 (extractelt v2f64:$S, 0)),
948           (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
949 def : Pat<(f64 (extractelt v2f64:$S, 1)),
950           (f64 (EXTRACT_SUBREG $S, sub_64))>;
951 }
952
953 // Additional fnmsub patterns: -a*c + b == -(a*c - b)
954 def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
955           (XSNMSUBADP $B, $C, $A)>;
956 def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B),
957           (XSNMSUBADP $B, $C, $A)>;
958
959 def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B),
960           (XVNMSUBADP $B, $C, $A)>;
961 def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B),
962           (XVNMSUBADP $B, $C, $A)>;
963
964 def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B),
965           (XVNMSUBASP $B, $C, $A)>;
966 def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B),
967           (XVNMSUBASP $B, $C, $A)>;
968
969 def : Pat<(v2f64 (bitconvert v4f32:$A)),
970           (COPY_TO_REGCLASS $A, VSRC)>;
971 def : Pat<(v2f64 (bitconvert v4i32:$A)),
972           (COPY_TO_REGCLASS $A, VSRC)>;
973 def : Pat<(v2f64 (bitconvert v8i16:$A)),
974           (COPY_TO_REGCLASS $A, VSRC)>;
975 def : Pat<(v2f64 (bitconvert v16i8:$A)),
976           (COPY_TO_REGCLASS $A, VSRC)>;
977
978 def : Pat<(v4f32 (bitconvert v2f64:$A)),
979           (COPY_TO_REGCLASS $A, VRRC)>;
980 def : Pat<(v4i32 (bitconvert v2f64:$A)),
981           (COPY_TO_REGCLASS $A, VRRC)>;
982 def : Pat<(v8i16 (bitconvert v2f64:$A)),
983           (COPY_TO_REGCLASS $A, VRRC)>;
984 def : Pat<(v16i8 (bitconvert v2f64:$A)),
985           (COPY_TO_REGCLASS $A, VRRC)>;
986
987 def : Pat<(v2i64 (bitconvert v4f32:$A)),
988           (COPY_TO_REGCLASS $A, VSRC)>;
989 def : Pat<(v2i64 (bitconvert v4i32:$A)),
990           (COPY_TO_REGCLASS $A, VSRC)>;
991 def : Pat<(v2i64 (bitconvert v8i16:$A)),
992           (COPY_TO_REGCLASS $A, VSRC)>;
993 def : Pat<(v2i64 (bitconvert v16i8:$A)),
994           (COPY_TO_REGCLASS $A, VSRC)>;
995
996 def : Pat<(v4f32 (bitconvert v2i64:$A)),
997           (COPY_TO_REGCLASS $A, VRRC)>;
998 def : Pat<(v4i32 (bitconvert v2i64:$A)),
999           (COPY_TO_REGCLASS $A, VRRC)>;
1000 def : Pat<(v8i16 (bitconvert v2i64:$A)),
1001           (COPY_TO_REGCLASS $A, VRRC)>;
1002 def : Pat<(v16i8 (bitconvert v2i64:$A)),
1003           (COPY_TO_REGCLASS $A, VRRC)>;
1004
1005 def : Pat<(v2f64 (bitconvert v2i64:$A)),
1006           (COPY_TO_REGCLASS $A, VRRC)>;
1007 def : Pat<(v2i64 (bitconvert v2f64:$A)),
1008           (COPY_TO_REGCLASS $A, VRRC)>;
1009
1010 def : Pat<(v2f64 (bitconvert v1i128:$A)),
1011           (COPY_TO_REGCLASS $A, VRRC)>;
1012 def : Pat<(v1i128 (bitconvert v2f64:$A)),
1013           (COPY_TO_REGCLASS $A, VRRC)>;
1014
1015 // sign extension patterns
1016 // To extend "in place" from v2i32 to v2i64, we have input data like:
1017 // | undef | i32 | undef | i32 |
1018 // but xvcvsxwdp expects the input in big-Endian format:
1019 // | i32 | undef | i32 | undef |
1020 // so we need to shift everything to the left by one i32 (word) before
1021 // the conversion.
1022 def : Pat<(sext_inreg v2i64:$C, v2i32),
1023           (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>;
1024 def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))),
1025           (XVCVSXWDP (XXSLDWI $C, $C, 1))>;
1026
1027 def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
1028           (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
1029 def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
1030           (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
1031
1032 def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
1033           (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
1034 def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
1035           (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
1036
1037 // Loads.
1038 let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
1039   def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1040
1041   // Stores.
1042   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
1043             (STXVD2X $rS, xoaddr:$dst)>;
1044   def : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
1045             (STXVD2X $rS, xoaddr:$dst)>;
1046   def : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
1047             (STXVW4X $rS, xoaddr:$dst)>;
1048   def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1049 }
1050 let Predicates = [IsBigEndian, HasVSX, HasOnlySwappingMemOps] in {
1051   def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1052   def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1053   def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1054   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1055   def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1056   def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1057   def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
1058   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
1059             (STXVW4X $rS, xoaddr:$dst)>;
1060 }
1061
1062 // Permutes.
1063 def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1064 def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
1065 def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
1066 def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
1067 def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1068
1069 // Selects.
1070 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
1071           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1072 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
1073           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1074 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
1075           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1076 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
1077           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1078 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
1079           (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1080 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
1081           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1082 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
1083           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1084 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
1085           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1086 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
1087           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1088 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
1089           (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1090
1091 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
1092           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1093 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
1094           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1095 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
1096           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1097 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
1098           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1099 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
1100           (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
1101 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
1102           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1103 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
1104           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1105 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
1106           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1107 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
1108           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1109 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
1110           (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1111
1112 // Divides.
1113 def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
1114           (XVDIVSP $A, $B)>;
1115 def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
1116           (XVDIVDP $A, $B)>;
1117
1118 // Reciprocal estimate
1119 def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1120           (XVRESP $A)>;
1121 def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1122           (XVREDP $A)>;
1123
1124 // Recip. square root estimate
1125 def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1126           (XVRSQRTESP $A)>;
1127 def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1128           (XVRSQRTEDP $A)>;
1129
1130 let Predicates = [IsLittleEndian] in {
1131 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1132           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1133 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1134           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1135 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1136           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1137 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1138           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1139 } // IsLittleEndian
1140
1141 let Predicates = [IsBigEndian] in {
1142 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1143           (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1144 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1145           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1146 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1147           (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1148 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1149           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1150 } // IsBigEndian
1151
1152 } // AddedComplexity
1153 } // HasVSX
1154
1155 def ScalarLoads {
1156   dag Li8 =       (i32 (extloadi8 xoaddr:$src));
1157   dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
1158   dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
1159   dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
1160   dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
1161
1162   dag Li16 =      (i32 (extloadi16 xoaddr:$src));
1163   dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
1164   dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
1165   dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
1166   dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
1167
1168   dag Li32 = (i32 (load xoaddr:$src));
1169 }
1170
1171 // The following VSX instructions were introduced in Power ISA 2.07
1172 /* FIXME: if the operands are v2i64, these patterns will not match.
1173    we should define new patterns or otherwise match the same patterns
1174    when the elements are larger than i32.
1175 */
1176 def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1177 def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1178 let Predicates = [HasP8Vector] in {
1179 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1180   let isCommutable = 1, UseVSXReg = 1 in {
1181     def XXLEQV : XX3Form<60, 186,
1182                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1183                          "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1184                          [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1185     def XXLNAND : XX3Form<60, 178,
1186                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1187                           "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1188                           [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1189                                                     v4i32:$XB)))]>;
1190   } // isCommutable, UseVSXReg
1191
1192   def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1193             (XXLEQV $A, $B)>;
1194
1195   let UseVSXReg = 1 in {
1196   def XXLORC : XX3Form<60, 170,
1197                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1198                        "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1199                        [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1200
1201   // VSX scalar loads introduced in ISA 2.07
1202   let mayLoad = 1, mayStore = 0 in {
1203     let CodeSize = 3 in
1204     def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1205                          "lxsspx $XT, $src", IIC_LdStLFD,
1206                          [(set f32:$XT, (load xoaddr:$src))]>;
1207     def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1208                           "lxsiwax $XT, $src", IIC_LdStLFD,
1209                           [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1210     def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1211                           "lxsiwzx $XT, $src", IIC_LdStLFD,
1212                           [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1213   } // mayLoad
1214
1215   // VSX scalar stores introduced in ISA 2.07
1216   let mayStore = 1, mayLoad = 0 in {
1217     let CodeSize = 3 in
1218     def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1219                           "stxsspx $XT, $dst", IIC_LdStSTFD,
1220                           [(store f32:$XT, xoaddr:$dst)]>;
1221     def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1222                           "stxsiwx $XT, $dst", IIC_LdStSTFD,
1223                           [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1224   } // mayStore
1225   } // UseVSXReg = 1
1226
1227   def : Pat<(f64 (extloadf32 xoaddr:$src)),
1228             (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>;
1229   def : Pat<(f32 (fpround (extloadf32 xoaddr:$src))),
1230             (f32 (LXSSPX xoaddr:$src))>;
1231   def : Pat<(f64 (fpextend f32:$src)),
1232             (COPY_TO_REGCLASS $src, VSFRC)>;
1233
1234   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1235             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1236   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1237             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1238   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1239             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1240   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1241             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1242   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1243             (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1244   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1245             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1246   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1247             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1248   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1249             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1250   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1251             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1252   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1253             (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1254
1255   let UseVSXReg = 1 in {
1256   // VSX Elementary Scalar FP arithmetic (SP)
1257   let isCommutable = 1 in {
1258     def XSADDSP : XX3Form<60, 0,
1259                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1260                           "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1261                           [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1262     def XSMULSP : XX3Form<60, 16,
1263                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1264                           "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1265                           [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1266   } // isCommutable
1267
1268   def XSDIVSP : XX3Form<60, 24,
1269                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1270                         "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1271                         [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1272   def XSRESP : XX2Form<60, 26,
1273                         (outs vssrc:$XT), (ins vssrc:$XB),
1274                         "xsresp $XT, $XB", IIC_VecFP,
1275                         [(set f32:$XT, (PPCfre f32:$XB))]>;
1276   def XSSQRTSP : XX2Form<60, 11,
1277                         (outs vssrc:$XT), (ins vssrc:$XB),
1278                         "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1279                         [(set f32:$XT, (fsqrt f32:$XB))]>;
1280   def XSRSQRTESP : XX2Form<60, 10,
1281                            (outs vssrc:$XT), (ins vssrc:$XB),
1282                            "xsrsqrtesp $XT, $XB", IIC_VecFP,
1283                            [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1284   def XSSUBSP : XX3Form<60, 8,
1285                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1286                         "xssubsp $XT, $XA, $XB", IIC_VecFP,
1287                         [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1288
1289   // FMA Instructions
1290   let BaseName = "XSMADDASP" in {
1291   let isCommutable = 1 in
1292   def XSMADDASP : XX3Form<60, 1,
1293                           (outs vssrc:$XT),
1294                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1295                           "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1296                           [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1297                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1298                           AltVSXFMARel;
1299   let IsVSXFMAAlt = 1 in
1300   def XSMADDMSP : XX3Form<60, 9,
1301                           (outs vssrc:$XT),
1302                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1303                           "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1304                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1305                           AltVSXFMARel;
1306   }
1307
1308   let BaseName = "XSMSUBASP" in {
1309   let isCommutable = 1 in
1310   def XSMSUBASP : XX3Form<60, 17,
1311                           (outs vssrc:$XT),
1312                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1313                           "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1314                           [(set f32:$XT, (fma f32:$XA, f32:$XB,
1315                                               (fneg f32:$XTi)))]>,
1316                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1317                           AltVSXFMARel;
1318   let IsVSXFMAAlt = 1 in
1319   def XSMSUBMSP : XX3Form<60, 25,
1320                           (outs vssrc:$XT),
1321                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1322                           "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1323                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1324                           AltVSXFMARel;
1325   }
1326
1327   let BaseName = "XSNMADDASP" in {
1328   let isCommutable = 1 in
1329   def XSNMADDASP : XX3Form<60, 129,
1330                           (outs vssrc:$XT),
1331                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1332                           "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1333                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1334                                                     f32:$XTi)))]>,
1335                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1336                           AltVSXFMARel;
1337   let IsVSXFMAAlt = 1 in
1338   def XSNMADDMSP : XX3Form<60, 137,
1339                           (outs vssrc:$XT),
1340                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1341                           "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1342                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1343                           AltVSXFMARel;
1344   }
1345
1346   let BaseName = "XSNMSUBASP" in {
1347   let isCommutable = 1 in
1348   def XSNMSUBASP : XX3Form<60, 145,
1349                           (outs vssrc:$XT),
1350                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1351                           "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1352                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1353                                                     (fneg f32:$XTi))))]>,
1354                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1355                           AltVSXFMARel;
1356   let IsVSXFMAAlt = 1 in
1357   def XSNMSUBMSP : XX3Form<60, 153,
1358                           (outs vssrc:$XT),
1359                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1360                           "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1361                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1362                           AltVSXFMARel;
1363   }
1364
1365   // Single Precision Conversions (FP <-> INT)
1366   def XSCVSXDSP : XX2Form<60, 312,
1367                       (outs vssrc:$XT), (ins vsfrc:$XB),
1368                       "xscvsxdsp $XT, $XB", IIC_VecFP,
1369                       [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1370   def XSCVUXDSP : XX2Form<60, 296,
1371                       (outs vssrc:$XT), (ins vsfrc:$XB),
1372                       "xscvuxdsp $XT, $XB", IIC_VecFP,
1373                       [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1374
1375   // Conversions between vector and scalar single precision
1376   def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1377                           "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1378   def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1379                           "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1380   } // UseVSXReg = 1
1381
1382   let Predicates = [IsLittleEndian] in {
1383   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1384             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1385   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1386             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1387   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1388             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1389   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1390             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1391   }
1392
1393   let Predicates = [IsBigEndian] in {
1394   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1395             (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1396   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1397             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1398   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1399             (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1400   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1401             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1402   }
1403   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.Li32)),
1404             (v4i32 (XXSPLTWs (LXSIWAX xoaddr:$src), 1))>;
1405 } // AddedComplexity = 400
1406 } // HasP8Vector
1407
1408 let UseVSXReg = 1, AddedComplexity = 400 in {
1409 let Predicates = [HasDirectMove] in {
1410   // VSX direct move instructions
1411   def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1412                               "mfvsrd $rA, $XT", IIC_VecGeneral,
1413                               [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1414       Requires<[In64BitMode]>;
1415   let isCodeGenOnly = 1 in
1416   def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vrrc:$XT),
1417                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1418                              []>,
1419       Requires<[In64BitMode]>;
1420   def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1421                                "mfvsrwz $rA, $XT", IIC_VecGeneral,
1422                                [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1423   def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1424                               "mtvsrd $XT, $rA", IIC_VecGeneral,
1425                               [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1426       Requires<[In64BitMode]>;
1427   def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1428                                "mtvsrwa $XT, $rA", IIC_VecGeneral,
1429                                [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1430   def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1431                                "mtvsrwz $XT, $rA", IIC_VecGeneral,
1432                                [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1433 } // HasDirectMove
1434
1435 let Predicates = [IsISA3_0, HasDirectMove] in {
1436   def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1437                               "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1438
1439   def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
1440                        "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1441                        []>, Requires<[In64BitMode]>;
1442
1443   def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1444                               "mfvsrld $rA, $XT", IIC_VecGeneral,
1445                               []>, Requires<[In64BitMode]>;
1446
1447 } // IsISA3_0, HasDirectMove
1448 } // UseVSXReg = 1
1449
1450 // We want to parse this from asm, but we don't want to emit this as it would
1451 // be emitted with a VSX reg. So leave Emit = 0 here.
1452 def : InstAlias<"mfvrd $rA, $XT",
1453                 (MFVRD g8rc:$rA, vrrc:$XT), 0>;
1454 def : InstAlias<"mffprd $rA, $src",
1455                 (MFVSRD g8rc:$rA, f8rc:$src)>;
1456
1457 /*  Direct moves of various widths from GPR's into VSR's. Each move lines
1458     the value up into element 0 (both BE and LE). Namely, entities smaller than
1459     a doubleword are shifted left and moved for BE. For LE, they're moved, then
1460     swapped to go into the least significant element of the VSR.
1461 */
1462 def MovesToVSR {
1463   dag BE_BYTE_0 =
1464     (MTVSRD
1465       (RLDICR
1466         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1467   dag BE_HALF_0 =
1468     (MTVSRD
1469       (RLDICR
1470         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1471   dag BE_WORD_0 =
1472     (MTVSRD
1473       (RLDICR
1474         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1475   dag BE_DWORD_0 = (MTVSRD $A);
1476
1477   dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1478   dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1479                                         LE_MTVSRW, sub_64));
1480   dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1481   dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1482                                          BE_DWORD_0, sub_64));
1483   dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1484 }
1485
1486 /*  Patterns for extracting elements out of vectors. Integer elements are
1487     extracted using direct move operations. Patterns for extracting elements
1488     whose indices are not available at compile time are also provided with
1489     various _VARIABLE_ patterns.
1490     The numbering for the DAG's is for LE, but when used on BE, the correct
1491     LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1492 */
1493 def VectorExtractions {
1494   // Doubleword extraction
1495   dag LE_DWORD_0 =
1496     (MFVSRD
1497       (EXTRACT_SUBREG
1498         (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1499                   (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1500   dag LE_DWORD_1 = (MFVSRD
1501                      (EXTRACT_SUBREG
1502                        (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1503
1504   // Word extraction
1505   dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1506   dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1507   dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1508                              (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1509   dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1510
1511   // Halfword extraction
1512   dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1513   dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1514   dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1515   dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1516   dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1517   dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1518   dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1519   dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1520
1521   // Byte extraction
1522   dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1523   dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1524   dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1525   dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1526   dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1527   dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1528   dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1529   dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1530   dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1531   dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1532   dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1533   dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1534   dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1535   dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1536   dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1537   dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1538
1539   /* Variable element number (BE and LE patterns must be specified separately)
1540      This is a rather involved process.
1541
1542      Conceptually, this is how the move is accomplished:
1543      1. Identify which doubleword contains the element
1544      2. Shift in the VMX register so that the correct doubleword is correctly
1545         lined up for the MFVSRD
1546      3. Perform the move so that the element (along with some extra stuff)
1547         is in the GPR
1548      4. Right shift within the GPR so that the element is right-justified
1549
1550      Of course, the index is an element number which has a different meaning
1551      on LE/BE so the patterns have to be specified separately.
1552
1553      Note: The final result will be the element right-justified with high
1554            order bits being arbitrarily defined (namely, whatever was in the
1555            vector register to the left of the value originally).
1556   */
1557
1558   /*  LE variable byte
1559       Number 1. above:
1560       - For elements 0-7, we shift left by 8 bytes since they're on the right
1561       - For elements 8-15, we need not shift (shift left by zero bytes)
1562       This is accomplished by inverting the bits of the index and AND-ing
1563       with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1564   */
1565   dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx));
1566
1567   //  Number 2. above:
1568   //  - Now that we set up the shift amount, we shift in the VMX register
1569   dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC);
1570
1571   //  Number 3. above:
1572   //  - The doubleword containing our element is moved to a GPR
1573   dag LE_MV_VBYTE = (MFVSRD
1574                       (EXTRACT_SUBREG
1575                         (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1576                         sub_64));
1577
1578   /*  Number 4. above:
1579       - Truncate the element number to the range 0-7 (8-15 are symmetrical
1580         and out of range values are truncated accordingly)
1581       - Multiply by 8 as we need to shift right by the number of bits, not bytes
1582       - Shift right in the GPR by the calculated value
1583   */
1584   dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1585                                        sub_32);
1586   dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1587                                          sub_32);
1588
1589   /*  LE variable halfword
1590       Number 1. above:
1591       - For elements 0-3, we shift left by 8 since they're on the right
1592       - For elements 4-7, we need not shift (shift left by zero bytes)
1593       Similarly to the byte pattern, we invert the bits of the index, but we
1594       AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1595       Of course, the shift is still by 8 bytes, so we must multiply by 2.
1596   */
1597   dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62));
1598
1599   //  Number 2. above:
1600   //  - Now that we set up the shift amount, we shift in the VMX register
1601   dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC);
1602
1603   //  Number 3. above:
1604   //  - The doubleword containing our element is moved to a GPR
1605   dag LE_MV_VHALF = (MFVSRD
1606                       (EXTRACT_SUBREG
1607                         (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1608                         sub_64));
1609
1610   /*  Number 4. above:
1611       - Truncate the element number to the range 0-3 (4-7 are symmetrical
1612         and out of range values are truncated accordingly)
1613       - Multiply by 16 as we need to shift right by the number of bits
1614       - Shift right in the GPR by the calculated value
1615   */
1616   dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1617                                        sub_32);
1618   dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1619                                          sub_32);
1620
1621   /*  LE variable word
1622       Number 1. above:
1623       - For elements 0-1, we shift left by 8 since they're on the right
1624       - For elements 2-3, we need not shift
1625   */
1626   dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61));
1627
1628   //  Number 2. above:
1629   //  - Now that we set up the shift amount, we shift in the VMX register
1630   dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC);
1631
1632   //  Number 3. above:
1633   //  - The doubleword containing our element is moved to a GPR
1634   dag LE_MV_VWORD = (MFVSRD
1635                       (EXTRACT_SUBREG
1636                         (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1637                         sub_64));
1638
1639   /*  Number 4. above:
1640       - Truncate the element number to the range 0-1 (2-3 are symmetrical
1641         and out of range values are truncated accordingly)
1642       - Multiply by 32 as we need to shift right by the number of bits
1643       - Shift right in the GPR by the calculated value
1644   */
1645   dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1646                                        sub_32);
1647   dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1648                                          sub_32);
1649
1650   /*  LE variable doubleword
1651       Number 1. above:
1652       - For element 0, we shift left by 8 since it's on the right
1653       - For element 1, we need not shift
1654   */
1655   dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60));
1656
1657   //  Number 2. above:
1658   //  - Now that we set up the shift amount, we shift in the VMX register
1659   dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC);
1660
1661   // Number 3. above:
1662   //  - The doubleword containing our element is moved to a GPR
1663   //  - Number 4. is not needed for the doubleword as the value is 64-bits
1664   dag LE_VARIABLE_DWORD =
1665         (MFVSRD (EXTRACT_SUBREG
1666                   (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1667                   sub_64));
1668
1669   /*  LE variable float
1670       - Shift the vector to line up the desired element to BE Word 0
1671       - Convert 32-bit float to a 64-bit single precision float
1672   */
1673   dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61));
1674   dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1675   dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1676
1677   /*  LE variable double
1678       Same as the LE doubleword except there is no move.
1679   */
1680   dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1681                                   (COPY_TO_REGCLASS $S, VRRC),
1682                                   LE_VDWORD_PERM_VEC);
1683   dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1684
1685   /*  BE variable byte
1686       The algorithm here is the same as the LE variable byte except:
1687       - The shift in the VMX register is by 0/8 for opposite element numbers so
1688         we simply AND the element number with 0x8
1689       - The order of elements after the move to GPR is reversed, so we invert
1690         the bits of the index prior to truncating to the range 0-7
1691   */
1692   dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8));
1693   dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC);
1694   dag BE_MV_VBYTE = (MFVSRD
1695                       (EXTRACT_SUBREG
1696                         (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1697                         sub_64));
1698   dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1699                                        sub_32);
1700   dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1701                                          sub_32);
1702
1703   /*  BE variable halfword
1704       The algorithm here is the same as the LE variable halfword except:
1705       - The shift in the VMX register is by 0/8 for opposite element numbers so
1706         we simply AND the element number with 0x4 and multiply by 2
1707       - The order of elements after the move to GPR is reversed, so we invert
1708         the bits of the index prior to truncating to the range 0-3
1709   */
1710   dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62));
1711   dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC);
1712   dag BE_MV_VHALF = (MFVSRD
1713                       (EXTRACT_SUBREG
1714                         (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1715                         sub_64));
1716   dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1717                                        sub_32);
1718   dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1719                                          sub_32);
1720
1721   /*  BE variable word
1722       The algorithm is the same as the LE variable word except:
1723       - The shift in the VMX register happens for opposite element numbers
1724       - The order of elements after the move to GPR is reversed, so we invert
1725         the bits of the index prior to truncating to the range 0-1
1726   */
1727   dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61));
1728   dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC);
1729   dag BE_MV_VWORD = (MFVSRD
1730                       (EXTRACT_SUBREG
1731                         (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1732                         sub_64));
1733   dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1734                                        sub_32);
1735   dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1736                                          sub_32);
1737
1738   /*  BE variable doubleword
1739       Same as the LE doubleword except we shift in the VMX register for opposite
1740       element indices.
1741   */
1742   dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60));
1743   dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC);
1744   dag BE_VARIABLE_DWORD =
1745         (MFVSRD (EXTRACT_SUBREG
1746                   (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1747                   sub_64));
1748
1749   /*  BE variable float
1750       - Shift the vector to line up the desired element to BE Word 0
1751       - Convert 32-bit float to a 64-bit single precision float
1752   */
1753   dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61));
1754   dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1755   dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1756
1757   /* BE variable double
1758       Same as the BE doubleword except there is no move.
1759   */
1760   dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1761                                   (COPY_TO_REGCLASS $S, VRRC),
1762                                   BE_VDWORD_PERM_VEC);
1763   dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1764 }
1765
1766 let AddedComplexity = 400 in {
1767 // v4f32 scalar <-> vector conversions (BE)
1768 let Predicates = [IsBigEndian, HasP8Vector] in {
1769   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1770             (v4f32 (XSCVDPSPN $A))>;
1771   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1772             (f32 (XSCVSPDPN $S))>;
1773   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1774             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1775   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1776             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1777   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1778             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1779   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1780             (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1781 } // IsBigEndian, HasP8Vector
1782
1783 // Variable index vector_extract for v2f64 does not require P8Vector
1784 let Predicates = [IsBigEndian, HasVSX] in
1785   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1786             (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1787
1788 let Predicates = [IsBigEndian, HasDirectMove] in {
1789   // v16i8 scalar <-> vector conversions (BE)
1790   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1791             (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1792   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1793             (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1794   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1795             (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1796   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1797             (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1798   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1799             (i32 VectorExtractions.LE_BYTE_15)>;
1800   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1801             (i32 VectorExtractions.LE_BYTE_14)>;
1802   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1803             (i32 VectorExtractions.LE_BYTE_13)>;
1804   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1805             (i32 VectorExtractions.LE_BYTE_12)>;
1806   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1807             (i32 VectorExtractions.LE_BYTE_11)>;
1808   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1809             (i32 VectorExtractions.LE_BYTE_10)>;
1810   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1811             (i32 VectorExtractions.LE_BYTE_9)>;
1812   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1813             (i32 VectorExtractions.LE_BYTE_8)>;
1814   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1815             (i32 VectorExtractions.LE_BYTE_7)>;
1816   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1817             (i32 VectorExtractions.LE_BYTE_6)>;
1818   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1819             (i32 VectorExtractions.LE_BYTE_5)>;
1820   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1821             (i32 VectorExtractions.LE_BYTE_4)>;
1822   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1823             (i32 VectorExtractions.LE_BYTE_3)>;
1824   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1825             (i32 VectorExtractions.LE_BYTE_2)>;
1826   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1827             (i32 VectorExtractions.LE_BYTE_1)>;
1828   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1829             (i32 VectorExtractions.LE_BYTE_0)>;
1830   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1831             (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1832
1833   // v8i16 scalar <-> vector conversions (BE)
1834   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1835             (i32 VectorExtractions.LE_HALF_7)>;
1836   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1837             (i32 VectorExtractions.LE_HALF_6)>;
1838   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1839             (i32 VectorExtractions.LE_HALF_5)>;
1840   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1841             (i32 VectorExtractions.LE_HALF_4)>;
1842   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1843             (i32 VectorExtractions.LE_HALF_3)>;
1844   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1845             (i32 VectorExtractions.LE_HALF_2)>;
1846   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1847             (i32 VectorExtractions.LE_HALF_1)>;
1848   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1849             (i32 VectorExtractions.LE_HALF_0)>;
1850   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1851             (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1852
1853   // v4i32 scalar <-> vector conversions (BE)
1854   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1855             (i32 VectorExtractions.LE_WORD_3)>;
1856   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1857             (i32 VectorExtractions.LE_WORD_2)>;
1858   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1859             (i32 VectorExtractions.LE_WORD_1)>;
1860   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1861             (i32 VectorExtractions.LE_WORD_0)>;
1862   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1863             (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1864
1865   // v2i64 scalar <-> vector conversions (BE)
1866   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1867             (i64 VectorExtractions.LE_DWORD_1)>;
1868   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1869             (i64 VectorExtractions.LE_DWORD_0)>;
1870   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1871             (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1872 } // IsBigEndian, HasDirectMove
1873
1874 // v4f32 scalar <-> vector conversions (LE)
1875 let Predicates = [IsLittleEndian, HasP8Vector] in {
1876   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1877             (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1878   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1879             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1880   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1881             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1882   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1883             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1884   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1885             (f32 (XSCVSPDPN $S))>;
1886   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1887             (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1888 } // IsLittleEndian, HasP8Vector
1889
1890 // Variable index vector_extract for v2f64 does not require P8Vector
1891 let Predicates = [IsLittleEndian, HasVSX] in
1892   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1893             (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1894
1895 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1896 def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1897
1898 let Predicates = [IsLittleEndian, HasDirectMove] in {
1899   // v16i8 scalar <-> vector conversions (LE)
1900   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1901             (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1902   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1903             (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1904   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1905             (v4i32 MovesToVSR.LE_WORD_0)>;
1906   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1907             (v2i64 MovesToVSR.LE_DWORD_0)>;
1908   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1909             (i32 VectorExtractions.LE_BYTE_0)>;
1910   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1911             (i32 VectorExtractions.LE_BYTE_1)>;
1912   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1913             (i32 VectorExtractions.LE_BYTE_2)>;
1914   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1915             (i32 VectorExtractions.LE_BYTE_3)>;
1916   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1917             (i32 VectorExtractions.LE_BYTE_4)>;
1918   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1919             (i32 VectorExtractions.LE_BYTE_5)>;
1920   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1921             (i32 VectorExtractions.LE_BYTE_6)>;
1922   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1923             (i32 VectorExtractions.LE_BYTE_7)>;
1924   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1925             (i32 VectorExtractions.LE_BYTE_8)>;
1926   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1927             (i32 VectorExtractions.LE_BYTE_9)>;
1928   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1929             (i32 VectorExtractions.LE_BYTE_10)>;
1930   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1931             (i32 VectorExtractions.LE_BYTE_11)>;
1932   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1933             (i32 VectorExtractions.LE_BYTE_12)>;
1934   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1935             (i32 VectorExtractions.LE_BYTE_13)>;
1936   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1937             (i32 VectorExtractions.LE_BYTE_14)>;
1938   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1939             (i32 VectorExtractions.LE_BYTE_15)>;
1940   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1941             (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
1942
1943   // v8i16 scalar <-> vector conversions (LE)
1944   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1945             (i32 VectorExtractions.LE_HALF_0)>;
1946   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1947             (i32 VectorExtractions.LE_HALF_1)>;
1948   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1949             (i32 VectorExtractions.LE_HALF_2)>;
1950   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1951             (i32 VectorExtractions.LE_HALF_3)>;
1952   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1953             (i32 VectorExtractions.LE_HALF_4)>;
1954   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1955             (i32 VectorExtractions.LE_HALF_5)>;
1956   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1957             (i32 VectorExtractions.LE_HALF_6)>;
1958   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1959             (i32 VectorExtractions.LE_HALF_7)>;
1960   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1961             (i32 VectorExtractions.LE_VARIABLE_HALF)>;
1962
1963   // v4i32 scalar <-> vector conversions (LE)
1964   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1965             (i32 VectorExtractions.LE_WORD_0)>;
1966   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1967             (i32 VectorExtractions.LE_WORD_1)>;
1968   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1969             (i32 VectorExtractions.LE_WORD_2)>;
1970   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1971             (i32 VectorExtractions.LE_WORD_3)>;
1972   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1973             (i32 VectorExtractions.LE_VARIABLE_WORD)>;
1974
1975   // v2i64 scalar <-> vector conversions (LE)
1976   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1977             (i64 VectorExtractions.LE_DWORD_0)>;
1978   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1979             (i64 VectorExtractions.LE_DWORD_1)>;
1980   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1981             (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
1982 } // IsLittleEndian, HasDirectMove
1983
1984 let Predicates = [HasDirectMove, HasVSX] in {
1985 // bitconvert f32 -> i32
1986 // (convert to 32-bit fp single, shift right 1 word, move to GPR)
1987 def : Pat<(i32 (bitconvert f32:$S)),
1988           (i32 (MFVSRWZ (EXTRACT_SUBREG
1989                           (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
1990                           sub_64)))>;
1991 // bitconvert i32 -> f32
1992 // (move to FPR, shift left 1 word, convert to 64-bit fp single)
1993 def : Pat<(f32 (bitconvert i32:$A)),
1994           (f32 (XSCVSPDPN
1995                  (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
1996
1997 // bitconvert f64 -> i64
1998 // (move to GPR, nothing else needed)
1999 def : Pat<(i64 (bitconvert f64:$S)),
2000           (i64 (MFVSRD $S))>;
2001
2002 // bitconvert i64 -> f64
2003 // (move to FPR, nothing else needed)
2004 def : Pat<(f64 (bitconvert i64:$S)),
2005           (f64 (MTVSRD $S))>;
2006 }
2007
2008 // Materialize a zero-vector of long long
2009 def : Pat<(v2i64 immAllZerosV),
2010           (v2i64 (XXLXORz))>;
2011 }
2012
2013 def AlignValues {
2014   dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2015   dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2016 }
2017
2018 // The following VSX instructions were introduced in Power ISA 3.0
2019 def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2020 let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2021
2022   // [PO VRT XO VRB XO /]
2023   class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2024                       list<dag> pattern>
2025     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2026                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2027
2028   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2029   class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2030                          list<dag> pattern>
2031     : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2032
2033   // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2034   // So we use different operand class for VRB
2035   class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2036                            RegisterOperand vbtype, list<dag> pattern>
2037     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2038                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2039
2040   let UseVSXReg = 1 in {
2041   // [PO T XO B XO BX /]
2042   class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2043                         list<dag> pattern>
2044     : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2045                       !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2046
2047   // [PO T XO B XO BX TX]
2048   class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2049                         RegisterOperand vtype, list<dag> pattern>
2050     : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2051                       !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2052
2053   // [PO T A B XO AX BX TX], src and dest register use different operand class
2054   class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2055                   RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2056                   InstrItinClass itin, list<dag> pattern>
2057     : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2058               !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2059   } // UseVSXReg = 1
2060
2061   // [PO VRT VRA VRB XO /]
2062   class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2063                       list<dag> pattern>
2064     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2065               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2066
2067   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2068   class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2069                          list<dag> pattern>
2070     : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2071
2072   //===--------------------------------------------------------------------===//
2073   // Quad-Precision Scalar Move Instructions:
2074
2075   // Copy Sign
2076   def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>;
2077
2078   // Absolute/Negative-Absolute/Negate
2079   def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp" , []>;
2080   def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp", []>;
2081   def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>;
2082
2083   //===--------------------------------------------------------------------===//
2084   // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2085
2086   // Add/Divide/Multiply/Subtract
2087   def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp" , []>;
2088   def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>;
2089   def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp" , []>;
2090   def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>;
2091   def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp" , []>;
2092   def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>;
2093   def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" , []>;
2094   def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>;
2095
2096   // Square-Root
2097   def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp" , []>;
2098   def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>;
2099
2100   // (Negative) Multiply-{Add/Subtract}
2101   def XSMADDQP  : X_VT5_VA5_VB5   <63, 388, "xsmaddqp"  , []>;
2102   def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>;
2103   def XSMSUBQP  : X_VT5_VA5_VB5   <63, 420, "xsmsubqp"  , []>;
2104   def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>;
2105   def XSNMADDQP : X_VT5_VA5_VB5   <63, 452, "xsnmaddqp" , []>;
2106   def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>;
2107   def XSNMSUBQP : X_VT5_VA5_VB5   <63, 484, "xsnmsubqp" , []>;
2108   def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>;
2109
2110   //===--------------------------------------------------------------------===//
2111   // Quad/Double-Precision Compare Instructions:
2112
2113   // [PO BF // VRA VRB XO /]
2114   class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2115                       list<dag> pattern>
2116     : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2117                !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2118     let Pattern = pattern;
2119   }
2120
2121   // QP Compare Ordered/Unordered
2122   def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2123   def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2124
2125   // DP/QP Compare Exponents
2126   def XSCMPEXPDP : XX3Form_1<60, 59,
2127                              (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2128                              "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>,
2129                    UseVSXReg;
2130   def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2131
2132   // DP Compare ==, >=, >, !=
2133   // Use vsrc for XT, because the entire register of XT is set.
2134   // XT.dword[1] = 0x0000_0000_0000_0000
2135   def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2136                                   IIC_FPCompare, []>;
2137   def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2138                                   IIC_FPCompare, []>;
2139   def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2140                                   IIC_FPCompare, []>;
2141   def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc,
2142                                   IIC_FPCompare, []>;
2143   let UseVSXReg = 1 in {
2144   // Vector Compare Not Equal
2145   def XVCMPNEDP  : XX3Form_Rc<60, 123,
2146                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2147                               "xvcmpnedp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2148   let Defs = [CR6] in
2149   def XVCMPNEDPo : XX3Form_Rc<60, 123,
2150                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2151                               "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2152                               isDOT;
2153   def XVCMPNESP  : XX3Form_Rc<60,  91,
2154                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2155                               "xvcmpnesp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2156   let Defs = [CR6] in
2157   def XVCMPNESPo : XX3Form_Rc<60,  91,
2158                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2159                               "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2160                               isDOT;
2161   } // UseVSXReg = 1
2162
2163   //===--------------------------------------------------------------------===//
2164   // Quad-Precision Floating-Point Conversion Instructions:
2165
2166   // Convert DP -> QP
2167   def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, []>;
2168
2169   // Round & Convert QP -> DP (dword[1] is set to zero)
2170   def XSCVQPDP  : X_VT5_XO5_VB5   <63, 20, 836, "xscvqpdp" , []>;
2171   def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>;
2172
2173   // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2174   def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2175   def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2176   def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2177   def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2178
2179   // Convert (Un)Signed DWord -> QP
2180   def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2181   def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2182
2183   let UseVSXReg = 1 in {
2184   //===--------------------------------------------------------------------===//
2185   // Round to Floating-Point Integer Instructions
2186
2187   // (Round &) Convert DP <-> HP
2188   // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2189   // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2190   // but we still use vsfrc for it.
2191   def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2192   def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2193
2194   // Vector HP -> SP
2195   def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2196   def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2197                                  [(set v4f32:$XT,
2198                                      (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2199
2200   } // UseVSXReg = 1
2201
2202   // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2203   // separate pattern so that it can convert the input register class from
2204   // VRRC(v8i16) to VSRC.
2205   def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2206             (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2207
2208   class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2209                                 list<dag> pattern>
2210     : Z23Form_1<opcode, xo,
2211                 (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2212                 !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2213     let RC = ex;
2214   }
2215
2216   // Round to Quad-Precision Integer [with Inexact]
2217   def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2218   def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2219
2220   // Round Quad-Precision to Double-Extended Precision (fp80)
2221   def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2222
2223   //===--------------------------------------------------------------------===//
2224   // Insert/Extract Instructions
2225
2226   // Insert Exponent DP/QP
2227   // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2228   def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2229                           "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg;
2230   // vB NOTE: only vB.dword[0] is used, that's why we don't use
2231   //          X_VT5_VA5_VB5 form
2232   def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2233                           "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2234
2235   // Extract Exponent/Significand DP/QP
2236   def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2237   def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2238
2239   def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2240   def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2241
2242   // Vector Insert Word
2243   let UseVSXReg = 1 in {
2244   // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2245   def XXINSERTW   :
2246     XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2247                      (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2248                      "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2249                      [(set v4i32:$XT, (PPCxxinsert v4i32:$XTi, v4i32:$XB,
2250                                                    imm32SExt16:$UIM))]>,
2251                      RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2252
2253   // Vector Extract Unsigned Word
2254   def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2255                                   (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2256                                   "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2257   } // UseVSXReg = 1
2258
2259   // Vector Insert Exponent DP/SP
2260   def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2261     IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2262   def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2263     IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2264
2265   // Vector Extract Exponent/Significand DP/SP
2266   def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2267                                  [(set v2i64: $XT,
2268                                   (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2269   def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2270                                  [(set v4i32: $XT,
2271                                   (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2272   def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2273                                  [(set v2i64: $XT,
2274                                   (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2275   def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2276                                  [(set v4i32: $XT,
2277                                   (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2278
2279   let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2280   // Extra patterns expanding to vector Extract Word/Insert Word
2281   def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2282             (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2283   def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2284             (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2285   } // AddedComplexity = 400, HasP9Vector
2286
2287   //===--------------------------------------------------------------------===//
2288
2289   // Test Data Class SP/DP/QP
2290   let UseVSXReg = 1 in {
2291   def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2292                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2293                               "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2294   def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2295                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2296                               "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2297   } // UseVSXReg = 1
2298   def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2299                               (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2300                               "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2301
2302   // Vector Test Data Class SP/DP
2303   let UseVSXReg = 1 in {
2304   def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2305                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2306                               "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2307                               [(set v4i32: $XT,
2308                                (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>;
2309   def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2310                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2311                               "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2312                               [(set v2i64: $XT,
2313                                (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>;
2314   } // UseVSXReg = 1
2315
2316   //===--------------------------------------------------------------------===//
2317
2318   // Maximum/Minimum Type-C/Type-J DP
2319   // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2320   def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2321                                  IIC_VecFP, []>;
2322   def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2323                                  IIC_VecFP, []>;
2324   def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2325                                  IIC_VecFP, []>;
2326   def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2327                                  IIC_VecFP, []>;
2328
2329   //===--------------------------------------------------------------------===//
2330
2331   // Vector Byte-Reverse H/W/D/Q Word
2332   def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2333   def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2334   def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2335   def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2336
2337   // Vector Permute
2338   def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2339                                 IIC_VecPerm, []>;
2340   def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2341                                 IIC_VecPerm, []>;
2342
2343   // Vector Splat Immediate Byte
2344   def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2345                             "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg;
2346
2347   //===--------------------------------------------------------------------===//
2348   // Vector/Scalar Load/Store Instructions
2349
2350   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2351   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2352   let mayLoad = 1, mayStore = 0 in {
2353   // Load Vector
2354   def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2355                             "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg;
2356   // Load DWord
2357   def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2358                        "lxsd $vD, $src", IIC_LdStLFD, []>;
2359   // Load SP from src, convert it to DP, and place in dword[0]
2360   def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2361                        "lxssp $vD, $src", IIC_LdStLFD, []>;
2362
2363   // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2364   // "out" and "in" dag
2365   class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2366                       RegisterOperand vtype, list<dag> pattern>
2367     : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2368               !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg;
2369
2370   // Load as Integer Byte/Halfword & Zero Indexed
2371   def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2372                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2373   def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2374                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2375
2376   // Load Vector Halfword*8/Byte*16 Indexed
2377   def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2378   def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2379
2380   // Load Vector Indexed
2381   def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2382                 [(set v2f64:$XT, (load xoaddr:$src))]>;
2383
2384   // Load Vector (Left-justified) with Length
2385   def LXVL : XX1Form<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2386                    "lxvl $XT, $src, $rB", IIC_LdStLoad,
2387                    [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>,
2388                     UseVSXReg;
2389   def LXVLL : XX1Form<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2390                    "lxvll $XT, $src, $rB", IIC_LdStLoad,
2391                    [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>,
2392                     UseVSXReg;
2393
2394   // Load Vector Word & Splat Indexed
2395   def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2396   } // mayLoad
2397
2398   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2399   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2400   let mayStore = 1, mayLoad = 0 in {
2401   // Store Vector
2402   def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2403                              "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg;
2404   // Store DWord
2405   def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2406                         "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2407   // Convert DP of dword[0] to SP, and Store to dst
2408   def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2409                         "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2410
2411   // [PO S RA RB XO SX]
2412   class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2413                       RegisterOperand vtype, list<dag> pattern>
2414     : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2415               !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg;
2416
2417   // Store as Integer Byte/Halfword Indexed
2418   def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2419                                [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2420   def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2421                                [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2422   let isCodeGenOnly = 1 in {
2423     def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vrrc, []>;
2424     def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vrrc, []>;
2425   }
2426
2427   // Store Vector Halfword*8/Byte*16 Indexed
2428   def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2429   def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2430
2431   // Store Vector Indexed
2432   def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
2433                  [(store v2f64:$XT, xoaddr:$dst)]>;
2434
2435   // Store Vector (Left-justified) with Length
2436   def STXVL : XX1Form<31, 397, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2437                    "stxvl $XT, $dst, $rB", IIC_LdStLoad,
2438                    [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, i64:$rB)]>,
2439                     UseVSXReg;
2440   def STXVLL : XX1Form<31, 429, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2441                    "stxvll $XT, $dst, $rB", IIC_LdStLoad,
2442                    [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, i64:$rB)]>,
2443                     UseVSXReg;
2444   } // mayStore
2445
2446   // Patterns for which instructions from ISA 3.0 are a better match
2447   let Predicates = [IsLittleEndian, HasP9Vector] in {
2448   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2449             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2450   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2451             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2452   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2453             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2454   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2455             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2456   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2457             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2458   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2459             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2460   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2461             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2462   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2463             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2464   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2465             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2466   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2467             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2468   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2469             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2470   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2471             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2472   } // IsLittleEndian, HasP9Vector
2473
2474   let Predicates = [IsBigEndian, HasP9Vector] in {
2475   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2476             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2477   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2478             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2479   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2480             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2481   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2482             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2483   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2484             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2485   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2486             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2487   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2488             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2489   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2490             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2491   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2492             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2493   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2494             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2495   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2496             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2497   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2498             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2499   } // IsLittleEndian, HasP9Vector
2500
2501   def : Pat<(v2f64 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2502   def : Pat<(v2i64 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2503   def : Pat<(v4f32 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2504   def : Pat<(v4i32 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2505   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
2506   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
2507   def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2508   def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2509   def : Pat<(store v4f32:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2510   def : Pat<(store v4i32:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2511   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
2512             (STXVX $rS, xoaddr:$dst)>;
2513   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
2514             (STXVX $rS, xoaddr:$dst)>;
2515
2516   def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
2517             (v4i32 (LXVWSX xoaddr:$src))>;
2518   def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
2519             (v4f32 (LXVWSX xoaddr:$src))>;
2520   def : Pat<(v4f32 (scalar_to_vector (f32 (fpround (extloadf32 xoaddr:$src))))),
2521             (v4f32 (LXVWSX xoaddr:$src))>;
2522
2523   // Build vectors from i8 loads
2524   def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
2525             (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
2526   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
2527             (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
2528   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
2529            (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
2530   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
2531             (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
2532   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
2533             (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
2534   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
2535             (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
2536
2537   // Build vectors from i16 loads
2538   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
2539             (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
2540   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
2541             (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
2542   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
2543            (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
2544   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
2545             (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
2546   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
2547             (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
2548
2549   let Predicates = [IsBigEndian, HasP9Vector] in {
2550   // Scalar stores of i8
2551   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2552             (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2553   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2554             (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2555   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2556             (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2557   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2558             (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2559   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2560             (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2561   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2562             (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2563   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2564             (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2565   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2566             (STXSIBXv $S, xoaddr:$dst)>;
2567   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2568             (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2569   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2570             (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2571   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2572             (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2573   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2574             (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2575   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2576             (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2577   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2578             (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2579   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2580             (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2581   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2582             (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2583
2584   // Scalar stores of i16
2585   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2586             (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2587   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2588             (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2589   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2590             (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2591   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2592             (STXSIHXv $S, xoaddr:$dst)>;
2593   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2594             (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2595   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2596             (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2597   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2598             (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2599   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2600             (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2601   } // IsBigEndian, HasP9Vector
2602
2603   let Predicates = [IsLittleEndian, HasP9Vector] in {
2604   // Scalar stores of i8
2605   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2606             (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2607   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2608             (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2609   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2610             (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2611   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2612             (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2613   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2614             (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2615   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2616             (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2617   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2618             (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2619   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2620             (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2621   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2622             (STXSIBXv $S, xoaddr:$dst)>;
2623   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2624             (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2625   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2626             (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2627   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2628             (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2629   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2630             (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2631   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2632             (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2633   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2634             (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2635   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2636             (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2637
2638   // Scalar stores of i16
2639   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2640             (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2641   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2642             (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2643   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2644             (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2645   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2646             (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2647   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2648             (STXSIHXv $S, xoaddr:$dst)>;
2649   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2650             (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2651   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2652             (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2653   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2654             (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2655   } // IsLittleEndian, HasP9Vector
2656
2657
2658   // Vector sign extensions
2659   def : Pat<(f64 (PPCVexts f64:$A, 1)),
2660             (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
2661   def : Pat<(f64 (PPCVexts f64:$A, 2)),
2662             (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
2663
2664   let isPseudo = 1 in {
2665     def DFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrix:$src),
2666                             "#DFLOADf32",
2667                             [(set f32:$XT, (load iaddr:$src))]>;
2668     def DFLOADf64  : Pseudo<(outs vsfrc:$XT), (ins memrix:$src),
2669                             "#DFLOADf64",
2670                             [(set f64:$XT, (load iaddr:$src))]>;
2671     def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst),
2672                             "#DFSTOREf32",
2673                             [(store f32:$XT, iaddr:$dst)]>;
2674     def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
2675                             "#DFSTOREf64",
2676                             [(store f64:$XT, iaddr:$dst)]>;
2677   }
2678   def : Pat<(f64 (extloadf32 iaddr:$src)),
2679             (COPY_TO_REGCLASS (DFLOADf32 iaddr:$src), VSFRC)>;
2680   def : Pat<(f32 (fpround (extloadf32 iaddr:$src))),
2681             (f32 (DFLOADf32 iaddr:$src))>;
2682 } // end HasP9Vector, AddedComplexity
2683
2684 // Integer extend helper dags 32 -> 64
2685 def AnyExts {
2686   dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
2687   dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
2688   dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
2689   dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
2690 }
2691
2692 def DblToFlt {
2693   dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
2694   dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
2695   dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
2696   dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
2697 }
2698 def FltToIntLoad {
2699   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
2700 }
2701 def FltToUIntLoad {
2702   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
2703 }
2704 def FltToLongLoad {
2705   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
2706 }
2707 def FltToULongLoad {
2708   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
2709 }
2710 def FltToLong {
2711   dag A = (i64 (PPCmfvsr (PPCfctidz (fpextend f32:$A))));
2712 }
2713 def FltToULong {
2714   dag A = (i64 (PPCmfvsr (PPCfctiduz (fpextend f32:$A))));
2715 }
2716 def DblToInt {
2717   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
2718 }
2719 def DblToUInt {
2720   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
2721 }
2722 def DblToLong {
2723   dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
2724 }
2725 def DblToULong {
2726   dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
2727 }
2728 def DblToIntLoad {
2729   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
2730 }
2731 def DblToUIntLoad {
2732   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
2733 }
2734 def DblToLongLoad {
2735   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
2736 }
2737 def DblToULongLoad {
2738   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
2739 }
2740
2741 // FP merge dags (for f32 -> v4f32)
2742 def MrgFP {
2743   dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
2744                                (COPY_TO_REGCLASS $C, VSRC), 0));
2745   dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
2746                                (COPY_TO_REGCLASS $D, VSRC), 0));
2747   dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
2748   dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
2749   dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
2750   dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
2751 }
2752
2753 // Patterns for BUILD_VECTOR nodes.
2754 def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
2755 let AddedComplexity = 400 in {
2756
2757   let Predicates = [HasVSX] in {
2758     // Build vectors of floating point converted to i32.
2759     def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
2760                                    DblToInt.A, DblToInt.A)),
2761               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
2762     def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
2763                                    DblToUInt.A, DblToUInt.A)),
2764               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
2765     def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
2766               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
2767                                (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
2768     def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
2769               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
2770                                (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
2771     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
2772               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2773                                 (XSCVDPSXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>;
2774     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
2775               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2776                                 (XSCVDPUXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>;
2777     def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
2778               (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
2779
2780     // Build vectors of floating point converted to i64.
2781     def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
2782               (v2i64 (XXPERMDIs
2783                        (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
2784     def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
2785               (v2i64 (XXPERMDIs
2786                        (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
2787     def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
2788               (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
2789     def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
2790               (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
2791   }
2792
2793   let Predicates = [HasVSX, NoP9Vector] in {
2794     // Load-and-splat with fp-to-int conversion (using X-Form VSX loads).
2795     def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
2796               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2797                                 (XSCVDPSXWS (LXSDX xoaddr:$A)), VSRC), 1))>;
2798     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
2799               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2800                                 (XSCVDPUXWS (LXSDX xoaddr:$A)), VSRC), 1))>;
2801     def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
2802               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
2803                                               (LXSSPX xoaddr:$A), VSFRC)), 0))>;
2804     def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
2805               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
2806                                               (LXSSPX xoaddr:$A), VSFRC)), 0))>;
2807   }
2808
2809   // Big endian, available on all targets with VSX
2810   let Predicates = [IsBigEndian, HasVSX] in {
2811     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2812               (v2f64 (XXPERMDI
2813                         (COPY_TO_REGCLASS $A, VSRC),
2814                         (COPY_TO_REGCLASS $B, VSRC), 0))>;
2815
2816     def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
2817               (VMRGEW MrgFP.AC, MrgFP.BD)>;
2818     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2819                                    DblToFlt.B0, DblToFlt.B1)),
2820               (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
2821   }
2822
2823   let Predicates = [IsLittleEndian, HasVSX] in {
2824   // Little endian, available on all targets with VSX
2825     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2826               (v2f64 (XXPERMDI
2827                         (COPY_TO_REGCLASS $B, VSRC),
2828                         (COPY_TO_REGCLASS $A, VSRC), 0))>;
2829
2830     def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
2831               (VMRGEW MrgFP.AC, MrgFP.BD)>;
2832     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2833                                    DblToFlt.B0, DblToFlt.B1)),
2834               (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
2835   }
2836
2837   let Predicates = [HasDirectMove] in {
2838     // Endianness-neutral constant splat on P8 and newer targets. The reason
2839     // for this pattern is that on targets with direct moves, we don't expand
2840     // BUILD_VECTOR nodes for v4i32.
2841     def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
2842                                    immSExt5NonZero:$A, immSExt5NonZero:$A)),
2843               (v4i32 (VSPLTISW imm:$A))>;
2844   }
2845
2846   let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
2847     // Big endian integer vectors using direct moves.
2848     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
2849               (v2i64 (XXPERMDI
2850                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
2851                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
2852     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2853               (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC),
2854                                    (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 0),
2855                       (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC),
2856                                    (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 0))>;
2857     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2858               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
2859   }
2860
2861   let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
2862     // Little endian integer vectors using direct moves.
2863     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
2864               (v2i64 (XXPERMDI
2865                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
2866                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
2867     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2868               (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC),
2869                                    (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 0),
2870                       (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC),
2871                                    (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 0))>;
2872     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2873               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
2874   }
2875
2876   let Predicates = [HasP9Vector] in {
2877     // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
2878     def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2879               (v4i32 (MTVSRWS $A))>;
2880     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2881               (v4i32 (MTVSRWS $A))>;
2882     def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2883                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2884                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2885                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2886                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2887                                    immAnyExt8:$A)),
2888               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
2889     def : Pat<(v16i8 immAllOnesV),
2890               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
2891     def : Pat<(v8i16 immAllOnesV),
2892               (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
2893     def : Pat<(v4i32 immAllOnesV),
2894               (v4i32 (XXSPLTIB 255))>;
2895     def : Pat<(v2i64 immAllOnesV),
2896               (v2i64 (XXSPLTIB 255))>;
2897     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
2898               (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
2899     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
2900               (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
2901     def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
2902               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2903                                 (XSCVDPSXWS (DFLOADf64 iaddr:$A)), VSRC), 1))>;
2904     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
2905               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2906                                 (XSCVDPUXWS (DFLOADf64 iaddr:$A)), VSRC), 1))>;
2907     def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
2908               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
2909                                               (DFLOADf32 iaddr:$A),
2910                                               VSFRC)), 0))>;
2911     def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
2912               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
2913                                               (DFLOADf32 iaddr:$A),
2914                                               VSFRC)), 0))>;
2915   }
2916
2917   let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
2918     def : Pat<(i64 (extractelt v2i64:$A, 1)),
2919               (i64 (MFVSRLD $A))>;
2920     // Better way to build integer vectors if we have MTVSRDD. Big endian.
2921     def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
2922               (v2i64 (MTVSRDD $rB, $rA))>;
2923     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2924               (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.A, AnyExts.C), VSRC),
2925                       (COPY_TO_REGCLASS (MTVSRDD AnyExts.B, AnyExts.D), VSRC))>;
2926   }
2927
2928   let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
2929     def : Pat<(i64 (extractelt v2i64:$A, 0)),
2930               (i64 (MFVSRLD $A))>;
2931     // Better way to build integer vectors if we have MTVSRDD. Little endian.
2932     def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
2933               (v2i64 (MTVSRDD $rB, $rA))>;
2934     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2935               (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.D, AnyExts.B), VSRC),
2936                       (COPY_TO_REGCLASS (MTVSRDD AnyExts.C, AnyExts.A), VSRC))>;
2937   }
2938 }