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