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