]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, 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 // PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
1070 // XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
1071 def : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), (XXPERMDI $src, $src, 2)>;
1072
1073 // Selects.
1074 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
1075           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1076 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
1077           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1078 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
1079           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1080 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
1081           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1082 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
1083           (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1084 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
1085           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1086 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
1087           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1088 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
1089           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1090 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
1091           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1092 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
1093           (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1094
1095 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
1096           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1097 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
1098           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1099 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
1100           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1101 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
1102           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1103 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
1104           (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
1105 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
1106           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1107 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
1108           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1109 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
1110           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1111 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
1112           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1113 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
1114           (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1115
1116 // Divides.
1117 def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
1118           (XVDIVSP $A, $B)>;
1119 def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
1120           (XVDIVDP $A, $B)>;
1121
1122 // Reciprocal estimate
1123 def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1124           (XVRESP $A)>;
1125 def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1126           (XVREDP $A)>;
1127
1128 // Recip. square root estimate
1129 def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1130           (XVRSQRTESP $A)>;
1131 def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1132           (XVRSQRTEDP $A)>;
1133
1134 let Predicates = [IsLittleEndian] in {
1135 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1136           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1137 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1138           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1139 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1140           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1141 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1142           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1143 } // IsLittleEndian
1144
1145 let Predicates = [IsBigEndian] in {
1146 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1147           (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1148 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1149           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1150 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1151           (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1152 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1153           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1154 } // IsBigEndian
1155
1156 } // AddedComplexity
1157 } // HasVSX
1158
1159 def ScalarLoads {
1160   dag Li8 =       (i32 (extloadi8 xoaddr:$src));
1161   dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
1162   dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
1163   dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
1164   dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
1165
1166   dag Li16 =      (i32 (extloadi16 xoaddr:$src));
1167   dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
1168   dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
1169   dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
1170   dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
1171
1172   dag Li32 = (i32 (load xoaddr:$src));
1173 }
1174
1175 // The following VSX instructions were introduced in Power ISA 2.07
1176 /* FIXME: if the operands are v2i64, these patterns will not match.
1177    we should define new patterns or otherwise match the same patterns
1178    when the elements are larger than i32.
1179 */
1180 def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1181 def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1182 let Predicates = [HasP8Vector] in {
1183 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1184   let isCommutable = 1, UseVSXReg = 1 in {
1185     def XXLEQV : XX3Form<60, 186,
1186                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1187                          "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1188                          [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1189     def XXLNAND : XX3Form<60, 178,
1190                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1191                           "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1192                           [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1193                                                     v4i32:$XB)))]>;
1194   } // isCommutable, UseVSXReg
1195
1196   def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1197             (XXLEQV $A, $B)>;
1198
1199   let UseVSXReg = 1 in {
1200   def XXLORC : XX3Form<60, 170,
1201                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1202                        "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1203                        [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1204
1205   // VSX scalar loads introduced in ISA 2.07
1206   let mayLoad = 1, mayStore = 0 in {
1207     let CodeSize = 3 in
1208     def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1209                          "lxsspx $XT, $src", IIC_LdStLFD,
1210                          [(set f32:$XT, (load xoaddr:$src))]>;
1211     def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1212                           "lxsiwax $XT, $src", IIC_LdStLFD,
1213                           [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1214     def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1215                           "lxsiwzx $XT, $src", IIC_LdStLFD,
1216                           [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1217   } // mayLoad
1218
1219   // VSX scalar stores introduced in ISA 2.07
1220   let mayStore = 1, mayLoad = 0 in {
1221     let CodeSize = 3 in
1222     def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1223                           "stxsspx $XT, $dst", IIC_LdStSTFD,
1224                           [(store f32:$XT, xoaddr:$dst)]>;
1225     def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1226                           "stxsiwx $XT, $dst", IIC_LdStSTFD,
1227                           [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1228   } // mayStore
1229   } // UseVSXReg = 1
1230
1231   def : Pat<(f64 (extloadf32 xoaddr:$src)),
1232             (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>;
1233   def : Pat<(f32 (fpround (extloadf32 xoaddr:$src))),
1234             (f32 (LXSSPX xoaddr:$src))>;
1235   def : Pat<(f64 (fpextend f32:$src)),
1236             (COPY_TO_REGCLASS $src, VSFRC)>;
1237
1238   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1239             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1240   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1241             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1242   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1243             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1244   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1245             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1246   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1247             (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1248   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1249             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1250   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1251             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1252   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1253             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1254   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1255             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1256   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1257             (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1258
1259   let UseVSXReg = 1 in {
1260   // VSX Elementary Scalar FP arithmetic (SP)
1261   let isCommutable = 1 in {
1262     def XSADDSP : XX3Form<60, 0,
1263                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1264                           "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1265                           [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1266     def XSMULSP : XX3Form<60, 16,
1267                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1268                           "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1269                           [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1270   } // isCommutable
1271
1272   def XSDIVSP : XX3Form<60, 24,
1273                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1274                         "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1275                         [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1276   def XSRESP : XX2Form<60, 26,
1277                         (outs vssrc:$XT), (ins vssrc:$XB),
1278                         "xsresp $XT, $XB", IIC_VecFP,
1279                         [(set f32:$XT, (PPCfre f32:$XB))]>;
1280   def XSSQRTSP : XX2Form<60, 11,
1281                         (outs vssrc:$XT), (ins vssrc:$XB),
1282                         "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1283                         [(set f32:$XT, (fsqrt f32:$XB))]>;
1284   def XSRSQRTESP : XX2Form<60, 10,
1285                            (outs vssrc:$XT), (ins vssrc:$XB),
1286                            "xsrsqrtesp $XT, $XB", IIC_VecFP,
1287                            [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1288   def XSSUBSP : XX3Form<60, 8,
1289                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1290                         "xssubsp $XT, $XA, $XB", IIC_VecFP,
1291                         [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1292
1293   // FMA Instructions
1294   let BaseName = "XSMADDASP" in {
1295   let isCommutable = 1 in
1296   def XSMADDASP : XX3Form<60, 1,
1297                           (outs vssrc:$XT),
1298                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1299                           "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1300                           [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1301                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1302                           AltVSXFMARel;
1303   let IsVSXFMAAlt = 1 in
1304   def XSMADDMSP : XX3Form<60, 9,
1305                           (outs vssrc:$XT),
1306                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1307                           "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1308                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1309                           AltVSXFMARel;
1310   }
1311
1312   let BaseName = "XSMSUBASP" in {
1313   let isCommutable = 1 in
1314   def XSMSUBASP : XX3Form<60, 17,
1315                           (outs vssrc:$XT),
1316                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1317                           "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1318                           [(set f32:$XT, (fma f32:$XA, f32:$XB,
1319                                               (fneg f32:$XTi)))]>,
1320                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1321                           AltVSXFMARel;
1322   let IsVSXFMAAlt = 1 in
1323   def XSMSUBMSP : XX3Form<60, 25,
1324                           (outs vssrc:$XT),
1325                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1326                           "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1327                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1328                           AltVSXFMARel;
1329   }
1330
1331   let BaseName = "XSNMADDASP" in {
1332   let isCommutable = 1 in
1333   def XSNMADDASP : XX3Form<60, 129,
1334                           (outs vssrc:$XT),
1335                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1336                           "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1337                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1338                                                     f32:$XTi)))]>,
1339                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1340                           AltVSXFMARel;
1341   let IsVSXFMAAlt = 1 in
1342   def XSNMADDMSP : XX3Form<60, 137,
1343                           (outs vssrc:$XT),
1344                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1345                           "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1346                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1347                           AltVSXFMARel;
1348   }
1349
1350   let BaseName = "XSNMSUBASP" in {
1351   let isCommutable = 1 in
1352   def XSNMSUBASP : XX3Form<60, 145,
1353                           (outs vssrc:$XT),
1354                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1355                           "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1356                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1357                                                     (fneg f32:$XTi))))]>,
1358                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1359                           AltVSXFMARel;
1360   let IsVSXFMAAlt = 1 in
1361   def XSNMSUBMSP : XX3Form<60, 153,
1362                           (outs vssrc:$XT),
1363                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1364                           "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1365                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1366                           AltVSXFMARel;
1367   }
1368
1369   // Single Precision Conversions (FP <-> INT)
1370   def XSCVSXDSP : XX2Form<60, 312,
1371                       (outs vssrc:$XT), (ins vsfrc:$XB),
1372                       "xscvsxdsp $XT, $XB", IIC_VecFP,
1373                       [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1374   def XSCVUXDSP : XX2Form<60, 296,
1375                       (outs vssrc:$XT), (ins vsfrc:$XB),
1376                       "xscvuxdsp $XT, $XB", IIC_VecFP,
1377                       [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1378
1379   // Conversions between vector and scalar single precision
1380   def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1381                           "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1382   def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1383                           "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1384   } // UseVSXReg = 1
1385
1386   let Predicates = [IsLittleEndian] in {
1387   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1388             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1389   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1390             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1391   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1392             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1393   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1394             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1395   }
1396
1397   let Predicates = [IsBigEndian] in {
1398   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1399             (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1400   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1401             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1402   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1403             (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1404   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1405             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1406   }
1407   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.Li32)),
1408             (v4i32 (XXSPLTWs (LXSIWAX xoaddr:$src), 1))>;
1409 } // AddedComplexity = 400
1410 } // HasP8Vector
1411
1412 let UseVSXReg = 1, AddedComplexity = 400 in {
1413 let Predicates = [HasDirectMove] in {
1414   // VSX direct move instructions
1415   def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1416                               "mfvsrd $rA, $XT", IIC_VecGeneral,
1417                               [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1418       Requires<[In64BitMode]>;
1419   let isCodeGenOnly = 1 in
1420   def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vrrc:$XT),
1421                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1422                              []>,
1423       Requires<[In64BitMode]>;
1424   def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1425                                "mfvsrwz $rA, $XT", IIC_VecGeneral,
1426                                [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1427   def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1428                               "mtvsrd $XT, $rA", IIC_VecGeneral,
1429                               [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1430       Requires<[In64BitMode]>;
1431   def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1432                                "mtvsrwa $XT, $rA", IIC_VecGeneral,
1433                                [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1434   def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1435                                "mtvsrwz $XT, $rA", IIC_VecGeneral,
1436                                [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1437 } // HasDirectMove
1438
1439 let Predicates = [IsISA3_0, HasDirectMove] in {
1440   def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1441                               "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1442
1443   def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1444                        "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1445                        []>, Requires<[In64BitMode]>;
1446
1447   def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1448                               "mfvsrld $rA, $XT", IIC_VecGeneral,
1449                               []>, Requires<[In64BitMode]>;
1450
1451 } // IsISA3_0, HasDirectMove
1452 } // UseVSXReg = 1
1453
1454 // We want to parse this from asm, but we don't want to emit this as it would
1455 // be emitted with a VSX reg. So leave Emit = 0 here.
1456 def : InstAlias<"mfvrd $rA, $XT",
1457                 (MFVRD g8rc:$rA, vrrc:$XT), 0>;
1458 def : InstAlias<"mffprd $rA, $src",
1459                 (MFVSRD g8rc:$rA, f8rc:$src)>;
1460
1461 /*  Direct moves of various widths from GPR's into VSR's. Each move lines
1462     the value up into element 0 (both BE and LE). Namely, entities smaller than
1463     a doubleword are shifted left and moved for BE. For LE, they're moved, then
1464     swapped to go into the least significant element of the VSR.
1465 */
1466 def MovesToVSR {
1467   dag BE_BYTE_0 =
1468     (MTVSRD
1469       (RLDICR
1470         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1471   dag BE_HALF_0 =
1472     (MTVSRD
1473       (RLDICR
1474         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1475   dag BE_WORD_0 =
1476     (MTVSRD
1477       (RLDICR
1478         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1479   dag BE_DWORD_0 = (MTVSRD $A);
1480
1481   dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1482   dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1483                                         LE_MTVSRW, sub_64));
1484   dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1485   dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1486                                          BE_DWORD_0, sub_64));
1487   dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1488 }
1489
1490 /*  Patterns for extracting elements out of vectors. Integer elements are
1491     extracted using direct move operations. Patterns for extracting elements
1492     whose indices are not available at compile time are also provided with
1493     various _VARIABLE_ patterns.
1494     The numbering for the DAG's is for LE, but when used on BE, the correct
1495     LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1496 */
1497 def VectorExtractions {
1498   // Doubleword extraction
1499   dag LE_DWORD_0 =
1500     (MFVSRD
1501       (EXTRACT_SUBREG
1502         (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1503                   (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1504   dag LE_DWORD_1 = (MFVSRD
1505                      (EXTRACT_SUBREG
1506                        (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1507
1508   // Word extraction
1509   dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1510   dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1511   dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1512                              (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1513   dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1514
1515   // Halfword extraction
1516   dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1517   dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1518   dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1519   dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1520   dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1521   dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1522   dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1523   dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1524
1525   // Byte extraction
1526   dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1527   dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1528   dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1529   dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1530   dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1531   dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1532   dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1533   dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1534   dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1535   dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1536   dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1537   dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1538   dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1539   dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1540   dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1541   dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1542
1543   /* Variable element number (BE and LE patterns must be specified separately)
1544      This is a rather involved process.
1545
1546      Conceptually, this is how the move is accomplished:
1547      1. Identify which doubleword contains the element
1548      2. Shift in the VMX register so that the correct doubleword is correctly
1549         lined up for the MFVSRD
1550      3. Perform the move so that the element (along with some extra stuff)
1551         is in the GPR
1552      4. Right shift within the GPR so that the element is right-justified
1553
1554      Of course, the index is an element number which has a different meaning
1555      on LE/BE so the patterns have to be specified separately.
1556
1557      Note: The final result will be the element right-justified with high
1558            order bits being arbitrarily defined (namely, whatever was in the
1559            vector register to the left of the value originally).
1560   */
1561
1562   /*  LE variable byte
1563       Number 1. above:
1564       - For elements 0-7, we shift left by 8 bytes since they're on the right
1565       - For elements 8-15, we need not shift (shift left by zero bytes)
1566       This is accomplished by inverting the bits of the index and AND-ing
1567       with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1568   */
1569   dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx));
1570
1571   //  Number 2. above:
1572   //  - Now that we set up the shift amount, we shift in the VMX register
1573   dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC);
1574
1575   //  Number 3. above:
1576   //  - The doubleword containing our element is moved to a GPR
1577   dag LE_MV_VBYTE = (MFVSRD
1578                       (EXTRACT_SUBREG
1579                         (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1580                         sub_64));
1581
1582   /*  Number 4. above:
1583       - Truncate the element number to the range 0-7 (8-15 are symmetrical
1584         and out of range values are truncated accordingly)
1585       - Multiply by 8 as we need to shift right by the number of bits, not bytes
1586       - Shift right in the GPR by the calculated value
1587   */
1588   dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1589                                        sub_32);
1590   dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1591                                          sub_32);
1592
1593   /*  LE variable halfword
1594       Number 1. above:
1595       - For elements 0-3, we shift left by 8 since they're on the right
1596       - For elements 4-7, we need not shift (shift left by zero bytes)
1597       Similarly to the byte pattern, we invert the bits of the index, but we
1598       AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1599       Of course, the shift is still by 8 bytes, so we must multiply by 2.
1600   */
1601   dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62));
1602
1603   //  Number 2. above:
1604   //  - Now that we set up the shift amount, we shift in the VMX register
1605   dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC);
1606
1607   //  Number 3. above:
1608   //  - The doubleword containing our element is moved to a GPR
1609   dag LE_MV_VHALF = (MFVSRD
1610                       (EXTRACT_SUBREG
1611                         (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1612                         sub_64));
1613
1614   /*  Number 4. above:
1615       - Truncate the element number to the range 0-3 (4-7 are symmetrical
1616         and out of range values are truncated accordingly)
1617       - Multiply by 16 as we need to shift right by the number of bits
1618       - Shift right in the GPR by the calculated value
1619   */
1620   dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1621                                        sub_32);
1622   dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1623                                          sub_32);
1624
1625   /*  LE variable word
1626       Number 1. above:
1627       - For elements 0-1, we shift left by 8 since they're on the right
1628       - For elements 2-3, we need not shift
1629   */
1630   dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61));
1631
1632   //  Number 2. above:
1633   //  - Now that we set up the shift amount, we shift in the VMX register
1634   dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC);
1635
1636   //  Number 3. above:
1637   //  - The doubleword containing our element is moved to a GPR
1638   dag LE_MV_VWORD = (MFVSRD
1639                       (EXTRACT_SUBREG
1640                         (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1641                         sub_64));
1642
1643   /*  Number 4. above:
1644       - Truncate the element number to the range 0-1 (2-3 are symmetrical
1645         and out of range values are truncated accordingly)
1646       - Multiply by 32 as we need to shift right by the number of bits
1647       - Shift right in the GPR by the calculated value
1648   */
1649   dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1650                                        sub_32);
1651   dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1652                                          sub_32);
1653
1654   /*  LE variable doubleword
1655       Number 1. above:
1656       - For element 0, we shift left by 8 since it's on the right
1657       - For element 1, we need not shift
1658   */
1659   dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60));
1660
1661   //  Number 2. above:
1662   //  - Now that we set up the shift amount, we shift in the VMX register
1663   dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC);
1664
1665   // Number 3. above:
1666   //  - The doubleword containing our element is moved to a GPR
1667   //  - Number 4. is not needed for the doubleword as the value is 64-bits
1668   dag LE_VARIABLE_DWORD =
1669         (MFVSRD (EXTRACT_SUBREG
1670                   (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1671                   sub_64));
1672
1673   /*  LE variable float
1674       - Shift the vector to line up the desired element to BE Word 0
1675       - Convert 32-bit float to a 64-bit single precision float
1676   */
1677   dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61));
1678   dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1679   dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1680
1681   /*  LE variable double
1682       Same as the LE doubleword except there is no move.
1683   */
1684   dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1685                                   (COPY_TO_REGCLASS $S, VRRC),
1686                                   LE_VDWORD_PERM_VEC);
1687   dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1688
1689   /*  BE variable byte
1690       The algorithm here is the same as the LE variable byte except:
1691       - The shift in the VMX register is by 0/8 for opposite element numbers so
1692         we simply AND the element number with 0x8
1693       - The order of elements after the move to GPR is reversed, so we invert
1694         the bits of the index prior to truncating to the range 0-7
1695   */
1696   dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8));
1697   dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC);
1698   dag BE_MV_VBYTE = (MFVSRD
1699                       (EXTRACT_SUBREG
1700                         (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1701                         sub_64));
1702   dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1703                                        sub_32);
1704   dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1705                                          sub_32);
1706
1707   /*  BE variable halfword
1708       The algorithm here is the same as the LE variable halfword except:
1709       - The shift in the VMX register is by 0/8 for opposite element numbers so
1710         we simply AND the element number with 0x4 and multiply by 2
1711       - The order of elements after the move to GPR is reversed, so we invert
1712         the bits of the index prior to truncating to the range 0-3
1713   */
1714   dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62));
1715   dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC);
1716   dag BE_MV_VHALF = (MFVSRD
1717                       (EXTRACT_SUBREG
1718                         (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1719                         sub_64));
1720   dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1721                                        sub_32);
1722   dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1723                                          sub_32);
1724
1725   /*  BE variable word
1726       The algorithm is the same as the LE variable word except:
1727       - The shift in the VMX register happens for opposite element numbers
1728       - The order of elements after the move to GPR is reversed, so we invert
1729         the bits of the index prior to truncating to the range 0-1
1730   */
1731   dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61));
1732   dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC);
1733   dag BE_MV_VWORD = (MFVSRD
1734                       (EXTRACT_SUBREG
1735                         (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1736                         sub_64));
1737   dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1738                                        sub_32);
1739   dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1740                                          sub_32);
1741
1742   /*  BE variable doubleword
1743       Same as the LE doubleword except we shift in the VMX register for opposite
1744       element indices.
1745   */
1746   dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60));
1747   dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC);
1748   dag BE_VARIABLE_DWORD =
1749         (MFVSRD (EXTRACT_SUBREG
1750                   (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1751                   sub_64));
1752
1753   /*  BE variable float
1754       - Shift the vector to line up the desired element to BE Word 0
1755       - Convert 32-bit float to a 64-bit single precision float
1756   */
1757   dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61));
1758   dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1759   dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1760
1761   /* BE variable double
1762       Same as the BE doubleword except there is no move.
1763   */
1764   dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1765                                   (COPY_TO_REGCLASS $S, VRRC),
1766                                   BE_VDWORD_PERM_VEC);
1767   dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1768 }
1769
1770 let AddedComplexity = 400 in {
1771 // v4f32 scalar <-> vector conversions (BE)
1772 let Predicates = [IsBigEndian, HasP8Vector] in {
1773   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1774             (v4f32 (XSCVDPSPN $A))>;
1775   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1776             (f32 (XSCVSPDPN $S))>;
1777   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1778             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1779   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1780             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1781   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1782             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1783   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1784             (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1785 } // IsBigEndian, HasP8Vector
1786
1787 // Variable index vector_extract for v2f64 does not require P8Vector
1788 let Predicates = [IsBigEndian, HasVSX] in
1789   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1790             (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1791
1792 let Predicates = [IsBigEndian, HasDirectMove] in {
1793   // v16i8 scalar <-> vector conversions (BE)
1794   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1795             (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1796   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1797             (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1798   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1799             (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1800   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1801             (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1802   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1803             (i32 VectorExtractions.LE_BYTE_15)>;
1804   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1805             (i32 VectorExtractions.LE_BYTE_14)>;
1806   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1807             (i32 VectorExtractions.LE_BYTE_13)>;
1808   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1809             (i32 VectorExtractions.LE_BYTE_12)>;
1810   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1811             (i32 VectorExtractions.LE_BYTE_11)>;
1812   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1813             (i32 VectorExtractions.LE_BYTE_10)>;
1814   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1815             (i32 VectorExtractions.LE_BYTE_9)>;
1816   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1817             (i32 VectorExtractions.LE_BYTE_8)>;
1818   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1819             (i32 VectorExtractions.LE_BYTE_7)>;
1820   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1821             (i32 VectorExtractions.LE_BYTE_6)>;
1822   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1823             (i32 VectorExtractions.LE_BYTE_5)>;
1824   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1825             (i32 VectorExtractions.LE_BYTE_4)>;
1826   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1827             (i32 VectorExtractions.LE_BYTE_3)>;
1828   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1829             (i32 VectorExtractions.LE_BYTE_2)>;
1830   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1831             (i32 VectorExtractions.LE_BYTE_1)>;
1832   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1833             (i32 VectorExtractions.LE_BYTE_0)>;
1834   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1835             (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1836
1837   // v8i16 scalar <-> vector conversions (BE)
1838   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1839             (i32 VectorExtractions.LE_HALF_7)>;
1840   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1841             (i32 VectorExtractions.LE_HALF_6)>;
1842   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1843             (i32 VectorExtractions.LE_HALF_5)>;
1844   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1845             (i32 VectorExtractions.LE_HALF_4)>;
1846   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1847             (i32 VectorExtractions.LE_HALF_3)>;
1848   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1849             (i32 VectorExtractions.LE_HALF_2)>;
1850   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1851             (i32 VectorExtractions.LE_HALF_1)>;
1852   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1853             (i32 VectorExtractions.LE_HALF_0)>;
1854   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1855             (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1856
1857   // v4i32 scalar <-> vector conversions (BE)
1858   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1859             (i32 VectorExtractions.LE_WORD_3)>;
1860   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1861             (i32 VectorExtractions.LE_WORD_2)>;
1862   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1863             (i32 VectorExtractions.LE_WORD_1)>;
1864   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1865             (i32 VectorExtractions.LE_WORD_0)>;
1866   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1867             (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1868
1869   // v2i64 scalar <-> vector conversions (BE)
1870   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1871             (i64 VectorExtractions.LE_DWORD_1)>;
1872   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1873             (i64 VectorExtractions.LE_DWORD_0)>;
1874   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1875             (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1876 } // IsBigEndian, HasDirectMove
1877
1878 // v4f32 scalar <-> vector conversions (LE)
1879 let Predicates = [IsLittleEndian, HasP8Vector] in {
1880   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1881             (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1882   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1883             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1884   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1885             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1886   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1887             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1888   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1889             (f32 (XSCVSPDPN $S))>;
1890   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1891             (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1892 } // IsLittleEndian, HasP8Vector
1893
1894 // Variable index vector_extract for v2f64 does not require P8Vector
1895 let Predicates = [IsLittleEndian, HasVSX] in
1896   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1897             (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1898
1899 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1900 def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1901
1902 let Predicates = [IsLittleEndian, HasDirectMove] in {
1903   // v16i8 scalar <-> vector conversions (LE)
1904   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1905             (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1906   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1907             (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1908   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1909             (v4i32 MovesToVSR.LE_WORD_0)>;
1910   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1911             (v2i64 MovesToVSR.LE_DWORD_0)>;
1912   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1913             (i32 VectorExtractions.LE_BYTE_0)>;
1914   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1915             (i32 VectorExtractions.LE_BYTE_1)>;
1916   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1917             (i32 VectorExtractions.LE_BYTE_2)>;
1918   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1919             (i32 VectorExtractions.LE_BYTE_3)>;
1920   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1921             (i32 VectorExtractions.LE_BYTE_4)>;
1922   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1923             (i32 VectorExtractions.LE_BYTE_5)>;
1924   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1925             (i32 VectorExtractions.LE_BYTE_6)>;
1926   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1927             (i32 VectorExtractions.LE_BYTE_7)>;
1928   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1929             (i32 VectorExtractions.LE_BYTE_8)>;
1930   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1931             (i32 VectorExtractions.LE_BYTE_9)>;
1932   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1933             (i32 VectorExtractions.LE_BYTE_10)>;
1934   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1935             (i32 VectorExtractions.LE_BYTE_11)>;
1936   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1937             (i32 VectorExtractions.LE_BYTE_12)>;
1938   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1939             (i32 VectorExtractions.LE_BYTE_13)>;
1940   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1941             (i32 VectorExtractions.LE_BYTE_14)>;
1942   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1943             (i32 VectorExtractions.LE_BYTE_15)>;
1944   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1945             (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
1946
1947   // v8i16 scalar <-> vector conversions (LE)
1948   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1949             (i32 VectorExtractions.LE_HALF_0)>;
1950   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1951             (i32 VectorExtractions.LE_HALF_1)>;
1952   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1953             (i32 VectorExtractions.LE_HALF_2)>;
1954   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1955             (i32 VectorExtractions.LE_HALF_3)>;
1956   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1957             (i32 VectorExtractions.LE_HALF_4)>;
1958   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1959             (i32 VectorExtractions.LE_HALF_5)>;
1960   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1961             (i32 VectorExtractions.LE_HALF_6)>;
1962   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1963             (i32 VectorExtractions.LE_HALF_7)>;
1964   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1965             (i32 VectorExtractions.LE_VARIABLE_HALF)>;
1966
1967   // v4i32 scalar <-> vector conversions (LE)
1968   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1969             (i32 VectorExtractions.LE_WORD_0)>;
1970   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1971             (i32 VectorExtractions.LE_WORD_1)>;
1972   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1973             (i32 VectorExtractions.LE_WORD_2)>;
1974   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1975             (i32 VectorExtractions.LE_WORD_3)>;
1976   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1977             (i32 VectorExtractions.LE_VARIABLE_WORD)>;
1978
1979   // v2i64 scalar <-> vector conversions (LE)
1980   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1981             (i64 VectorExtractions.LE_DWORD_0)>;
1982   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1983             (i64 VectorExtractions.LE_DWORD_1)>;
1984   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1985             (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
1986 } // IsLittleEndian, HasDirectMove
1987
1988 let Predicates = [HasDirectMove, HasVSX] in {
1989 // bitconvert f32 -> i32
1990 // (convert to 32-bit fp single, shift right 1 word, move to GPR)
1991 def : Pat<(i32 (bitconvert f32:$S)),
1992           (i32 (MFVSRWZ (EXTRACT_SUBREG
1993                           (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
1994                           sub_64)))>;
1995 // bitconvert i32 -> f32
1996 // (move to FPR, shift left 1 word, convert to 64-bit fp single)
1997 def : Pat<(f32 (bitconvert i32:$A)),
1998           (f32 (XSCVSPDPN
1999                  (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
2000
2001 // bitconvert f64 -> i64
2002 // (move to GPR, nothing else needed)
2003 def : Pat<(i64 (bitconvert f64:$S)),
2004           (i64 (MFVSRD $S))>;
2005
2006 // bitconvert i64 -> f64
2007 // (move to FPR, nothing else needed)
2008 def : Pat<(f64 (bitconvert i64:$S)),
2009           (f64 (MTVSRD $S))>;
2010 }
2011
2012 // Materialize a zero-vector of long long
2013 def : Pat<(v2i64 immAllZerosV),
2014           (v2i64 (XXLXORz))>;
2015 }
2016
2017 def AlignValues {
2018   dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2019   dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2020 }
2021
2022 // The following VSX instructions were introduced in Power ISA 3.0
2023 def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2024 let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2025
2026   // [PO VRT XO VRB XO /]
2027   class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2028                       list<dag> pattern>
2029     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2030                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2031
2032   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2033   class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2034                          list<dag> pattern>
2035     : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2036
2037   // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2038   // So we use different operand class for VRB
2039   class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2040                            RegisterOperand vbtype, list<dag> pattern>
2041     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2042                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2043
2044   let UseVSXReg = 1 in {
2045   // [PO T XO B XO BX /]
2046   class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2047                         list<dag> pattern>
2048     : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2049                       !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2050
2051   // [PO T XO B XO BX TX]
2052   class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2053                         RegisterOperand vtype, list<dag> pattern>
2054     : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2055                       !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2056
2057   // [PO T A B XO AX BX TX], src and dest register use different operand class
2058   class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2059                   RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2060                   InstrItinClass itin, list<dag> pattern>
2061     : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2062               !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2063   } // UseVSXReg = 1
2064
2065   // [PO VRT VRA VRB XO /]
2066   class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2067                       list<dag> pattern>
2068     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2069               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2070
2071   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2072   class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2073                          list<dag> pattern>
2074     : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2075
2076   //===--------------------------------------------------------------------===//
2077   // Quad-Precision Scalar Move Instructions:
2078
2079   // Copy Sign
2080   def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>;
2081
2082   // Absolute/Negative-Absolute/Negate
2083   def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp" , []>;
2084   def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp", []>;
2085   def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>;
2086
2087   //===--------------------------------------------------------------------===//
2088   // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2089
2090   // Add/Divide/Multiply/Subtract
2091   def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp" , []>;
2092   def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>;
2093   def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp" , []>;
2094   def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>;
2095   def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp" , []>;
2096   def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>;
2097   def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" , []>;
2098   def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>;
2099
2100   // Square-Root
2101   def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp" , []>;
2102   def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>;
2103
2104   // (Negative) Multiply-{Add/Subtract}
2105   def XSMADDQP  : X_VT5_VA5_VB5   <63, 388, "xsmaddqp"  , []>;
2106   def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>;
2107   def XSMSUBQP  : X_VT5_VA5_VB5   <63, 420, "xsmsubqp"  , []>;
2108   def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>;
2109   def XSNMADDQP : X_VT5_VA5_VB5   <63, 452, "xsnmaddqp" , []>;
2110   def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>;
2111   def XSNMSUBQP : X_VT5_VA5_VB5   <63, 484, "xsnmsubqp" , []>;
2112   def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>;
2113
2114   //===--------------------------------------------------------------------===//
2115   // Quad/Double-Precision Compare Instructions:
2116
2117   // [PO BF // VRA VRB XO /]
2118   class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2119                       list<dag> pattern>
2120     : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2121                !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2122     let Pattern = pattern;
2123   }
2124
2125   // QP Compare Ordered/Unordered
2126   def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2127   def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2128
2129   // DP/QP Compare Exponents
2130   def XSCMPEXPDP : XX3Form_1<60, 59,
2131                              (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2132                              "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>,
2133                    UseVSXReg;
2134   def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2135
2136   // DP Compare ==, >=, >, !=
2137   // Use vsrc for XT, because the entire register of XT is set.
2138   // XT.dword[1] = 0x0000_0000_0000_0000
2139   def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2140                                   IIC_FPCompare, []>;
2141   def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2142                                   IIC_FPCompare, []>;
2143   def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2144                                   IIC_FPCompare, []>;
2145   def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc,
2146                                   IIC_FPCompare, []>;
2147   let UseVSXReg = 1 in {
2148   // Vector Compare Not Equal
2149   def XVCMPNEDP  : XX3Form_Rc<60, 123,
2150                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2151                               "xvcmpnedp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2152   let Defs = [CR6] in
2153   def XVCMPNEDPo : XX3Form_Rc<60, 123,
2154                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2155                               "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2156                               isDOT;
2157   def XVCMPNESP  : XX3Form_Rc<60,  91,
2158                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2159                               "xvcmpnesp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2160   let Defs = [CR6] in
2161   def XVCMPNESPo : XX3Form_Rc<60,  91,
2162                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2163                               "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2164                               isDOT;
2165   } // UseVSXReg = 1
2166
2167   //===--------------------------------------------------------------------===//
2168   // Quad-Precision Floating-Point Conversion Instructions:
2169
2170   // Convert DP -> QP
2171   def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, []>;
2172
2173   // Round & Convert QP -> DP (dword[1] is set to zero)
2174   def XSCVQPDP  : X_VT5_XO5_VB5   <63, 20, 836, "xscvqpdp" , []>;
2175   def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>;
2176
2177   // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2178   def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2179   def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2180   def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2181   def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2182
2183   // Convert (Un)Signed DWord -> QP
2184   def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2185   def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2186
2187   let UseVSXReg = 1 in {
2188   //===--------------------------------------------------------------------===//
2189   // Round to Floating-Point Integer Instructions
2190
2191   // (Round &) Convert DP <-> HP
2192   // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2193   // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2194   // but we still use vsfrc for it.
2195   def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2196   def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2197
2198   // Vector HP -> SP
2199   def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2200   def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2201                                  [(set v4f32:$XT,
2202                                      (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2203
2204   } // UseVSXReg = 1
2205
2206   // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2207   // separate pattern so that it can convert the input register class from
2208   // VRRC(v8i16) to VSRC.
2209   def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2210             (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2211
2212   class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2213                                 list<dag> pattern>
2214     : Z23Form_1<opcode, xo,
2215                 (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2216                 !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2217     let RC = ex;
2218   }
2219
2220   // Round to Quad-Precision Integer [with Inexact]
2221   def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2222   def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2223
2224   // Round Quad-Precision to Double-Extended Precision (fp80)
2225   def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2226
2227   //===--------------------------------------------------------------------===//
2228   // Insert/Extract Instructions
2229
2230   // Insert Exponent DP/QP
2231   // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2232   def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2233                           "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg;
2234   // vB NOTE: only vB.dword[0] is used, that's why we don't use
2235   //          X_VT5_VA5_VB5 form
2236   def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2237                           "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2238
2239   // Extract Exponent/Significand DP/QP
2240   def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2241   def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2242
2243   def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2244   def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2245
2246   // Vector Insert Word
2247   let UseVSXReg = 1 in {
2248   // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2249   def XXINSERTW   :
2250     XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2251                      (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2252                      "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2253                      [(set v4i32:$XT, (PPCxxinsert v4i32:$XTi, v4i32:$XB,
2254                                                    imm32SExt16:$UIM))]>,
2255                      RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2256
2257   // Vector Extract Unsigned Word
2258   def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2259                                   (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2260                                   "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2261   } // UseVSXReg = 1
2262
2263   // Vector Insert Exponent DP/SP
2264   def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2265     IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2266   def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2267     IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2268
2269   // Vector Extract Exponent/Significand DP/SP
2270   def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2271                                  [(set v2i64: $XT,
2272                                   (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2273   def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2274                                  [(set v4i32: $XT,
2275                                   (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2276   def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2277                                  [(set v2i64: $XT,
2278                                   (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2279   def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2280                                  [(set v4i32: $XT,
2281                                   (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2282
2283   let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2284   // Extra patterns expanding to vector Extract Word/Insert Word
2285   def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2286             (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2287   def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2288             (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2289   } // AddedComplexity = 400, HasP9Vector
2290
2291   //===--------------------------------------------------------------------===//
2292
2293   // Test Data Class SP/DP/QP
2294   let UseVSXReg = 1 in {
2295   def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2296                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2297                               "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2298   def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2299                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2300                               "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2301   } // UseVSXReg = 1
2302   def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2303                               (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2304                               "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2305
2306   // Vector Test Data Class SP/DP
2307   let UseVSXReg = 1 in {
2308   def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2309                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2310                               "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2311                               [(set v4i32: $XT,
2312                                (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>;
2313   def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2314                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2315                               "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2316                               [(set v2i64: $XT,
2317                                (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>;
2318   } // UseVSXReg = 1
2319
2320   //===--------------------------------------------------------------------===//
2321
2322   // Maximum/Minimum Type-C/Type-J DP
2323   // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2324   def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2325                                  IIC_VecFP, []>;
2326   def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2327                                  IIC_VecFP, []>;
2328   def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2329                                  IIC_VecFP, []>;
2330   def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2331                                  IIC_VecFP, []>;
2332
2333   //===--------------------------------------------------------------------===//
2334
2335   // Vector Byte-Reverse H/W/D/Q Word
2336   def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2337   def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2338   def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2339   def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2340
2341   // Vector Permute
2342   def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2343                                 IIC_VecPerm, []>;
2344   def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2345                                 IIC_VecPerm, []>;
2346
2347   // Vector Splat Immediate Byte
2348   def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2349                             "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg;
2350
2351   //===--------------------------------------------------------------------===//
2352   // Vector/Scalar Load/Store Instructions
2353
2354   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2355   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2356   let mayLoad = 1, mayStore = 0 in {
2357   // Load Vector
2358   def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2359                             "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg;
2360   // Load DWord
2361   def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2362                        "lxsd $vD, $src", IIC_LdStLFD, []>;
2363   // Load SP from src, convert it to DP, and place in dword[0]
2364   def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2365                        "lxssp $vD, $src", IIC_LdStLFD, []>;
2366
2367   // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2368   // "out" and "in" dag
2369   class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2370                       RegisterOperand vtype, list<dag> pattern>
2371     : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2372               !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg;
2373
2374   // Load as Integer Byte/Halfword & Zero Indexed
2375   def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2376                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2377   def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2378                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2379
2380   // Load Vector Halfword*8/Byte*16 Indexed
2381   def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2382   def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2383
2384   // Load Vector Indexed
2385   def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2386                 [(set v2f64:$XT, (load xaddr:$src))]>;
2387   // Load Vector (Left-justified) with Length
2388   def LXVL : XX1Form<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2389                    "lxvl $XT, $src, $rB", IIC_LdStLoad,
2390                    [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>,
2391                     UseVSXReg;
2392   def LXVLL : XX1Form<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2393                    "lxvll $XT, $src, $rB", IIC_LdStLoad,
2394                    [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>,
2395                     UseVSXReg;
2396
2397   // Load Vector Word & Splat Indexed
2398   def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2399   } // mayLoad
2400
2401   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2402   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2403   let mayStore = 1, mayLoad = 0 in {
2404   // Store Vector
2405   def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2406                              "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg;
2407   // Store DWord
2408   def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2409                         "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2410   // Convert DP of dword[0] to SP, and Store to dst
2411   def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2412                         "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2413
2414   // [PO S RA RB XO SX]
2415   class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2416                       RegisterOperand vtype, list<dag> pattern>
2417     : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2418               !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg;
2419
2420   // Store as Integer Byte/Halfword Indexed
2421   def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2422                                [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2423   def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2424                                [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2425   let isCodeGenOnly = 1 in {
2426     def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vrrc, []>;
2427     def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vrrc, []>;
2428   }
2429
2430   // Store Vector Halfword*8/Byte*16 Indexed
2431   def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2432   def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2433
2434   // Store Vector Indexed
2435   def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
2436                  [(store v2f64:$XT, xaddr:$dst)]>;
2437
2438   // Store Vector (Left-justified) with Length
2439   def STXVL : XX1Form<31, 397, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2440                    "stxvl $XT, $dst, $rB", IIC_LdStLoad,
2441                    [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, i64:$rB)]>,
2442                     UseVSXReg;
2443   def STXVLL : XX1Form<31, 429, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2444                    "stxvll $XT, $dst, $rB", IIC_LdStLoad,
2445                    [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, i64:$rB)]>,
2446                     UseVSXReg;
2447   } // mayStore
2448
2449   // Patterns for which instructions from ISA 3.0 are a better match
2450   let Predicates = [IsLittleEndian, HasP9Vector] in {
2451   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2452             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2453   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2454             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2455   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2456             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2457   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2458             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2459   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2460             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2461   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2462             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2463   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2464             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2465   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2466             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2467   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2468             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2469   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2470             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2471   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2472             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2473   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2474             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2475   } // IsLittleEndian, HasP9Vector
2476
2477   let Predicates = [IsBigEndian, HasP9Vector] in {
2478   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2479             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2480   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2481             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2482   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2483             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2484   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2485             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2486   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2487             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2488   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2489             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2490   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2491             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2492   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2493             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2494   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2495             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2496   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2497             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2498   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2499             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2500   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2501             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2502   } // IsLittleEndian, HasP9Vector
2503
2504   // D-Form Load/Store
2505   def : Pat<(v4i32 (load iaddr:$src)), (LXV memrix16:$src)>;
2506   def : Pat<(v4f32 (load iaddr:$src)), (LXV memrix16:$src)>;
2507   def : Pat<(v2i64 (load iaddr:$src)), (LXV memrix16:$src)>;
2508   def : Pat<(v2f64 (load iaddr:$src)), (LXV memrix16:$src)>;
2509   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddr:$src)), (LXV memrix16:$src)>;
2510   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddr:$src)), (LXV memrix16:$src)>;
2511
2512   def : Pat<(store v4f32:$rS, iaddr:$dst), (STXV $rS, memrix16:$dst)>;
2513   def : Pat<(store v4i32:$rS, iaddr:$dst), (STXV $rS, memrix16:$dst)>;
2514   def : Pat<(store v2f64:$rS, iaddr:$dst), (STXV $rS, memrix16:$dst)>;
2515   def : Pat<(store v2i64:$rS, iaddr:$dst), (STXV $rS, memrix16:$dst)>;
2516   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddr:$dst),
2517             (STXV $rS, memrix16:$dst)>;
2518   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddr:$dst),
2519             (STXV $rS, memrix16:$dst)>;
2520
2521
2522   def : Pat<(v2f64 (load xaddr:$src)), (LXVX xaddr:$src)>;
2523   def : Pat<(v2i64 (load xaddr:$src)), (LXVX xaddr:$src)>;
2524   def : Pat<(v4f32 (load xaddr:$src)), (LXVX xaddr:$src)>;
2525   def : Pat<(v4i32 (load xaddr:$src)), (LXVX xaddr:$src)>;
2526   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xaddr:$src)), (LXVX xaddr:$src)>;
2527   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xaddr:$src)), (LXVX xaddr:$src)>;
2528   def : Pat<(store v2f64:$rS, xaddr:$dst), (STXVX $rS, xaddr:$dst)>;
2529   def : Pat<(store v2i64:$rS, xaddr:$dst), (STXVX $rS, xaddr:$dst)>;
2530   def : Pat<(store v4f32:$rS, xaddr:$dst), (STXVX $rS, xaddr:$dst)>;
2531   def : Pat<(store v4i32:$rS, xaddr:$dst), (STXVX $rS, xaddr:$dst)>;
2532   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xaddr:$dst),
2533             (STXVX $rS, xaddr:$dst)>;
2534   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xaddr:$dst),
2535             (STXVX $rS, xaddr:$dst)>;
2536   def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
2537             (v4i32 (LXVWSX xoaddr:$src))>;
2538   def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
2539             (v4f32 (LXVWSX xoaddr:$src))>;
2540   def : Pat<(v4f32 (scalar_to_vector (f32 (fpround (extloadf32 xoaddr:$src))))),
2541             (v4f32 (LXVWSX xoaddr:$src))>;
2542
2543   // Build vectors from i8 loads
2544   def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
2545             (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
2546   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
2547             (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
2548   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
2549            (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
2550   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
2551             (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
2552   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
2553             (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
2554   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
2555             (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
2556
2557   // Build vectors from i16 loads
2558   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
2559             (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
2560   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
2561             (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
2562   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
2563            (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
2564   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
2565             (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
2566   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
2567             (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
2568
2569   let Predicates = [IsBigEndian, HasP9Vector] in {
2570   // Scalar stores of i8
2571   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2572             (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2573   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2574             (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2575   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2576             (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2577   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2578             (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2579   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2580             (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2581   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2582             (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2583   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2584             (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2585   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2586             (STXSIBXv $S, xoaddr:$dst)>;
2587   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2588             (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2589   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2590             (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2591   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2592             (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2593   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2594             (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2595   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2596             (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2597   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2598             (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2599   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2600             (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2601   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2602             (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2603
2604   // Scalar stores of i16
2605   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2606             (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2607   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2608             (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2609   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2610             (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2611   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2612             (STXSIHXv $S, xoaddr:$dst)>;
2613   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2614             (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2615   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2616             (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2617   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2618             (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2619   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2620             (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2621   } // IsBigEndian, HasP9Vector
2622
2623   let Predicates = [IsLittleEndian, HasP9Vector] in {
2624   // Scalar stores of i8
2625   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2626             (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2627   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2628             (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2629   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2630             (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2631   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2632             (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2633   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2634             (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2635   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2636             (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2637   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2638             (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2639   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2640             (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2641   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2642             (STXSIBXv $S, xoaddr:$dst)>;
2643   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2644             (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2645   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2646             (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2647   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2648             (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2649   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2650             (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2651   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2652             (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2653   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2654             (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2655   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2656             (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2657
2658   // Scalar stores of i16
2659   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2660             (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2661   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2662             (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2663   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2664             (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2665   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2666             (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2667   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2668             (STXSIHXv $S, xoaddr:$dst)>;
2669   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2670             (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2671   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2672             (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2673   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2674             (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2675   } // IsLittleEndian, HasP9Vector
2676
2677
2678   // Vector sign extensions
2679   def : Pat<(f64 (PPCVexts f64:$A, 1)),
2680             (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
2681   def : Pat<(f64 (PPCVexts f64:$A, 2)),
2682             (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
2683
2684   let isPseudo = 1 in {
2685     def DFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrix:$src),
2686                             "#DFLOADf32",
2687                             [(set f32:$XT, (load iaddr:$src))]>;
2688     def DFLOADf64  : Pseudo<(outs vsfrc:$XT), (ins memrix:$src),
2689                             "#DFLOADf64",
2690                             [(set f64:$XT, (load iaddr:$src))]>;
2691     def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst),
2692                             "#DFSTOREf32",
2693                             [(store f32:$XT, iaddr:$dst)]>;
2694     def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
2695                             "#DFSTOREf64",
2696                             [(store f64:$XT, iaddr:$dst)]>;
2697   }
2698   def : Pat<(f64 (extloadf32 iaddr:$src)),
2699             (COPY_TO_REGCLASS (DFLOADf32 iaddr:$src), VSFRC)>;
2700   def : Pat<(f32 (fpround (extloadf32 iaddr:$src))),
2701             (f32 (DFLOADf32 iaddr:$src))>;
2702 } // end HasP9Vector, AddedComplexity
2703
2704 // Integer extend helper dags 32 -> 64
2705 def AnyExts {
2706   dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
2707   dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
2708   dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
2709   dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
2710 }
2711
2712 def DblToFlt {
2713   dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
2714   dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
2715   dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
2716   dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
2717 }
2718 def FltToIntLoad {
2719   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
2720 }
2721 def FltToUIntLoad {
2722   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
2723 }
2724 def FltToLongLoad {
2725   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
2726 }
2727 def FltToLongLoadP9 {
2728   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddr:$A)))));
2729 }
2730 def FltToULongLoad {
2731   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
2732 }
2733 def FltToULongLoadP9 {
2734   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddr:$A)))));
2735 }
2736 def FltToLong {
2737   dag A = (i64 (PPCmfvsr (PPCfctidz (fpextend f32:$A))));
2738 }
2739 def FltToULong {
2740   dag A = (i64 (PPCmfvsr (PPCfctiduz (fpextend f32:$A))));
2741 }
2742 def DblToInt {
2743   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
2744 }
2745 def DblToUInt {
2746   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
2747 }
2748 def DblToLong {
2749   dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
2750 }
2751 def DblToULong {
2752   dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
2753 }
2754 def DblToIntLoad {
2755   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
2756 }
2757 def DblToIntLoadP9 {
2758   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddr:$A)))));
2759 }
2760 def DblToUIntLoad {
2761   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
2762 }
2763 def DblToUIntLoadP9 {
2764   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddr:$A)))));
2765 }
2766 def DblToLongLoad {
2767   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
2768 }
2769 def DblToULongLoad {
2770   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
2771 }
2772
2773 // FP merge dags (for f32 -> v4f32)
2774 def MrgFP {
2775   dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
2776                                (COPY_TO_REGCLASS $C, VSRC), 0));
2777   dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
2778                                (COPY_TO_REGCLASS $D, VSRC), 0));
2779   dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
2780   dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
2781   dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
2782   dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
2783 }
2784
2785 // Patterns for BUILD_VECTOR nodes.
2786 def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
2787 let AddedComplexity = 400 in {
2788
2789   let Predicates = [HasVSX] in {
2790     // Build vectors of floating point converted to i32.
2791     def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
2792                                    DblToInt.A, DblToInt.A)),
2793               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
2794     def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
2795                                    DblToUInt.A, DblToUInt.A)),
2796               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
2797     def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
2798               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
2799                                (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
2800     def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
2801               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
2802                                (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
2803     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
2804               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2805                                 (XSCVDPSXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>;
2806     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
2807               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2808                                 (XSCVDPUXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>;
2809     def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
2810               (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
2811
2812     // Build vectors of floating point converted to i64.
2813     def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
2814               (v2i64 (XXPERMDIs
2815                        (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
2816     def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
2817               (v2i64 (XXPERMDIs
2818                        (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
2819     def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
2820               (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
2821     def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
2822               (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
2823   }
2824
2825   let Predicates = [HasVSX, NoP9Vector] in {
2826     // Load-and-splat with fp-to-int conversion (using X-Form VSX loads).
2827     def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
2828               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2829                                 (XSCVDPSXWS (LXSDX xoaddr:$A)), VSRC), 1))>;
2830     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
2831               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2832                                 (XSCVDPUXWS (LXSDX xoaddr:$A)), VSRC), 1))>;
2833     def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
2834               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
2835                                               (LXSSPX xoaddr:$A), VSFRC)), 0))>;
2836     def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
2837               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
2838                                               (LXSSPX xoaddr:$A), VSFRC)), 0))>;
2839   }
2840
2841   // Big endian, available on all targets with VSX
2842   let Predicates = [IsBigEndian, HasVSX] in {
2843     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2844               (v2f64 (XXPERMDI
2845                         (COPY_TO_REGCLASS $A, VSRC),
2846                         (COPY_TO_REGCLASS $B, VSRC), 0))>;
2847
2848     def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
2849               (VMRGEW MrgFP.AC, MrgFP.BD)>;
2850     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2851                                    DblToFlt.B0, DblToFlt.B1)),
2852               (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
2853   }
2854
2855   let Predicates = [IsLittleEndian, HasVSX] in {
2856   // Little endian, available on all targets with VSX
2857     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2858               (v2f64 (XXPERMDI
2859                         (COPY_TO_REGCLASS $B, VSRC),
2860                         (COPY_TO_REGCLASS $A, VSRC), 0))>;
2861
2862     def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
2863               (VMRGEW MrgFP.AC, MrgFP.BD)>;
2864     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2865                                    DblToFlt.B0, DblToFlt.B1)),
2866               (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
2867   }
2868
2869   let Predicates = [HasDirectMove] in {
2870     // Endianness-neutral constant splat on P8 and newer targets. The reason
2871     // for this pattern is that on targets with direct moves, we don't expand
2872     // BUILD_VECTOR nodes for v4i32.
2873     def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
2874                                    immSExt5NonZero:$A, immSExt5NonZero:$A)),
2875               (v4i32 (VSPLTISW imm:$A))>;
2876   }
2877
2878   let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
2879     // Big endian integer vectors using direct moves.
2880     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
2881               (v2i64 (XXPERMDI
2882                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
2883                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
2884     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2885               (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC),
2886                                    (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 0),
2887                       (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC),
2888                                    (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 0))>;
2889     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2890               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
2891   }
2892
2893   let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
2894     // Little endian integer vectors using direct moves.
2895     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
2896               (v2i64 (XXPERMDI
2897                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
2898                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
2899     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2900               (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC),
2901                                    (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 0),
2902                       (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC),
2903                                    (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 0))>;
2904     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2905               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
2906   }
2907
2908   let Predicates = [HasP9Vector] in {
2909     // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
2910     def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2911               (v4i32 (MTVSRWS $A))>;
2912     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2913               (v4i32 (MTVSRWS $A))>;
2914     def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2915                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2916                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2917                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2918                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2919                                    immAnyExt8:$A)),
2920               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
2921     def : Pat<(v16i8 immAllOnesV),
2922               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
2923     def : Pat<(v8i16 immAllOnesV),
2924               (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
2925     def : Pat<(v4i32 immAllOnesV),
2926               (v4i32 (XXSPLTIB 255))>;
2927     def : Pat<(v2i64 immAllOnesV),
2928               (v2i64 (XXSPLTIB 255))>;
2929     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
2930               (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
2931     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
2932               (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
2933     def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
2934               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2935                                 (XSCVDPSXWS (DFLOADf64 iaddr:$A)), VSRC), 1))>;
2936     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
2937               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2938                                 (XSCVDPUXWS (DFLOADf64 iaddr:$A)), VSRC), 1))>;
2939     def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
2940               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
2941                                               (DFLOADf32 iaddr:$A),
2942                                               VSFRC)), 0))>;
2943     def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
2944               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
2945                                               (DFLOADf32 iaddr:$A),
2946                                               VSFRC)), 0))>;
2947   }
2948
2949   let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
2950     def : Pat<(i64 (extractelt v2i64:$A, 1)),
2951               (i64 (MFVSRLD $A))>;
2952     // Better way to build integer vectors if we have MTVSRDD. Big endian.
2953     def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
2954               (v2i64 (MTVSRDD $rB, $rA))>;
2955     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2956               (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.A, AnyExts.C), VSRC),
2957                       (COPY_TO_REGCLASS (MTVSRDD AnyExts.B, AnyExts.D), VSRC))>;
2958   }
2959
2960   let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
2961     def : Pat<(i64 (extractelt v2i64:$A, 0)),
2962               (i64 (MFVSRLD $A))>;
2963     // Better way to build integer vectors if we have MTVSRDD. Little endian.
2964     def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
2965               (v2i64 (MTVSRDD $rB, $rA))>;
2966     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2967               (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.D, AnyExts.B), VSRC),
2968                       (COPY_TO_REGCLASS (MTVSRDD AnyExts.C, AnyExts.A), VSRC))>;
2969   }
2970 }