]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/PowerPC/PPCInstrVSX.td
Merge compiler-rt trunk r338150, and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / PowerPC / PPCInstrVSX.td
1 //===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the VSX extension to the PowerPC instruction set.
11 //
12 //===----------------------------------------------------------------------===//
13
14 // *********************************** NOTE ***********************************
15 // ** For POWER8 Little Endian, the VSX swap optimization relies on knowing  **
16 // ** which VMX and VSX instructions are lane-sensitive and which are not.   **
17 // ** A lane-sensitive instruction relies, implicitly or explicitly, on      **
18 // ** whether lanes are numbered from left to right.  An instruction like    **
19 // ** VADDFP is not lane-sensitive, because each lane of the result vector   **
20 // ** relies only on the corresponding lane of the source vectors.  However, **
21 // ** an instruction like VMULESB is lane-sensitive, because "even" and      **
22 // ** "odd" lanes are different for big-endian and little-endian numbering.  **
23 // **                                                                        **
24 // ** When adding new VMX and VSX instructions, please consider whether they **
25 // ** are lane-sensitive.  If so, they must be added to a switch statement   **
26 // ** in PPCVSXSwapRemoval::gatherVectorInstructions().                      **
27 // ****************************************************************************
28
29 def PPCRegVSRCAsmOperand : AsmOperandClass {
30   let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
31 }
32 def vsrc : RegisterOperand<VSRC> {
33   let ParserMatchClass = PPCRegVSRCAsmOperand;
34 }
35
36 def PPCRegVSFRCAsmOperand : AsmOperandClass {
37   let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
38 }
39 def vsfrc : RegisterOperand<VSFRC> {
40   let ParserMatchClass = PPCRegVSFRCAsmOperand;
41 }
42
43 def PPCRegVSSRCAsmOperand : AsmOperandClass {
44   let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
45 }
46 def vssrc : RegisterOperand<VSSRC> {
47   let ParserMatchClass = PPCRegVSSRCAsmOperand;
48 }
49
50 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_memOp<31, 588,
130                         (outs vsfrc:$XT), (ins memrr:$src),
131                         "lxsdx $XT, $src", IIC_LdStLFD,
132                         []>;
133
134     // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
135     let isPseudo = 1, CodeSize = 3 in
136       def XFLOADf64  : PseudoXFormMemOp<(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_memOp<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_memOp<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_memOp<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_memOp<31, 716,
161                         (outs), (ins vsfrc:$XT, memrr:$dst),
162                         "stxsdx $XT, $dst", IIC_LdStSTFD,
163                         []>;
164
165     // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
166     let isPseudo = 1, CodeSize = 3 in
167       def XFSTOREf64 : PseudoXFormMemOp<(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_memOp<31, 972,
175                          (outs), (ins vsrc:$XT, memrr:$dst),
176                          "stxvd2x $XT, $dst", IIC_LdStSTFD,
177                          []>;
178
179     def STXVW4X : XX1Form_memOp<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 def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
1204 let Predicates = [HasP8Vector] in {
1205 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1206   let isCommutable = 1, UseVSXReg = 1 in {
1207     def XXLEQV : XX3Form<60, 186,
1208                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1209                          "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1210                          [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1211     def XXLNAND : XX3Form<60, 178,
1212                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1213                           "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1214                           [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1215                                                     v4i32:$XB)))]>;
1216   } // isCommutable, UseVSXReg
1217
1218   def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1219             (XXLEQV $A, $B)>;
1220
1221   let UseVSXReg = 1 in {
1222   def XXLORC : XX3Form<60, 170,
1223                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1224                        "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1225                        [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1226
1227   // VSX scalar loads introduced in ISA 2.07
1228   let mayLoad = 1, mayStore = 0 in {
1229     let CodeSize = 3 in
1230     def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1231                          "lxsspx $XT, $src", IIC_LdStLFD, []>;
1232     def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1233                           "lxsiwax $XT, $src", IIC_LdStLFD, []>;
1234     def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1235                           "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
1236
1237     // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it
1238     // would cause these Pseudos are not expanded in expandPostRAPseudos()
1239     let isPseudo = 1 in {
1240       // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
1241       let CodeSize = 3 in
1242       def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
1243                               "#XFLOADf32",
1244                               [(set f32:$XT, (load xoaddr:$src))]>;
1245       // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
1246       def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1247                          "#LIWAX",
1248                          [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1249       // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
1250       def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1251                          "#LIWZX",
1252                          [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1253     }
1254   } // mayLoad
1255
1256   // VSX scalar stores introduced in ISA 2.07
1257   let mayStore = 1, mayLoad = 0 in {
1258     let CodeSize = 3 in
1259     def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1260                           "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
1261     def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1262                           "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
1263
1264     // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it
1265     // would cause these Pseudos are not expanded in expandPostRAPseudos()
1266     let isPseudo = 1 in {
1267       // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
1268       let CodeSize = 3 in
1269       def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
1270                               "#XFSTOREf32",
1271                               [(store f32:$XT, xoaddr:$dst)]>;
1272       // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
1273       def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1274                          "#STIWX",
1275                         [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1276     }
1277   } // mayStore
1278   } // UseVSXReg = 1
1279
1280   def : Pat<(f64 (extloadf32 xoaddr:$src)),
1281             (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
1282   def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
1283             (f32 (XFLOADf32 xoaddr:$src))>;
1284   def : Pat<(f64 (fpextend f32:$src)),
1285             (COPY_TO_REGCLASS $src, VSFRC)>;
1286
1287   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1288             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1289   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1290             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1291   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1292             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1293   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1294             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1295   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1296             (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1297   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1298             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1299   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1300             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1301   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1302             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1303   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1304             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1305   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1306             (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1307
1308   let UseVSXReg = 1 in {
1309   // VSX Elementary Scalar FP arithmetic (SP)
1310   let isCommutable = 1 in {
1311     def XSADDSP : XX3Form<60, 0,
1312                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1313                           "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1314                           [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1315     def XSMULSP : XX3Form<60, 16,
1316                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1317                           "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1318                           [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1319   } // isCommutable
1320
1321   def XSDIVSP : XX3Form<60, 24,
1322                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1323                         "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1324                         [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1325   def XSRESP : XX2Form<60, 26,
1326                         (outs vssrc:$XT), (ins vssrc:$XB),
1327                         "xsresp $XT, $XB", IIC_VecFP,
1328                         [(set f32:$XT, (PPCfre f32:$XB))]>;
1329   def XSRSP : XX2Form<60, 281,
1330                         (outs vssrc:$XT), (ins vsfrc:$XB),
1331                         "xsrsp $XT, $XB", IIC_VecFP, []>;
1332   def XSSQRTSP : XX2Form<60, 11,
1333                         (outs vssrc:$XT), (ins vssrc:$XB),
1334                         "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1335                         [(set f32:$XT, (fsqrt f32:$XB))]>;
1336   def XSRSQRTESP : XX2Form<60, 10,
1337                            (outs vssrc:$XT), (ins vssrc:$XB),
1338                            "xsrsqrtesp $XT, $XB", IIC_VecFP,
1339                            [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1340   def XSSUBSP : XX3Form<60, 8,
1341                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1342                         "xssubsp $XT, $XA, $XB", IIC_VecFP,
1343                         [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1344
1345   // FMA Instructions
1346   let BaseName = "XSMADDASP" in {
1347   let isCommutable = 1 in
1348   def XSMADDASP : XX3Form<60, 1,
1349                           (outs vssrc:$XT),
1350                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1351                           "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1352                           [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1353                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1354                           AltVSXFMARel;
1355   let IsVSXFMAAlt = 1 in
1356   def XSMADDMSP : XX3Form<60, 9,
1357                           (outs vssrc:$XT),
1358                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1359                           "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1360                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1361                           AltVSXFMARel;
1362   }
1363
1364   let BaseName = "XSMSUBASP" in {
1365   let isCommutable = 1 in
1366   def XSMSUBASP : XX3Form<60, 17,
1367                           (outs vssrc:$XT),
1368                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1369                           "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1370                           [(set f32:$XT, (fma f32:$XA, f32:$XB,
1371                                               (fneg f32:$XTi)))]>,
1372                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1373                           AltVSXFMARel;
1374   let IsVSXFMAAlt = 1 in
1375   def XSMSUBMSP : XX3Form<60, 25,
1376                           (outs vssrc:$XT),
1377                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1378                           "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1379                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1380                           AltVSXFMARel;
1381   }
1382
1383   let BaseName = "XSNMADDASP" in {
1384   let isCommutable = 1 in
1385   def XSNMADDASP : XX3Form<60, 129,
1386                           (outs vssrc:$XT),
1387                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1388                           "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1389                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1390                                                     f32:$XTi)))]>,
1391                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1392                           AltVSXFMARel;
1393   let IsVSXFMAAlt = 1 in
1394   def XSNMADDMSP : XX3Form<60, 137,
1395                           (outs vssrc:$XT),
1396                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1397                           "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1398                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1399                           AltVSXFMARel;
1400   }
1401
1402   let BaseName = "XSNMSUBASP" in {
1403   let isCommutable = 1 in
1404   def XSNMSUBASP : XX3Form<60, 145,
1405                           (outs vssrc:$XT),
1406                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1407                           "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1408                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1409                                                     (fneg f32:$XTi))))]>,
1410                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1411                           AltVSXFMARel;
1412   let IsVSXFMAAlt = 1 in
1413   def XSNMSUBMSP : XX3Form<60, 153,
1414                           (outs vssrc:$XT),
1415                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1416                           "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1417                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1418                           AltVSXFMARel;
1419   }
1420
1421   // Single Precision Conversions (FP <-> INT)
1422   def XSCVSXDSP : XX2Form<60, 312,
1423                       (outs vssrc:$XT), (ins vsfrc:$XB),
1424                       "xscvsxdsp $XT, $XB", IIC_VecFP,
1425                       [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1426   def XSCVUXDSP : XX2Form<60, 296,
1427                       (outs vssrc:$XT), (ins vsfrc:$XB),
1428                       "xscvuxdsp $XT, $XB", IIC_VecFP,
1429                       [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1430
1431   // Conversions between vector and scalar single precision
1432   def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1433                           "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1434   def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1435                           "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1436   } // UseVSXReg = 1
1437
1438   let Predicates = [IsLittleEndian] in {
1439   def : Pat<(f32 (PPCfcfids
1440                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1441             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1442   def : Pat<(f32 (PPCfcfids
1443                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1444             (f32 (XSCVSXDSP (COPY_TO_REGCLASS
1445                               (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1446   def : Pat<(f32 (PPCfcfidus
1447                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1448             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1449   def : Pat<(f32 (PPCfcfidus
1450                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1451             (f32 (XSCVUXDSP (COPY_TO_REGCLASS
1452                               (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1453   }
1454
1455   let Predicates = [IsBigEndian] in {
1456   def : Pat<(f32 (PPCfcfids
1457                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1458             (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1459   def : Pat<(f32 (PPCfcfids
1460                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1461             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1462   def : Pat<(f32 (PPCfcfidus
1463                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1464             (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1465   def : Pat<(f32 (PPCfcfidus
1466                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1467             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1468   }
1469   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.Li32)),
1470             (v4i32 (XXSPLTWs (LIWAX xoaddr:$src), 1))>;
1471
1472   // Instructions for converting float to i64 feeding a store.
1473   let Predicates = [NoP9Vector] in {
1474   def : Pat<(PPCstore_scal_int_from_vsr
1475               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
1476             (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
1477   def : Pat<(PPCstore_scal_int_from_vsr
1478               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
1479             (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
1480   }
1481
1482   // Instructions for converting float to i32 feeding a store.
1483   def : Pat<(PPCstore_scal_int_from_vsr
1484               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
1485             (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
1486   def : Pat<(PPCstore_scal_int_from_vsr
1487               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
1488             (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
1489
1490 } // AddedComplexity = 400
1491 } // HasP8Vector
1492
1493 let UseVSXReg = 1, AddedComplexity = 400 in {
1494 let Predicates = [HasDirectMove] in {
1495   // VSX direct move instructions
1496   def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1497                               "mfvsrd $rA, $XT", IIC_VecGeneral,
1498                               [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1499       Requires<[In64BitMode]>;
1500   let isCodeGenOnly = 1 in
1501   def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vrrc:$XT),
1502                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1503                              []>,
1504       Requires<[In64BitMode]>;
1505   def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1506                                "mfvsrwz $rA, $XT", IIC_VecGeneral,
1507                                [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1508   def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1509                               "mtvsrd $XT, $rA", IIC_VecGeneral,
1510                               [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1511       Requires<[In64BitMode]>;
1512   def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1513                                "mtvsrwa $XT, $rA", IIC_VecGeneral,
1514                                [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1515   def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1516                                "mtvsrwz $XT, $rA", IIC_VecGeneral,
1517                                [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1518 } // HasDirectMove
1519
1520 let Predicates = [IsISA3_0, HasDirectMove] in {
1521   def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1522                               "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1523
1524   def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1525                        "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1526                        []>, Requires<[In64BitMode]>;
1527
1528   def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1529                               "mfvsrld $rA, $XT", IIC_VecGeneral,
1530                               []>, Requires<[In64BitMode]>;
1531
1532 } // IsISA3_0, HasDirectMove
1533 } // UseVSXReg = 1
1534
1535 // We want to parse this from asm, but we don't want to emit this as it would
1536 // be emitted with a VSX reg. So leave Emit = 0 here.
1537 def : InstAlias<"mfvrd $rA, $XT",
1538                 (MFVRD g8rc:$rA, vrrc:$XT), 0>;
1539 def : InstAlias<"mffprd $rA, $src",
1540                 (MFVSRD g8rc:$rA, f8rc:$src)>;
1541
1542 /*  Direct moves of various widths from GPR's into VSR's. Each move lines
1543     the value up into element 0 (both BE and LE). Namely, entities smaller than
1544     a doubleword are shifted left and moved for BE. For LE, they're moved, then
1545     swapped to go into the least significant element of the VSR.
1546 */
1547 def MovesToVSR {
1548   dag BE_BYTE_0 =
1549     (MTVSRD
1550       (RLDICR
1551         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1552   dag BE_HALF_0 =
1553     (MTVSRD
1554       (RLDICR
1555         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1556   dag BE_WORD_0 =
1557     (MTVSRD
1558       (RLDICR
1559         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1560   dag BE_DWORD_0 = (MTVSRD $A);
1561
1562   dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1563   dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1564                                         LE_MTVSRW, sub_64));
1565   dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1566   dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1567                                          BE_DWORD_0, sub_64));
1568   dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1569 }
1570
1571 /*  Patterns for extracting elements out of vectors. Integer elements are
1572     extracted using direct move operations. Patterns for extracting elements
1573     whose indices are not available at compile time are also provided with
1574     various _VARIABLE_ patterns.
1575     The numbering for the DAG's is for LE, but when used on BE, the correct
1576     LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1577 */
1578 def VectorExtractions {
1579   // Doubleword extraction
1580   dag LE_DWORD_0 =
1581     (MFVSRD
1582       (EXTRACT_SUBREG
1583         (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1584                   (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1585   dag LE_DWORD_1 = (MFVSRD
1586                      (EXTRACT_SUBREG
1587                        (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1588
1589   // Word extraction
1590   dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1591   dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1592   dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1593                              (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1594   dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1595
1596   // Halfword extraction
1597   dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1598   dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1599   dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1600   dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1601   dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1602   dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1603   dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1604   dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1605
1606   // Byte extraction
1607   dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1608   dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1609   dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1610   dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1611   dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1612   dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1613   dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1614   dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1615   dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1616   dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1617   dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1618   dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1619   dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1620   dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1621   dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1622   dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1623
1624   /* Variable element number (BE and LE patterns must be specified separately)
1625      This is a rather involved process.
1626
1627      Conceptually, this is how the move is accomplished:
1628      1. Identify which doubleword contains the element
1629      2. Shift in the VMX register so that the correct doubleword is correctly
1630         lined up for the MFVSRD
1631      3. Perform the move so that the element (along with some extra stuff)
1632         is in the GPR
1633      4. Right shift within the GPR so that the element is right-justified
1634
1635      Of course, the index is an element number which has a different meaning
1636      on LE/BE so the patterns have to be specified separately.
1637
1638      Note: The final result will be the element right-justified with high
1639            order bits being arbitrarily defined (namely, whatever was in the
1640            vector register to the left of the value originally).
1641   */
1642
1643   /*  LE variable byte
1644       Number 1. above:
1645       - For elements 0-7, we shift left by 8 bytes since they're on the right
1646       - For elements 8-15, we need not shift (shift left by zero bytes)
1647       This is accomplished by inverting the bits of the index and AND-ing
1648       with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1649   */
1650   dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
1651
1652   //  Number 2. above:
1653   //  - Now that we set up the shift amount, we shift in the VMX register
1654   dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
1655
1656   //  Number 3. above:
1657   //  - The doubleword containing our element is moved to a GPR
1658   dag LE_MV_VBYTE = (MFVSRD
1659                       (EXTRACT_SUBREG
1660                         (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1661                         sub_64));
1662
1663   /*  Number 4. above:
1664       - Truncate the element number to the range 0-7 (8-15 are symmetrical
1665         and out of range values are truncated accordingly)
1666       - Multiply by 8 as we need to shift right by the number of bits, not bytes
1667       - Shift right in the GPR by the calculated value
1668   */
1669   dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1670                                        sub_32);
1671   dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1672                                          sub_32);
1673
1674   /*  LE variable halfword
1675       Number 1. above:
1676       - For elements 0-3, we shift left by 8 since they're on the right
1677       - For elements 4-7, we need not shift (shift left by zero bytes)
1678       Similarly to the byte pattern, we invert the bits of the index, but we
1679       AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1680       Of course, the shift is still by 8 bytes, so we must multiply by 2.
1681   */
1682   dag LE_VHALF_PERM_VEC =
1683     (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
1684
1685   //  Number 2. above:
1686   //  - Now that we set up the shift amount, we shift in the VMX register
1687   dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
1688
1689   //  Number 3. above:
1690   //  - The doubleword containing our element is moved to a GPR
1691   dag LE_MV_VHALF = (MFVSRD
1692                       (EXTRACT_SUBREG
1693                         (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1694                         sub_64));
1695
1696   /*  Number 4. above:
1697       - Truncate the element number to the range 0-3 (4-7 are symmetrical
1698         and out of range values are truncated accordingly)
1699       - Multiply by 16 as we need to shift right by the number of bits
1700       - Shift right in the GPR by the calculated value
1701   */
1702   dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1703                                        sub_32);
1704   dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1705                                          sub_32);
1706
1707   /*  LE variable word
1708       Number 1. above:
1709       - For elements 0-1, we shift left by 8 since they're on the right
1710       - For elements 2-3, we need not shift
1711   */
1712   dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1713                                        (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
1714
1715   //  Number 2. above:
1716   //  - Now that we set up the shift amount, we shift in the VMX register
1717   dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
1718
1719   //  Number 3. above:
1720   //  - The doubleword containing our element is moved to a GPR
1721   dag LE_MV_VWORD = (MFVSRD
1722                       (EXTRACT_SUBREG
1723                         (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1724                         sub_64));
1725
1726   /*  Number 4. above:
1727       - Truncate the element number to the range 0-1 (2-3 are symmetrical
1728         and out of range values are truncated accordingly)
1729       - Multiply by 32 as we need to shift right by the number of bits
1730       - Shift right in the GPR by the calculated value
1731   */
1732   dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1733                                        sub_32);
1734   dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1735                                          sub_32);
1736
1737   /*  LE variable doubleword
1738       Number 1. above:
1739       - For element 0, we shift left by 8 since it's on the right
1740       - For element 1, we need not shift
1741   */
1742   dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1743                                         (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
1744
1745   //  Number 2. above:
1746   //  - Now that we set up the shift amount, we shift in the VMX register
1747   dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
1748
1749   // Number 3. above:
1750   //  - The doubleword containing our element is moved to a GPR
1751   //  - Number 4. is not needed for the doubleword as the value is 64-bits
1752   dag LE_VARIABLE_DWORD =
1753         (MFVSRD (EXTRACT_SUBREG
1754                   (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1755                   sub_64));
1756
1757   /*  LE variable float
1758       - Shift the vector to line up the desired element to BE Word 0
1759       - Convert 32-bit float to a 64-bit single precision float
1760   */
1761   dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
1762                                   (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
1763   dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1764   dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1765
1766   /*  LE variable double
1767       Same as the LE doubleword except there is no move.
1768   */
1769   dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1770                                          (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1771                                          LE_VDWORD_PERM_VEC));
1772   dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1773
1774   /*  BE variable byte
1775       The algorithm here is the same as the LE variable byte except:
1776       - The shift in the VMX register is by 0/8 for opposite element numbers so
1777         we simply AND the element number with 0x8
1778       - The order of elements after the move to GPR is reversed, so we invert
1779         the bits of the index prior to truncating to the range 0-7
1780   */
1781   dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDIo8 $Idx, 8)));
1782   dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
1783   dag BE_MV_VBYTE = (MFVSRD
1784                       (EXTRACT_SUBREG
1785                         (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1786                         sub_64));
1787   dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1788                                        sub_32);
1789   dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1790                                          sub_32);
1791
1792   /*  BE variable halfword
1793       The algorithm here is the same as the LE variable halfword except:
1794       - The shift in the VMX register is by 0/8 for opposite element numbers so
1795         we simply AND the element number with 0x4 and multiply by 2
1796       - The order of elements after the move to GPR is reversed, so we invert
1797         the bits of the index prior to truncating to the range 0-3
1798   */
1799   dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
1800                                        (RLDICR (ANDIo8 $Idx, 4), 1, 62)));
1801   dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
1802   dag BE_MV_VHALF = (MFVSRD
1803                       (EXTRACT_SUBREG
1804                         (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1805                         sub_64));
1806   dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1807                                        sub_32);
1808   dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1809                                          sub_32);
1810
1811   /*  BE variable word
1812       The algorithm is the same as the LE variable word except:
1813       - The shift in the VMX register happens for opposite element numbers
1814       - The order of elements after the move to GPR is reversed, so we invert
1815         the bits of the index prior to truncating to the range 0-1
1816   */
1817   dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1818                                        (RLDICR (ANDIo8 $Idx, 2), 2, 61)));
1819   dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
1820   dag BE_MV_VWORD = (MFVSRD
1821                       (EXTRACT_SUBREG
1822                         (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1823                         sub_64));
1824   dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1825                                        sub_32);
1826   dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1827                                          sub_32);
1828
1829   /*  BE variable doubleword
1830       Same as the LE doubleword except we shift in the VMX register for opposite
1831       element indices.
1832   */
1833   dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1834                                         (RLDICR (ANDIo8 $Idx, 1), 3, 60)));
1835   dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
1836   dag BE_VARIABLE_DWORD =
1837         (MFVSRD (EXTRACT_SUBREG
1838                   (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1839                   sub_64));
1840
1841   /*  BE variable float
1842       - Shift the vector to line up the desired element to BE Word 0
1843       - Convert 32-bit float to a 64-bit single precision float
1844   */
1845   dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
1846   dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1847   dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1848
1849   /* BE variable double
1850       Same as the BE doubleword except there is no move.
1851   */
1852   dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1853                                          (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1854                                          BE_VDWORD_PERM_VEC));
1855   dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1856 }
1857
1858 def NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">;
1859 let AddedComplexity = 400 in {
1860 // v4f32 scalar <-> vector conversions (BE)
1861 let Predicates = [IsBigEndian, HasP8Vector] in {
1862   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1863             (v4f32 (XSCVDPSPN $A))>;
1864   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1865             (f32 (XSCVSPDPN $S))>;
1866   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1867             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1868   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1869             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1870   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1871             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1872   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1873             (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1874 } // IsBigEndian, HasP8Vector
1875
1876 // Variable index vector_extract for v2f64 does not require P8Vector
1877 let Predicates = [IsBigEndian, HasVSX] in
1878   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1879             (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1880
1881 let Predicates = [IsBigEndian, HasDirectMove] in {
1882   // v16i8 scalar <-> vector conversions (BE)
1883   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1884             (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1885   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1886             (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1887   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1888             (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1889   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1890             (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1891
1892   // v2i64 scalar <-> vector conversions (BE)
1893   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1894             (i64 VectorExtractions.LE_DWORD_1)>;
1895   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1896             (i64 VectorExtractions.LE_DWORD_0)>;
1897   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1898             (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1899 } // IsBigEndian, HasDirectMove
1900
1901 let Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in {
1902   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1903             (i32 VectorExtractions.LE_BYTE_15)>;
1904   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1905             (i32 VectorExtractions.LE_BYTE_14)>;
1906   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1907             (i32 VectorExtractions.LE_BYTE_13)>;
1908   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1909             (i32 VectorExtractions.LE_BYTE_12)>;
1910   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1911             (i32 VectorExtractions.LE_BYTE_11)>;
1912   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1913             (i32 VectorExtractions.LE_BYTE_10)>;
1914   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1915             (i32 VectorExtractions.LE_BYTE_9)>;
1916   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1917             (i32 VectorExtractions.LE_BYTE_8)>;
1918   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1919             (i32 VectorExtractions.LE_BYTE_7)>;
1920   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1921             (i32 VectorExtractions.LE_BYTE_6)>;
1922   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1923             (i32 VectorExtractions.LE_BYTE_5)>;
1924   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1925             (i32 VectorExtractions.LE_BYTE_4)>;
1926   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1927             (i32 VectorExtractions.LE_BYTE_3)>;
1928   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1929             (i32 VectorExtractions.LE_BYTE_2)>;
1930   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1931             (i32 VectorExtractions.LE_BYTE_1)>;
1932   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1933             (i32 VectorExtractions.LE_BYTE_0)>;
1934   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1935             (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1936
1937   // v8i16 scalar <-> vector conversions (BE)
1938   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1939             (i32 VectorExtractions.LE_HALF_7)>;
1940   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1941             (i32 VectorExtractions.LE_HALF_6)>;
1942   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1943             (i32 VectorExtractions.LE_HALF_5)>;
1944   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1945             (i32 VectorExtractions.LE_HALF_4)>;
1946   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1947             (i32 VectorExtractions.LE_HALF_3)>;
1948   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1949             (i32 VectorExtractions.LE_HALF_2)>;
1950   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1951             (i32 VectorExtractions.LE_HALF_1)>;
1952   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1953             (i32 VectorExtractions.LE_HALF_0)>;
1954   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1955             (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1956
1957   // v4i32 scalar <-> vector conversions (BE)
1958   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1959             (i32 VectorExtractions.LE_WORD_3)>;
1960   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1961             (i32 VectorExtractions.LE_WORD_2)>;
1962   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1963             (i32 VectorExtractions.LE_WORD_1)>;
1964   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1965             (i32 VectorExtractions.LE_WORD_0)>;
1966   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1967             (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1968 } // IsBigEndian, HasDirectMove, NoP9Altivec
1969
1970 // v4f32 scalar <-> vector conversions (LE)
1971 let Predicates = [IsLittleEndian, HasP8Vector] in {
1972   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1973             (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1974   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1975             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1976   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1977             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1978   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1979             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1980   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1981             (f32 (XSCVSPDPN $S))>;
1982   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1983             (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1984 } // IsLittleEndian, HasP8Vector
1985
1986 // Variable index vector_extract for v2f64 does not require P8Vector
1987 let Predicates = [IsLittleEndian, HasVSX] in
1988   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1989             (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1990
1991 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1992 def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1993
1994 // Variable index unsigned vector_extract on Power9
1995 let Predicates = [HasP9Altivec, IsLittleEndian] in {
1996   def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
1997             (VEXTUBRX $Idx, $S)>;
1998
1999   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2000             (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2001   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2002             (VEXTUHRX (LI8 0), $S)>;
2003   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2004             (VEXTUHRX (LI8 2), $S)>;
2005   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2006             (VEXTUHRX (LI8 4), $S)>;
2007   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2008             (VEXTUHRX (LI8 6), $S)>;
2009   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2010             (VEXTUHRX (LI8 8), $S)>;
2011   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2012             (VEXTUHRX (LI8 10), $S)>;
2013   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2014             (VEXTUHRX (LI8 12), $S)>;
2015   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2016             (VEXTUHRX (LI8 14), $S)>;
2017
2018   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2019             (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2020   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2021             (VEXTUWRX (LI8 0), $S)>;
2022   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2023             (VEXTUWRX (LI8 4), $S)>;
2024   // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2025   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2026             (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2027             (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2028   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2029             (VEXTUWRX (LI8 12), $S)>;
2030
2031   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2032             (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2033   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2034             (EXTSW (VEXTUWRX (LI8 0), $S))>;
2035   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2036             (EXTSW (VEXTUWRX (LI8 4), $S))>;
2037   // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2038   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2039             (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2040             (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2041   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2042             (EXTSW (VEXTUWRX (LI8 12), $S))>;
2043
2044   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2045             (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
2046   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2047             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
2048   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2049             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
2050   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2051             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
2052   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2053             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
2054   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2055             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
2056   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2057             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
2058   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2059             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
2060   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2061             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
2062   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2063             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
2064   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2065             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
2066   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2067             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
2068   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2069             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
2070   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2071             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
2072   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2073             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
2074   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2075             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
2076   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2077             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
2078
2079   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2080             (i32 (EXTRACT_SUBREG (VEXTUHRX
2081             (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2082   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2083             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
2084   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2085             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
2086   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2087             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
2088   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2089             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
2090   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2091             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
2092   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2093             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
2094   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2095             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
2096   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2097             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
2098
2099   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2100             (i32 (EXTRACT_SUBREG (VEXTUWRX
2101             (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2102   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2103             (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
2104   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2105             (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
2106   // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2107   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2108             (i32 VectorExtractions.LE_WORD_2)>;
2109   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2110             (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
2111 }
2112
2113 let Predicates = [HasP9Altivec, IsBigEndian] in {
2114   def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
2115             (VEXTUBLX $Idx, $S)>;
2116
2117   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2118             (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2119   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2120             (VEXTUHLX (LI8 0), $S)>;
2121   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2122             (VEXTUHLX (LI8 2), $S)>;
2123   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2124             (VEXTUHLX (LI8 4), $S)>;
2125   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2126             (VEXTUHLX (LI8 6), $S)>;
2127   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2128             (VEXTUHLX (LI8 8), $S)>;
2129   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2130             (VEXTUHLX (LI8 10), $S)>;
2131   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2132             (VEXTUHLX (LI8 12), $S)>;
2133   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2134             (VEXTUHLX (LI8 14), $S)>;
2135
2136   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2137             (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2138   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2139             (VEXTUWLX (LI8 0), $S)>;
2140
2141   // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2142   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2143             (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2144             (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2145   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2146             (VEXTUWLX (LI8 8), $S)>;
2147   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2148             (VEXTUWLX (LI8 12), $S)>;
2149
2150   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2151             (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2152   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2153             (EXTSW (VEXTUWLX (LI8 0), $S))>;
2154   // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2155   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2156             (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2157             (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2158   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2159             (EXTSW (VEXTUWLX (LI8 8), $S))>;
2160   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2161             (EXTSW (VEXTUWLX (LI8 12), $S))>;
2162
2163   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2164             (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
2165   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2166             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
2167   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2168             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
2169   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2170             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
2171   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2172             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
2173   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2174             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
2175   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2176             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
2177   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2178             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
2179   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2180             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
2181   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2182             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
2183   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2184             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
2185   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2186             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
2187   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2188             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
2189   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2190             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
2191   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2192             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
2193   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2194             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
2195   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2196             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
2197
2198   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2199             (i32 (EXTRACT_SUBREG (VEXTUHLX
2200             (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2201   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2202             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
2203   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2204             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
2205   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2206             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
2207   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2208             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
2209   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2210             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
2211   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2212             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
2213   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2214             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
2215   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2216             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
2217
2218   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2219             (i32 (EXTRACT_SUBREG (VEXTUWLX
2220             (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2221   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2222             (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
2223   // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2224   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2225             (i32 VectorExtractions.LE_WORD_2)>;
2226   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2227             (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
2228   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2229             (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
2230 }
2231
2232 let Predicates = [IsLittleEndian, HasDirectMove] in {
2233   // v16i8 scalar <-> vector conversions (LE)
2234   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
2235             (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2236   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
2237             (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2238   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2239             (v4i32 MovesToVSR.LE_WORD_0)>;
2240   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
2241             (v2i64 MovesToVSR.LE_DWORD_0)>;
2242   // v2i64 scalar <-> vector conversions (LE)
2243   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
2244             (i64 VectorExtractions.LE_DWORD_0)>;
2245   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
2246             (i64 VectorExtractions.LE_DWORD_1)>;
2247   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
2248             (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
2249 } // IsLittleEndian, HasDirectMove
2250
2251 let Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in {
2252   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2253             (i32 VectorExtractions.LE_BYTE_0)>;
2254   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2255             (i32 VectorExtractions.LE_BYTE_1)>;
2256   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2257             (i32 VectorExtractions.LE_BYTE_2)>;
2258   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2259             (i32 VectorExtractions.LE_BYTE_3)>;
2260   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2261             (i32 VectorExtractions.LE_BYTE_4)>;
2262   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2263             (i32 VectorExtractions.LE_BYTE_5)>;
2264   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2265             (i32 VectorExtractions.LE_BYTE_6)>;
2266   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2267             (i32 VectorExtractions.LE_BYTE_7)>;
2268   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2269             (i32 VectorExtractions.LE_BYTE_8)>;
2270   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2271             (i32 VectorExtractions.LE_BYTE_9)>;
2272   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2273             (i32 VectorExtractions.LE_BYTE_10)>;
2274   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2275             (i32 VectorExtractions.LE_BYTE_11)>;
2276   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2277             (i32 VectorExtractions.LE_BYTE_12)>;
2278   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2279             (i32 VectorExtractions.LE_BYTE_13)>;
2280   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2281             (i32 VectorExtractions.LE_BYTE_14)>;
2282   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2283             (i32 VectorExtractions.LE_BYTE_15)>;
2284   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2285             (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
2286
2287   // v8i16 scalar <-> vector conversions (LE)
2288   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2289             (i32 VectorExtractions.LE_HALF_0)>;
2290   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2291             (i32 VectorExtractions.LE_HALF_1)>;
2292   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2293             (i32 VectorExtractions.LE_HALF_2)>;
2294   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2295             (i32 VectorExtractions.LE_HALF_3)>;
2296   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2297             (i32 VectorExtractions.LE_HALF_4)>;
2298   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2299             (i32 VectorExtractions.LE_HALF_5)>;
2300   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2301             (i32 VectorExtractions.LE_HALF_6)>;
2302   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
2303             (i32 VectorExtractions.LE_HALF_7)>;
2304   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2305             (i32 VectorExtractions.LE_VARIABLE_HALF)>;
2306
2307   // v4i32 scalar <-> vector conversions (LE)
2308   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2309             (i32 VectorExtractions.LE_WORD_0)>;
2310   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2311             (i32 VectorExtractions.LE_WORD_1)>;
2312   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2313             (i32 VectorExtractions.LE_WORD_2)>;
2314   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2315             (i32 VectorExtractions.LE_WORD_3)>;
2316   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2317             (i32 VectorExtractions.LE_VARIABLE_WORD)>;
2318 } // IsLittleEndian, HasDirectMove, NoP9Altivec
2319
2320 let Predicates = [HasDirectMove, HasVSX] in {
2321 // bitconvert f32 -> i32
2322 // (convert to 32-bit fp single, shift right 1 word, move to GPR)
2323 def : Pat<(i32 (bitconvert f32:$S)),
2324           (i32 (MFVSRWZ (EXTRACT_SUBREG
2325                           (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
2326                           sub_64)))>;
2327 // bitconvert i32 -> f32
2328 // (move to FPR, shift left 1 word, convert to 64-bit fp single)
2329 def : Pat<(f32 (bitconvert i32:$A)),
2330           (f32 (XSCVSPDPN
2331                  (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
2332
2333 // bitconvert f64 -> i64
2334 // (move to GPR, nothing else needed)
2335 def : Pat<(i64 (bitconvert f64:$S)),
2336           (i64 (MFVSRD $S))>;
2337
2338 // bitconvert i64 -> f64
2339 // (move to FPR, nothing else needed)
2340 def : Pat<(f64 (bitconvert i64:$S)),
2341           (f64 (MTVSRD $S))>;
2342 }
2343
2344 // Materialize a zero-vector of long long
2345 def : Pat<(v2i64 immAllZerosV),
2346           (v2i64 (XXLXORz))>;
2347 }
2348
2349 def AlignValues {
2350   dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2351   dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2352 }
2353
2354 // The following VSX instructions were introduced in Power ISA 3.0
2355 def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2356 let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2357
2358   // [PO VRT XO VRB XO /]
2359   class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2360                       list<dag> pattern>
2361     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2362                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2363
2364   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2365   class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2366                          list<dag> pattern>
2367     : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2368
2369   // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2370   // So we use different operand class for VRB
2371   class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2372                            RegisterOperand vbtype, list<dag> pattern>
2373     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2374                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2375
2376   // [PO VRT XO VRB XO /]
2377   class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2378                       list<dag> pattern>
2379     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
2380                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2381
2382   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2383   class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2384                          list<dag> pattern>
2385     : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isDOT;
2386
2387   let UseVSXReg = 1 in {
2388   // [PO T XO B XO BX /]
2389   class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2390                         list<dag> pattern>
2391     : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2392                       !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2393
2394   // [PO T XO B XO BX TX]
2395   class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2396                         RegisterOperand vtype, list<dag> pattern>
2397     : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2398                       !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2399
2400   // [PO T A B XO AX BX TX], src and dest register use different operand class
2401   class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2402                   RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2403                   InstrItinClass itin, list<dag> pattern>
2404     : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2405               !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2406   } // UseVSXReg = 1
2407
2408   // [PO VRT VRA VRB XO /]
2409   class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2410                       list<dag> pattern>
2411     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2412               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2413
2414   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2415   class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2416                          list<dag> pattern>
2417     : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2418
2419   // [PO VRT VRA VRB XO /]
2420   class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
2421                           list<dag> pattern>
2422     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
2423               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
2424               RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
2425
2426   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2427   class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
2428                           list<dag> pattern>
2429     : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isDOT;
2430
2431   //===--------------------------------------------------------------------===//
2432   // Quad-Precision Scalar Move Instructions:
2433
2434   // Copy Sign
2435   def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
2436                                 [(set f128:$vT,
2437                                       (fcopysign f128:$vB, f128:$vA))]>;
2438
2439   // Absolute/Negative-Absolute/Negate
2440   def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
2441                                 [(set f128:$vT, (fabs f128:$vB))]>;
2442   def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
2443                                 [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
2444   def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
2445                                 [(set f128:$vT, (fneg f128:$vB))]>;
2446
2447   //===--------------------------------------------------------------------===//
2448   // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2449
2450   // Add/Divide/Multiply/Subtract
2451   let isCommutable = 1 in {
2452   def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
2453                                    [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>;
2454   def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
2455                                   [(set f128:$vT,
2456                                   (int_ppc_addf128_round_to_odd
2457                                   f128:$vA, f128:$vB))]>;
2458   def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
2459                                    [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>;
2460   def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
2461                                   [(set f128:$vT,
2462                                   (int_ppc_mulf128_round_to_odd
2463                                   f128:$vA, f128:$vB))]>;
2464   }
2465
2466   def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
2467                                    [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>;
2468   def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
2469                                   [(set f128:$vT,
2470                                   (int_ppc_subf128_round_to_odd
2471                                   f128:$vA, f128:$vB))]>;
2472   def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
2473                                    [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>;
2474   def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
2475                                   [(set f128:$vT,
2476                                   (int_ppc_divf128_round_to_odd
2477                                   f128:$vA, f128:$vB))]>;
2478
2479   // Square-Root
2480   def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
2481                                    [(set f128:$vT, (fsqrt f128:$vB))]>;
2482   def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
2483                                   [(set f128:$vT,
2484                                   (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
2485
2486   // (Negative) Multiply-{Add/Subtract}
2487   def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
2488                                     [(set f128:$vT,
2489                                           (fma f128:$vA, f128:$vB,
2490                                                f128:$vTi))]>;
2491
2492   def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
2493                                       [(set f128:$vT,
2494                                       (int_ppc_fmaf128_round_to_odd
2495                                       f128:$vA,f128:$vB,f128:$vTi))]>;
2496
2497   def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
2498                                        [(set f128:$vT,
2499                                              (fma f128:$vA, f128:$vB,
2500                                                   (fneg f128:$vTi)))]>;
2501   def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
2502                                       [(set f128:$vT,
2503                                       (int_ppc_fmaf128_round_to_odd
2504                                       f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
2505   def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
2506                                      [(set f128:$vT,
2507                                            (fneg (fma f128:$vA, f128:$vB,
2508                                                       f128:$vTi)))]>;
2509   def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
2510                                       [(set f128:$vT,
2511                                       (fneg (int_ppc_fmaf128_round_to_odd
2512                                       f128:$vA, f128:$vB, f128:$vTi)))]>;
2513   def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
2514                                      [(set f128:$vT,
2515                                            (fneg (fma f128:$vA, f128:$vB,
2516                                                       (fneg f128:$vTi))))]>;
2517   def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
2518                                       [(set f128:$vT,
2519                                       (fneg (int_ppc_fmaf128_round_to_odd
2520                                       f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
2521
2522   // Additional fnmsub patterns: -a*c + b == -(a*c - b)
2523   def : Pat<(fma (fneg f128:$A), f128:$C, f128:$B), (XSNMSUBQP $B, $C, $A)>;
2524   def : Pat<(fma f128:$A, (fneg f128:$C), f128:$B), (XSNMSUBQP $B, $C, $A)>;
2525
2526   //===--------------------------------------------------------------------===//
2527   // Quad/Double-Precision Compare Instructions:
2528
2529   // [PO BF // VRA VRB XO /]
2530   class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2531                       list<dag> pattern>
2532     : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2533                !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2534     let Pattern = pattern;
2535   }
2536
2537   // QP Compare Ordered/Unordered
2538   def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2539   def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2540
2541   // DP/QP Compare Exponents
2542   def XSCMPEXPDP : XX3Form_1<60, 59,
2543                              (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2544                              "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>,
2545                    UseVSXReg;
2546   def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2547
2548   // DP Compare ==, >=, >, !=
2549   // Use vsrc for XT, because the entire register of XT is set.
2550   // XT.dword[1] = 0x0000_0000_0000_0000
2551   def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2552                                   IIC_FPCompare, []>;
2553   def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2554                                   IIC_FPCompare, []>;
2555   def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2556                                   IIC_FPCompare, []>;
2557
2558   //===--------------------------------------------------------------------===//
2559   // Quad-Precision Floating-Point Conversion Instructions:
2560
2561   // Convert DP -> QP
2562   def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
2563                                      [(set f128:$vT, (fpextend f64:$vB))]>;
2564
2565   // Round & Convert QP -> DP (dword[1] is set to zero)
2566   def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
2567   def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
2568                                         [(set f64:$vT,
2569                                         (int_ppc_truncf128_round_to_odd
2570                                         f128:$vB))]>;
2571
2572   // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2573   def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2574   def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2575   def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2576   def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2577
2578   // Convert (Un)Signed DWord -> QP.
2579   def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2580   def : Pat<(f128 (sint_to_fp i64:$src)),
2581             (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
2582   def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))),
2583             (f128 (XSCVSDQP $src))>;
2584   def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))),
2585             (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
2586
2587   def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2588   def : Pat<(f128 (uint_to_fp i64:$src)),
2589             (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
2590   def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))),
2591             (f128 (XSCVUDQP $src))>;
2592
2593   // Convert (Un)Signed Word -> QP.
2594   def : Pat<(f128 (sint_to_fp i32:$src)),
2595             (f128 (XSCVSDQP (MTVSRWA $src)))>;
2596   def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
2597             (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
2598   def : Pat<(f128 (uint_to_fp i32:$src)),
2599             (f128 (XSCVUDQP (MTVSRWZ $src)))>;
2600   def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))),
2601             (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
2602
2603   let UseVSXReg = 1 in {
2604   //===--------------------------------------------------------------------===//
2605   // Round to Floating-Point Integer Instructions
2606
2607   // (Round &) Convert DP <-> HP
2608   // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2609   // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2610   // but we still use vsfrc for it.
2611   def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2612   def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2613
2614   // Vector HP -> SP
2615   def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2616   def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2617                                  [(set v4f32:$XT,
2618                                      (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2619
2620   } // UseVSXReg = 1
2621
2622   // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2623   // separate pattern so that it can convert the input register class from
2624   // VRRC(v8i16) to VSRC.
2625   def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2626             (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2627
2628   class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2629                                 list<dag> pattern>
2630     : Z23Form_8<opcode, xo,
2631                 (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2632                 !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2633     let RC = ex;
2634   }
2635
2636   // Round to Quad-Precision Integer [with Inexact]
2637   def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2638   def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2639
2640   // Use current rounding mode
2641   def : Pat<(f128 (fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
2642   // Round to nearest, ties away from zero
2643   def : Pat<(f128 (fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
2644   // Round towards Zero
2645   def : Pat<(f128 (ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
2646   // Round towards +Inf
2647   def : Pat<(f128 (fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
2648   // Round towards -Inf
2649   def : Pat<(f128 (ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
2650
2651   // Use current rounding mode, [with Inexact]
2652   def : Pat<(f128 (frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
2653
2654   // Round Quad-Precision to Double-Extended Precision (fp80)
2655   def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2656
2657   //===--------------------------------------------------------------------===//
2658   // Insert/Extract Instructions
2659
2660   // Insert Exponent DP/QP
2661   // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2662   def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2663                           "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg;
2664   // vB NOTE: only vB.dword[0] is used, that's why we don't use
2665   //          X_VT5_VA5_VB5 form
2666   def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2667                           "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2668
2669   // Extract Exponent/Significand DP/QP
2670   def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2671   def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2672
2673   def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2674   def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2675
2676   // Vector Insert Word
2677   let UseVSXReg = 1 in {
2678   // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2679   def XXINSERTW   :
2680     XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2681                      (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2682                      "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2683                      [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
2684                                                    imm32SExt16:$UIM))]>,
2685                      RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2686
2687   // Vector Extract Unsigned Word
2688   def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2689                                   (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2690                                   "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2691   } // UseVSXReg = 1
2692
2693   // Vector Insert Exponent DP/SP
2694   def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2695     IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2696   def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2697     IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2698
2699   // Vector Extract Exponent/Significand DP/SP
2700   def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2701                                  [(set v2i64: $XT,
2702                                   (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2703   def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2704                                  [(set v4i32: $XT,
2705                                   (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2706   def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2707                                  [(set v2i64: $XT,
2708                                   (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2709   def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2710                                  [(set v4i32: $XT,
2711                                   (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2712
2713   let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2714   // Extra patterns expanding to vector Extract Word/Insert Word
2715   def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2716             (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2717   def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2718             (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2719   } // AddedComplexity = 400, HasP9Vector
2720
2721   //===--------------------------------------------------------------------===//
2722
2723   // Test Data Class SP/DP/QP
2724   let UseVSXReg = 1 in {
2725   def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2726                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2727                               "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2728   def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2729                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2730                               "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2731   } // UseVSXReg = 1
2732   def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2733                               (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2734                               "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2735
2736   // Vector Test Data Class SP/DP
2737   let UseVSXReg = 1 in {
2738   def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2739                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2740                               "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2741                               [(set v4i32: $XT,
2742                                (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>;
2743   def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2744                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2745                               "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2746                               [(set v2i64: $XT,
2747                                (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>;
2748   } // UseVSXReg = 1
2749
2750   //===--------------------------------------------------------------------===//
2751
2752   // Maximum/Minimum Type-C/Type-J DP
2753   // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2754   def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2755                                  IIC_VecFP, []>;
2756   def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2757                                  IIC_VecFP, []>;
2758   def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2759                                  IIC_VecFP, []>;
2760   def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2761                                  IIC_VecFP, []>;
2762
2763   //===--------------------------------------------------------------------===//
2764
2765   // Vector Byte-Reverse H/W/D/Q Word
2766   def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2767   def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2768   def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2769   def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2770
2771   // Vector Reverse
2772   def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)),
2773             (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2774   def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)),
2775             (v4i32 (XXBRW $A))>;
2776   def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)),
2777             (v2i64 (XXBRD $A))>;
2778   def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)),
2779             (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2780
2781   // Vector Permute
2782   def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2783                                 IIC_VecPerm, []>;
2784   def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2785                                 IIC_VecPerm, []>;
2786
2787   // Vector Splat Immediate Byte
2788   def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2789                             "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg;
2790
2791   //===--------------------------------------------------------------------===//
2792   // Vector/Scalar Load/Store Instructions
2793
2794   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2795   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2796   let mayLoad = 1, mayStore = 0 in {
2797   // Load Vector
2798   def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2799                             "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg;
2800   // Load DWord
2801   def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2802                        "lxsd $vD, $src", IIC_LdStLFD, []>;
2803   // Load SP from src, convert it to DP, and place in dword[0]
2804   def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2805                        "lxssp $vD, $src", IIC_LdStLFD, []>;
2806
2807   // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2808   // "out" and "in" dag
2809   class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2810                       RegisterOperand vtype, list<dag> pattern>
2811     : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2812               !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg;
2813
2814   // Load as Integer Byte/Halfword & Zero Indexed
2815   def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2816                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2817   def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2818                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2819
2820   // Load Vector Halfword*8/Byte*16 Indexed
2821   def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2822   def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2823
2824   // Load Vector Indexed
2825   def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2826                 [(set v2f64:$XT, (load xaddr:$src))]>;
2827   // Load Vector (Left-justified) with Length
2828   def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2829                    "lxvl $XT, $src, $rB", IIC_LdStLoad,
2830                    [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>,
2831                     UseVSXReg;
2832   def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2833                    "lxvll $XT, $src, $rB", IIC_LdStLoad,
2834                    [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>,
2835                     UseVSXReg;
2836
2837   // Load Vector Word & Splat Indexed
2838   def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2839   } // mayLoad
2840
2841   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2842   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2843   let mayStore = 1, mayLoad = 0 in {
2844   // Store Vector
2845   def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2846                              "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg;
2847   // Store DWord
2848   def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2849                         "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2850   // Convert DP of dword[0] to SP, and Store to dst
2851   def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2852                         "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2853
2854   // [PO S RA RB XO SX]
2855   class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2856                       RegisterOperand vtype, list<dag> pattern>
2857     : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2858               !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg;
2859
2860   // Store as Integer Byte/Halfword Indexed
2861   def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2862                                [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2863   def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2864                                [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2865   let isCodeGenOnly = 1 in {
2866     def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vrrc, []>;
2867     def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vrrc, []>;
2868   }
2869
2870   // Store Vector Halfword*8/Byte*16 Indexed
2871   def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2872   def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2873
2874   // Store Vector Indexed
2875   def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
2876                  [(store v2f64:$XT, xaddr:$dst)]>;
2877
2878   // Store Vector (Left-justified) with Length
2879   def STXVL : XX1Form_memOp<31, 397, (outs),
2880                             (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2881                             "stxvl $XT, $dst, $rB", IIC_LdStLoad,
2882                             [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
2883                               i64:$rB)]>,
2884                             UseVSXReg;
2885   def STXVLL : XX1Form_memOp<31, 429, (outs),
2886                             (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2887                             "stxvll $XT, $dst, $rB", IIC_LdStLoad,
2888                             [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
2889                               i64:$rB)]>,
2890                             UseVSXReg;
2891   } // mayStore
2892
2893   let Predicates = [IsLittleEndian] in {
2894   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2895            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
2896   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2897            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
2898   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2899            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
2900   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2901            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
2902   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2903            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
2904   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2905            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
2906   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2907            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
2908   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2909            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
2910   }
2911
2912   let Predicates = [IsBigEndian] in {
2913   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2914            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
2915   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2916            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
2917   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2918            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
2919   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2920            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
2921   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2922            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
2923   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2924            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
2925   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2926            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
2927   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2928            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
2929   }
2930
2931   // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
2932   // of f64
2933   def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
2934             (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
2935   def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
2936             (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
2937
2938   // Patterns for which instructions from ISA 3.0 are a better match
2939   let Predicates = [IsLittleEndian, HasP9Vector] in {
2940   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
2941             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2942   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
2943             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2944   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
2945             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2946   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
2947             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2948   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
2949             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
2950   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
2951             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
2952   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
2953             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
2954   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
2955             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
2956   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2957             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2958   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2959             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2960   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2961             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2962   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2963             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2964   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2965             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2966   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2967             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2968   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2969             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2970   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2971             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2972   } // IsLittleEndian, HasP9Vector
2973
2974   let Predicates = [IsBigEndian, HasP9Vector] in {
2975   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
2976             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2977   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
2978             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2979   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
2980             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2981   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
2982             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2983   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
2984             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
2985   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
2986             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
2987   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
2988             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
2989   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
2990             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
2991   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2992             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2993   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2994             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2995   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2996             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2997   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2998             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2999   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
3000             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3001   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
3002             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
3003   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
3004             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
3005   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3006             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
3007   } // IsLittleEndian, HasP9Vector
3008
3009   // D-Form Load/Store
3010   def : Pat<(v4i32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3011   def : Pat<(v4f32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3012   def : Pat<(v2i64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3013   def : Pat<(v2f64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3014   def : Pat<(f128  (quadwOffsetLoad iqaddr:$src)),
3015             (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3016   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iqaddr:$src)), (LXV memrix16:$src)>;
3017   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iqaddr:$src)), (LXV memrix16:$src)>;
3018
3019   def : Pat<(quadwOffsetStore v4f32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3020   def : Pat<(quadwOffsetStore v4i32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3021   def : Pat<(quadwOffsetStore v2f64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3022   def : Pat<(quadwOffsetStore  f128:$rS, iqaddr:$dst),
3023             (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3024   def : Pat<(quadwOffsetStore v2i64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3025   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iqaddr:$dst),
3026             (STXV $rS, memrix16:$dst)>;
3027   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iqaddr:$dst),
3028             (STXV $rS, memrix16:$dst)>;
3029
3030
3031   def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3032   def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3033   def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3034   def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3035   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
3036   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
3037   def : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
3038             (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
3039   def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
3040             (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3041   def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
3042             (STXVX $rS, xoaddr:$dst)>;
3043   def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
3044             (STXVX $rS, xoaddr:$dst)>;
3045   def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
3046             (STXVX $rS, xoaddr:$dst)>;
3047   def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
3048             (STXVX $rS, xoaddr:$dst)>;
3049   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3050             (STXVX $rS, xoaddr:$dst)>;
3051   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
3052             (STXVX $rS, xoaddr:$dst)>;
3053   def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3054             (v4i32 (LXVWSX xoaddr:$src))>;
3055   def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3056             (v4f32 (LXVWSX xoaddr:$src))>;
3057   def : Pat<(v4f32 (scalar_to_vector
3058                      (f32 (fpround (f64 (extloadf32 xoaddr:$src)))))),
3059             (v4f32 (LXVWSX xoaddr:$src))>;
3060
3061   // Build vectors from i8 loads
3062   def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
3063             (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
3064   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
3065             (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
3066   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
3067            (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
3068   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
3069             (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
3070   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
3071             (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
3072   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
3073             (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
3074
3075   // Build vectors from i16 loads
3076   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
3077             (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
3078   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
3079             (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
3080   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
3081            (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
3082   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
3083             (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
3084   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
3085             (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
3086
3087   let Predicates = [IsBigEndian, HasP9Vector] in {
3088   // Scalar stores of i8
3089   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3090             (STXSIBXv (v16i8 (VSLDOI $S, $S, 9)), xoaddr:$dst)>;
3091   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3092             (STXSIBXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3093   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3094             (STXSIBXv (v16i8 (VSLDOI $S, $S, 11)), xoaddr:$dst)>;
3095   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3096             (STXSIBXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3097   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3098             (STXSIBXv (v16i8 (VSLDOI $S, $S, 13)), xoaddr:$dst)>;
3099   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3100             (STXSIBXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3101   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3102             (STXSIBXv (v16i8 (VSLDOI $S, $S, 15)), xoaddr:$dst)>;
3103   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3104             (STXSIBXv $S, xoaddr:$dst)>;
3105   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3106             (STXSIBXv (v16i8 (VSLDOI $S, $S, 1)), xoaddr:$dst)>;
3107   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3108             (STXSIBXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3109   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3110             (STXSIBXv (v16i8 (VSLDOI $S, $S, 3)), xoaddr:$dst)>;
3111   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3112             (STXSIBXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3113   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3114             (STXSIBXv (v16i8 (VSLDOI $S, $S, 5)), xoaddr:$dst)>;
3115   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3116             (STXSIBXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3117   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3118             (STXSIBXv (v16i8 (VSLDOI $S, $S, 7)), xoaddr:$dst)>;
3119   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3120             (STXSIBXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3121
3122   // Scalar stores of i16
3123   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3124             (STXSIHXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3125   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3126             (STXSIHXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3127   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3128             (STXSIHXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3129   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3130             (STXSIHXv $S, xoaddr:$dst)>;
3131   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3132             (STXSIHXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3133   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3134             (STXSIHXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3135   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3136             (STXSIHXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3137   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3138             (STXSIHXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3139   } // IsBigEndian, HasP9Vector
3140
3141   let Predicates = [IsLittleEndian, HasP9Vector] in {
3142   // Scalar stores of i8
3143   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3144             (STXSIBXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3145   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3146             (STXSIBXv (v16i8 (VSLDOI $S, $S, 7)), xoaddr:$dst)>;
3147   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3148             (STXSIBXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3149   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3150             (STXSIBXv (v16i8 (VSLDOI $S, $S, 5)), xoaddr:$dst)>;
3151   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3152             (STXSIBXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3153   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3154             (STXSIBXv (v16i8 (VSLDOI $S, $S, 3)), xoaddr:$dst)>;
3155   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3156             (STXSIBXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3157   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3158             (STXSIBXv (v16i8 (VSLDOI $S, $S, 1)), xoaddr:$dst)>;
3159   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3160             (STXSIBXv $S, xoaddr:$dst)>;
3161   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3162             (STXSIBXv (v16i8 (VSLDOI $S, $S, 15)), xoaddr:$dst)>;
3163   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3164             (STXSIBXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3165   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3166             (STXSIBXv (v16i8 (VSLDOI $S, $S, 13)), xoaddr:$dst)>;
3167   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3168             (STXSIBXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3169   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3170             (STXSIBXv (v16i8 (VSLDOI $S, $S, 11)), xoaddr:$dst)>;
3171   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3172             (STXSIBXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3173   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3174             (STXSIBXv (v16i8 (VSLDOI $S, $S, 9)), xoaddr:$dst)>;
3175
3176   // Scalar stores of i16
3177   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3178             (STXSIHXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3179   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3180             (STXSIHXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3181   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3182             (STXSIHXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3183   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3184             (STXSIHXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3185   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3186             (STXSIHXv $S, xoaddr:$dst)>;
3187   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3188             (STXSIHXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3189   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3190             (STXSIHXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3191   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3192             (STXSIHXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3193   } // IsLittleEndian, HasP9Vector
3194
3195
3196   // Vector sign extensions
3197   def : Pat<(f64 (PPCVexts f64:$A, 1)),
3198             (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
3199   def : Pat<(f64 (PPCVexts f64:$A, 2)),
3200             (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
3201
3202   let isPseudo = 1 in {
3203     def DFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrix:$src),
3204                             "#DFLOADf32",
3205                             [(set f32:$XT, (load ixaddr:$src))]>;
3206     def DFLOADf64  : Pseudo<(outs vsfrc:$XT), (ins memrix:$src),
3207                             "#DFLOADf64",
3208                             [(set f64:$XT, (load ixaddr:$src))]>;
3209     def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst),
3210                             "#DFSTOREf32",
3211                             [(store f32:$XT, ixaddr:$dst)]>;
3212     def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
3213                             "#DFSTOREf64",
3214                             [(store f64:$XT, ixaddr:$dst)]>;
3215   }
3216   def : Pat<(f64 (extloadf32 ixaddr:$src)),
3217             (COPY_TO_REGCLASS (DFLOADf32 ixaddr:$src), VSFRC)>;
3218   def : Pat<(f32 (fpround (f64 (extloadf32 ixaddr:$src)))),
3219             (f32 (DFLOADf32 ixaddr:$src))>;
3220
3221   let Predicates = [IsBigEndian, HasP9Vector] in {
3222
3223     // (Un)Signed DWord vector extract -> QP
3224     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3225               (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3226     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3227               (f128 (XSCVSDQP
3228                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3229     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3230               (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3231     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3232               (f128 (XSCVUDQP
3233                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3234
3235     // (Un)Signed Word vector extract -> QP
3236     def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
3237               (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
3238     foreach Idx = [0,2,3] in {
3239       def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
3240                 (f128 (XSCVSDQP (EXTRACT_SUBREG
3241                                 (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
3242     }
3243     foreach Idx = 0-3 in {
3244       def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
3245                 (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
3246     }
3247
3248     // (Un)Signed HWord vector extract -> QP
3249     foreach Idx = 0-7 in {
3250       def : Pat<(f128 (sint_to_fp
3251                         (i32 (sext_inreg
3252                                (vector_extract v8i16:$src, Idx), i16)))),
3253               (f128 (XSCVSDQP (EXTRACT_SUBREG
3254                                 (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
3255                                 sub_64)))>;
3256       // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
3257       def : Pat<(f128 (uint_to_fp
3258                         (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
3259                 (f128 (XSCVUDQP (EXTRACT_SUBREG
3260                                   (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
3261     }
3262
3263     // (Un)Signed Byte vector extract -> QP
3264     foreach Idx = 0-15 in {
3265       def : Pat<(f128 (sint_to_fp
3266                         (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
3267                                          i8)))),
3268                 (f128 (XSCVSDQP (EXTRACT_SUBREG
3269                                   (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
3270       def : Pat<(f128 (uint_to_fp
3271                         (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
3272                 (f128 (XSCVUDQP
3273                         (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
3274     }
3275
3276     // Unsiged int in vsx register -> QP
3277     def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
3278               (f128 (XSCVUDQP
3279                       (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
3280   } // IsBigEndian, HasP9Vector
3281
3282   let Predicates = [IsLittleEndian, HasP9Vector] in {
3283
3284     // (Un)Signed DWord vector extract -> QP
3285     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3286               (f128 (XSCVSDQP
3287                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3288     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3289               (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3290     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3291               (f128 (XSCVUDQP
3292                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3293     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3294               (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3295
3296     // (Un)Signed Word vector extract -> QP
3297     foreach Idx = [[0,3],[1,2],[3,0]] in {
3298       def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
3299                 (f128 (XSCVSDQP (EXTRACT_SUBREG
3300                                   (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
3301                                   sub_64)))>;
3302     }
3303     def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
3304               (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
3305
3306     foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
3307       def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
3308                 (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
3309     }
3310
3311     // (Un)Signed HWord vector extract -> QP
3312     // The Nested foreach lists identifies the vector element and corresponding
3313     // register byte location.
3314     foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
3315       def : Pat<(f128 (sint_to_fp
3316                         (i32 (sext_inreg
3317                                (vector_extract v8i16:$src, !head(Idx)), i16)))),
3318                 (f128 (XSCVSDQP
3319                         (EXTRACT_SUBREG (VEXTSH2D
3320                                           (VEXTRACTUH !head(!tail(Idx)), $src)),
3321                                         sub_64)))>;
3322       def : Pat<(f128 (uint_to_fp
3323                         (and (i32 (vector_extract v8i16:$src, !head(Idx))),
3324                              65535))),
3325                 (f128 (XSCVUDQP (EXTRACT_SUBREG
3326                                   (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
3327     }
3328
3329     // (Un)Signed Byte vector extract -> QP
3330     foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
3331                    [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
3332       def : Pat<(f128 (sint_to_fp
3333                         (i32 (sext_inreg
3334                                (vector_extract v16i8:$src, !head(Idx)), i8)))),
3335                 (f128 (XSCVSDQP
3336                         (EXTRACT_SUBREG
3337                           (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
3338                           sub_64)))>;
3339       def : Pat<(f128 (uint_to_fp
3340                         (and (i32 (vector_extract v16i8:$src, !head(Idx))),
3341                              255))),
3342                 (f128 (XSCVUDQP
3343                         (EXTRACT_SUBREG
3344                           (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
3345     }
3346
3347     // Unsiged int in vsx register -> QP
3348     def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
3349               (f128 (XSCVUDQP
3350                       (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
3351   } // IsLittleEndian, HasP9Vector
3352
3353   // Convert (Un)Signed DWord in memory -> QP
3354   def : Pat<(f128 (sint_to_fp (i64 (load xaddr:$src)))),
3355             (f128 (XSCVSDQP (LXSDX xaddr:$src)))>;
3356   def : Pat<(f128 (sint_to_fp (i64 (load ixaddr:$src)))),
3357             (f128 (XSCVSDQP (LXSD ixaddr:$src)))>;
3358   def : Pat<(f128 (uint_to_fp (i64 (load xaddr:$src)))),
3359             (f128 (XSCVUDQP (LXSDX xaddr:$src)))>;
3360   def : Pat<(f128 (uint_to_fp (i64 (load ixaddr:$src)))),
3361             (f128 (XSCVUDQP (LXSD ixaddr:$src)))>;
3362
3363   // Convert Unsigned HWord in memory -> QP
3364   def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
3365             (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
3366
3367   // Convert Unsigned Byte in memory -> QP
3368   def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
3369             (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
3370
3371   // Truncate & Convert QP -> (Un)Signed (D)Word.
3372   def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3373   def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3374   def : Pat<(i32 (fp_to_sint f128:$src)),
3375             (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
3376   def : Pat<(i32 (fp_to_uint f128:$src)),
3377             (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
3378
3379   // Instructions for store(fptosi).
3380   // The 8-byte version is repeated here due to availability of D-Form STXSD.
3381   def : Pat<(PPCstore_scal_int_from_vsr
3382               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddr:$dst, 8),
3383             (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3384                     xaddr:$dst)>;
3385   def : Pat<(PPCstore_scal_int_from_vsr
3386               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ixaddr:$dst, 8),
3387             (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3388                    ixaddr:$dst)>;
3389   def : Pat<(PPCstore_scal_int_from_vsr
3390               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
3391             (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3392   def : Pat<(PPCstore_scal_int_from_vsr
3393               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
3394             (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3395   def : Pat<(PPCstore_scal_int_from_vsr
3396               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
3397             (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3398   def : Pat<(PPCstore_scal_int_from_vsr
3399               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddr:$dst, 8),
3400             (STXSDX (XSCVDPSXDS f64:$src), xaddr:$dst)>;
3401   def : Pat<(PPCstore_scal_int_from_vsr
3402               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ixaddr:$dst, 8),
3403             (STXSD (XSCVDPSXDS f64:$src), ixaddr:$dst)>;
3404   def : Pat<(PPCstore_scal_int_from_vsr
3405               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
3406             (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3407   def : Pat<(PPCstore_scal_int_from_vsr
3408               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
3409             (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3410
3411   // Instructions for store(fptoui).
3412   def : Pat<(PPCstore_scal_int_from_vsr
3413               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddr:$dst, 8),
3414             (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3415                     xaddr:$dst)>;
3416   def : Pat<(PPCstore_scal_int_from_vsr
3417               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ixaddr:$dst, 8),
3418             (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3419                    ixaddr:$dst)>;
3420   def : Pat<(PPCstore_scal_int_from_vsr
3421               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
3422             (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3423   def : Pat<(PPCstore_scal_int_from_vsr
3424               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
3425             (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3426   def : Pat<(PPCstore_scal_int_from_vsr
3427               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
3428             (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3429   def : Pat<(PPCstore_scal_int_from_vsr
3430               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddr:$dst, 8),
3431             (STXSDX (XSCVDPUXDS f64:$src), xaddr:$dst)>;
3432   def : Pat<(PPCstore_scal_int_from_vsr
3433               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ixaddr:$dst, 8),
3434             (STXSD (XSCVDPUXDS f64:$src), ixaddr:$dst)>;
3435   def : Pat<(PPCstore_scal_int_from_vsr
3436               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
3437             (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3438   def : Pat<(PPCstore_scal_int_from_vsr
3439               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
3440             (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3441
3442   // Round & Convert QP -> DP/SP
3443   def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>;
3444   def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
3445
3446   // Convert SP -> QP
3447   def : Pat<(f128 (fpextend f32:$src)),
3448             (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
3449
3450 } // end HasP9Vector, AddedComplexity
3451
3452 let AddedComplexity = 400 in {
3453   let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in {
3454     def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
3455               (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
3456   }
3457   let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in {
3458     def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
3459               (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
3460   }
3461 }
3462
3463 let Predicates = [HasP9Vector] in {
3464   let isPseudo = 1 in {
3465     let mayStore = 1 in {
3466       def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
3467                                             (ins spilltovsrrc:$XT, memrr:$dst),
3468                                             "#SPILLTOVSR_STX", []>;
3469       def SPILLTOVSR_ST : Pseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
3470                                 "#SPILLTOVSR_ST", []>;
3471     }
3472     let mayLoad = 1 in {
3473       def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
3474                                             (ins memrr:$src),
3475                                             "#SPILLTOVSR_LDX", []>;
3476       def SPILLTOVSR_LD : Pseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
3477                                 "#SPILLTOVSR_LD", []>;
3478
3479     }
3480   }
3481 }
3482 // Integer extend helper dags 32 -> 64
3483 def AnyExts {
3484   dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
3485   dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
3486   dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
3487   dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
3488 }
3489
3490 def DblToFlt {
3491   dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
3492   dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
3493   dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
3494   dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
3495 }
3496
3497 def ByteToWord {
3498   dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
3499   dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
3500   dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
3501   dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
3502   dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
3503   dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
3504   dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
3505   dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
3506 }
3507
3508 def ByteToDWord {
3509   dag LE_A0 = (i64 (sext_inreg
3510               (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
3511   dag LE_A1 = (i64 (sext_inreg
3512               (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
3513   dag BE_A0 = (i64 (sext_inreg
3514               (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
3515   dag BE_A1 = (i64 (sext_inreg
3516               (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
3517 }
3518
3519 def HWordToWord {
3520   dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
3521   dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
3522   dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
3523   dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
3524   dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
3525   dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
3526   dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
3527   dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
3528 }
3529
3530 def HWordToDWord {
3531   dag LE_A0 = (i64 (sext_inreg
3532               (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
3533   dag LE_A1 = (i64 (sext_inreg
3534               (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
3535   dag BE_A0 = (i64 (sext_inreg
3536               (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
3537   dag BE_A1 = (i64 (sext_inreg
3538               (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
3539 }
3540
3541 def WordToDWord {
3542   dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
3543   dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
3544   dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
3545   dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
3546 }
3547
3548 def FltToIntLoad {
3549   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
3550 }
3551 def FltToUIntLoad {
3552   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
3553 }
3554 def FltToLongLoad {
3555   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
3556 }
3557 def FltToLongLoadP9 {
3558   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ixaddr:$A)))));
3559 }
3560 def FltToULongLoad {
3561   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
3562 }
3563 def FltToULongLoadP9 {
3564   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ixaddr:$A)))));
3565 }
3566 def FltToLong {
3567   dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
3568 }
3569 def FltToULong {
3570   dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
3571 }
3572 def DblToInt {
3573   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
3574 }
3575 def DblToUInt {
3576   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
3577 }
3578 def DblToLong {
3579   dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
3580 }
3581 def DblToULong {
3582   dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
3583 }
3584 def DblToIntLoad {
3585   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
3586 }
3587 def DblToIntLoadP9 {
3588   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ixaddr:$A)))));
3589 }
3590 def DblToUIntLoad {
3591   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
3592 }
3593 def DblToUIntLoadP9 {
3594   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ixaddr:$A)))));
3595 }
3596 def DblToLongLoad {
3597   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
3598 }
3599 def DblToULongLoad {
3600   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
3601 }
3602
3603 // FP merge dags (for f32 -> v4f32)
3604 def MrgFP {
3605   dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
3606                                (COPY_TO_REGCLASS $C, VSRC), 0));
3607   dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
3608                                (COPY_TO_REGCLASS $D, VSRC), 0));
3609   dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
3610   dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
3611   dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
3612   dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
3613 }
3614
3615 // Patterns for BUILD_VECTOR nodes.
3616 let AddedComplexity = 400 in {
3617
3618   let Predicates = [HasVSX] in {
3619     // Build vectors of floating point converted to i32.
3620     def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
3621                                    DblToInt.A, DblToInt.A)),
3622               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
3623     def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
3624                                    DblToUInt.A, DblToUInt.A)),
3625               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
3626     def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
3627               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
3628                                (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
3629     def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
3630               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
3631                                (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
3632     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3633               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3634                                 (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3635     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3636               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3637                                 (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3638     def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
3639               (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
3640
3641     // Build vectors of floating point converted to i64.
3642     def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
3643               (v2i64 (XXPERMDIs
3644                        (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
3645     def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
3646               (v2i64 (XXPERMDIs
3647                        (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
3648     def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
3649               (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
3650     def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
3651               (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
3652   }
3653
3654   let Predicates = [HasVSX, NoP9Vector] in {
3655     // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
3656     def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
3657               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3658                                 (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3659     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
3660               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3661                                 (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3662     def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
3663               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3664                                               (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3665     def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
3666               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3667                                               (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3668   }
3669
3670   // Big endian, available on all targets with VSX
3671   let Predicates = [IsBigEndian, HasVSX] in {
3672     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
3673               (v2f64 (XXPERMDI
3674                         (COPY_TO_REGCLASS $A, VSRC),
3675                         (COPY_TO_REGCLASS $B, VSRC), 0))>;
3676
3677     def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
3678               (VMRGEW MrgFP.AC, MrgFP.BD)>;
3679     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
3680                                    DblToFlt.B0, DblToFlt.B1)),
3681               (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
3682   }
3683
3684   let Predicates = [IsLittleEndian, HasVSX] in {
3685   // Little endian, available on all targets with VSX
3686     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
3687               (v2f64 (XXPERMDI
3688                         (COPY_TO_REGCLASS $B, VSRC),
3689                         (COPY_TO_REGCLASS $A, VSRC), 0))>;
3690
3691     def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
3692               (VMRGEW MrgFP.AC, MrgFP.BD)>;
3693     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
3694                                    DblToFlt.B0, DblToFlt.B1)),
3695               (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
3696   }
3697
3698   let Predicates = [HasDirectMove] in {
3699     // Endianness-neutral constant splat on P8 and newer targets. The reason
3700     // for this pattern is that on targets with direct moves, we don't expand
3701     // BUILD_VECTOR nodes for v4i32.
3702     def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
3703                                    immSExt5NonZero:$A, immSExt5NonZero:$A)),
3704               (v4i32 (VSPLTISW imm:$A))>;
3705   }
3706
3707   let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
3708     // Big endian integer vectors using direct moves.
3709     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3710               (v2i64 (XXPERMDI
3711                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
3712                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
3713     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3714               (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC),
3715                                    (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 0),
3716                       (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC),
3717                                    (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 0))>;
3718     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3719               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3720   }
3721
3722   let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
3723     // Little endian integer vectors using direct moves.
3724     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3725               (v2i64 (XXPERMDI
3726                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
3727                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
3728     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3729               (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC),
3730                                    (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 0),
3731                       (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC),
3732                                    (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 0))>;
3733     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3734               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3735   }
3736
3737   let Predicates = [HasP9Vector] in {
3738     // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
3739     def : Pat<(v4i32 (scalar_to_vector i32:$A)),
3740               (v4i32 (MTVSRWS $A))>;
3741     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3742               (v4i32 (MTVSRWS $A))>;
3743     def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3744                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3745                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3746                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3747                                    immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3748                                    immAnyExt8:$A)),
3749               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
3750     def : Pat<(v16i8 immAllOnesV),
3751               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
3752     def : Pat<(v8i16 immAllOnesV),
3753               (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
3754     def : Pat<(v4i32 immAllOnesV),
3755               (v4i32 (XXSPLTIB 255))>;
3756     def : Pat<(v2i64 immAllOnesV),
3757               (v2i64 (XXSPLTIB 255))>;
3758     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3759               (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
3760     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3761               (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
3762     def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
3763               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3764                                 (XSCVDPSXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>;
3765     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
3766               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3767                                 (XSCVDPUXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>;
3768     def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
3769               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3770                                               (DFLOADf32 ixaddr:$A),
3771                                               VSFRC)), 0))>;
3772     def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
3773               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3774                                               (DFLOADf32 ixaddr:$A),
3775                                               VSFRC)), 0))>;
3776   }
3777
3778   let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
3779     def : Pat<(i64 (extractelt v2i64:$A, 1)),
3780               (i64 (MFVSRLD $A))>;
3781     // Better way to build integer vectors if we have MTVSRDD. Big endian.
3782     def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
3783               (v2i64 (MTVSRDD $rB, $rA))>;
3784     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3785               (VMRGOW
3786                 (v4i32 (COPY_TO_REGCLASS (MTVSRDD AnyExts.A, AnyExts.C), VSRC)),
3787                 (v4i32
3788                   (COPY_TO_REGCLASS (MTVSRDD AnyExts.B, AnyExts.D), VSRC)))>;
3789   }
3790
3791   let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
3792     def : Pat<(i64 (extractelt v2i64:$A, 0)),
3793               (i64 (MFVSRLD $A))>;
3794     // Better way to build integer vectors if we have MTVSRDD. Little endian.
3795     def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
3796               (v2i64 (MTVSRDD $rB, $rA))>;
3797     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3798               (VMRGOW
3799                 (v4i32 (COPY_TO_REGCLASS (MTVSRDD AnyExts.D, AnyExts.B), VSRC)),
3800                 (v4i32
3801                   (COPY_TO_REGCLASS (MTVSRDD AnyExts.C, AnyExts.A), VSRC)))>;
3802   }
3803   // P9 Altivec instructions that can be used to build vectors.
3804   // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
3805   // with complexities of existing build vector patterns in this file.
3806   let Predicates = [HasP9Altivec, IsLittleEndian] in {
3807     def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
3808               (v2i64 (VEXTSW2D $A))>;
3809     def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
3810               (v2i64 (VEXTSH2D $A))>;
3811     def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
3812                       HWordToWord.LE_A2, HWordToWord.LE_A3)),
3813               (v4i32 (VEXTSH2W $A))>;
3814     def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
3815                       ByteToWord.LE_A2, ByteToWord.LE_A3)),
3816               (v4i32 (VEXTSB2W $A))>;
3817     def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
3818               (v2i64 (VEXTSB2D $A))>;
3819   }
3820
3821   let Predicates = [HasP9Altivec, IsBigEndian] in {
3822     def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
3823               (v2i64 (VEXTSW2D $A))>;
3824     def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
3825               (v2i64 (VEXTSH2D $A))>;
3826     def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
3827                       HWordToWord.BE_A2, HWordToWord.BE_A3)),
3828               (v4i32 (VEXTSH2W $A))>;
3829     def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
3830                       ByteToWord.BE_A2, ByteToWord.BE_A3)),
3831               (v4i32 (VEXTSB2W $A))>;
3832     def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
3833               (v2i64 (VEXTSB2D $A))>;
3834   }
3835
3836   let Predicates = [HasP9Altivec] in {
3837     def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)),
3838               (v2i64 (VEXTSB2D $A))>;
3839     def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)),
3840               (v2i64 (VEXTSH2D $A))>;
3841     def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)),
3842               (v2i64 (VEXTSW2D $A))>;
3843     def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)),
3844               (v4i32 (VEXTSB2W $A))>;
3845     def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)),
3846               (v4i32 (VEXTSH2W $A))>;
3847   }
3848 }