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