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