]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
Import libucl 20170219
[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 def HasVSX : Predicate<"PPCSubTarget->hasVSX()">;
93 def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">;
94 def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">;
95
96 let Predicates = [HasVSX] in {
97 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
98 let hasSideEffects = 0 in { // VSX instructions don't have side effects.
99 let Uses = [RM] in {
100
101   // Load indexed instructions
102   let mayLoad = 1 in {
103     def LXSDX : XX1Form<31, 588,
104                         (outs vsfrc:$XT), (ins memrr:$src),
105                         "lxsdx $XT, $src", IIC_LdStLFD,
106                         [(set f64:$XT, (load xoaddr:$src))]>;
107
108     def LXVD2X : XX1Form<31, 844,
109                          (outs vsrc:$XT), (ins memrr:$src),
110                          "lxvd2x $XT, $src", IIC_LdStLFD,
111                          [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
112
113     def LXVDSX : XX1Form<31, 332,
114                          (outs vsrc:$XT), (ins memrr:$src),
115                          "lxvdsx $XT, $src", IIC_LdStLFD, []>;
116
117     def LXVW4X : XX1Form<31, 780,
118                          (outs vsrc:$XT), (ins memrr:$src),
119                          "lxvw4x $XT, $src", IIC_LdStLFD,
120                          [(set v4i32:$XT, (int_ppc_vsx_lxvw4x xoaddr:$src))]>;
121   } // mayLoad
122
123   // Store indexed instructions
124   let mayStore = 1 in {
125     def STXSDX : XX1Form<31, 716,
126                         (outs), (ins vsfrc:$XT, memrr:$dst),
127                         "stxsdx $XT, $dst", IIC_LdStSTFD,
128                         [(store f64:$XT, xoaddr:$dst)]>;
129
130     def STXVD2X : XX1Form<31, 972,
131                          (outs), (ins vsrc:$XT, memrr:$dst),
132                          "stxvd2x $XT, $dst", IIC_LdStSTFD,
133                          [(store v2f64:$XT, xoaddr:$dst)]>;
134
135     def STXVW4X : XX1Form<31, 908,
136                          (outs), (ins vsrc:$XT, memrr:$dst),
137                          "stxvw4x $XT, $dst", IIC_LdStSTFD,
138                          [(store v4i32:$XT, xoaddr:$dst)]>;
139
140   } // mayStore
141
142   // Add/Mul Instructions
143   let isCommutable = 1 in {
144     def XSADDDP : XX3Form<60, 32,
145                           (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
146                           "xsadddp $XT, $XA, $XB", IIC_VecFP,
147                           [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>;
148     def XSMULDP : XX3Form<60, 48,
149                           (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
150                           "xsmuldp $XT, $XA, $XB", IIC_VecFP,
151                           [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>;
152
153     def XVADDDP : XX3Form<60, 96,
154                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
155                           "xvadddp $XT, $XA, $XB", IIC_VecFP,
156                           [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>;
157
158     def XVADDSP : XX3Form<60, 64,
159                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
160                           "xvaddsp $XT, $XA, $XB", IIC_VecFP,
161                           [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>;
162
163     def XVMULDP : XX3Form<60, 112,
164                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
165                           "xvmuldp $XT, $XA, $XB", IIC_VecFP,
166                           [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>;
167
168     def XVMULSP : XX3Form<60, 80,
169                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
170                           "xvmulsp $XT, $XA, $XB", IIC_VecFP,
171                           [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>;
172   }
173
174   // Subtract Instructions
175   def XSSUBDP : XX3Form<60, 40,
176                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
177                         "xssubdp $XT, $XA, $XB", IIC_VecFP,
178                         [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>;
179
180   def XVSUBDP : XX3Form<60, 104,
181                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
182                         "xvsubdp $XT, $XA, $XB", IIC_VecFP,
183                         [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>;
184   def XVSUBSP : XX3Form<60, 72,
185                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
186                         "xvsubsp $XT, $XA, $XB", IIC_VecFP,
187                         [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>;
188
189   // FMA Instructions
190   let BaseName = "XSMADDADP" in {
191   let isCommutable = 1 in
192   def XSMADDADP : XX3Form<60, 33,
193                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
194                           "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
195                           [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>,
196                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
197                           AltVSXFMARel;
198   let IsVSXFMAAlt = 1 in
199   def XSMADDMDP : XX3Form<60, 41,
200                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
201                           "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
202                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
203                           AltVSXFMARel;
204   }
205
206   let BaseName = "XSMSUBADP" in {
207   let isCommutable = 1 in
208   def XSMSUBADP : XX3Form<60, 49,
209                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
210                           "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
211                           [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
212                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
213                           AltVSXFMARel;
214   let IsVSXFMAAlt = 1 in
215   def XSMSUBMDP : XX3Form<60, 57,
216                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
217                           "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
218                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
219                           AltVSXFMARel;
220   }
221
222   let BaseName = "XSNMADDADP" in {
223   let isCommutable = 1 in
224   def XSNMADDADP : XX3Form<60, 161,
225                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
226                           "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
227                           [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>,
228                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
229                           AltVSXFMARel;
230   let IsVSXFMAAlt = 1 in
231   def XSNMADDMDP : XX3Form<60, 169,
232                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
233                           "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
234                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
235                           AltVSXFMARel;
236   }
237
238   let BaseName = "XSNMSUBADP" in {
239   let isCommutable = 1 in
240   def XSNMSUBADP : XX3Form<60, 177,
241                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
242                           "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
243                           [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
244                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
245                           AltVSXFMARel;
246   let IsVSXFMAAlt = 1 in
247   def XSNMSUBMDP : XX3Form<60, 185,
248                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
249                           "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
250                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
251                           AltVSXFMARel;
252   }
253
254   let BaseName = "XVMADDADP" in {
255   let isCommutable = 1 in
256   def XVMADDADP : XX3Form<60, 97,
257                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
258                           "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
259                           [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
260                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
261                           AltVSXFMARel;
262   let IsVSXFMAAlt = 1 in
263   def XVMADDMDP : XX3Form<60, 105,
264                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
265                           "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
266                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
267                           AltVSXFMARel;
268   }
269
270   let BaseName = "XVMADDASP" in {
271   let isCommutable = 1 in
272   def XVMADDASP : XX3Form<60, 65,
273                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
274                           "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
275                           [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
276                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
277                           AltVSXFMARel;
278   let IsVSXFMAAlt = 1 in
279   def XVMADDMSP : XX3Form<60, 73,
280                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
281                           "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
282                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
283                           AltVSXFMARel;
284   }
285
286   let BaseName = "XVMSUBADP" in {
287   let isCommutable = 1 in
288   def XVMSUBADP : XX3Form<60, 113,
289                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
290                           "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
291                           [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
292                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
293                           AltVSXFMARel;
294   let IsVSXFMAAlt = 1 in
295   def XVMSUBMDP : XX3Form<60, 121,
296                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
297                           "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
298                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
299                           AltVSXFMARel;
300   }
301
302   let BaseName = "XVMSUBASP" in {
303   let isCommutable = 1 in
304   def XVMSUBASP : XX3Form<60, 81,
305                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
306                           "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
307                           [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
308                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
309                           AltVSXFMARel;
310   let IsVSXFMAAlt = 1 in
311   def XVMSUBMSP : XX3Form<60, 89,
312                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
313                           "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
314                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
315                           AltVSXFMARel;
316   }
317
318   let BaseName = "XVNMADDADP" in {
319   let isCommutable = 1 in
320   def XVNMADDADP : XX3Form<60, 225,
321                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
322                           "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
323                           [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
324                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
325                           AltVSXFMARel;
326   let IsVSXFMAAlt = 1 in
327   def XVNMADDMDP : XX3Form<60, 233,
328                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
329                           "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
330                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
331                           AltVSXFMARel;
332   }
333
334   let BaseName = "XVNMADDASP" in {
335   let isCommutable = 1 in
336   def XVNMADDASP : XX3Form<60, 193,
337                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
338                           "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
339                           [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
340                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
341                           AltVSXFMARel;
342   let IsVSXFMAAlt = 1 in
343   def XVNMADDMSP : XX3Form<60, 201,
344                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
345                           "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
346                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
347                           AltVSXFMARel;
348   }
349
350   let BaseName = "XVNMSUBADP" in {
351   let isCommutable = 1 in
352   def XVNMSUBADP : XX3Form<60, 241,
353                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
354                           "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
355                           [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
356                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
357                           AltVSXFMARel;
358   let IsVSXFMAAlt = 1 in
359   def XVNMSUBMDP : XX3Form<60, 249,
360                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
361                           "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
362                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
363                           AltVSXFMARel;
364   }
365
366   let BaseName = "XVNMSUBASP" in {
367   let isCommutable = 1 in
368   def XVNMSUBASP : XX3Form<60, 209,
369                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
370                           "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
371                           [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
372                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
373                           AltVSXFMARel;
374   let IsVSXFMAAlt = 1 in
375   def XVNMSUBMSP : XX3Form<60, 217,
376                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
377                           "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
378                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
379                           AltVSXFMARel;
380   }
381
382   // Division Instructions
383   def XSDIVDP : XX3Form<60, 56,
384                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
385                         "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
386                         [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>;
387   def XSSQRTDP : XX2Form<60, 75,
388                         (outs vsfrc:$XT), (ins vsfrc:$XB),
389                         "xssqrtdp $XT, $XB", IIC_FPSqrtD,
390                         [(set f64:$XT, (fsqrt f64:$XB))]>;
391
392   def XSREDP : XX2Form<60, 90,
393                         (outs vsfrc:$XT), (ins vsfrc:$XB),
394                         "xsredp $XT, $XB", IIC_VecFP,
395                         [(set f64:$XT, (PPCfre f64:$XB))]>;
396   def XSRSQRTEDP : XX2Form<60, 74,
397                            (outs vsfrc:$XT), (ins vsfrc:$XB),
398                            "xsrsqrtedp $XT, $XB", IIC_VecFP,
399                            [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
400
401   def XSTDIVDP : XX3Form_1<60, 61,
402                          (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
403                          "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
404   def XSTSQRTDP : XX2Form_1<60, 106,
405                           (outs crrc:$crD), (ins vsfrc:$XB),
406                           "xstsqrtdp $crD, $XB", IIC_FPCompare, []>;
407
408   def XVDIVDP : XX3Form<60, 120,
409                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
410                         "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
411                         [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>;
412   def XVDIVSP : XX3Form<60, 88,
413                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
414                         "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
415                         [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>;
416
417   def XVSQRTDP : XX2Form<60, 203,
418                         (outs vsrc:$XT), (ins vsrc:$XB),
419                         "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
420                         [(set v2f64:$XT, (fsqrt v2f64:$XB))]>;
421   def XVSQRTSP : XX2Form<60, 139,
422                         (outs vsrc:$XT), (ins vsrc:$XB),
423                         "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
424                         [(set v4f32:$XT, (fsqrt v4f32:$XB))]>;
425
426   def XVTDIVDP : XX3Form_1<60, 125,
427                          (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
428                          "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
429   def XVTDIVSP : XX3Form_1<60, 93,
430                          (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
431                          "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
432
433   def XVTSQRTDP : XX2Form_1<60, 234,
434                           (outs crrc:$crD), (ins vsrc:$XB),
435                           "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
436   def XVTSQRTSP : XX2Form_1<60, 170,
437                           (outs crrc:$crD), (ins vsrc:$XB),
438                           "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
439
440   def XVREDP : XX2Form<60, 218,
441                         (outs vsrc:$XT), (ins vsrc:$XB),
442                         "xvredp $XT, $XB", IIC_VecFP,
443                         [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
444   def XVRESP : XX2Form<60, 154,
445                         (outs vsrc:$XT), (ins vsrc:$XB),
446                         "xvresp $XT, $XB", IIC_VecFP,
447                         [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
448
449   def XVRSQRTEDP : XX2Form<60, 202,
450                            (outs vsrc:$XT), (ins vsrc:$XB),
451                            "xvrsqrtedp $XT, $XB", IIC_VecFP,
452                            [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
453   def XVRSQRTESP : XX2Form<60, 138,
454                            (outs vsrc:$XT), (ins vsrc:$XB),
455                            "xvrsqrtesp $XT, $XB", IIC_VecFP,
456                            [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
457
458   // Compare Instructions
459   def XSCMPODP : XX3Form_1<60, 43,
460                            (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
461                            "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
462   def XSCMPUDP : XX3Form_1<60, 35,
463                            (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
464                            "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
465
466   defm XVCMPEQDP : XX3Form_Rcr<60, 99,
467                              "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
468                              int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
469   defm XVCMPEQSP : XX3Form_Rcr<60, 67,
470                              "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
471                              int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
472   defm XVCMPGEDP : XX3Form_Rcr<60, 115,
473                              "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
474                              int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
475   defm XVCMPGESP : XX3Form_Rcr<60, 83,
476                              "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
477                              int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
478   defm XVCMPGTDP : XX3Form_Rcr<60, 107,
479                              "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
480                              int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
481   defm XVCMPGTSP : XX3Form_Rcr<60, 75,
482                              "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
483                              int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
484
485   // Move Instructions
486   def XSABSDP : XX2Form<60, 345,
487                       (outs vsfrc:$XT), (ins vsfrc:$XB),
488                       "xsabsdp $XT, $XB", IIC_VecFP,
489                       [(set f64:$XT, (fabs f64:$XB))]>;
490   def XSNABSDP : XX2Form<60, 361,
491                       (outs vsfrc:$XT), (ins vsfrc:$XB),
492                       "xsnabsdp $XT, $XB", IIC_VecFP,
493                       [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
494   def XSNEGDP : XX2Form<60, 377,
495                       (outs vsfrc:$XT), (ins vsfrc:$XB),
496                       "xsnegdp $XT, $XB", IIC_VecFP,
497                       [(set f64:$XT, (fneg f64:$XB))]>;
498   def XSCPSGNDP : XX3Form<60, 176,
499                       (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
500                       "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
501                       [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
502
503   def XVABSDP : XX2Form<60, 473,
504                       (outs vsrc:$XT), (ins vsrc:$XB),
505                       "xvabsdp $XT, $XB", IIC_VecFP,
506                       [(set v2f64:$XT, (fabs v2f64:$XB))]>;
507
508   def XVABSSP : XX2Form<60, 409,
509                       (outs vsrc:$XT), (ins vsrc:$XB),
510                       "xvabssp $XT, $XB", IIC_VecFP,
511                       [(set v4f32:$XT, (fabs v4f32:$XB))]>;
512
513   def XVCPSGNDP : XX3Form<60, 240,
514                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
515                       "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
516                       [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
517   def XVCPSGNSP : XX3Form<60, 208,
518                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
519                       "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
520                       [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
521
522   def XVNABSDP : XX2Form<60, 489,
523                       (outs vsrc:$XT), (ins vsrc:$XB),
524                       "xvnabsdp $XT, $XB", IIC_VecFP,
525                       [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
526   def XVNABSSP : XX2Form<60, 425,
527                       (outs vsrc:$XT), (ins vsrc:$XB),
528                       "xvnabssp $XT, $XB", IIC_VecFP,
529                       [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
530
531   def XVNEGDP : XX2Form<60, 505,
532                       (outs vsrc:$XT), (ins vsrc:$XB),
533                       "xvnegdp $XT, $XB", IIC_VecFP,
534                       [(set v2f64:$XT, (fneg v2f64:$XB))]>;
535   def XVNEGSP : XX2Form<60, 441,
536                       (outs vsrc:$XT), (ins vsrc:$XB),
537                       "xvnegsp $XT, $XB", IIC_VecFP,
538                       [(set v4f32:$XT, (fneg v4f32:$XB))]>;
539
540   // Conversion Instructions
541   def XSCVDPSP : XX2Form<60, 265,
542                       (outs vsfrc:$XT), (ins vsfrc:$XB),
543                       "xscvdpsp $XT, $XB", IIC_VecFP, []>;
544   def XSCVDPSXDS : XX2Form<60, 344,
545                       (outs vsfrc:$XT), (ins vsfrc:$XB),
546                       "xscvdpsxds $XT, $XB", IIC_VecFP,
547                       [(set f64:$XT, (PPCfctidz f64:$XB))]>;
548   def XSCVDPSXWS : XX2Form<60, 88,
549                       (outs vsfrc:$XT), (ins vsfrc:$XB),
550                       "xscvdpsxws $XT, $XB", IIC_VecFP,
551                       [(set f64:$XT, (PPCfctiwz f64:$XB))]>;
552   def XSCVDPUXDS : XX2Form<60, 328,
553                       (outs vsfrc:$XT), (ins vsfrc:$XB),
554                       "xscvdpuxds $XT, $XB", IIC_VecFP,
555                       [(set f64:$XT, (PPCfctiduz f64:$XB))]>;
556   def XSCVDPUXWS : XX2Form<60, 72,
557                       (outs vsfrc:$XT), (ins vsfrc:$XB),
558                       "xscvdpuxws $XT, $XB", IIC_VecFP,
559                       [(set f64:$XT, (PPCfctiwuz f64:$XB))]>;
560   def XSCVSPDP : XX2Form<60, 329,
561                       (outs vsfrc:$XT), (ins vsfrc:$XB),
562                       "xscvspdp $XT, $XB", IIC_VecFP, []>;
563   def XSCVSXDDP : XX2Form<60, 376,
564                       (outs vsfrc:$XT), (ins vsfrc:$XB),
565                       "xscvsxddp $XT, $XB", IIC_VecFP,
566                       [(set f64:$XT, (PPCfcfid f64:$XB))]>;
567   def XSCVUXDDP : XX2Form<60, 360,
568                       (outs vsfrc:$XT), (ins vsfrc:$XB),
569                       "xscvuxddp $XT, $XB", IIC_VecFP,
570                       [(set f64:$XT, (PPCfcfidu f64:$XB))]>;
571
572   def XVCVDPSP : XX2Form<60, 393,
573                       (outs vsrc:$XT), (ins vsrc:$XB),
574                       "xvcvdpsp $XT, $XB", IIC_VecFP, []>;
575   def XVCVDPSXDS : XX2Form<60, 472,
576                       (outs vsrc:$XT), (ins vsrc:$XB),
577                       "xvcvdpsxds $XT, $XB", IIC_VecFP,
578                       [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>;
579   def XVCVDPSXWS : XX2Form<60, 216,
580                       (outs vsrc:$XT), (ins vsrc:$XB),
581                       "xvcvdpsxws $XT, $XB", IIC_VecFP, []>;
582   def XVCVDPUXDS : XX2Form<60, 456,
583                       (outs vsrc:$XT), (ins vsrc:$XB),
584                       "xvcvdpuxds $XT, $XB", IIC_VecFP,
585                       [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>;
586   def XVCVDPUXWS : XX2Form<60, 200,
587                       (outs vsrc:$XT), (ins vsrc:$XB),
588                       "xvcvdpuxws $XT, $XB", IIC_VecFP, []>;
589
590   def XVCVSPDP : XX2Form<60, 457,
591                       (outs vsrc:$XT), (ins vsrc:$XB),
592                       "xvcvspdp $XT, $XB", IIC_VecFP, []>;
593   def XVCVSPSXDS : XX2Form<60, 408,
594                       (outs vsrc:$XT), (ins vsrc:$XB),
595                       "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
596   def XVCVSPSXWS : XX2Form<60, 152,
597                       (outs vsrc:$XT), (ins vsrc:$XB),
598                       "xvcvspsxws $XT, $XB", IIC_VecFP, []>;
599   def XVCVSPUXDS : XX2Form<60, 392,
600                       (outs vsrc:$XT), (ins vsrc:$XB),
601                       "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
602   def XVCVSPUXWS : XX2Form<60, 136,
603                       (outs vsrc:$XT), (ins vsrc:$XB),
604                       "xvcvspuxws $XT, $XB", IIC_VecFP, []>;
605   def XVCVSXDDP : XX2Form<60, 504,
606                       (outs vsrc:$XT), (ins vsrc:$XB),
607                       "xvcvsxddp $XT, $XB", IIC_VecFP,
608                       [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>;
609   def XVCVSXDSP : XX2Form<60, 440,
610                       (outs vsrc:$XT), (ins vsrc:$XB),
611                       "xvcvsxdsp $XT, $XB", IIC_VecFP, []>;
612   def XVCVSXWDP : XX2Form<60, 248,
613                       (outs vsrc:$XT), (ins vsrc:$XB),
614                       "xvcvsxwdp $XT, $XB", IIC_VecFP, []>;
615   def XVCVSXWSP : XX2Form<60, 184,
616                       (outs vsrc:$XT), (ins vsrc:$XB),
617                       "xvcvsxwsp $XT, $XB", IIC_VecFP,
618                       [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>;
619   def XVCVUXDDP : XX2Form<60, 488,
620                       (outs vsrc:$XT), (ins vsrc:$XB),
621                       "xvcvuxddp $XT, $XB", IIC_VecFP,
622                       [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>;
623   def XVCVUXDSP : XX2Form<60, 424,
624                       (outs vsrc:$XT), (ins vsrc:$XB),
625                       "xvcvuxdsp $XT, $XB", IIC_VecFP, []>;
626   def XVCVUXWDP : XX2Form<60, 232,
627                       (outs vsrc:$XT), (ins vsrc:$XB),
628                       "xvcvuxwdp $XT, $XB", IIC_VecFP, []>;
629   def XVCVUXWSP : XX2Form<60, 168,
630                       (outs vsrc:$XT), (ins vsrc:$XB),
631                       "xvcvuxwsp $XT, $XB", IIC_VecFP, []>;
632
633   // Rounding Instructions
634   def XSRDPI : XX2Form<60, 73,
635                       (outs vsfrc:$XT), (ins vsfrc:$XB),
636                       "xsrdpi $XT, $XB", IIC_VecFP,
637                       [(set f64:$XT, (frnd f64:$XB))]>;
638   def XSRDPIC : XX2Form<60, 107,
639                       (outs vsfrc:$XT), (ins vsfrc:$XB),
640                       "xsrdpic $XT, $XB", IIC_VecFP,
641                       [(set f64:$XT, (fnearbyint f64:$XB))]>;
642   def XSRDPIM : XX2Form<60, 121,
643                       (outs vsfrc:$XT), (ins vsfrc:$XB),
644                       "xsrdpim $XT, $XB", IIC_VecFP,
645                       [(set f64:$XT, (ffloor f64:$XB))]>;
646   def XSRDPIP : XX2Form<60, 105,
647                       (outs vsfrc:$XT), (ins vsfrc:$XB),
648                       "xsrdpip $XT, $XB", IIC_VecFP,
649                       [(set f64:$XT, (fceil f64:$XB))]>;
650   def XSRDPIZ : XX2Form<60, 89,
651                       (outs vsfrc:$XT), (ins vsfrc:$XB),
652                       "xsrdpiz $XT, $XB", IIC_VecFP,
653                       [(set f64:$XT, (ftrunc f64:$XB))]>;
654
655   def XVRDPI : XX2Form<60, 201,
656                       (outs vsrc:$XT), (ins vsrc:$XB),
657                       "xvrdpi $XT, $XB", IIC_VecFP,
658                       [(set v2f64:$XT, (frnd v2f64:$XB))]>;
659   def XVRDPIC : XX2Form<60, 235,
660                       (outs vsrc:$XT), (ins vsrc:$XB),
661                       "xvrdpic $XT, $XB", IIC_VecFP,
662                       [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
663   def XVRDPIM : XX2Form<60, 249,
664                       (outs vsrc:$XT), (ins vsrc:$XB),
665                       "xvrdpim $XT, $XB", IIC_VecFP,
666                       [(set v2f64:$XT, (ffloor v2f64:$XB))]>;
667   def XVRDPIP : XX2Form<60, 233,
668                       (outs vsrc:$XT), (ins vsrc:$XB),
669                       "xvrdpip $XT, $XB", IIC_VecFP,
670                       [(set v2f64:$XT, (fceil v2f64:$XB))]>;
671   def XVRDPIZ : XX2Form<60, 217,
672                       (outs vsrc:$XT), (ins vsrc:$XB),
673                       "xvrdpiz $XT, $XB", IIC_VecFP,
674                       [(set v2f64:$XT, (ftrunc v2f64:$XB))]>;
675
676   def XVRSPI : XX2Form<60, 137,
677                       (outs vsrc:$XT), (ins vsrc:$XB),
678                       "xvrspi $XT, $XB", IIC_VecFP,
679                       [(set v4f32:$XT, (frnd v4f32:$XB))]>;
680   def XVRSPIC : XX2Form<60, 171,
681                       (outs vsrc:$XT), (ins vsrc:$XB),
682                       "xvrspic $XT, $XB", IIC_VecFP,
683                       [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
684   def XVRSPIM : XX2Form<60, 185,
685                       (outs vsrc:$XT), (ins vsrc:$XB),
686                       "xvrspim $XT, $XB", IIC_VecFP,
687                       [(set v4f32:$XT, (ffloor v4f32:$XB))]>;
688   def XVRSPIP : XX2Form<60, 169,
689                       (outs vsrc:$XT), (ins vsrc:$XB),
690                       "xvrspip $XT, $XB", IIC_VecFP,
691                       [(set v4f32:$XT, (fceil v4f32:$XB))]>;
692   def XVRSPIZ : XX2Form<60, 153,
693                       (outs vsrc:$XT), (ins vsrc:$XB),
694                       "xvrspiz $XT, $XB", IIC_VecFP,
695                       [(set v4f32:$XT, (ftrunc v4f32:$XB))]>;
696
697   // Max/Min Instructions
698   let isCommutable = 1 in {
699   def XSMAXDP : XX3Form<60, 160,
700                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
701                         "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
702                         [(set vsfrc:$XT,
703                               (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
704   def XSMINDP : XX3Form<60, 168,
705                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
706                         "xsmindp $XT, $XA, $XB", IIC_VecFP,
707                         [(set vsfrc:$XT,
708                               (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
709
710   def XVMAXDP : XX3Form<60, 224,
711                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
712                         "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
713                         [(set vsrc:$XT,
714                               (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
715   def XVMINDP : XX3Form<60, 232,
716                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
717                         "xvmindp $XT, $XA, $XB", IIC_VecFP,
718                         [(set vsrc:$XT,
719                               (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
720
721   def XVMAXSP : XX3Form<60, 192,
722                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
723                         "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
724                         [(set vsrc:$XT,
725                               (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
726   def XVMINSP : XX3Form<60, 200,
727                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
728                         "xvminsp $XT, $XA, $XB", IIC_VecFP,
729                         [(set vsrc:$XT,
730                               (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
731   } // isCommutable
732 } // Uses = [RM]
733
734   // Logical Instructions
735   let isCommutable = 1 in
736   def XXLAND : XX3Form<60, 130,
737                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
738                        "xxland $XT, $XA, $XB", IIC_VecGeneral,
739                        [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
740   def XXLANDC : XX3Form<60, 138,
741                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
742                         "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
743                         [(set v4i32:$XT, (and v4i32:$XA,
744                                               (vnot_ppc v4i32:$XB)))]>;
745   let isCommutable = 1 in {
746   def XXLNOR : XX3Form<60, 162,
747                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
748                        "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
749                        [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
750                                                    v4i32:$XB)))]>;
751   def XXLOR : XX3Form<60, 146,
752                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
753                       "xxlor $XT, $XA, $XB", IIC_VecGeneral,
754                       [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
755   let isCodeGenOnly = 1 in
756   def XXLORf: XX3Form<60, 146,
757                       (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
758                       "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
759   def XXLXOR : XX3Form<60, 154,
760                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
761                        "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
762                        [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
763   } // isCommutable
764
765   // Permutation Instructions
766   def XXMRGHW : XX3Form<60, 18,
767                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
768                        "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
769   def XXMRGLW : XX3Form<60, 50,
770                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
771                        "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
772
773   def XXPERMDI : XX3Form_2<60, 10,
774                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
775                        "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm, []>;
776   def XXSEL : XX4Form<60, 3,
777                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
778                       "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
779
780   def XXSLDWI : XX3Form_2<60, 2,
781                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
782                        "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
783                        [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
784                                                   imm32SExt16:$SHW))]>;
785   def XXSPLTW : XX2Form_2<60, 164,
786                        (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
787                        "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
788                        [(set v4i32:$XT,
789                              (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
790 } // hasSideEffects
791
792 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
793 // instruction selection into a branch sequence.
794 let usesCustomInserter = 1,    // Expanded after instruction selection.
795     PPC970_Single = 1 in {
796
797   def SELECT_CC_VSRC: Pseudo<(outs vsrc:$dst),
798                              (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
799                              "#SELECT_CC_VSRC",
800                              []>;
801   def SELECT_VSRC: Pseudo<(outs vsrc:$dst),
802                           (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
803                           "#SELECT_VSRC",
804                           [(set v2f64:$dst,
805                                 (select i1:$cond, v2f64:$T, v2f64:$F))]>;
806   def SELECT_CC_VSFRC: Pseudo<(outs f8rc:$dst),
807                               (ins crrc:$cond, f8rc:$T, f8rc:$F,
808                                i32imm:$BROPC), "#SELECT_CC_VSFRC",
809                               []>;
810   def SELECT_VSFRC: Pseudo<(outs f8rc:$dst),
811                            (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
812                            "#SELECT_VSFRC",
813                            [(set f64:$dst,
814                                  (select i1:$cond, f64:$T, f64:$F))]>;
815   def SELECT_CC_VSSRC: Pseudo<(outs f4rc:$dst),
816                               (ins crrc:$cond, f4rc:$T, f4rc:$F,
817                                i32imm:$BROPC), "#SELECT_CC_VSSRC",
818                               []>;
819   def SELECT_VSSRC: Pseudo<(outs f4rc:$dst),
820                            (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
821                            "#SELECT_VSSRC",
822                            [(set f32:$dst,
823                                  (select i1:$cond, f32:$T, f32:$F))]>;
824 } // usesCustomInserter
825 } // AddedComplexity
826
827 def : InstAlias<"xvmovdp $XT, $XB",
828                 (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
829 def : InstAlias<"xvmovsp $XT, $XB",
830                 (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
831
832 def : InstAlias<"xxspltd $XT, $XB, 0",
833                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
834 def : InstAlias<"xxspltd $XT, $XB, 1",
835                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
836 def : InstAlias<"xxmrghd $XT, $XA, $XB",
837                 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
838 def : InstAlias<"xxmrgld $XT, $XA, $XB",
839                 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
840 def : InstAlias<"xxswapd $XT, $XB",
841                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
842
843 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
844
845 let Predicates = [IsBigEndian] in {
846 def : Pat<(v2f64 (scalar_to_vector f64:$A)),
847           (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
848
849 def : Pat<(f64 (extractelt v2f64:$S, 0)),
850           (f64 (EXTRACT_SUBREG $S, sub_64))>;
851 def : Pat<(f64 (extractelt v2f64:$S, 1)),
852           (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
853 }
854
855 let Predicates = [IsLittleEndian] in {
856 def : Pat<(v2f64 (scalar_to_vector f64:$A)),
857           (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
858                            (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
859
860 def : Pat<(f64 (extractelt v2f64:$S, 0)),
861           (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
862 def : Pat<(f64 (extractelt v2f64:$S, 1)),
863           (f64 (EXTRACT_SUBREG $S, sub_64))>;
864 }
865
866 // Additional fnmsub patterns: -a*c + b == -(a*c - b)
867 def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
868           (XSNMSUBADP $B, $C, $A)>;
869 def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B),
870           (XSNMSUBADP $B, $C, $A)>;
871
872 def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B),
873           (XVNMSUBADP $B, $C, $A)>;
874 def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B),
875           (XVNMSUBADP $B, $C, $A)>;
876
877 def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B),
878           (XVNMSUBASP $B, $C, $A)>;
879 def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B),
880           (XVNMSUBASP $B, $C, $A)>;
881
882 def : Pat<(v2f64 (bitconvert v4f32:$A)),
883           (COPY_TO_REGCLASS $A, VSRC)>;
884 def : Pat<(v2f64 (bitconvert v4i32:$A)),
885           (COPY_TO_REGCLASS $A, VSRC)>;
886 def : Pat<(v2f64 (bitconvert v8i16:$A)),
887           (COPY_TO_REGCLASS $A, VSRC)>;
888 def : Pat<(v2f64 (bitconvert v16i8:$A)),
889           (COPY_TO_REGCLASS $A, VSRC)>;
890
891 def : Pat<(v4f32 (bitconvert v2f64:$A)),
892           (COPY_TO_REGCLASS $A, VRRC)>;
893 def : Pat<(v4i32 (bitconvert v2f64:$A)),
894           (COPY_TO_REGCLASS $A, VRRC)>;
895 def : Pat<(v8i16 (bitconvert v2f64:$A)),
896           (COPY_TO_REGCLASS $A, VRRC)>;
897 def : Pat<(v16i8 (bitconvert v2f64:$A)),
898           (COPY_TO_REGCLASS $A, VRRC)>;
899
900 def : Pat<(v2i64 (bitconvert v4f32:$A)),
901           (COPY_TO_REGCLASS $A, VSRC)>;
902 def : Pat<(v2i64 (bitconvert v4i32:$A)),
903           (COPY_TO_REGCLASS $A, VSRC)>;
904 def : Pat<(v2i64 (bitconvert v8i16:$A)),
905           (COPY_TO_REGCLASS $A, VSRC)>;
906 def : Pat<(v2i64 (bitconvert v16i8:$A)),
907           (COPY_TO_REGCLASS $A, VSRC)>;
908
909 def : Pat<(v4f32 (bitconvert v2i64:$A)),
910           (COPY_TO_REGCLASS $A, VRRC)>;
911 def : Pat<(v4i32 (bitconvert v2i64:$A)),
912           (COPY_TO_REGCLASS $A, VRRC)>;
913 def : Pat<(v8i16 (bitconvert v2i64:$A)),
914           (COPY_TO_REGCLASS $A, VRRC)>;
915 def : Pat<(v16i8 (bitconvert v2i64:$A)),
916           (COPY_TO_REGCLASS $A, VRRC)>;
917
918 def : Pat<(v2f64 (bitconvert v2i64:$A)),
919           (COPY_TO_REGCLASS $A, VRRC)>;
920 def : Pat<(v2i64 (bitconvert v2f64:$A)),
921           (COPY_TO_REGCLASS $A, VRRC)>;
922
923 def : Pat<(v2f64 (bitconvert v1i128:$A)),
924           (COPY_TO_REGCLASS $A, VRRC)>;
925 def : Pat<(v1i128 (bitconvert v2f64:$A)),
926           (COPY_TO_REGCLASS $A, VRRC)>;
927
928 // sign extension patterns
929 // To extend "in place" from v2i32 to v2i64, we have input data like:
930 // | undef | i32 | undef | i32 |
931 // but xvcvsxwdp expects the input in big-Endian format:
932 // | i32 | undef | i32 | undef |
933 // so we need to shift everything to the left by one i32 (word) before
934 // the conversion.
935 def : Pat<(sext_inreg v2i64:$C, v2i32),
936           (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>;
937 def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))),
938           (XVCVSXWDP (XXSLDWI $C, $C, 1))>;
939
940 def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
941           (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
942 def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
943           (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
944
945 def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
946           (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
947 def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
948           (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
949
950 // Loads.
951 def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
952 def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
953 def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
954 def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
955
956 // Stores.
957 def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
958           (STXVD2X $rS, xoaddr:$dst)>;
959 def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
960 def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
961           (STXVW4X $rS, xoaddr:$dst)>;
962 def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
963
964 // Permutes.
965 def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
966 def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
967 def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
968 def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
969 def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
970
971 // Selects.
972 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
973           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
974 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
975           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
976 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
977           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
978 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
979           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
980 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
981           (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
982 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
983           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
984 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
985           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
986 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
987           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
988 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
989           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
990 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
991           (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
992
993 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
994           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
995 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
996           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
997 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
998           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
999 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
1000           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1001 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
1002           (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
1003 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
1004           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1005 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
1006           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1007 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
1008           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1009 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
1010           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1011 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
1012           (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1013
1014 // Divides.
1015 def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
1016           (XVDIVSP $A, $B)>;
1017 def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
1018           (XVDIVDP $A, $B)>;
1019
1020 // Reciprocal estimate
1021 def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1022           (XVRESP $A)>;
1023 def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1024           (XVREDP $A)>;
1025
1026 // Recip. square root estimate
1027 def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1028           (XVRSQRTESP $A)>;
1029 def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1030           (XVRSQRTEDP $A)>;
1031
1032 let Predicates = [IsLittleEndian] in {
1033 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1034           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1035 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1036           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1037 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1038           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1039 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1040           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1041 } // IsLittleEndian
1042
1043 let Predicates = [IsBigEndian] in {
1044 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1045           (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1046 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1047           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1048 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1049           (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1050 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1051           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1052 } // IsBigEndian
1053
1054 } // AddedComplexity
1055 } // HasVSX
1056
1057 // The following VSX instructions were introduced in Power ISA 2.07
1058 /* FIXME: if the operands are v2i64, these patterns will not match.
1059    we should define new patterns or otherwise match the same patterns
1060    when the elements are larger than i32.
1061 */
1062 def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1063 def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1064 let Predicates = [HasP8Vector] in {
1065 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1066   let isCommutable = 1 in {
1067     def XXLEQV : XX3Form<60, 186,
1068                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1069                          "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1070                          [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1071     def XXLNAND : XX3Form<60, 178,
1072                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1073                           "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1074                           [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1075                                                     v4i32:$XB)))]>;
1076   } // isCommutable
1077
1078   def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1079             (XXLEQV $A, $B)>;
1080
1081   def XXLORC : XX3Form<60, 170,
1082                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1083                        "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1084                        [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1085
1086   // VSX scalar loads introduced in ISA 2.07
1087   let mayLoad = 1 in {
1088     def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1089                          "lxsspx $XT, $src", IIC_LdStLFD,
1090                          [(set f32:$XT, (load xoaddr:$src))]>;
1091     def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1092                           "lxsiwax $XT, $src", IIC_LdStLFD,
1093                           [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1094     def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1095                           "lxsiwzx $XT, $src", IIC_LdStLFD,
1096                           [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1097   } // mayLoad
1098
1099   // VSX scalar stores introduced in ISA 2.07
1100   let mayStore = 1 in {
1101     def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1102                           "stxsspx $XT, $dst", IIC_LdStSTFD,
1103                           [(store f32:$XT, xoaddr:$dst)]>;
1104     def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1105                           "stxsiwx $XT, $dst", IIC_LdStSTFD,
1106                           [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1107   } // mayStore
1108
1109   def : Pat<(f64 (extloadf32 xoaddr:$src)),
1110             (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>;
1111   def : Pat<(f64 (fextend f32:$src)),
1112             (COPY_TO_REGCLASS $src, VSFRC)>;
1113
1114   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1115             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1116   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1117             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1118   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1119             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1120   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1121             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1122   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1123             (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1124   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1125             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1126   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1127             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1128   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1129             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1130   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1131             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1132   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1133             (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1134
1135   // VSX Elementary Scalar FP arithmetic (SP)
1136   let isCommutable = 1 in {
1137     def XSADDSP : XX3Form<60, 0,
1138                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1139                           "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1140                           [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1141     def XSMULSP : XX3Form<60, 16,
1142                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1143                           "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1144                           [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1145   } // isCommutable
1146
1147   def XSDIVSP : XX3Form<60, 24,
1148                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1149                         "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1150                         [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1151   def XSRESP : XX2Form<60, 26,
1152                         (outs vssrc:$XT), (ins vssrc:$XB),
1153                         "xsresp $XT, $XB", IIC_VecFP,
1154                         [(set f32:$XT, (PPCfre f32:$XB))]>;
1155   def XSSQRTSP : XX2Form<60, 11,
1156                         (outs vssrc:$XT), (ins vssrc:$XB),
1157                         "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1158                         [(set f32:$XT, (fsqrt f32:$XB))]>;
1159   def XSRSQRTESP : XX2Form<60, 10,
1160                            (outs vssrc:$XT), (ins vssrc:$XB),
1161                            "xsrsqrtesp $XT, $XB", IIC_VecFP,
1162                            [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1163   def XSSUBSP : XX3Form<60, 8,
1164                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1165                         "xssubsp $XT, $XA, $XB", IIC_VecFP,
1166                         [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1167
1168   // FMA Instructions
1169   let BaseName = "XSMADDASP" in {
1170   let isCommutable = 1 in
1171   def XSMADDASP : XX3Form<60, 1,
1172                           (outs vssrc:$XT),
1173                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1174                           "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1175                           [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1176                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1177                           AltVSXFMARel;
1178   let IsVSXFMAAlt = 1 in
1179   def XSMADDMSP : XX3Form<60, 9,
1180                           (outs vssrc:$XT),
1181                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1182                           "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1183                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1184                           AltVSXFMARel;
1185   }
1186
1187   let BaseName = "XSMSUBASP" in {
1188   let isCommutable = 1 in
1189   def XSMSUBASP : XX3Form<60, 17,
1190                           (outs vssrc:$XT),
1191                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1192                           "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1193                           [(set f32:$XT, (fma f32:$XA, f32:$XB,
1194                                               (fneg f32:$XTi)))]>,
1195                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1196                           AltVSXFMARel;
1197   let IsVSXFMAAlt = 1 in
1198   def XSMSUBMSP : XX3Form<60, 25,
1199                           (outs vssrc:$XT),
1200                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1201                           "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1202                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1203                           AltVSXFMARel;
1204   }
1205
1206   let BaseName = "XSNMADDASP" in {
1207   let isCommutable = 1 in
1208   def XSNMADDASP : XX3Form<60, 129,
1209                           (outs vssrc:$XT),
1210                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1211                           "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1212                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1213                                                     f32:$XTi)))]>,
1214                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1215                           AltVSXFMARel;
1216   let IsVSXFMAAlt = 1 in
1217   def XSNMADDMSP : XX3Form<60, 137,
1218                           (outs vssrc:$XT),
1219                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1220                           "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1221                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1222                           AltVSXFMARel;
1223   }
1224
1225   let BaseName = "XSNMSUBASP" in {
1226   let isCommutable = 1 in
1227   def XSNMSUBASP : XX3Form<60, 145,
1228                           (outs vssrc:$XT),
1229                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1230                           "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1231                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1232                                                     (fneg f32:$XTi))))]>,
1233                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1234                           AltVSXFMARel;
1235   let IsVSXFMAAlt = 1 in
1236   def XSNMSUBMSP : XX3Form<60, 153,
1237                           (outs vssrc:$XT),
1238                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1239                           "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1240                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1241                           AltVSXFMARel;
1242   }
1243
1244   // Single Precision Conversions (FP <-> INT)
1245   def XSCVSXDSP : XX2Form<60, 312,
1246                       (outs vssrc:$XT), (ins vsfrc:$XB),
1247                       "xscvsxdsp $XT, $XB", IIC_VecFP,
1248                       [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1249   def XSCVUXDSP : XX2Form<60, 296,
1250                       (outs vssrc:$XT), (ins vsfrc:$XB),
1251                       "xscvuxdsp $XT, $XB", IIC_VecFP,
1252                       [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1253
1254   // Conversions between vector and scalar single precision
1255   def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1256                           "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1257   def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1258                           "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1259
1260   let Predicates = [IsLittleEndian] in {
1261   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1262             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1263   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1264             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1265   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1266             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1267   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1268             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1269   }
1270
1271   let Predicates = [IsBigEndian] in {
1272   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1273             (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1274   def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1275             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1276   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1277             (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1278   def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1279             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1280   }
1281 } // AddedComplexity = 400
1282 } // HasP8Vector
1283
1284 let Predicates = [HasDirectMove] in {
1285   // VSX direct move instructions
1286   def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1287                               "mfvsrd $rA, $XT", IIC_VecGeneral,
1288                               [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1289       Requires<[In64BitMode]>;
1290   def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1291                                "mfvsrwz $rA, $XT", IIC_VecGeneral,
1292                                [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1293   def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1294                               "mtvsrd $XT, $rA", IIC_VecGeneral,
1295                               [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1296       Requires<[In64BitMode]>;
1297   def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1298                                "mtvsrwa $XT, $rA", IIC_VecGeneral,
1299                                [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1300   def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1301                                "mtvsrwz $XT, $rA", IIC_VecGeneral,
1302                                [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1303 } // HasDirectMove
1304
1305 let Predicates = [IsISA3_0, HasDirectMove] in {
1306   def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1307                               "mtvsrws $XT, $rA", IIC_VecGeneral,
1308                               []>;
1309
1310   def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
1311                        "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1312                        []>, Requires<[In64BitMode]>;
1313
1314   def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1315                               "mfvsrld $rA, $XT", IIC_VecGeneral,
1316                               []>, Requires<[In64BitMode]>;
1317
1318 } // IsISA3_0, HasDirectMove
1319
1320 /*  Direct moves of various widths from GPR's into VSR's. Each move lines
1321     the value up into element 0 (both BE and LE). Namely, entities smaller than
1322     a doubleword are shifted left and moved for BE. For LE, they're moved, then
1323     swapped to go into the least significant element of the VSR.
1324 */
1325 def MovesToVSR {
1326   dag BE_BYTE_0 =
1327     (MTVSRD
1328       (RLDICR
1329         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1330   dag BE_HALF_0 =
1331     (MTVSRD
1332       (RLDICR
1333         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1334   dag BE_WORD_0 =
1335     (MTVSRD
1336       (RLDICR
1337         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1338   dag BE_DWORD_0 = (MTVSRD $A);
1339
1340   dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1341   dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1342                                         LE_MTVSRW, sub_64));
1343   dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1344   dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1345                                          BE_DWORD_0, sub_64));
1346   dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1347 }
1348
1349 /*  Patterns for extracting elements out of vectors. Integer elements are
1350     extracted using direct move operations. Patterns for extracting elements
1351     whose indices are not available at compile time are also provided with
1352     various _VARIABLE_ patterns.
1353     The numbering for the DAG's is for LE, but when used on BE, the correct
1354     LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1355 */
1356 def VectorExtractions {
1357   // Doubleword extraction
1358   dag LE_DWORD_0 =
1359     (MFVSRD
1360       (EXTRACT_SUBREG
1361         (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1362                   (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1363   dag LE_DWORD_1 = (MFVSRD
1364                      (EXTRACT_SUBREG
1365                        (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1366
1367   // Word extraction
1368   dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1369   dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1370   dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1371                              (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1372   dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1373
1374   // Halfword extraction
1375   dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1376   dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1377   dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1378   dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1379   dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1380   dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1381   dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1382   dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1383
1384   // Byte extraction
1385   dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1386   dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1387   dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1388   dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1389   dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1390   dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1391   dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1392   dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1393   dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1394   dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1395   dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1396   dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1397   dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1398   dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1399   dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1400   dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1401
1402   /* Variable element number (BE and LE patterns must be specified separately)
1403      This is a rather involved process.
1404
1405      Conceptually, this is how the move is accomplished:
1406      1. Identify which doubleword contains the element
1407      2. Shift in the VMX register so that the correct doubleword is correctly
1408         lined up for the MFVSRD
1409      3. Perform the move so that the element (along with some extra stuff)
1410         is in the GPR
1411      4. Right shift within the GPR so that the element is right-justified
1412
1413      Of course, the index is an element number which has a different meaning
1414      on LE/BE so the patterns have to be specified separately.
1415
1416      Note: The final result will be the element right-justified with high
1417            order bits being arbitrarily defined (namely, whatever was in the
1418            vector register to the left of the value originally).
1419   */
1420
1421   /*  LE variable byte
1422       Number 1. above:
1423       - For elements 0-7, we shift left by 8 bytes since they're on the right
1424       - For elements 8-15, we need not shift (shift left by zero bytes)
1425       This is accomplished by inverting the bits of the index and AND-ing
1426       with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1427   */
1428   dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx));
1429
1430   //  Number 2. above:
1431   //  - Now that we set up the shift amount, we shift in the VMX register
1432   dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC);
1433
1434   //  Number 3. above:
1435   //  - The doubleword containing our element is moved to a GPR
1436   dag LE_MV_VBYTE = (MFVSRD
1437                       (EXTRACT_SUBREG
1438                         (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1439                         sub_64));
1440
1441   /*  Number 4. above:
1442       - Truncate the element number to the range 0-7 (8-15 are symmetrical
1443         and out of range values are truncated accordingly)
1444       - Multiply by 8 as we need to shift right by the number of bits, not bytes
1445       - Shift right in the GPR by the calculated value
1446   */
1447   dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1448                                        sub_32);
1449   dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1450                                          sub_32);
1451
1452   /*  LE variable halfword
1453       Number 1. above:
1454       - For elements 0-3, we shift left by 8 since they're on the right
1455       - For elements 4-7, we need not shift (shift left by zero bytes)
1456       Similarly to the byte pattern, we invert the bits of the index, but we
1457       AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1458       Of course, the shift is still by 8 bytes, so we must multiply by 2.
1459   */
1460   dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62));
1461
1462   //  Number 2. above:
1463   //  - Now that we set up the shift amount, we shift in the VMX register
1464   dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC);
1465
1466   //  Number 3. above:
1467   //  - The doubleword containing our element is moved to a GPR
1468   dag LE_MV_VHALF = (MFVSRD
1469                       (EXTRACT_SUBREG
1470                         (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1471                         sub_64));
1472
1473   /*  Number 4. above:
1474       - Truncate the element number to the range 0-3 (4-7 are symmetrical
1475         and out of range values are truncated accordingly)
1476       - Multiply by 16 as we need to shift right by the number of bits
1477       - Shift right in the GPR by the calculated value
1478   */
1479   dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1480                                        sub_32);
1481   dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1482                                          sub_32);
1483
1484   /*  LE variable word
1485       Number 1. above:
1486       - For elements 0-1, we shift left by 8 since they're on the right
1487       - For elements 2-3, we need not shift
1488   */
1489   dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61));
1490
1491   //  Number 2. above:
1492   //  - Now that we set up the shift amount, we shift in the VMX register
1493   dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC);
1494
1495   //  Number 3. above:
1496   //  - The doubleword containing our element is moved to a GPR
1497   dag LE_MV_VWORD = (MFVSRD
1498                       (EXTRACT_SUBREG
1499                         (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1500                         sub_64));
1501
1502   /*  Number 4. above:
1503       - Truncate the element number to the range 0-1 (2-3 are symmetrical
1504         and out of range values are truncated accordingly)
1505       - Multiply by 32 as we need to shift right by the number of bits
1506       - Shift right in the GPR by the calculated value
1507   */
1508   dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1509                                        sub_32);
1510   dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1511                                          sub_32);
1512
1513   /*  LE variable doubleword
1514       Number 1. above:
1515       - For element 0, we shift left by 8 since it's on the right
1516       - For element 1, we need not shift
1517   */
1518   dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60));
1519
1520   //  Number 2. above:
1521   //  - Now that we set up the shift amount, we shift in the VMX register
1522   dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC);
1523
1524   // Number 3. above:
1525   //  - The doubleword containing our element is moved to a GPR
1526   //  - Number 4. is not needed for the doubleword as the value is 64-bits
1527   dag LE_VARIABLE_DWORD =
1528         (MFVSRD (EXTRACT_SUBREG
1529                   (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1530                   sub_64));
1531
1532   /*  LE variable float
1533       - Shift the vector to line up the desired element to BE Word 0
1534       - Convert 32-bit float to a 64-bit single precision float
1535   */
1536   dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61));
1537   dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1538   dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1539
1540   /*  LE variable double
1541       Same as the LE doubleword except there is no move.
1542   */
1543   dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1544                                   (COPY_TO_REGCLASS $S, VRRC),
1545                                   LE_VDWORD_PERM_VEC);
1546   dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1547
1548   /*  BE variable byte
1549       The algorithm here is the same as the LE variable byte except:
1550       - The shift in the VMX register is by 0/8 for opposite element numbers so
1551         we simply AND the element number with 0x8
1552       - The order of elements after the move to GPR is reversed, so we invert
1553         the bits of the index prior to truncating to the range 0-7
1554   */
1555   dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8));
1556   dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC);
1557   dag BE_MV_VBYTE = (MFVSRD
1558                       (EXTRACT_SUBREG
1559                         (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1560                         sub_64));
1561   dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1562                                        sub_32);
1563   dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1564                                          sub_32);
1565
1566   /*  BE variable halfword
1567       The algorithm here is the same as the LE variable halfword except:
1568       - The shift in the VMX register is by 0/8 for opposite element numbers so
1569         we simply AND the element number with 0x4 and multiply by 2
1570       - The order of elements after the move to GPR is reversed, so we invert
1571         the bits of the index prior to truncating to the range 0-3
1572   */
1573   dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62));
1574   dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC);
1575   dag BE_MV_VHALF = (MFVSRD
1576                       (EXTRACT_SUBREG
1577                         (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1578                         sub_64));
1579   dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1580                                        sub_32);
1581   dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1582                                          sub_32);
1583
1584   /*  BE variable word
1585       The algorithm is the same as the LE variable word except:
1586       - The shift in the VMX register happens for opposite element numbers
1587       - The order of elements after the move to GPR is reversed, so we invert
1588         the bits of the index prior to truncating to the range 0-1
1589   */
1590   dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61));
1591   dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC);
1592   dag BE_MV_VWORD = (MFVSRD
1593                       (EXTRACT_SUBREG
1594                         (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1595                         sub_64));
1596   dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1597                                        sub_32);
1598   dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1599                                          sub_32);
1600
1601   /*  BE variable doubleword
1602       Same as the LE doubleword except we shift in the VMX register for opposite
1603       element indices.
1604   */
1605   dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60));
1606   dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC);
1607   dag BE_VARIABLE_DWORD =
1608         (MFVSRD (EXTRACT_SUBREG
1609                   (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1610                   sub_64));
1611
1612   /*  BE variable float
1613       - Shift the vector to line up the desired element to BE Word 0
1614       - Convert 32-bit float to a 64-bit single precision float
1615   */
1616   dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61));
1617   dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1618   dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1619
1620   /* BE variable double
1621       Same as the BE doubleword except there is no move.
1622   */
1623   dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1624                                   (COPY_TO_REGCLASS $S, VRRC),
1625                                   BE_VDWORD_PERM_VEC);
1626   dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1627 }
1628
1629 // v4f32 scalar <-> vector conversions (BE)
1630 let Predicates = [IsBigEndian, HasP8Vector] in {
1631   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1632             (v4f32 (XSCVDPSPN $A))>;
1633   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1634             (f32 (XSCVSPDPN $S))>;
1635   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1636             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1637   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1638             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1639   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1640             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1641   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1642             (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1643 } // IsBigEndian, HasP8Vector
1644
1645 // Variable index vector_extract for v2f64 does not require P8Vector
1646 let Predicates = [IsBigEndian, HasVSX] in
1647   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1648             (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1649
1650 let Predicates = [IsBigEndian, HasDirectMove] in {
1651   // v16i8 scalar <-> vector conversions (BE)
1652   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1653             (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1654   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1655             (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1656   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1657             (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1658   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1659             (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1660   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1661             (i32 VectorExtractions.LE_BYTE_15)>;
1662   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1663             (i32 VectorExtractions.LE_BYTE_14)>;
1664   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1665             (i32 VectorExtractions.LE_BYTE_13)>;
1666   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1667             (i32 VectorExtractions.LE_BYTE_12)>;
1668   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1669             (i32 VectorExtractions.LE_BYTE_11)>;
1670   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1671             (i32 VectorExtractions.LE_BYTE_10)>;
1672   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1673             (i32 VectorExtractions.LE_BYTE_9)>;
1674   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1675             (i32 VectorExtractions.LE_BYTE_8)>;
1676   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1677             (i32 VectorExtractions.LE_BYTE_7)>;
1678   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1679             (i32 VectorExtractions.LE_BYTE_6)>;
1680   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1681             (i32 VectorExtractions.LE_BYTE_5)>;
1682   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1683             (i32 VectorExtractions.LE_BYTE_4)>;
1684   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1685             (i32 VectorExtractions.LE_BYTE_3)>;
1686   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1687             (i32 VectorExtractions.LE_BYTE_2)>;
1688   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1689             (i32 VectorExtractions.LE_BYTE_1)>;
1690   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1691             (i32 VectorExtractions.LE_BYTE_0)>;
1692   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1693             (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1694
1695   // v8i16 scalar <-> vector conversions (BE)
1696   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1697             (i32 VectorExtractions.LE_HALF_7)>;
1698   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1699             (i32 VectorExtractions.LE_HALF_6)>;
1700   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1701             (i32 VectorExtractions.LE_HALF_5)>;
1702   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1703             (i32 VectorExtractions.LE_HALF_4)>;
1704   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1705             (i32 VectorExtractions.LE_HALF_3)>;
1706   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1707             (i32 VectorExtractions.LE_HALF_2)>;
1708   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1709             (i32 VectorExtractions.LE_HALF_1)>;
1710   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1711             (i32 VectorExtractions.LE_HALF_0)>;
1712   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1713             (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1714
1715   // v4i32 scalar <-> vector conversions (BE)
1716   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1717             (i32 VectorExtractions.LE_WORD_3)>;
1718   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1719             (i32 VectorExtractions.LE_WORD_2)>;
1720   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1721             (i32 VectorExtractions.LE_WORD_1)>;
1722   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1723             (i32 VectorExtractions.LE_WORD_0)>;
1724   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1725             (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1726
1727   // v2i64 scalar <-> vector conversions (BE)
1728   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1729             (i64 VectorExtractions.LE_DWORD_1)>;
1730   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1731             (i64 VectorExtractions.LE_DWORD_0)>;
1732   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1733             (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1734 } // IsBigEndian, HasDirectMove
1735
1736 // v4f32 scalar <-> vector conversions (LE)
1737 let Predicates = [IsLittleEndian, HasP8Vector] in {
1738   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1739             (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1740   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1741             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1742   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1743             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1744   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1745             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1746   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1747             (f32 (XSCVSPDPN $S))>;
1748   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1749             (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1750 } // IsLittleEndian, HasP8Vector
1751
1752 // Variable index vector_extract for v2f64 does not require P8Vector
1753 let Predicates = [IsLittleEndian, HasVSX] in
1754   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1755             (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1756
1757 let Predicates = [IsLittleEndian, HasDirectMove] in {
1758   // v16i8 scalar <-> vector conversions (LE)
1759   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1760             (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1761   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1762             (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1763   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1764             (v4i32 MovesToVSR.LE_WORD_0)>;
1765   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1766             (v2i64 MovesToVSR.LE_DWORD_0)>;
1767   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1768             (i32 VectorExtractions.LE_BYTE_0)>;
1769   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1770             (i32 VectorExtractions.LE_BYTE_1)>;
1771   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1772             (i32 VectorExtractions.LE_BYTE_2)>;
1773   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1774             (i32 VectorExtractions.LE_BYTE_3)>;
1775   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1776             (i32 VectorExtractions.LE_BYTE_4)>;
1777   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1778             (i32 VectorExtractions.LE_BYTE_5)>;
1779   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1780             (i32 VectorExtractions.LE_BYTE_6)>;
1781   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1782             (i32 VectorExtractions.LE_BYTE_7)>;
1783   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1784             (i32 VectorExtractions.LE_BYTE_8)>;
1785   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1786             (i32 VectorExtractions.LE_BYTE_9)>;
1787   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1788             (i32 VectorExtractions.LE_BYTE_10)>;
1789   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1790             (i32 VectorExtractions.LE_BYTE_11)>;
1791   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1792             (i32 VectorExtractions.LE_BYTE_12)>;
1793   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1794             (i32 VectorExtractions.LE_BYTE_13)>;
1795   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1796             (i32 VectorExtractions.LE_BYTE_14)>;
1797   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1798             (i32 VectorExtractions.LE_BYTE_15)>;
1799   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1800             (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
1801
1802   // v8i16 scalar <-> vector conversions (LE)
1803   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1804             (i32 VectorExtractions.LE_HALF_0)>;
1805   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1806             (i32 VectorExtractions.LE_HALF_1)>;
1807   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1808             (i32 VectorExtractions.LE_HALF_2)>;
1809   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1810             (i32 VectorExtractions.LE_HALF_3)>;
1811   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1812             (i32 VectorExtractions.LE_HALF_4)>;
1813   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1814             (i32 VectorExtractions.LE_HALF_5)>;
1815   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1816             (i32 VectorExtractions.LE_HALF_6)>;
1817   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1818             (i32 VectorExtractions.LE_HALF_7)>;
1819   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1820             (i32 VectorExtractions.LE_VARIABLE_HALF)>;
1821
1822   // v4i32 scalar <-> vector conversions (LE)
1823   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1824             (i32 VectorExtractions.LE_WORD_0)>;
1825   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1826             (i32 VectorExtractions.LE_WORD_1)>;
1827   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1828             (i32 VectorExtractions.LE_WORD_2)>;
1829   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1830             (i32 VectorExtractions.LE_WORD_3)>;
1831   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1832             (i32 VectorExtractions.LE_VARIABLE_WORD)>;
1833
1834   // v2i64 scalar <-> vector conversions (LE)
1835   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1836             (i64 VectorExtractions.LE_DWORD_0)>;
1837   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1838             (i64 VectorExtractions.LE_DWORD_1)>;
1839   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1840             (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
1841 } // IsLittleEndian, HasDirectMove
1842
1843 let Predicates = [HasDirectMove, HasVSX] in {
1844 // bitconvert f32 -> i32
1845 // (convert to 32-bit fp single, shift right 1 word, move to GPR)
1846 def : Pat<(i32 (bitconvert f32:$S)),
1847           (i32 (MFVSRWZ (EXTRACT_SUBREG
1848                           (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
1849                           sub_64)))>;
1850 // bitconvert i32 -> f32
1851 // (move to FPR, shift left 1 word, convert to 64-bit fp single)
1852 def : Pat<(f32 (bitconvert i32:$A)),
1853           (f32 (XSCVSPDPN
1854                  (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
1855
1856 // bitconvert f64 -> i64
1857 // (move to GPR, nothing else needed)
1858 def : Pat<(i64 (bitconvert f64:$S)),
1859           (i64 (MFVSRD $S))>;
1860
1861 // bitconvert i64 -> f64
1862 // (move to FPR, nothing else needed)
1863 def : Pat<(f64 (bitconvert i64:$S)),
1864           (f64 (MTVSRD $S))>;
1865 }
1866
1867 def AlignValues {
1868   dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
1869   dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
1870 }
1871
1872 // The following VSX instructions were introduced in Power ISA 3.0
1873 def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
1874 let AddedComplexity = 400, Predicates = [HasP9Vector] in {
1875
1876   // [PO VRT XO VRB XO /]
1877   class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1878                       list<dag> pattern>
1879     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
1880                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1881
1882   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
1883   class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1884                          list<dag> pattern>
1885     : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
1886
1887   // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
1888   // So we use different operand class for VRB
1889   class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
1890                            RegisterOperand vbtype, list<dag> pattern>
1891     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
1892                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
1893
1894   // [PO T XO B XO BX /]
1895   class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
1896                         list<dag> pattern>
1897     : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
1898                       !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
1899
1900   // [PO T XO B XO BX TX]
1901   class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
1902                         RegisterOperand vtype, list<dag> pattern>
1903     : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
1904                       !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
1905
1906   // [PO T A B XO AX BX TX], src and dest register use different operand class
1907   class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
1908                   RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
1909                   InstrItinClass itin, list<dag> pattern>
1910     : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
1911               !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
1912
1913   // [PO VRT VRA VRB XO /]
1914   class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
1915                       list<dag> pattern>
1916     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
1917               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
1918
1919   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
1920   class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
1921                          list<dag> pattern>
1922     : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
1923
1924   //===--------------------------------------------------------------------===//
1925   // Quad-Precision Scalar Move Instructions:
1926
1927   // Copy Sign
1928   def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>;
1929
1930   // Absolute/Negative-Absolute/Negate
1931   def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp" , []>;
1932   def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp", []>;
1933   def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>;
1934
1935   //===--------------------------------------------------------------------===//
1936   // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
1937
1938   // Add/Divide/Multiply/Subtract
1939   def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp" , []>;
1940   def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>;
1941   def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp" , []>;
1942   def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>;
1943   def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp" , []>;
1944   def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>;
1945   def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" , []>;
1946   def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>;
1947
1948   // Square-Root
1949   def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp" , []>;
1950   def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>;
1951
1952   // (Negative) Multiply-{Add/Subtract}
1953   def XSMADDQP  : X_VT5_VA5_VB5   <63, 388, "xsmaddqp"  , []>;
1954   def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>;
1955   def XSMSUBQP  : X_VT5_VA5_VB5   <63, 420, "xsmsubqp"  , []>;
1956   def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>;
1957   def XSNMADDQP : X_VT5_VA5_VB5   <63, 452, "xsnmaddqp" , []>;
1958   def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>;
1959   def XSNMSUBQP : X_VT5_VA5_VB5   <63, 484, "xsnmsubqp" , []>;
1960   def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>;
1961
1962   //===--------------------------------------------------------------------===//
1963   // Quad/Double-Precision Compare Instructions:
1964
1965   // [PO BF // VRA VRB XO /]
1966   class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
1967                       list<dag> pattern>
1968     : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
1969                !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
1970     let Pattern = pattern;
1971   }
1972
1973   // QP Compare Ordered/Unordered
1974   def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
1975   def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
1976
1977   // DP/QP Compare Exponents
1978   def XSCMPEXPDP : XX3Form_1<60, 59,
1979                              (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
1980                              "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
1981   def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
1982
1983   // DP Compare ==, >=, >, !=
1984   // Use vsrc for XT, because the entire register of XT is set.
1985   // XT.dword[1] = 0x0000_0000_0000_0000
1986   def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
1987                                   IIC_FPCompare, []>;
1988   def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
1989                                   IIC_FPCompare, []>;
1990   def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
1991                                   IIC_FPCompare, []>;
1992   def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc,
1993                                   IIC_FPCompare, []>;
1994   // Vector Compare Not Equal
1995   def XVCMPNEDP  : XX3Form_Rc<60, 123,
1996                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1997                               "xvcmpnedp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
1998   let Defs = [CR6] in
1999   def XVCMPNEDPo : XX3Form_Rc<60, 123,
2000                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2001                               "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2002                               isDOT;
2003   def XVCMPNESP  : XX3Form_Rc<60,  91,
2004                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2005                               "xvcmpnesp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2006   let Defs = [CR6] in
2007   def XVCMPNESPo : XX3Form_Rc<60,  91,
2008                               (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2009                               "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2010                               isDOT;
2011
2012   //===--------------------------------------------------------------------===//
2013   // Quad-Precision Floating-Point Conversion Instructions:
2014
2015   // Convert DP -> QP
2016   def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vsfrc, []>;
2017
2018   // Round & Convert QP -> DP (dword[1] is set to zero)
2019   def XSCVQPDP  : X_VT5_XO5_VB5   <63, 20, 836, "xscvqpdp" , []>;
2020   def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>;
2021
2022   // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2023   def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2024   def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2025   def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2026   def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2027
2028   // Convert (Un)Signed DWord -> QP
2029   def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vsfrc, []>;
2030   def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vsfrc, []>;
2031
2032   //===--------------------------------------------------------------------===//
2033   // Round to Floating-Point Integer Instructions
2034
2035   // (Round &) Convert DP <-> HP
2036   // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2037   // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2038   // but we still use vsfrc for it.
2039   def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2040   def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2041
2042   // Vector HP -> SP
2043   def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2044   def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc, []>;
2045
2046   class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2047                                 list<dag> pattern>
2048     : Z23Form_1<opcode, xo,
2049                 (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2050                 !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2051     let RC = ex;
2052   }
2053
2054   // Round to Quad-Precision Integer [with Inexact]
2055   def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2056   def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2057
2058   // Round Quad-Precision to Double-Extended Precision (fp80)
2059   def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2060
2061   //===--------------------------------------------------------------------===//
2062   // Insert/Extract Instructions
2063
2064   // Insert Exponent DP/QP
2065   // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2066   def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2067                           "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
2068   // vB NOTE: only vB.dword[0] is used, that's why we don't use
2069   //          X_VT5_VA5_VB5 form
2070   def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2071                           "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2072
2073   // Extract Exponent/Significand DP/QP
2074   def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2075   def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2076   def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2077   def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2078
2079   // Vector Insert Word
2080   // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2081   def XXINSERTW   :
2082     XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2083                      (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2084                      "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2085                      [(set v4i32:$XT, (PPCxxinsert v4i32:$XTi, v4i32:$XB,
2086                                                    imm32SExt16:$UIM))]>,
2087                      RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2088
2089   // Vector Extract Unsigned Word
2090   def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2091                                   (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2092                                   "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2093
2094   // Vector Insert Exponent DP/SP
2095   def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2096                                  IIC_VecFP, []>;
2097   def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2098                                  IIC_VecFP, []>;
2099
2100   // Vector Extract Exponent/Significand DP/SP
2101   def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc, []>;
2102   def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc, []>;
2103   def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc, []>;
2104   def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc, []>;
2105
2106   //===--------------------------------------------------------------------===//
2107
2108   // Test Data Class SP/DP/QP
2109   def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2110                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2111                               "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2112   def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2113                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2114                               "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2115   def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2116                               (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2117                               "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2118
2119   // Vector Test Data Class SP/DP
2120   def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2121                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2122                               "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP, []>;
2123   def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2124                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2125                               "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP, []>;
2126
2127   //===--------------------------------------------------------------------===//
2128
2129   // Maximum/Minimum Type-C/Type-J DP
2130   // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2131   def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2132                                  IIC_VecFP, []>;
2133   def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2134                                  IIC_VecFP, []>;
2135   def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2136                                  IIC_VecFP, []>;
2137   def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2138                                  IIC_VecFP, []>;
2139
2140   //===--------------------------------------------------------------------===//
2141
2142   // Vector Byte-Reverse H/W/D/Q Word
2143   def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2144   def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2145   def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2146   def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2147
2148   // Vector Permute
2149   def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2150                                 IIC_VecPerm, []>;
2151   def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2152                                 IIC_VecPerm, []>;
2153
2154   // Vector Splat Immediate Byte
2155   def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2156                             "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
2157
2158   //===--------------------------------------------------------------------===//
2159   // Vector/Scalar Load/Store Instructions
2160
2161   let mayLoad = 1 in {
2162   // Load Vector
2163   def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2164                             "lxv $XT, $src", IIC_LdStLFD, []>;
2165   // Load DWord
2166   def LXSD  : DSForm_1<57, 2, (outs vrrc:$vD), (ins memrix:$src),
2167                        "lxsd $vD, $src", IIC_LdStLFD, []>;
2168   // Load SP from src, convert it to DP, and place in dword[0]
2169   def LXSSP : DSForm_1<57, 3, (outs vrrc:$vD), (ins memrix:$src),
2170                        "lxssp $vD, $src", IIC_LdStLFD, []>;
2171
2172   // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2173   // "out" and "in" dag
2174   class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2175                       RegisterOperand vtype, list<dag> pattern>
2176     : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2177               !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
2178
2179   // Load as Integer Byte/Halfword & Zero Indexed
2180   def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc, []>;
2181   def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc, []>;
2182
2183   // Load Vector Halfword*8/Byte*16 Indexed
2184   def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2185   def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2186
2187   // Load Vector Indexed
2188   def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc, []>;
2189
2190   // Load Vector (Left-justified) with Length
2191   def LXVL    : X_XT6_RA5_RB5<31, 269, "lxvl"   , vsrc, []>;
2192   def LXVLL   : X_XT6_RA5_RB5<31, 301, "lxvll"  , vsrc, []>;
2193
2194   // Load Vector Word & Splat Indexed
2195   def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2196   } // end mayLoad
2197
2198   let mayStore = 1 in {
2199   // Store Vector
2200   def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2201                              "stxv $XT, $dst", IIC_LdStSTFD, []>;
2202   // Store DWord
2203   def STXSD  : DSForm_1<61, 2, (outs), (ins vrrc:$vS, memrix:$dst),
2204                         "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2205   // Convert DP of dword[0] to SP, and Store to dst
2206   def STXSSP : DSForm_1<61, 3, (outs), (ins vrrc:$vS, memrix:$dst),
2207                         "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2208
2209   // [PO S RA RB XO SX]
2210   class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2211                       RegisterOperand vtype, list<dag> pattern>
2212     : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2213               !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
2214
2215   // Store as Integer Byte/Halfword Indexed
2216   def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc, []>;
2217   def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc, []>;
2218
2219   // Store Vector Halfword*8/Byte*16 Indexed
2220   def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2221   def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2222
2223   // Store Vector Indexed
2224   def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc, []>;
2225
2226   // Store Vector (Left-justified) with Length
2227   def STXVL    : X_XS6_RA5_RB5<31,  397, "stxvl"   , vsrc, []>;
2228   def STXVLL   : X_XS6_RA5_RB5<31,  429, "stxvll"  , vsrc, []>;
2229   } // end mayStore
2230
2231   // Patterns for which instructions from ISA 3.0 are a better match
2232   let Predicates = [IsLittleEndian, HasP9Vector] in {
2233   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2234             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2235   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2236             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2237   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2238             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2239   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2240             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2241   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2242             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2243   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2244             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2245   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2246             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2247   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2248             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2249   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2250             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2251   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2252             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2253   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2254             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2255   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2256             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2257   } // IsLittleEndian, HasP9Vector
2258
2259   let Predicates = [IsBigEndian, HasP9Vector] in {
2260   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2261             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2262   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2263             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2264   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2265             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2266   def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2267             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2268   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2269             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2270   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2271             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2272   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2273             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2274   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2275             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2276   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2277             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2278   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2279             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2280   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2281             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2282   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2283             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2284   } // IsLittleEndian, HasP9Vector
2285 } // end HasP9Vector, AddedComplexity