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