[yaml2obj/obj2yaml] - Add support for .stack_sizes sections.
[llvm-complete.git] / lib / Target / PowerPC / PPCInstrVSX.td
blob910d98dc108c75eb0d18dd1211c1c42503d5894b
1 //===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===//
2 // 
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 // 
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the VSX extension to the PowerPC instruction set.
11 //===----------------------------------------------------------------------===//
13 // *********************************** NOTE ***********************************
14 // ** For POWER8 Little Endian, the VSX swap optimization relies on knowing  **
15 // ** which VMX and VSX instructions are lane-sensitive and which are not.   **
16 // ** A lane-sensitive instruction relies, implicitly or explicitly, on      **
17 // ** whether lanes are numbered from left to right.  An instruction like    **
18 // ** VADDFP is not lane-sensitive, because each lane of the result vector   **
19 // ** relies only on the corresponding lane of the source vectors.  However, **
20 // ** an instruction like VMULESB is lane-sensitive, because "even" and      **
21 // ** "odd" lanes are different for big-endian and little-endian numbering.  **
22 // **                                                                        **
23 // ** When adding new VMX and VSX instructions, please consider whether they **
24 // ** are lane-sensitive.  If so, they must be added to a switch statement   **
25 // ** in PPCVSXSwapRemoval::gatherVectorInstructions().                      **
26 // ****************************************************************************
28 def PPCRegVSRCAsmOperand : AsmOperandClass {
29   let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
31 def vsrc : RegisterOperand<VSRC> {
32   let ParserMatchClass = PPCRegVSRCAsmOperand;
35 def PPCRegVSFRCAsmOperand : AsmOperandClass {
36   let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
38 def vsfrc : RegisterOperand<VSFRC> {
39   let ParserMatchClass = PPCRegVSFRCAsmOperand;
42 def PPCRegVSSRCAsmOperand : AsmOperandClass {
43   let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
45 def vssrc : RegisterOperand<VSSRC> {
46   let ParserMatchClass = PPCRegVSSRCAsmOperand;
49 def PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass {
50   let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber";
53 def spilltovsrrc : RegisterOperand<SPILLTOVSRRC> {
54   let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand;
57 def SDT_PPCldvsxlh : SDTypeProfile<1, 1, [
58   SDTCisVT<0, v4f32>, SDTCisPtrTy<1>
59 ]>;
61 def SDT_PPCfpexth : SDTypeProfile<1, 2, [
62   SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>, SDTCisPtrTy<2>
63 ]>;
65 def SDT_PPCldsplat : SDTypeProfile<1, 1, [
66   SDTCisVec<0>, SDTCisPtrTy<1>
67 ]>;
69 // Little-endian-specific nodes.
70 def SDT_PPClxvd2x : SDTypeProfile<1, 1, [
71   SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
72 ]>;
73 def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
74   SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
75 ]>;
76 def SDT_PPCxxswapd : SDTypeProfile<1, 1, [
77   SDTCisSameAs<0, 1>
78 ]>;
79 def SDTVecConv : SDTypeProfile<1, 2, [
80   SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>
81 ]>;
82 def SDTVabsd : SDTypeProfile<1, 3, [
83   SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<3, i32>
84 ]>;
85 def SDT_PPCld_vec_be : SDTypeProfile<1, 1, [
86   SDTCisVec<0>, SDTCisPtrTy<1>
87 ]>;
88 def SDT_PPCst_vec_be : SDTypeProfile<0, 2, [
89   SDTCisVec<0>, SDTCisPtrTy<1>
90 ]>;
92 def PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
93                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
94 def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
95                         [SDNPHasChain, SDNPMayStore]>;
96 def PPCld_vec_be  : SDNode<"PPCISD::LOAD_VEC_BE", SDT_PPCld_vec_be,
97                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
98 def PPCst_vec_be : SDNode<"PPCISD::STORE_VEC_BE", SDT_PPCst_vec_be,
99                         [SDNPHasChain, SDNPMayStore]>;
100 def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
101 def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
102 def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
103 def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
104 def PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
105 def PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
106 def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
107 def PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>;
109 def PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>;
110 def PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
111                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
112 def PPCldsplat : SDNode<"PPCISD::LD_SPLAT", SDT_PPCldsplat,
113                         [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
115 multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
116                     string asmstr, InstrItinClass itin, Intrinsic Int,
117                     ValueType OutTy, ValueType InTy> {
118   let BaseName = asmbase in {
119     def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
120                        !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
121                        [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
122     let Defs = [CR6] in
123     def o    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
124                        !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
125                        [(set InTy:$XT,
126                                 (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>,
127                        isDOT;
128   }
131 // Instruction form with a single input register for instructions such as
132 // XXPERMDI. The reason for defining this is that specifying multiple chained
133 // operands (such as loads) to an instruction will perform both chained
134 // operations rather than coalescing them into a single register - even though
135 // the source memory location is the same. This simply forces the instruction
136 // to use the same register for both inputs.
137 // For example, an output DAG such as this:
138 //   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
139 // would result in two load instructions emitted and used as separate inputs
140 // to the XXPERMDI instruction.
141 class XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
142                  InstrItinClass itin, list<dag> pattern>
143   : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
144     let XB = XA;
147 def HasVSX : Predicate<"PPCSubTarget->hasVSX()">;
148 def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">;
149 def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">;
150 def HasOnlySwappingMemOps : Predicate<"!PPCSubTarget->hasP9Vector()">;
152 let Predicates = [HasVSX] in {
153 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
154 let hasSideEffects = 0 in { // VSX instructions don't have side effects.
155 let Uses = [RM] in {
157   // Load indexed instructions
158   let mayLoad = 1, mayStore = 0 in {
159     let CodeSize = 3 in
160     def LXSDX : XX1Form_memOp<31, 588,
161                         (outs vsfrc:$XT), (ins memrr:$src),
162                         "lxsdx $XT, $src", IIC_LdStLFD,
163                         []>;
165     // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
166     let CodeSize = 3 in
167       def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
168                               "#XFLOADf64",
169                               [(set f64:$XT, (load xoaddr:$src))]>;
171     let Predicates = [HasVSX, HasOnlySwappingMemOps] in
172     def LXVD2X : XX1Form_memOp<31, 844,
173                          (outs vsrc:$XT), (ins memrr:$src),
174                          "lxvd2x $XT, $src", IIC_LdStLFD,
175                          [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
177     def LXVDSX : XX1Form_memOp<31, 332,
178                          (outs vsrc:$XT), (ins memrr:$src),
179                          "lxvdsx $XT, $src", IIC_LdStLFD, []>;
181     let Predicates = [HasVSX, HasOnlySwappingMemOps] in
182     def LXVW4X : XX1Form_memOp<31, 780,
183                          (outs vsrc:$XT), (ins memrr:$src),
184                          "lxvw4x $XT, $src", IIC_LdStLFD,
185                          []>;
186   } // mayLoad
188   // Store indexed instructions
189   let mayStore = 1, mayLoad = 0 in {
190     let CodeSize = 3 in
191     def STXSDX : XX1Form_memOp<31, 716,
192                         (outs), (ins vsfrc:$XT, memrr:$dst),
193                         "stxsdx $XT, $dst", IIC_LdStSTFD,
194                         []>;
196     // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
197     let CodeSize = 3 in
198       def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
199                               "#XFSTOREf64",
200                               [(store f64:$XT, xoaddr:$dst)]>;
202     let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
203     // The behaviour of this instruction is endianness-specific so we provide no
204     // pattern to match it without considering endianness.
205     def STXVD2X : XX1Form_memOp<31, 972,
206                          (outs), (ins vsrc:$XT, memrr:$dst),
207                          "stxvd2x $XT, $dst", IIC_LdStSTFD,
208                          []>;
210     def STXVW4X : XX1Form_memOp<31, 908,
211                          (outs), (ins vsrc:$XT, memrr:$dst),
212                          "stxvw4x $XT, $dst", IIC_LdStSTFD,
213                          []>;
214     }
215   } // mayStore
217   // Add/Mul Instructions
218   let isCommutable = 1 in {
219     def XSADDDP : XX3Form<60, 32,
220                           (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
221                           "xsadddp $XT, $XA, $XB", IIC_VecFP,
222                           [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>;
223     def XSMULDP : XX3Form<60, 48,
224                           (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
225                           "xsmuldp $XT, $XA, $XB", IIC_VecFP,
226                           [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>;
228     def XVADDDP : XX3Form<60, 96,
229                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
230                           "xvadddp $XT, $XA, $XB", IIC_VecFP,
231                           [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>;
233     def XVADDSP : XX3Form<60, 64,
234                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
235                           "xvaddsp $XT, $XA, $XB", IIC_VecFP,
236                           [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>;
238     def XVMULDP : XX3Form<60, 112,
239                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
240                           "xvmuldp $XT, $XA, $XB", IIC_VecFP,
241                           [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>;
243     def XVMULSP : XX3Form<60, 80,
244                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
245                           "xvmulsp $XT, $XA, $XB", IIC_VecFP,
246                           [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>;
247   }
249   // Subtract Instructions
250   def XSSUBDP : XX3Form<60, 40,
251                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
252                         "xssubdp $XT, $XA, $XB", IIC_VecFP,
253                         [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>;
255   def XVSUBDP : XX3Form<60, 104,
256                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
257                         "xvsubdp $XT, $XA, $XB", IIC_VecFP,
258                         [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>;
259   def XVSUBSP : XX3Form<60, 72,
260                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
261                         "xvsubsp $XT, $XA, $XB", IIC_VecFP,
262                         [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>;
264   // FMA Instructions
265   let BaseName = "XSMADDADP" in {
266   let isCommutable = 1 in
267   def XSMADDADP : XX3Form<60, 33,
268                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
269                           "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
270                           [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>,
271                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
272                           AltVSXFMARel;
273   let IsVSXFMAAlt = 1 in
274   def XSMADDMDP : XX3Form<60, 41,
275                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
276                           "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
277                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
278                           AltVSXFMARel;
279   }
281   let BaseName = "XSMSUBADP" in {
282   let isCommutable = 1 in
283   def XSMSUBADP : XX3Form<60, 49,
284                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
285                           "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
286                           [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
287                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
288                           AltVSXFMARel;
289   let IsVSXFMAAlt = 1 in
290   def XSMSUBMDP : XX3Form<60, 57,
291                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
292                           "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
293                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
294                           AltVSXFMARel;
295   }
297   let BaseName = "XSNMADDADP" in {
298   let isCommutable = 1 in
299   def XSNMADDADP : XX3Form<60, 161,
300                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
301                           "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
302                           [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>,
303                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
304                           AltVSXFMARel;
305   let IsVSXFMAAlt = 1 in
306   def XSNMADDMDP : XX3Form<60, 169,
307                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
308                           "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
309                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
310                           AltVSXFMARel;
311   }
313   let BaseName = "XSNMSUBADP" in {
314   let isCommutable = 1 in
315   def XSNMSUBADP : XX3Form<60, 177,
316                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
317                           "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
318                           [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
319                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
320                           AltVSXFMARel;
321   let IsVSXFMAAlt = 1 in
322   def XSNMSUBMDP : XX3Form<60, 185,
323                           (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
324                           "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
325                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
326                           AltVSXFMARel;
327   }
329   let BaseName = "XVMADDADP" in {
330   let isCommutable = 1 in
331   def XVMADDADP : XX3Form<60, 97,
332                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
333                           "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
334                           [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
335                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
336                           AltVSXFMARel;
337   let IsVSXFMAAlt = 1 in
338   def XVMADDMDP : XX3Form<60, 105,
339                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
340                           "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
341                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
342                           AltVSXFMARel;
343   }
345   let BaseName = "XVMADDASP" in {
346   let isCommutable = 1 in
347   def XVMADDASP : XX3Form<60, 65,
348                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
349                           "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
350                           [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
351                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
352                           AltVSXFMARel;
353   let IsVSXFMAAlt = 1 in
354   def XVMADDMSP : XX3Form<60, 73,
355                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
356                           "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
357                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
358                           AltVSXFMARel;
359   }
361   let BaseName = "XVMSUBADP" in {
362   let isCommutable = 1 in
363   def XVMSUBADP : XX3Form<60, 113,
364                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
365                           "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
366                           [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
367                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
368                           AltVSXFMARel;
369   let IsVSXFMAAlt = 1 in
370   def XVMSUBMDP : XX3Form<60, 121,
371                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
372                           "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
373                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
374                           AltVSXFMARel;
375   }
377   let BaseName = "XVMSUBASP" in {
378   let isCommutable = 1 in
379   def XVMSUBASP : XX3Form<60, 81,
380                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
381                           "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
382                           [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
383                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
384                           AltVSXFMARel;
385   let IsVSXFMAAlt = 1 in
386   def XVMSUBMSP : XX3Form<60, 89,
387                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
388                           "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
389                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
390                           AltVSXFMARel;
391   }
393   let BaseName = "XVNMADDADP" in {
394   let isCommutable = 1 in
395   def XVNMADDADP : XX3Form<60, 225,
396                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
397                           "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
398                           [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
399                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
400                           AltVSXFMARel;
401   let IsVSXFMAAlt = 1 in
402   def XVNMADDMDP : XX3Form<60, 233,
403                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
404                           "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
405                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
406                           AltVSXFMARel;
407   }
409   let BaseName = "XVNMADDASP" in {
410   let isCommutable = 1 in
411   def XVNMADDASP : XX3Form<60, 193,
412                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
413                           "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
414                           [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
415                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
416                           AltVSXFMARel;
417   let IsVSXFMAAlt = 1 in
418   def XVNMADDMSP : XX3Form<60, 201,
419                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
420                           "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
421                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
422                           AltVSXFMARel;
423   }
425   let BaseName = "XVNMSUBADP" in {
426   let isCommutable = 1 in
427   def XVNMSUBADP : XX3Form<60, 241,
428                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
429                           "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
430                           [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
431                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
432                           AltVSXFMARel;
433   let IsVSXFMAAlt = 1 in
434   def XVNMSUBMDP : XX3Form<60, 249,
435                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
436                           "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
437                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
438                           AltVSXFMARel;
439   }
441   let BaseName = "XVNMSUBASP" in {
442   let isCommutable = 1 in
443   def XVNMSUBASP : XX3Form<60, 209,
444                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
445                           "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
446                           [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
447                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
448                           AltVSXFMARel;
449   let IsVSXFMAAlt = 1 in
450   def XVNMSUBMSP : XX3Form<60, 217,
451                           (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
452                           "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
453                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
454                           AltVSXFMARel;
455   }
457   // Division Instructions
458   def XSDIVDP : XX3Form<60, 56,
459                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
460                         "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
461                         [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>;
462   def XSSQRTDP : XX2Form<60, 75,
463                         (outs vsfrc:$XT), (ins vsfrc:$XB),
464                         "xssqrtdp $XT, $XB", IIC_FPSqrtD,
465                         [(set f64:$XT, (fsqrt f64:$XB))]>;
467   def XSREDP : XX2Form<60, 90,
468                         (outs vsfrc:$XT), (ins vsfrc:$XB),
469                         "xsredp $XT, $XB", IIC_VecFP,
470                         [(set f64:$XT, (PPCfre f64:$XB))]>;
471   def XSRSQRTEDP : XX2Form<60, 74,
472                            (outs vsfrc:$XT), (ins vsfrc:$XB),
473                            "xsrsqrtedp $XT, $XB", IIC_VecFP,
474                            [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
476   def XSTDIVDP : XX3Form_1<60, 61,
477                          (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
478                          "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
479   def XSTSQRTDP : XX2Form_1<60, 106,
480                           (outs crrc:$crD), (ins vsfrc:$XB),
481                           "xstsqrtdp $crD, $XB", IIC_FPCompare, []>;
483   def XVDIVDP : XX3Form<60, 120,
484                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
485                         "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
486                         [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>;
487   def XVDIVSP : XX3Form<60, 88,
488                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
489                         "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
490                         [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>;
492   def XVSQRTDP : XX2Form<60, 203,
493                         (outs vsrc:$XT), (ins vsrc:$XB),
494                         "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
495                         [(set v2f64:$XT, (fsqrt v2f64:$XB))]>;
496   def XVSQRTSP : XX2Form<60, 139,
497                         (outs vsrc:$XT), (ins vsrc:$XB),
498                         "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
499                         [(set v4f32:$XT, (fsqrt v4f32:$XB))]>;
501   def XVTDIVDP : XX3Form_1<60, 125,
502                          (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
503                          "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
504   def XVTDIVSP : XX3Form_1<60, 93,
505                          (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
506                          "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
508   def XVTSQRTDP : XX2Form_1<60, 234,
509                           (outs crrc:$crD), (ins vsrc:$XB),
510                           "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
511   def XVTSQRTSP : XX2Form_1<60, 170,
512                           (outs crrc:$crD), (ins vsrc:$XB),
513                           "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
515   def XVREDP : XX2Form<60, 218,
516                         (outs vsrc:$XT), (ins vsrc:$XB),
517                         "xvredp $XT, $XB", IIC_VecFP,
518                         [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
519   def XVRESP : XX2Form<60, 154,
520                         (outs vsrc:$XT), (ins vsrc:$XB),
521                         "xvresp $XT, $XB", IIC_VecFP,
522                         [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
524   def XVRSQRTEDP : XX2Form<60, 202,
525                            (outs vsrc:$XT), (ins vsrc:$XB),
526                            "xvrsqrtedp $XT, $XB", IIC_VecFP,
527                            [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
528   def XVRSQRTESP : XX2Form<60, 138,
529                            (outs vsrc:$XT), (ins vsrc:$XB),
530                            "xvrsqrtesp $XT, $XB", IIC_VecFP,
531                            [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
533   // Compare Instructions
534   def XSCMPODP : XX3Form_1<60, 43,
535                            (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
536                            "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
537   def XSCMPUDP : XX3Form_1<60, 35,
538                            (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
539                            "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
541   defm XVCMPEQDP : XX3Form_Rcr<60, 99,
542                              "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
543                              int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
544   defm XVCMPEQSP : XX3Form_Rcr<60, 67,
545                              "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
546                              int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
547   defm XVCMPGEDP : XX3Form_Rcr<60, 115,
548                              "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
549                              int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
550   defm XVCMPGESP : XX3Form_Rcr<60, 83,
551                              "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
552                              int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
553   defm XVCMPGTDP : XX3Form_Rcr<60, 107,
554                              "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
555                              int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
556   defm XVCMPGTSP : XX3Form_Rcr<60, 75,
557                              "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
558                              int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
560   // Move Instructions
561   def XSABSDP : XX2Form<60, 345,
562                       (outs vsfrc:$XT), (ins vsfrc:$XB),
563                       "xsabsdp $XT, $XB", IIC_VecFP,
564                       [(set f64:$XT, (fabs f64:$XB))]>;
565   def XSNABSDP : XX2Form<60, 361,
566                       (outs vsfrc:$XT), (ins vsfrc:$XB),
567                       "xsnabsdp $XT, $XB", IIC_VecFP,
568                       [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
569   def XSNEGDP : XX2Form<60, 377,
570                       (outs vsfrc:$XT), (ins vsfrc:$XB),
571                       "xsnegdp $XT, $XB", IIC_VecFP,
572                       [(set f64:$XT, (fneg f64:$XB))]>;
573   def XSCPSGNDP : XX3Form<60, 176,
574                       (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
575                       "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
576                       [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
578   def XVABSDP : XX2Form<60, 473,
579                       (outs vsrc:$XT), (ins vsrc:$XB),
580                       "xvabsdp $XT, $XB", IIC_VecFP,
581                       [(set v2f64:$XT, (fabs v2f64:$XB))]>;
583   def XVABSSP : XX2Form<60, 409,
584                       (outs vsrc:$XT), (ins vsrc:$XB),
585                       "xvabssp $XT, $XB", IIC_VecFP,
586                       [(set v4f32:$XT, (fabs v4f32:$XB))]>;
588   def XVCPSGNDP : XX3Form<60, 240,
589                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
590                       "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
591                       [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
592   def XVCPSGNSP : XX3Form<60, 208,
593                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
594                       "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
595                       [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
597   def XVNABSDP : XX2Form<60, 489,
598                       (outs vsrc:$XT), (ins vsrc:$XB),
599                       "xvnabsdp $XT, $XB", IIC_VecFP,
600                       [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
601   def XVNABSSP : XX2Form<60, 425,
602                       (outs vsrc:$XT), (ins vsrc:$XB),
603                       "xvnabssp $XT, $XB", IIC_VecFP,
604                       [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
606   def XVNEGDP : XX2Form<60, 505,
607                       (outs vsrc:$XT), (ins vsrc:$XB),
608                       "xvnegdp $XT, $XB", IIC_VecFP,
609                       [(set v2f64:$XT, (fneg v2f64:$XB))]>;
610   def XVNEGSP : XX2Form<60, 441,
611                       (outs vsrc:$XT), (ins vsrc:$XB),
612                       "xvnegsp $XT, $XB", IIC_VecFP,
613                       [(set v4f32:$XT, (fneg v4f32:$XB))]>;
615   // Conversion Instructions
616   def XSCVDPSP : XX2Form<60, 265,
617                       (outs vsfrc:$XT), (ins vsfrc:$XB),
618                       "xscvdpsp $XT, $XB", IIC_VecFP, []>;
619   def XSCVDPSXDS : XX2Form<60, 344,
620                       (outs vsfrc:$XT), (ins vsfrc:$XB),
621                       "xscvdpsxds $XT, $XB", IIC_VecFP,
622                       [(set f64:$XT, (PPCfctidz f64:$XB))]>;
623   let isCodeGenOnly = 1 in
624   def XSCVDPSXDSs : XX2Form<60, 344,
625                       (outs vssrc:$XT), (ins vssrc:$XB),
626                       "xscvdpsxds $XT, $XB", IIC_VecFP,
627                       [(set f32:$XT, (PPCfctidz f32:$XB))]>;
628   def XSCVDPSXWS : XX2Form<60, 88,
629                       (outs vsfrc:$XT), (ins vsfrc:$XB),
630                       "xscvdpsxws $XT, $XB", IIC_VecFP,
631                       [(set f64:$XT, (PPCfctiwz f64:$XB))]>;
632   let isCodeGenOnly = 1 in
633   def XSCVDPSXWSs : XX2Form<60, 88,
634                       (outs vssrc:$XT), (ins vssrc:$XB),
635                       "xscvdpsxws $XT, $XB", IIC_VecFP,
636                       [(set f32:$XT, (PPCfctiwz f32:$XB))]>;
637   def XSCVDPUXDS : XX2Form<60, 328,
638                       (outs vsfrc:$XT), (ins vsfrc:$XB),
639                       "xscvdpuxds $XT, $XB", IIC_VecFP,
640                       [(set f64:$XT, (PPCfctiduz f64:$XB))]>;
641   let isCodeGenOnly = 1 in
642   def XSCVDPUXDSs : XX2Form<60, 328,
643                       (outs vssrc:$XT), (ins vssrc:$XB),
644                       "xscvdpuxds $XT, $XB", IIC_VecFP,
645                       [(set f32:$XT, (PPCfctiduz f32:$XB))]>;
646   def XSCVDPUXWS : XX2Form<60, 72,
647                       (outs vsfrc:$XT), (ins vsfrc:$XB),
648                       "xscvdpuxws $XT, $XB", IIC_VecFP,
649                       [(set f64:$XT, (PPCfctiwuz f64:$XB))]>;
650   let isCodeGenOnly = 1 in
651   def XSCVDPUXWSs : XX2Form<60, 72,
652                       (outs vssrc:$XT), (ins vssrc:$XB),
653                       "xscvdpuxws $XT, $XB", IIC_VecFP,
654                       [(set f32:$XT, (PPCfctiwuz f32:$XB))]>;
655   def XSCVSPDP : XX2Form<60, 329,
656                       (outs vsfrc:$XT), (ins vsfrc:$XB),
657                       "xscvspdp $XT, $XB", IIC_VecFP, []>;
658   def XSCVSXDDP : XX2Form<60, 376,
659                       (outs vsfrc:$XT), (ins vsfrc:$XB),
660                       "xscvsxddp $XT, $XB", IIC_VecFP,
661                       [(set f64:$XT, (PPCfcfid f64:$XB))]>;
662   def XSCVUXDDP : XX2Form<60, 360,
663                       (outs vsfrc:$XT), (ins vsfrc:$XB),
664                       "xscvuxddp $XT, $XB", IIC_VecFP,
665                       [(set f64:$XT, (PPCfcfidu f64:$XB))]>;
667   def XVCVDPSP : XX2Form<60, 393,
668                       (outs vsrc:$XT), (ins vsrc:$XB),
669                       "xvcvdpsp $XT, $XB", IIC_VecFP,
670                       [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
671   def XVCVDPSXDS : XX2Form<60, 472,
672                       (outs vsrc:$XT), (ins vsrc:$XB),
673                       "xvcvdpsxds $XT, $XB", IIC_VecFP,
674                       [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>;
675   def XVCVDPSXWS : XX2Form<60, 216,
676                       (outs vsrc:$XT), (ins vsrc:$XB),
677                       "xvcvdpsxws $XT, $XB", IIC_VecFP,
678                       [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
679   def XVCVDPUXDS : XX2Form<60, 456,
680                       (outs vsrc:$XT), (ins vsrc:$XB),
681                       "xvcvdpuxds $XT, $XB", IIC_VecFP,
682                       [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>;
683   def XVCVDPUXWS : XX2Form<60, 200,
684                       (outs vsrc:$XT), (ins vsrc:$XB),
685                       "xvcvdpuxws $XT, $XB", IIC_VecFP,
686                       [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
688   def XVCVSPDP : XX2Form<60, 457,
689                       (outs vsrc:$XT), (ins vsrc:$XB),
690                       "xvcvspdp $XT, $XB", IIC_VecFP,
691                       [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
692   def XVCVSPSXDS : XX2Form<60, 408,
693                       (outs vsrc:$XT), (ins vsrc:$XB),
694                       "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
695   def XVCVSPSXWS : XX2Form<60, 152,
696                       (outs vsrc:$XT), (ins vsrc:$XB),
697                       "xvcvspsxws $XT, $XB", IIC_VecFP,
698                       [(set v4i32:$XT, (fp_to_sint v4f32:$XB))]>;
699   def XVCVSPUXDS : XX2Form<60, 392,
700                       (outs vsrc:$XT), (ins vsrc:$XB),
701                       "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
702   def XVCVSPUXWS : XX2Form<60, 136,
703                       (outs vsrc:$XT), (ins vsrc:$XB),
704                       "xvcvspuxws $XT, $XB", IIC_VecFP,
705                       [(set v4i32:$XT, (fp_to_uint v4f32:$XB))]>;
706   def XVCVSXDDP : XX2Form<60, 504,
707                       (outs vsrc:$XT), (ins vsrc:$XB),
708                       "xvcvsxddp $XT, $XB", IIC_VecFP,
709                       [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>;
710   def XVCVSXDSP : XX2Form<60, 440,
711                       (outs vsrc:$XT), (ins vsrc:$XB),
712                       "xvcvsxdsp $XT, $XB", IIC_VecFP,
713                       [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
714   def XVCVSXWDP : XX2Form<60, 248,
715                       (outs vsrc:$XT), (ins vsrc:$XB),
716                       "xvcvsxwdp $XT, $XB", IIC_VecFP,
717                       [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
718   def XVCVSXWSP : XX2Form<60, 184,
719                       (outs vsrc:$XT), (ins vsrc:$XB),
720                       "xvcvsxwsp $XT, $XB", IIC_VecFP,
721                       [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>;
722   def XVCVUXDDP : XX2Form<60, 488,
723                       (outs vsrc:$XT), (ins vsrc:$XB),
724                       "xvcvuxddp $XT, $XB", IIC_VecFP,
725                       [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>;
726   def XVCVUXDSP : XX2Form<60, 424,
727                       (outs vsrc:$XT), (ins vsrc:$XB),
728                       "xvcvuxdsp $XT, $XB", IIC_VecFP,
729                       [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
730   def XVCVUXWDP : XX2Form<60, 232,
731                       (outs vsrc:$XT), (ins vsrc:$XB),
732                       "xvcvuxwdp $XT, $XB", IIC_VecFP,
733                       [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
734   def XVCVUXWSP : XX2Form<60, 168,
735                       (outs vsrc:$XT), (ins vsrc:$XB),
736                       "xvcvuxwsp $XT, $XB", IIC_VecFP,
737                       [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>;
739   // Rounding Instructions
740   def XSRDPI : XX2Form<60, 73,
741                       (outs vsfrc:$XT), (ins vsfrc:$XB),
742                       "xsrdpi $XT, $XB", IIC_VecFP,
743                       [(set f64:$XT, (fround f64:$XB))]>;
744   def XSRDPIC : XX2Form<60, 107,
745                       (outs vsfrc:$XT), (ins vsfrc:$XB),
746                       "xsrdpic $XT, $XB", IIC_VecFP,
747                       [(set f64:$XT, (fnearbyint f64:$XB))]>;
748   def XSRDPIM : XX2Form<60, 121,
749                       (outs vsfrc:$XT), (ins vsfrc:$XB),
750                       "xsrdpim $XT, $XB", IIC_VecFP,
751                       [(set f64:$XT, (ffloor f64:$XB))]>;
752   def XSRDPIP : XX2Form<60, 105,
753                       (outs vsfrc:$XT), (ins vsfrc:$XB),
754                       "xsrdpip $XT, $XB", IIC_VecFP,
755                       [(set f64:$XT, (fceil f64:$XB))]>;
756   def XSRDPIZ : XX2Form<60, 89,
757                       (outs vsfrc:$XT), (ins vsfrc:$XB),
758                       "xsrdpiz $XT, $XB", IIC_VecFP,
759                       [(set f64:$XT, (ftrunc f64:$XB))]>;
761   def XVRDPI : XX2Form<60, 201,
762                       (outs vsrc:$XT), (ins vsrc:$XB),
763                       "xvrdpi $XT, $XB", IIC_VecFP,
764                       [(set v2f64:$XT, (fround v2f64:$XB))]>;
765   def XVRDPIC : XX2Form<60, 235,
766                       (outs vsrc:$XT), (ins vsrc:$XB),
767                       "xvrdpic $XT, $XB", IIC_VecFP,
768                       [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
769   def XVRDPIM : XX2Form<60, 249,
770                       (outs vsrc:$XT), (ins vsrc:$XB),
771                       "xvrdpim $XT, $XB", IIC_VecFP,
772                       [(set v2f64:$XT, (ffloor v2f64:$XB))]>;
773   def XVRDPIP : XX2Form<60, 233,
774                       (outs vsrc:$XT), (ins vsrc:$XB),
775                       "xvrdpip $XT, $XB", IIC_VecFP,
776                       [(set v2f64:$XT, (fceil v2f64:$XB))]>;
777   def XVRDPIZ : XX2Form<60, 217,
778                       (outs vsrc:$XT), (ins vsrc:$XB),
779                       "xvrdpiz $XT, $XB", IIC_VecFP,
780                       [(set v2f64:$XT, (ftrunc v2f64:$XB))]>;
782   def XVRSPI : XX2Form<60, 137,
783                       (outs vsrc:$XT), (ins vsrc:$XB),
784                       "xvrspi $XT, $XB", IIC_VecFP,
785                       [(set v4f32:$XT, (fround v4f32:$XB))]>;
786   def XVRSPIC : XX2Form<60, 171,
787                       (outs vsrc:$XT), (ins vsrc:$XB),
788                       "xvrspic $XT, $XB", IIC_VecFP,
789                       [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
790   def XVRSPIM : XX2Form<60, 185,
791                       (outs vsrc:$XT), (ins vsrc:$XB),
792                       "xvrspim $XT, $XB", IIC_VecFP,
793                       [(set v4f32:$XT, (ffloor v4f32:$XB))]>;
794   def XVRSPIP : XX2Form<60, 169,
795                       (outs vsrc:$XT), (ins vsrc:$XB),
796                       "xvrspip $XT, $XB", IIC_VecFP,
797                       [(set v4f32:$XT, (fceil v4f32:$XB))]>;
798   def XVRSPIZ : XX2Form<60, 153,
799                       (outs vsrc:$XT), (ins vsrc:$XB),
800                       "xvrspiz $XT, $XB", IIC_VecFP,
801                       [(set v4f32:$XT, (ftrunc v4f32:$XB))]>;
803   // Max/Min Instructions
804   let isCommutable = 1 in {
805   def XSMAXDP : XX3Form<60, 160,
806                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
807                         "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
808                         [(set vsfrc:$XT,
809                               (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
810   def XSMINDP : XX3Form<60, 168,
811                         (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
812                         "xsmindp $XT, $XA, $XB", IIC_VecFP,
813                         [(set vsfrc:$XT,
814                               (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
816   def XVMAXDP : XX3Form<60, 224,
817                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
818                         "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
819                         [(set vsrc:$XT,
820                               (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
821   def XVMINDP : XX3Form<60, 232,
822                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
823                         "xvmindp $XT, $XA, $XB", IIC_VecFP,
824                         [(set vsrc:$XT,
825                               (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
827   def XVMAXSP : XX3Form<60, 192,
828                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
829                         "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
830                         [(set vsrc:$XT,
831                               (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
832   def XVMINSP : XX3Form<60, 200,
833                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
834                         "xvminsp $XT, $XA, $XB", IIC_VecFP,
835                         [(set vsrc:$XT,
836                               (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
837   } // isCommutable
838 } // Uses = [RM]
840   // Logical Instructions
841   let isCommutable = 1 in
842   def XXLAND : XX3Form<60, 130,
843                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
844                        "xxland $XT, $XA, $XB", IIC_VecGeneral,
845                        [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
846   def XXLANDC : XX3Form<60, 138,
847                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
848                         "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
849                         [(set v4i32:$XT, (and v4i32:$XA,
850                                               (vnot_ppc v4i32:$XB)))]>;
851   let isCommutable = 1 in {
852   def XXLNOR : XX3Form<60, 162,
853                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
854                        "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
855                        [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
856                                                    v4i32:$XB)))]>;
857   def XXLOR : XX3Form<60, 146,
858                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
859                       "xxlor $XT, $XA, $XB", IIC_VecGeneral,
860                       [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
861   let isCodeGenOnly = 1 in
862   def XXLORf: XX3Form<60, 146,
863                       (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
864                       "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
865   def XXLXOR : XX3Form<60, 154,
866                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
867                        "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
868                        [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
869   } // isCommutable
871   let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
872       isReMaterializable = 1 in {
873     def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
874                        "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
875                        [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
876     def XXLXORdpz : XX3Form_SameOp<60, 154,
877                          (outs vsfrc:$XT), (ins),
878                          "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
879                          [(set f64:$XT, (fpimm0))]>;
880     def XXLXORspz : XX3Form_SameOp<60, 154,
881                          (outs vssrc:$XT), (ins),
882                          "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
883                          [(set f32:$XT, (fpimm0))]>;
884   }
886   // Permutation Instructions
887   def XXMRGHW : XX3Form<60, 18,
888                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
889                        "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
890   def XXMRGLW : XX3Form<60, 50,
891                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
892                        "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
894   def XXPERMDI : XX3Form_2<60, 10,
895                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
896                        "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
897                        [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
898                          imm32SExt16:$DM))]>;
899   let isCodeGenOnly = 1 in
900   def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
901                              "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
902   def XXSEL : XX4Form<60, 3,
903                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
904                       "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
906   def XXSLDWI : XX3Form_2<60, 2,
907                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
908                        "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
909                        [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
910                                                   imm32SExt16:$SHW))]>;
912   let isCodeGenOnly = 1 in
913   def XXSLDWIs : XX3Form_2s<60, 2,
914                        (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
915                        "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
917   def XXSPLTW : XX2Form_2<60, 164,
918                        (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
919                        "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
920                        [(set v4i32:$XT,
921                              (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
922   let isCodeGenOnly = 1 in
923   def XXSPLTWs : XX2Form_2<60, 164,
924                        (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
925                        "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
927 } // hasSideEffects
929 // SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
930 // instruction selection into a branch sequence.
931 let PPC970_Single = 1 in {
933   def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
934                              (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
935                              "#SELECT_CC_VSRC",
936                              []>;
937   def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
938                           (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
939                           "#SELECT_VSRC",
940                           [(set v2f64:$dst,
941                                 (select i1:$cond, v2f64:$T, v2f64:$F))]>;
942   def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
943                               (ins crrc:$cond, f8rc:$T, f8rc:$F,
944                                i32imm:$BROPC), "#SELECT_CC_VSFRC",
945                               []>;
946   def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
947                            (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
948                            "#SELECT_VSFRC",
949                            [(set f64:$dst,
950                                  (select i1:$cond, f64:$T, f64:$F))]>;
951   def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
952                               (ins crrc:$cond, f4rc:$T, f4rc:$F,
953                                i32imm:$BROPC), "#SELECT_CC_VSSRC",
954                               []>;
955   def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
956                            (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
957                            "#SELECT_VSSRC",
958                            [(set f32:$dst,
959                                  (select i1:$cond, f32:$T, f32:$F))]>;
961 } // AddedComplexity
963 def : InstAlias<"xvmovdp $XT, $XB",
964                 (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
965 def : InstAlias<"xvmovsp $XT, $XB",
966                 (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
968 def : InstAlias<"xxspltd $XT, $XB, 0",
969                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
970 def : InstAlias<"xxspltd $XT, $XB, 1",
971                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
972 def : InstAlias<"xxmrghd $XT, $XA, $XB",
973                 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
974 def : InstAlias<"xxmrgld $XT, $XA, $XB",
975                 (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
976 def : InstAlias<"xxswapd $XT, $XB",
977                 (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
978 def : InstAlias<"xxspltd $XT, $XB, 0",
979                 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
980 def : InstAlias<"xxspltd $XT, $XB, 1",
981                 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
982 def : InstAlias<"xxswapd $XT, $XB",
983                 (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
985 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
987 def : Pat<(v4i32 (vnot_ppc v4i32:$A)),
988           (v4i32 (XXLNOR $A, $A))>;
989 def : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A),
990                      (and v4i32:$B, v4i32:$C))),
991           (v4i32 (XXSEL $A, $B, $C))>;
993 let Predicates = [IsBigEndian] in {
994 def : Pat<(v2f64 (scalar_to_vector f64:$A)),
995           (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
997 def : Pat<(f64 (extractelt v2f64:$S, 0)),
998           (f64 (EXTRACT_SUBREG $S, sub_64))>;
999 def : Pat<(f64 (extractelt v2f64:$S, 1)),
1000           (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
1003 let Predicates = [IsLittleEndian] in {
1004 def : Pat<(v2f64 (scalar_to_vector f64:$A)),
1005           (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
1006                            (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
1008 def : Pat<(f64 (extractelt v2f64:$S, 0)),
1009           (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
1010 def : Pat<(f64 (extractelt v2f64:$S, 1)),
1011           (f64 (EXTRACT_SUBREG $S, sub_64))>;
1014 // Additional fnmsub patterns: -a*c + b == -(a*c - b)
1015 def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
1016           (XSNMSUBADP $B, $C, $A)>;
1017 def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B),
1018           (XSNMSUBADP $B, $C, $A)>;
1020 def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B),
1021           (XVNMSUBADP $B, $C, $A)>;
1022 def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B),
1023           (XVNMSUBADP $B, $C, $A)>;
1025 def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B),
1026           (XVNMSUBASP $B, $C, $A)>;
1027 def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B),
1028           (XVNMSUBASP $B, $C, $A)>;
1030 def : Pat<(v2f64 (bitconvert v4f32:$A)),
1031           (COPY_TO_REGCLASS $A, VSRC)>;
1032 def : Pat<(v2f64 (bitconvert v4i32:$A)),
1033           (COPY_TO_REGCLASS $A, VSRC)>;
1034 def : Pat<(v2f64 (bitconvert v8i16:$A)),
1035           (COPY_TO_REGCLASS $A, VSRC)>;
1036 def : Pat<(v2f64 (bitconvert v16i8:$A)),
1037           (COPY_TO_REGCLASS $A, VSRC)>;
1039 def : Pat<(v4f32 (bitconvert v2f64:$A)),
1040           (COPY_TO_REGCLASS $A, VRRC)>;
1041 def : Pat<(v4i32 (bitconvert v2f64:$A)),
1042           (COPY_TO_REGCLASS $A, VRRC)>;
1043 def : Pat<(v8i16 (bitconvert v2f64:$A)),
1044           (COPY_TO_REGCLASS $A, VRRC)>;
1045 def : Pat<(v16i8 (bitconvert v2f64:$A)),
1046           (COPY_TO_REGCLASS $A, VRRC)>;
1048 def : Pat<(v2i64 (bitconvert v4f32:$A)),
1049           (COPY_TO_REGCLASS $A, VSRC)>;
1050 def : Pat<(v2i64 (bitconvert v4i32:$A)),
1051           (COPY_TO_REGCLASS $A, VSRC)>;
1052 def : Pat<(v2i64 (bitconvert v8i16:$A)),
1053           (COPY_TO_REGCLASS $A, VSRC)>;
1054 def : Pat<(v2i64 (bitconvert v16i8:$A)),
1055           (COPY_TO_REGCLASS $A, VSRC)>;
1057 def : Pat<(v4f32 (bitconvert v2i64:$A)),
1058           (COPY_TO_REGCLASS $A, VRRC)>;
1059 def : Pat<(v4i32 (bitconvert v2i64:$A)),
1060           (COPY_TO_REGCLASS $A, VRRC)>;
1061 def : Pat<(v8i16 (bitconvert v2i64:$A)),
1062           (COPY_TO_REGCLASS $A, VRRC)>;
1063 def : Pat<(v16i8 (bitconvert v2i64:$A)),
1064           (COPY_TO_REGCLASS $A, VRRC)>;
1066 def : Pat<(v2f64 (bitconvert v2i64:$A)),
1067           (COPY_TO_REGCLASS $A, VRRC)>;
1068 def : Pat<(v2i64 (bitconvert v2f64:$A)),
1069           (COPY_TO_REGCLASS $A, VRRC)>;
1071 def : Pat<(v2f64 (bitconvert v1i128:$A)),
1072           (COPY_TO_REGCLASS $A, VRRC)>;
1073 def : Pat<(v1i128 (bitconvert v2f64:$A)),
1074           (COPY_TO_REGCLASS $A, VRRC)>;
1076 def : Pat<(v2i64 (bitconvert f128:$A)),
1077           (COPY_TO_REGCLASS $A, VRRC)>;
1078 def : Pat<(v4i32 (bitconvert f128:$A)),
1079           (COPY_TO_REGCLASS $A, VRRC)>;
1080 def : Pat<(v8i16 (bitconvert f128:$A)),
1081           (COPY_TO_REGCLASS $A, VRRC)>;
1082 def : Pat<(v16i8 (bitconvert f128:$A)),
1083           (COPY_TO_REGCLASS $A, VRRC)>;
1085 def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
1086           (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
1087 def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
1088           (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
1090 def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
1091           (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
1092 def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
1093           (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
1095 def : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
1096 def : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
1098 // Loads.
1099 let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
1100   def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1102   // Stores.
1103   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
1104             (STXVD2X $rS, xoaddr:$dst)>;
1105   def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1108 // Load vector big endian order
1109 let Predicates = [IsLittleEndian, HasVSX] in {
1110   def : Pat<(v2f64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1111   def : Pat<(PPCst_vec_be v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1112   def : Pat<(v4f32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1113   def : Pat<(PPCst_vec_be v4f32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
1114   def : Pat<(v2i64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1115   def : Pat<(PPCst_vec_be v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1116   def : Pat<(v4i32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1117   def : Pat<(PPCst_vec_be v4i32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
1120 let Predicates = [IsBigEndian, HasVSX, HasOnlySwappingMemOps] in {
1121   def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1122   def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1123   def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1124   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1125   def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1126   def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1127   def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
1128   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
1129             (STXVW4X $rS, xoaddr:$dst)>;
1132 // Permutes.
1133 def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1134 def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
1135 def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
1136 def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
1137 def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1139 // PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
1140 // XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
1141 def : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), (XXPERMDI $src, $src, 2)>;
1143 // Selects.
1144 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
1145           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1146 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
1147           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1148 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
1149           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1150 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
1151           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1152 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
1153           (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1154 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
1155           (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1156 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
1157           (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1158 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
1159           (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1160 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
1161           (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1162 def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
1163           (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1165 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
1166           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1167 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
1168           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1169 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
1170           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1171 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
1172           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1173 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
1174           (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
1175 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
1176           (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1177 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
1178           (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1179 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
1180           (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1181 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
1182           (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1183 def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
1184           (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1186 // Divides.
1187 def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
1188           (XVDIVSP $A, $B)>;
1189 def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
1190           (XVDIVDP $A, $B)>;
1192 // Reciprocal estimate
1193 def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1194           (XVRESP $A)>;
1195 def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1196           (XVREDP $A)>;
1198 // Recip. square root estimate
1199 def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1200           (XVRSQRTESP $A)>;
1201 def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1202           (XVRSQRTEDP $A)>;
1204 // Vector selection
1205 def : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
1206           (COPY_TO_REGCLASS 
1207                  (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
1208                         (COPY_TO_REGCLASS $vB, VSRC), 
1209                         (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
1210 def : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
1211           (COPY_TO_REGCLASS 
1212                  (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
1213                         (COPY_TO_REGCLASS $vB, VSRC), 
1214                         (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
1215 def : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
1216           (XXSEL $vC, $vB, $vA)>;
1217 def : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
1218           (XXSEL $vC, $vB, $vA)>;
1219 def : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
1220           (XXSEL $vC, $vB, $vA)>;
1221 def : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
1222           (XXSEL $vC, $vB, $vA)>;
1224 def : Pat<(v4f32 (fmaxnum v4f32:$src1, v4f32:$src2)),
1225           (v4f32 (XVMAXSP $src1, $src2))>;
1226 def : Pat<(v4f32 (fminnum v4f32:$src1, v4f32:$src2)),
1227           (v4f32 (XVMINSP $src1, $src2))>;
1228 def : Pat<(v2f64 (fmaxnum v2f64:$src1, v2f64:$src2)),
1229           (v2f64 (XVMAXDP $src1, $src2))>;
1230 def : Pat<(v2f64 (fminnum v2f64:$src1, v2f64:$src2)),
1231           (v2f64 (XVMINDP $src1, $src2))>;
1233 let Predicates = [IsLittleEndian] in {
1234 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1235           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1236 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1237           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1238 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1239           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1240 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1241           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1242 } // IsLittleEndian
1244 let Predicates = [IsBigEndian] in {
1245 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1246           (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1247 def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1248           (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1249 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1250           (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1251 def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1252           (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1253 } // IsBigEndian
1255 } // AddedComplexity
1256 } // HasVSX
1258 def ScalarLoads {
1259   dag Li8 =       (i32 (extloadi8 xoaddr:$src));
1260   dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
1261   dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
1262   dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
1263   dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
1265   dag Li16 =      (i32 (extloadi16 xoaddr:$src));
1266   dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
1267   dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
1268   dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
1269   dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
1271   dag Li32 = (i32 (load xoaddr:$src));
1274 def DWToSPExtractConv {
1275   dag El0US1 = (f32 (PPCfcfidus
1276                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
1277   dag El1US1 = (f32 (PPCfcfidus
1278                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
1279   dag El0US2 = (f32 (PPCfcfidus
1280                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
1281   dag El1US2 = (f32 (PPCfcfidus
1282                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
1283   dag El0SS1 = (f32 (PPCfcfids
1284                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
1285   dag El1SS1 = (f32 (PPCfcfids
1286                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
1287   dag El0SS2 = (f32 (PPCfcfids
1288                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
1289   dag El1SS2 = (f32 (PPCfcfids
1290                     (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
1291   dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
1292   dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
1295 // The following VSX instructions were introduced in Power ISA 2.07
1296 /* FIXME: if the operands are v2i64, these patterns will not match.
1297    we should define new patterns or otherwise match the same patterns
1298    when the elements are larger than i32.
1300 def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1301 def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1302 def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
1303 let Predicates = [HasP8Vector] in {
1304 let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1305   let isCommutable = 1 in {
1306     def XXLEQV : XX3Form<60, 186,
1307                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1308                          "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1309                          [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1310     def XXLNAND : XX3Form<60, 178,
1311                           (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1312                           "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1313                           [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1314                                                     v4i32:$XB)))]>;
1315   } // isCommutable
1317   def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1318             (XXLEQV $A, $B)>;
1320   let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
1321       isReMaterializable = 1 in {
1322     def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
1323                          "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
1324                          [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
1325   }
1327   def XXLORC : XX3Form<60, 170,
1328                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1329                        "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1330                        [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1332   // VSX scalar loads introduced in ISA 2.07
1333   let mayLoad = 1, mayStore = 0 in {
1334     let CodeSize = 3 in
1335     def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1336                          "lxsspx $XT, $src", IIC_LdStLFD, []>;
1337     def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1338                           "lxsiwax $XT, $src", IIC_LdStLFD, []>;
1339     def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1340                           "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
1342     // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
1343     let CodeSize = 3 in
1344     def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
1345                             "#XFLOADf32",
1346                             [(set f32:$XT, (load xoaddr:$src))]>;
1347     // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
1348     def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1349                        "#LIWAX",
1350                        [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1351     // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
1352     def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1353                        "#LIWZX",
1354                        [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1355   } // mayLoad
1357   // VSX scalar stores introduced in ISA 2.07
1358   let mayStore = 1, mayLoad = 0 in {
1359     let CodeSize = 3 in
1360     def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1361                           "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
1362     def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1363                           "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
1365     // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
1366     let CodeSize = 3 in
1367     def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
1368                             "#XFSTOREf32",
1369                             [(store f32:$XT, xoaddr:$dst)]>;
1370     // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
1371     def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1372                        "#STIWX",
1373                       [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1374   } // mayStore
1376   def : Pat<(f64 (extloadf32 xoaddr:$src)),
1377             (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
1378   def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
1379             (f32 (XFLOADf32 xoaddr:$src))>;
1380   def : Pat<(f64 (fpextend f32:$src)),
1381             (COPY_TO_REGCLASS $src, VSFRC)>;
1383   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1384             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1385   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1386             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1387   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1388             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1389   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1390             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1391   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1392             (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1393   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1394             (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1395   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1396             (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1397   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1398             (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1399   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1400             (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1401   def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1402             (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1404   // VSX Elementary Scalar FP arithmetic (SP)
1405   let isCommutable = 1 in {
1406     def XSADDSP : XX3Form<60, 0,
1407                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1408                           "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1409                           [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1410     def XSMULSP : XX3Form<60, 16,
1411                           (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1412                           "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1413                           [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1414   } // isCommutable
1415   def XSSUBSP : XX3Form<60, 8,
1416                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1417                         "xssubsp $XT, $XA, $XB", IIC_VecFP,
1418                         [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1419   def XSDIVSP : XX3Form<60, 24,
1420                         (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1421                         "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1422                         [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1423   def XSRESP : XX2Form<60, 26,
1424                         (outs vssrc:$XT), (ins vssrc:$XB),
1425                         "xsresp $XT, $XB", IIC_VecFP,
1426                         [(set f32:$XT, (PPCfre f32:$XB))]>;
1427   def XSRSP : XX2Form<60, 281,
1428                         (outs vssrc:$XT), (ins vsfrc:$XB),
1429                         "xsrsp $XT, $XB", IIC_VecFP, []>;
1430   def XSSQRTSP : XX2Form<60, 11,
1431                         (outs vssrc:$XT), (ins vssrc:$XB),
1432                         "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1433                         [(set f32:$XT, (fsqrt f32:$XB))]>;
1434   def XSRSQRTESP : XX2Form<60, 10,
1435                            (outs vssrc:$XT), (ins vssrc:$XB),
1436                            "xsrsqrtesp $XT, $XB", IIC_VecFP,
1437                            [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1439   // FMA Instructions
1440   let BaseName = "XSMADDASP" in {
1441   let isCommutable = 1 in
1442   def XSMADDASP : XX3Form<60, 1,
1443                           (outs vssrc:$XT),
1444                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1445                           "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1446                           [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1447                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1448                           AltVSXFMARel;
1449   let IsVSXFMAAlt = 1 in
1450   def XSMADDMSP : XX3Form<60, 9,
1451                           (outs vssrc:$XT),
1452                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1453                           "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1454                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1455                           AltVSXFMARel;
1456   }
1458   let BaseName = "XSMSUBASP" in {
1459   let isCommutable = 1 in
1460   def XSMSUBASP : XX3Form<60, 17,
1461                           (outs vssrc:$XT),
1462                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1463                           "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1464                           [(set f32:$XT, (fma f32:$XA, f32:$XB,
1465                                               (fneg f32:$XTi)))]>,
1466                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1467                           AltVSXFMARel;
1468   let IsVSXFMAAlt = 1 in
1469   def XSMSUBMSP : XX3Form<60, 25,
1470                           (outs vssrc:$XT),
1471                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1472                           "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1473                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1474                           AltVSXFMARel;
1475   }
1477   let BaseName = "XSNMADDASP" in {
1478   let isCommutable = 1 in
1479   def XSNMADDASP : XX3Form<60, 129,
1480                           (outs vssrc:$XT),
1481                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1482                           "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1483                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1484                                                     f32:$XTi)))]>,
1485                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1486                           AltVSXFMARel;
1487   let IsVSXFMAAlt = 1 in
1488   def XSNMADDMSP : XX3Form<60, 137,
1489                           (outs vssrc:$XT),
1490                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1491                           "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1492                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1493                           AltVSXFMARel;
1494   }
1496   let BaseName = "XSNMSUBASP" in {
1497   let isCommutable = 1 in
1498   def XSNMSUBASP : XX3Form<60, 145,
1499                           (outs vssrc:$XT),
1500                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1501                           "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1502                           [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1503                                                     (fneg f32:$XTi))))]>,
1504                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1505                           AltVSXFMARel;
1506   let IsVSXFMAAlt = 1 in
1507   def XSNMSUBMSP : XX3Form<60, 153,
1508                           (outs vssrc:$XT),
1509                           (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1510                           "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1511                           RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1512                           AltVSXFMARel;
1513   }
1515   // Single Precision Conversions (FP <-> INT)
1516   def XSCVSXDSP : XX2Form<60, 312,
1517                       (outs vssrc:$XT), (ins vsfrc:$XB),
1518                       "xscvsxdsp $XT, $XB", IIC_VecFP,
1519                       [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1520   def XSCVUXDSP : XX2Form<60, 296,
1521                       (outs vssrc:$XT), (ins vsfrc:$XB),
1522                       "xscvuxdsp $XT, $XB", IIC_VecFP,
1523                       [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1525   // Conversions between vector and scalar single precision
1526   def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1527                           "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1528   def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1529                           "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1531   let Predicates = [IsLittleEndian] in {
1532   def : Pat<DWToSPExtractConv.El0SS1,
1533             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
1534   def : Pat<DWToSPExtractConv.El1SS1,
1535             (f32 (XSCVSXDSP (COPY_TO_REGCLASS
1536                               (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
1537   def : Pat<DWToSPExtractConv.El0US1,
1538             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
1539   def : Pat<DWToSPExtractConv.El1US1,
1540             (f32 (XSCVUXDSP (COPY_TO_REGCLASS
1541                               (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
1542   }
1544   let Predicates = [IsBigEndian] in {
1545   def : Pat<DWToSPExtractConv.El0SS1,
1546             (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
1547   def : Pat<DWToSPExtractConv.El1SS1,
1548             (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
1549   def : Pat<DWToSPExtractConv.El0US1,
1550             (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
1551   def : Pat<DWToSPExtractConv.El1US1,
1552             (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
1553   }
1555   // Instructions for converting float to i64 feeding a store.
1556   let Predicates = [NoP9Vector] in {
1557   def : Pat<(PPCstore_scal_int_from_vsr
1558               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
1559             (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
1560   def : Pat<(PPCstore_scal_int_from_vsr
1561               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
1562             (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
1563   }
1565   // Instructions for converting float to i32 feeding a store.
1566   def : Pat<(PPCstore_scal_int_from_vsr
1567               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
1568             (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
1569   def : Pat<(PPCstore_scal_int_from_vsr
1570               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
1571             (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
1573   def : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
1574             (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
1575                            (COPY_TO_REGCLASS $src2, VRRC)))>;
1576   def : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
1577             (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
1578                            (COPY_TO_REGCLASS $src2, VRRC)))>;
1579   def : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
1580             (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
1581                            (COPY_TO_REGCLASS $src2, VRRC)))>;
1582   def : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
1583             (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
1584                            (COPY_TO_REGCLASS $src2, VRRC)))>;
1585 } // AddedComplexity = 400
1586 } // HasP8Vector
1588 let AddedComplexity = 400 in {
1589 let Predicates = [HasDirectMove] in {
1590   // VSX direct move instructions
1591   def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1592                               "mfvsrd $rA, $XT", IIC_VecGeneral,
1593                               [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1594       Requires<[In64BitMode]>;
1595   let isCodeGenOnly = 1 in
1596   def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
1597                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1598                              []>,
1599       Requires<[In64BitMode]>;
1600   def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1601                                "mfvsrwz $rA, $XT", IIC_VecGeneral,
1602                                [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1603   let isCodeGenOnly = 1 in
1604   def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
1605                                "mfvsrwz $rA, $XT", IIC_VecGeneral,
1606                                []>;
1607   def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1608                               "mtvsrd $XT, $rA", IIC_VecGeneral,
1609                               [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1610       Requires<[In64BitMode]>;
1611   let isCodeGenOnly = 1 in
1612   def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
1613                               "mtvsrd $XT, $rA", IIC_VecGeneral,
1614                               []>,
1615       Requires<[In64BitMode]>;
1616   def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1617                                "mtvsrwa $XT, $rA", IIC_VecGeneral,
1618                                [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1619   let isCodeGenOnly = 1 in
1620   def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
1621                                "mtvsrwa $XT, $rA", IIC_VecGeneral,
1622                                []>;
1623   def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1624                                "mtvsrwz $XT, $rA", IIC_VecGeneral,
1625                                [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1626   let isCodeGenOnly = 1 in
1627   def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
1628                                "mtvsrwz $XT, $rA", IIC_VecGeneral,
1629                                []>;
1630 } // HasDirectMove
1632 let Predicates = [IsISA3_0, HasDirectMove] in {
1633   def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1634                               "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1636   def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1637                        "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1638                        []>, Requires<[In64BitMode]>;
1640   def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1641                               "mfvsrld $rA, $XT", IIC_VecGeneral,
1642                               []>, Requires<[In64BitMode]>;
1644 } // IsISA3_0, HasDirectMove
1645 } // AddedComplexity = 400
1647 // We want to parse this from asm, but we don't want to emit this as it would
1648 // be emitted with a VSX reg. So leave Emit = 0 here.
1649 def : InstAlias<"mfvrd $rA, $XT",
1650                 (MFVRD g8rc:$rA, vrrc:$XT), 0>;
1651 def : InstAlias<"mffprd $rA, $src",
1652                 (MFVSRD g8rc:$rA, f8rc:$src)>;
1653 def : InstAlias<"mtvrd $XT, $rA",
1654                 (MTVRD vrrc:$XT, g8rc:$rA), 0>;
1655 def : InstAlias<"mtfprd $dst, $rA",
1656                 (MTVSRD f8rc:$dst, g8rc:$rA)>;
1657 def : InstAlias<"mfvrwz $rA, $XT",
1658                 (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
1659 def : InstAlias<"mffprwz $rA, $src",
1660                 (MFVSRWZ gprc:$rA, f8rc:$src)>;
1661 def : InstAlias<"mtvrwa $XT, $rA",
1662                 (MTVRWA vrrc:$XT, gprc:$rA), 0>;
1663 def : InstAlias<"mtfprwa $dst, $rA",
1664                 (MTVSRWA f8rc:$dst, gprc:$rA)>;
1665 def : InstAlias<"mtvrwz $XT, $rA",
1666                 (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
1667 def : InstAlias<"mtfprwz $dst, $rA",
1668                 (MTVSRWZ f8rc:$dst, gprc:$rA)>;
1670 /*  Direct moves of various widths from GPR's into VSR's. Each move lines
1671     the value up into element 0 (both BE and LE). Namely, entities smaller than
1672     a doubleword are shifted left and moved for BE. For LE, they're moved, then
1673     swapped to go into the least significant element of the VSR.
1675 def MovesToVSR {
1676   dag BE_BYTE_0 =
1677     (MTVSRD
1678       (RLDICR
1679         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1680   dag BE_HALF_0 =
1681     (MTVSRD
1682       (RLDICR
1683         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1684   dag BE_WORD_0 =
1685     (MTVSRD
1686       (RLDICR
1687         (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1688   dag BE_DWORD_0 = (MTVSRD $A);
1690   dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1691   dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1692                                         LE_MTVSRW, sub_64));
1693   dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1694   dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1695                                          BE_DWORD_0, sub_64));
1696   dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1699 /*  Patterns for extracting elements out of vectors. Integer elements are
1700     extracted using direct move operations. Patterns for extracting elements
1701     whose indices are not available at compile time are also provided with
1702     various _VARIABLE_ patterns.
1703     The numbering for the DAG's is for LE, but when used on BE, the correct
1704     LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1706 def VectorExtractions {
1707   // Doubleword extraction
1708   dag LE_DWORD_0 =
1709     (MFVSRD
1710       (EXTRACT_SUBREG
1711         (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1712                   (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1713   dag LE_DWORD_1 = (MFVSRD
1714                      (EXTRACT_SUBREG
1715                        (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1717   // Word extraction
1718   dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1719   dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1720   dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1721                              (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1722   dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1724   // Halfword extraction
1725   dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1726   dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1727   dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1728   dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1729   dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1730   dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1731   dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1732   dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1734   // Byte extraction
1735   dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1736   dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1737   dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1738   dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1739   dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1740   dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1741   dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1742   dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1743   dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1744   dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1745   dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1746   dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1747   dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1748   dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1749   dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1750   dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1752   /* Variable element number (BE and LE patterns must be specified separately)
1753      This is a rather involved process.
1755      Conceptually, this is how the move is accomplished:
1756      1. Identify which doubleword contains the element
1757      2. Shift in the VMX register so that the correct doubleword is correctly
1758         lined up for the MFVSRD
1759      3. Perform the move so that the element (along with some extra stuff)
1760         is in the GPR
1761      4. Right shift within the GPR so that the element is right-justified
1763      Of course, the index is an element number which has a different meaning
1764      on LE/BE so the patterns have to be specified separately.
1766      Note: The final result will be the element right-justified with high
1767            order bits being arbitrarily defined (namely, whatever was in the
1768            vector register to the left of the value originally).
1769   */
1771   /*  LE variable byte
1772       Number 1. above:
1773       - For elements 0-7, we shift left by 8 bytes since they're on the right
1774       - For elements 8-15, we need not shift (shift left by zero bytes)
1775       This is accomplished by inverting the bits of the index and AND-ing
1776       with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1777   */
1778   dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
1780   //  Number 2. above:
1781   //  - Now that we set up the shift amount, we shift in the VMX register
1782   dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
1784   //  Number 3. above:
1785   //  - The doubleword containing our element is moved to a GPR
1786   dag LE_MV_VBYTE = (MFVSRD
1787                       (EXTRACT_SUBREG
1788                         (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1789                         sub_64));
1791   /*  Number 4. above:
1792       - Truncate the element number to the range 0-7 (8-15 are symmetrical
1793         and out of range values are truncated accordingly)
1794       - Multiply by 8 as we need to shift right by the number of bits, not bytes
1795       - Shift right in the GPR by the calculated value
1796   */
1797   dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1798                                        sub_32);
1799   dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1800                                          sub_32);
1802   /*  LE variable halfword
1803       Number 1. above:
1804       - For elements 0-3, we shift left by 8 since they're on the right
1805       - For elements 4-7, we need not shift (shift left by zero bytes)
1806       Similarly to the byte pattern, we invert the bits of the index, but we
1807       AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1808       Of course, the shift is still by 8 bytes, so we must multiply by 2.
1809   */
1810   dag LE_VHALF_PERM_VEC =
1811     (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
1813   //  Number 2. above:
1814   //  - Now that we set up the shift amount, we shift in the VMX register
1815   dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
1817   //  Number 3. above:
1818   //  - The doubleword containing our element is moved to a GPR
1819   dag LE_MV_VHALF = (MFVSRD
1820                       (EXTRACT_SUBREG
1821                         (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1822                         sub_64));
1824   /*  Number 4. above:
1825       - Truncate the element number to the range 0-3 (4-7 are symmetrical
1826         and out of range values are truncated accordingly)
1827       - Multiply by 16 as we need to shift right by the number of bits
1828       - Shift right in the GPR by the calculated value
1829   */
1830   dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1831                                        sub_32);
1832   dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1833                                          sub_32);
1835   /*  LE variable word
1836       Number 1. above:
1837       - For elements 0-1, we shift left by 8 since they're on the right
1838       - For elements 2-3, we need not shift
1839   */
1840   dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1841                                        (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
1843   //  Number 2. above:
1844   //  - Now that we set up the shift amount, we shift in the VMX register
1845   dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
1847   //  Number 3. above:
1848   //  - The doubleword containing our element is moved to a GPR
1849   dag LE_MV_VWORD = (MFVSRD
1850                       (EXTRACT_SUBREG
1851                         (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1852                         sub_64));
1854   /*  Number 4. above:
1855       - Truncate the element number to the range 0-1 (2-3 are symmetrical
1856         and out of range values are truncated accordingly)
1857       - Multiply by 32 as we need to shift right by the number of bits
1858       - Shift right in the GPR by the calculated value
1859   */
1860   dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1861                                        sub_32);
1862   dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1863                                          sub_32);
1865   /*  LE variable doubleword
1866       Number 1. above:
1867       - For element 0, we shift left by 8 since it's on the right
1868       - For element 1, we need not shift
1869   */
1870   dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1871                                         (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
1873   //  Number 2. above:
1874   //  - Now that we set up the shift amount, we shift in the VMX register
1875   dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
1877   // Number 3. above:
1878   //  - The doubleword containing our element is moved to a GPR
1879   //  - Number 4. is not needed for the doubleword as the value is 64-bits
1880   dag LE_VARIABLE_DWORD =
1881         (MFVSRD (EXTRACT_SUBREG
1882                   (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1883                   sub_64));
1885   /*  LE variable float
1886       - Shift the vector to line up the desired element to BE Word 0
1887       - Convert 32-bit float to a 64-bit single precision float
1888   */
1889   dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
1890                                   (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
1891   dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1892   dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1894   /*  LE variable double
1895       Same as the LE doubleword except there is no move.
1896   */
1897   dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1898                                          (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1899                                          LE_VDWORD_PERM_VEC));
1900   dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1902   /*  BE variable byte
1903       The algorithm here is the same as the LE variable byte except:
1904       - The shift in the VMX register is by 0/8 for opposite element numbers so
1905         we simply AND the element number with 0x8
1906       - The order of elements after the move to GPR is reversed, so we invert
1907         the bits of the index prior to truncating to the range 0-7
1908   */
1909   dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDIo8 $Idx, 8)));
1910   dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
1911   dag BE_MV_VBYTE = (MFVSRD
1912                       (EXTRACT_SUBREG
1913                         (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1914                         sub_64));
1915   dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1916                                        sub_32);
1917   dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1918                                          sub_32);
1920   /*  BE variable halfword
1921       The algorithm here is the same as the LE variable halfword except:
1922       - The shift in the VMX register is by 0/8 for opposite element numbers so
1923         we simply AND the element number with 0x4 and multiply by 2
1924       - The order of elements after the move to GPR is reversed, so we invert
1925         the bits of the index prior to truncating to the range 0-3
1926   */
1927   dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
1928                                        (RLDICR (ANDIo8 $Idx, 4), 1, 62)));
1929   dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
1930   dag BE_MV_VHALF = (MFVSRD
1931                       (EXTRACT_SUBREG
1932                         (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1933                         sub_64));
1934   dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1935                                        sub_32);
1936   dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1937                                          sub_32);
1939   /*  BE variable word
1940       The algorithm is the same as the LE variable word except:
1941       - The shift in the VMX register happens for opposite element numbers
1942       - The order of elements after the move to GPR is reversed, so we invert
1943         the bits of the index prior to truncating to the range 0-1
1944   */
1945   dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1946                                        (RLDICR (ANDIo8 $Idx, 2), 2, 61)));
1947   dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
1948   dag BE_MV_VWORD = (MFVSRD
1949                       (EXTRACT_SUBREG
1950                         (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1951                         sub_64));
1952   dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1953                                        sub_32);
1954   dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1955                                          sub_32);
1957   /*  BE variable doubleword
1958       Same as the LE doubleword except we shift in the VMX register for opposite
1959       element indices.
1960   */
1961   dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1962                                         (RLDICR (ANDIo8 $Idx, 1), 3, 60)));
1963   dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
1964   dag BE_VARIABLE_DWORD =
1965         (MFVSRD (EXTRACT_SUBREG
1966                   (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1967                   sub_64));
1969   /*  BE variable float
1970       - Shift the vector to line up the desired element to BE Word 0
1971       - Convert 32-bit float to a 64-bit single precision float
1972   */
1973   dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
1974   dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1975   dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1977   /* BE variable double
1978       Same as the BE doubleword except there is no move.
1979   */
1980   dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1981                                          (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1982                                          BE_VDWORD_PERM_VEC));
1983   dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1986 def NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">;
1987 let AddedComplexity = 400 in {
1988 // v4f32 scalar <-> vector conversions (BE)
1989 let Predicates = [IsBigEndian, HasP8Vector] in {
1990   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1991             (v4f32 (XSCVDPSPN $A))>;
1992   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1993             (f32 (XSCVSPDPN $S))>;
1994   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1995             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1996   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1997             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1998   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1999             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
2000   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
2001             (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
2002 } // IsBigEndian, HasP8Vector
2004 // Variable index vector_extract for v2f64 does not require P8Vector
2005 let Predicates = [IsBigEndian, HasVSX] in
2006   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2007             (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
2009 let Predicates = [IsBigEndian, HasDirectMove] in {
2010   // v16i8 scalar <-> vector conversions (BE)
2011   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
2012             (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
2013   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
2014             (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
2015   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2016             (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
2017   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
2018             (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
2020   // v2i64 scalar <-> vector conversions (BE)
2021   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
2022             (i64 VectorExtractions.LE_DWORD_1)>;
2023   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
2024             (i64 VectorExtractions.LE_DWORD_0)>;
2025   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
2026             (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
2027 } // IsBigEndian, HasDirectMove
2029 let Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in {
2030   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2031             (i32 VectorExtractions.LE_BYTE_15)>;
2032   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2033             (i32 VectorExtractions.LE_BYTE_14)>;
2034   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2035             (i32 VectorExtractions.LE_BYTE_13)>;
2036   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2037             (i32 VectorExtractions.LE_BYTE_12)>;
2038   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2039             (i32 VectorExtractions.LE_BYTE_11)>;
2040   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2041             (i32 VectorExtractions.LE_BYTE_10)>;
2042   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2043             (i32 VectorExtractions.LE_BYTE_9)>;
2044   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2045             (i32 VectorExtractions.LE_BYTE_8)>;
2046   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2047             (i32 VectorExtractions.LE_BYTE_7)>;
2048   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2049             (i32 VectorExtractions.LE_BYTE_6)>;
2050   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2051             (i32 VectorExtractions.LE_BYTE_5)>;
2052   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2053             (i32 VectorExtractions.LE_BYTE_4)>;
2054   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2055             (i32 VectorExtractions.LE_BYTE_3)>;
2056   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2057             (i32 VectorExtractions.LE_BYTE_2)>;
2058   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2059             (i32 VectorExtractions.LE_BYTE_1)>;
2060   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2061             (i32 VectorExtractions.LE_BYTE_0)>;
2062   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2063             (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
2065   // v8i16 scalar <-> vector conversions (BE)
2066   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2067             (i32 VectorExtractions.LE_HALF_7)>;
2068   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2069             (i32 VectorExtractions.LE_HALF_6)>;
2070   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2071             (i32 VectorExtractions.LE_HALF_5)>;
2072   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2073             (i32 VectorExtractions.LE_HALF_4)>;
2074   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2075             (i32 VectorExtractions.LE_HALF_3)>;
2076   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2077             (i32 VectorExtractions.LE_HALF_2)>;
2078   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2079             (i32 VectorExtractions.LE_HALF_1)>;
2080   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
2081             (i32 VectorExtractions.LE_HALF_0)>;
2082   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2083             (i32 VectorExtractions.BE_VARIABLE_HALF)>;
2085   // v4i32 scalar <-> vector conversions (BE)
2086   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2087             (i32 VectorExtractions.LE_WORD_3)>;
2088   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2089             (i32 VectorExtractions.LE_WORD_2)>;
2090   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2091             (i32 VectorExtractions.LE_WORD_1)>;
2092   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2093             (i32 VectorExtractions.LE_WORD_0)>;
2094   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2095             (i32 VectorExtractions.BE_VARIABLE_WORD)>;
2096 } // IsBigEndian, HasDirectMove, NoP9Altivec
2098 // v4f32 scalar <-> vector conversions (LE)
2099 let Predicates = [IsLittleEndian, HasP8Vector] in {
2100   def : Pat<(v4f32 (scalar_to_vector f32:$A)),
2101             (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
2102   def : Pat<(f32 (vector_extract v4f32:$S, 0)),
2103             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
2104   def : Pat<(f32 (vector_extract v4f32:$S, 1)),
2105             (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
2106   def : Pat<(f32 (vector_extract v4f32:$S, 2)),
2107             (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
2108   def : Pat<(f32 (vector_extract v4f32:$S, 3)),
2109             (f32 (XSCVSPDPN $S))>;
2110   def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
2111             (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
2112 } // IsLittleEndian, HasP8Vector
2114 // Variable index vector_extract for v2f64 does not require P8Vector
2115 let Predicates = [IsLittleEndian, HasVSX] in
2116   def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2117             (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
2119 def : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
2120             (STXVD2X $rS, xoaddr:$dst)>;
2121 def : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
2122             (STXVW4X $rS, xoaddr:$dst)>;
2123 def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2124 def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2126 // Variable index unsigned vector_extract on Power9
2127 let Predicates = [HasP9Altivec, IsLittleEndian] in {
2128   def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
2129             (VEXTUBRX $Idx, $S)>;
2131   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2132             (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2133   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2134             (VEXTUHRX (LI8 0), $S)>;
2135   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2136             (VEXTUHRX (LI8 2), $S)>;
2137   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2138             (VEXTUHRX (LI8 4), $S)>;
2139   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2140             (VEXTUHRX (LI8 6), $S)>;
2141   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2142             (VEXTUHRX (LI8 8), $S)>;
2143   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2144             (VEXTUHRX (LI8 10), $S)>;
2145   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2146             (VEXTUHRX (LI8 12), $S)>;
2147   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2148             (VEXTUHRX (LI8 14), $S)>;
2150   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2151             (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2152   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2153             (VEXTUWRX (LI8 0), $S)>;
2154   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2155             (VEXTUWRX (LI8 4), $S)>;
2156   // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2157   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2158             (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2159             (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2160   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2161             (VEXTUWRX (LI8 12), $S)>;
2163   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2164             (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2165   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2166             (EXTSW (VEXTUWRX (LI8 0), $S))>;
2167   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2168             (EXTSW (VEXTUWRX (LI8 4), $S))>;
2169   // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2170   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2171             (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2172             (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2173   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2174             (EXTSW (VEXTUWRX (LI8 12), $S))>;
2176   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2177             (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
2178   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2179             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
2180   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2181             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
2182   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2183             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
2184   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2185             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
2186   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2187             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
2188   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2189             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
2190   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2191             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
2192   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2193             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
2194   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2195             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
2196   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2197             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
2198   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2199             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
2200   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2201             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
2202   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2203             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
2204   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2205             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
2206   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2207             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
2208   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2209             (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
2211   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2212             (i32 (EXTRACT_SUBREG (VEXTUHRX
2213             (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2214   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2215             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
2216   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2217             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
2218   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2219             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
2220   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2221             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
2222   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2223             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
2224   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2225             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
2226   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2227             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
2228   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2229             (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
2231   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2232             (i32 (EXTRACT_SUBREG (VEXTUWRX
2233             (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2234   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2235             (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
2236   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2237             (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
2238   // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2239   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2240             (i32 VectorExtractions.LE_WORD_2)>;
2241   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2242             (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
2245 let Predicates = [HasP9Altivec, IsBigEndian] in {
2246   def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
2247             (VEXTUBLX $Idx, $S)>;
2249   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2250             (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2251   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2252             (VEXTUHLX (LI8 0), $S)>;
2253   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2254             (VEXTUHLX (LI8 2), $S)>;
2255   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2256             (VEXTUHLX (LI8 4), $S)>;
2257   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2258             (VEXTUHLX (LI8 6), $S)>;
2259   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2260             (VEXTUHLX (LI8 8), $S)>;
2261   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2262             (VEXTUHLX (LI8 10), $S)>;
2263   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2264             (VEXTUHLX (LI8 12), $S)>;
2265   def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2266             (VEXTUHLX (LI8 14), $S)>;
2268   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2269             (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2270   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2271             (VEXTUWLX (LI8 0), $S)>;
2273   // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2274   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2275             (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2276             (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2277   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2278             (VEXTUWLX (LI8 8), $S)>;
2279   def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2280             (VEXTUWLX (LI8 12), $S)>;
2282   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2283             (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2284   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2285             (EXTSW (VEXTUWLX (LI8 0), $S))>;
2286   // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2287   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2288             (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2289             (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2290   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2291             (EXTSW (VEXTUWLX (LI8 8), $S))>;
2292   def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2293             (EXTSW (VEXTUWLX (LI8 12), $S))>;
2295   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2296             (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
2297   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2298             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
2299   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2300             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
2301   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2302             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
2303   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2304             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
2305   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2306             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
2307   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2308             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
2309   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2310             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
2311   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2312             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
2313   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2314             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
2315   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2316             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
2317   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2318             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
2319   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2320             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
2321   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2322             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
2323   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2324             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
2325   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2326             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
2327   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2328             (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
2330   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2331             (i32 (EXTRACT_SUBREG (VEXTUHLX
2332             (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2333   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2334             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
2335   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2336             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
2337   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2338             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
2339   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2340             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
2341   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2342             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
2343   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2344             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
2345   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2346             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
2347   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2348             (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
2350   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2351             (i32 (EXTRACT_SUBREG (VEXTUWLX
2352             (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2353   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2354             (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
2355   // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2356   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2357             (i32 VectorExtractions.LE_WORD_2)>;
2358   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2359             (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
2360   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2361             (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
2364 let Predicates = [IsLittleEndian, HasDirectMove] in {
2365   // v16i8 scalar <-> vector conversions (LE)
2366   def : Pat<(v16i8 (scalar_to_vector i32:$A)),
2367             (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2368   def : Pat<(v8i16 (scalar_to_vector i32:$A)),
2369             (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2370   def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2371             (v4i32 MovesToVSR.LE_WORD_0)>;
2372   def : Pat<(v2i64 (scalar_to_vector i64:$A)),
2373             (v2i64 MovesToVSR.LE_DWORD_0)>;
2374   // v2i64 scalar <-> vector conversions (LE)
2375   def : Pat<(i64 (vector_extract v2i64:$S, 0)),
2376             (i64 VectorExtractions.LE_DWORD_0)>;
2377   def : Pat<(i64 (vector_extract v2i64:$S, 1)),
2378             (i64 VectorExtractions.LE_DWORD_1)>;
2379   def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
2380             (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
2381 } // IsLittleEndian, HasDirectMove
2383 let Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in {
2384   def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2385             (i32 VectorExtractions.LE_BYTE_0)>;
2386   def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2387             (i32 VectorExtractions.LE_BYTE_1)>;
2388   def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2389             (i32 VectorExtractions.LE_BYTE_2)>;
2390   def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2391             (i32 VectorExtractions.LE_BYTE_3)>;
2392   def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2393             (i32 VectorExtractions.LE_BYTE_4)>;
2394   def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2395             (i32 VectorExtractions.LE_BYTE_5)>;
2396   def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2397             (i32 VectorExtractions.LE_BYTE_6)>;
2398   def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2399             (i32 VectorExtractions.LE_BYTE_7)>;
2400   def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2401             (i32 VectorExtractions.LE_BYTE_8)>;
2402   def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2403             (i32 VectorExtractions.LE_BYTE_9)>;
2404   def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2405             (i32 VectorExtractions.LE_BYTE_10)>;
2406   def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2407             (i32 VectorExtractions.LE_BYTE_11)>;
2408   def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2409             (i32 VectorExtractions.LE_BYTE_12)>;
2410   def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2411             (i32 VectorExtractions.LE_BYTE_13)>;
2412   def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2413             (i32 VectorExtractions.LE_BYTE_14)>;
2414   def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2415             (i32 VectorExtractions.LE_BYTE_15)>;
2416   def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2417             (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
2419   // v8i16 scalar <-> vector conversions (LE)
2420   def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2421             (i32 VectorExtractions.LE_HALF_0)>;
2422   def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2423             (i32 VectorExtractions.LE_HALF_1)>;
2424   def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2425             (i32 VectorExtractions.LE_HALF_2)>;
2426   def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2427             (i32 VectorExtractions.LE_HALF_3)>;
2428   def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2429             (i32 VectorExtractions.LE_HALF_4)>;
2430   def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2431             (i32 VectorExtractions.LE_HALF_5)>;
2432   def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2433             (i32 VectorExtractions.LE_HALF_6)>;
2434   def : Pat<(i32 (vector_extract v8i16:$S, 7)),
2435             (i32 VectorExtractions.LE_HALF_7)>;
2436   def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2437             (i32 VectorExtractions.LE_VARIABLE_HALF)>;
2439   // v4i32 scalar <-> vector conversions (LE)
2440   def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2441             (i32 VectorExtractions.LE_WORD_0)>;
2442   def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2443             (i32 VectorExtractions.LE_WORD_1)>;
2444   def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2445             (i32 VectorExtractions.LE_WORD_2)>;
2446   def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2447             (i32 VectorExtractions.LE_WORD_3)>;
2448   def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2449             (i32 VectorExtractions.LE_VARIABLE_WORD)>;
2450 } // IsLittleEndian, HasDirectMove, NoP9Altivec
2452 let Predicates = [HasDirectMove, HasVSX] in {
2453 // bitconvert f32 -> i32
2454 // (convert to 32-bit fp single, shift right 1 word, move to GPR)
2455 def : Pat<(i32 (bitconvert f32:$S)),
2456           (i32 (MFVSRWZ (EXTRACT_SUBREG
2457                           (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
2458                           sub_64)))>;
2459 // bitconvert i32 -> f32
2460 // (move to FPR, shift left 1 word, convert to 64-bit fp single)
2461 def : Pat<(f32 (bitconvert i32:$A)),
2462           (f32 (XSCVSPDPN
2463                  (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
2465 // bitconvert f64 -> i64
2466 // (move to GPR, nothing else needed)
2467 def : Pat<(i64 (bitconvert f64:$S)),
2468           (i64 (MFVSRD $S))>;
2470 // bitconvert i64 -> f64
2471 // (move to FPR, nothing else needed)
2472 def : Pat<(f64 (bitconvert i64:$S)),
2473           (f64 (MTVSRD $S))>;
2476 // Materialize a zero-vector of long long
2477 def : Pat<(v2i64 immAllZerosV),
2478           (v2i64 (XXLXORz))>;
2481 def AlignValues {
2482   dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2483   dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2486 // The following VSX instructions were introduced in Power ISA 3.0
2487 def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2488 let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2490   // [PO VRT XO VRB XO /]
2491   class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2492                       list<dag> pattern>
2493     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2494                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2496   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2497   class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2498                          list<dag> pattern>
2499     : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2501   // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2502   // So we use different operand class for VRB
2503   class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2504                            RegisterOperand vbtype, list<dag> pattern>
2505     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2506                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2508   // [PO VRT XO VRB XO /]
2509   class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2510                       list<dag> pattern>
2511     : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
2512                     !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2514   // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2515   class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2516                          list<dag> pattern>
2517     : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isDOT;
2519   // [PO T XO B XO BX /]
2520   class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2521                         list<dag> pattern>
2522     : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2523                       !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2525   // [PO T XO B XO BX TX]
2526   class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2527                         RegisterOperand vtype, list<dag> pattern>
2528     : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2529                       !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2531   // [PO T A B XO AX BX TX], src and dest register use different operand class
2532   class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2533                   RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2534                   InstrItinClass itin, list<dag> pattern>
2535     : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2536               !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2538   // [PO VRT VRA VRB XO /]
2539   class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2540                       list<dag> pattern>
2541     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2542               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2544   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2545   class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2546                          list<dag> pattern>
2547     : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2549   // [PO VRT VRA VRB XO /]
2550   class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
2551                           list<dag> pattern>
2552     : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
2553               !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
2554               RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
2556   // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2557   class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
2558                           list<dag> pattern>
2559     : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isDOT;
2561   //===--------------------------------------------------------------------===//
2562   // Quad-Precision Scalar Move Instructions:
2564   // Copy Sign
2565   def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
2566                                 [(set f128:$vT,
2567                                       (fcopysign f128:$vB, f128:$vA))]>;
2569   // Absolute/Negative-Absolute/Negate
2570   def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
2571                                 [(set f128:$vT, (fabs f128:$vB))]>;
2572   def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
2573                                 [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
2574   def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
2575                                 [(set f128:$vT, (fneg f128:$vB))]>;
2577   //===--------------------------------------------------------------------===//
2578   // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2580   // Add/Divide/Multiply/Subtract
2581   let isCommutable = 1 in {
2582   def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
2583                                    [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>;
2584   def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
2585                                    [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>;
2586   }
2587   def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
2588                                    [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>;
2589   def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
2590                                    [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>;
2591   // Square-Root
2592   def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
2593                                    [(set f128:$vT, (fsqrt f128:$vB))]>;
2594   // (Negative) Multiply-{Add/Subtract}
2595   def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
2596                                     [(set f128:$vT,
2597                                           (fma f128:$vA, f128:$vB,
2598                                                f128:$vTi))]>;
2599   def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
2600                                        [(set f128:$vT,
2601                                              (fma f128:$vA, f128:$vB,
2602                                                   (fneg f128:$vTi)))]>;
2603   def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
2604                                      [(set f128:$vT,
2605                                            (fneg (fma f128:$vA, f128:$vB,
2606                                                       f128:$vTi)))]>;
2607   def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
2608                                      [(set f128:$vT,
2609                                            (fneg (fma f128:$vA, f128:$vB,
2610                                                       (fneg f128:$vTi))))]>;
2612   let isCommutable = 1 in {
2613   def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
2614                                   [(set f128:$vT,
2615                                   (int_ppc_addf128_round_to_odd
2616                                   f128:$vA, f128:$vB))]>;
2617   def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
2618                                   [(set f128:$vT,
2619                                   (int_ppc_mulf128_round_to_odd
2620                                   f128:$vA, f128:$vB))]>;
2621   }
2622   def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
2623                                   [(set f128:$vT,
2624                                   (int_ppc_subf128_round_to_odd
2625                                   f128:$vA, f128:$vB))]>;
2626   def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
2627                                   [(set f128:$vT,
2628                                   (int_ppc_divf128_round_to_odd
2629                                   f128:$vA, f128:$vB))]>;
2630   def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
2631                                   [(set f128:$vT,
2632                                   (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
2635   def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
2636                                       [(set f128:$vT,
2637                                       (int_ppc_fmaf128_round_to_odd
2638                                       f128:$vA,f128:$vB,f128:$vTi))]>;
2640   def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
2641                                       [(set f128:$vT,
2642                                       (int_ppc_fmaf128_round_to_odd
2643                                       f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
2644   def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
2645                                       [(set f128:$vT,
2646                                       (fneg (int_ppc_fmaf128_round_to_odd
2647                                       f128:$vA, f128:$vB, f128:$vTi)))]>;
2648   def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
2649                                       [(set f128:$vT,
2650                                       (fneg (int_ppc_fmaf128_round_to_odd
2651                                       f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
2653   // Additional fnmsub patterns: -a*c + b == -(a*c - b)
2654   def : Pat<(fma (fneg f128:$A), f128:$C, f128:$B), (XSNMSUBQP $B, $C, $A)>;
2655   def : Pat<(fma f128:$A, (fneg f128:$C), f128:$B), (XSNMSUBQP $B, $C, $A)>;
2657   //===--------------------------------------------------------------------===//
2658   // Quad/Double-Precision Compare Instructions:
2660   // [PO BF // VRA VRB XO /]
2661   class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2662                       list<dag> pattern>
2663     : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2664                !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2665     let Pattern = pattern;
2666   }
2668   // QP Compare Ordered/Unordered
2669   def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2670   def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2672   // DP/QP Compare Exponents
2673   def XSCMPEXPDP : XX3Form_1<60, 59,
2674                              (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2675                              "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
2676   def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2678   // DP Compare ==, >=, >, !=
2679   // Use vsrc for XT, because the entire register of XT is set.
2680   // XT.dword[1] = 0x0000_0000_0000_0000
2681   def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2682                                   IIC_FPCompare, []>;
2683   def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2684                                   IIC_FPCompare, []>;
2685   def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2686                                   IIC_FPCompare, []>;
2688   //===--------------------------------------------------------------------===//
2689   // Quad-Precision Floating-Point Conversion Instructions:
2691   // Convert DP -> QP
2692   def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
2693                                      [(set f128:$vT, (fpextend f64:$vB))]>;
2695   // Round & Convert QP -> DP (dword[1] is set to zero)
2696   def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
2697   def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
2698                                         [(set f64:$vT,
2699                                         (int_ppc_truncf128_round_to_odd
2700                                         f128:$vB))]>;
2702   // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2703   def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2704   def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2705   def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2706   def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2708   // Convert (Un)Signed DWord -> QP.
2709   def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2710   def : Pat<(f128 (sint_to_fp i64:$src)),
2711             (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
2712   def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))),
2713             (f128 (XSCVSDQP $src))>;
2714   def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))),
2715             (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
2717   def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2718   def : Pat<(f128 (uint_to_fp i64:$src)),
2719             (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
2720   def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))),
2721             (f128 (XSCVUDQP $src))>;
2723   // Convert (Un)Signed Word -> QP.
2724   def : Pat<(f128 (sint_to_fp i32:$src)),
2725             (f128 (XSCVSDQP (MTVSRWA $src)))>;
2726   def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
2727             (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
2728   def : Pat<(f128 (uint_to_fp i32:$src)),
2729             (f128 (XSCVUDQP (MTVSRWZ $src)))>;
2730   def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))),
2731             (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
2733   //===--------------------------------------------------------------------===//
2734   // Round to Floating-Point Integer Instructions
2736   // (Round &) Convert DP <-> HP
2737   // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2738   // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2739   // but we still use vsfrc for it.
2740   def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2741   def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2743   // Vector HP -> SP
2744   def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2745   def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2746                                  [(set v4f32:$XT,
2747                                      (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2749   // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2750   // separate pattern so that it can convert the input register class from
2751   // VRRC(v8i16) to VSRC.
2752   def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2753             (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2755   class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2756                                 list<dag> pattern>
2757     : Z23Form_8<opcode, xo,
2758                 (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2759                 !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2760     let RC = ex;
2761   }
2763   // Round to Quad-Precision Integer [with Inexact]
2764   def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2765   def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2767   // Use current rounding mode
2768   def : Pat<(f128 (fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
2769   // Round to nearest, ties away from zero
2770   def : Pat<(f128 (fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
2771   // Round towards Zero
2772   def : Pat<(f128 (ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
2773   // Round towards +Inf
2774   def : Pat<(f128 (fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
2775   // Round towards -Inf
2776   def : Pat<(f128 (ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
2778   // Use current rounding mode, [with Inexact]
2779   def : Pat<(f128 (frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
2781   // Round Quad-Precision to Double-Extended Precision (fp80)
2782   def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2784   //===--------------------------------------------------------------------===//
2785   // Insert/Extract Instructions
2787   // Insert Exponent DP/QP
2788   // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2789   def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2790                           "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
2791   // vB NOTE: only vB.dword[0] is used, that's why we don't use
2792   //          X_VT5_VA5_VB5 form
2793   def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2794                           "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2796   def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
2797             (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
2799   // Extract Exponent/Significand DP/QP
2800   def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2801   def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2803   def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2804   def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2806   def : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
2807             (i64 (MFVSRD (EXTRACT_SUBREG
2808                            (v2i64 (XSXEXPQP $vA)), sub_64)))>;
2810   // Vector Insert Word
2811   // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2812   def XXINSERTW   :
2813     XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2814                      (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2815                      "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2816                      [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
2817                                                    imm32SExt16:$UIM))]>,
2818                      RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2820   // Vector Extract Unsigned Word
2821   def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2822                                   (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2823                                   "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2825   // Vector Insert Exponent DP/SP
2826   def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2827     IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2828   def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2829     IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2831   // Vector Extract Exponent/Significand DP/SP
2832   def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2833                                  [(set v2i64: $XT,
2834                                   (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2835   def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2836                                  [(set v4i32: $XT,
2837                                   (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2838   def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2839                                  [(set v2i64: $XT,
2840                                   (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2841   def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2842                                  [(set v4i32: $XT,
2843                                   (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2845   let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2846   // Extra patterns expanding to vector Extract Word/Insert Word
2847   def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2848             (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2849   def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2850             (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2851   } // AddedComplexity = 400, HasP9Vector
2853   //===--------------------------------------------------------------------===//
2855   // Test Data Class SP/DP/QP
2856   def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2857                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2858                               "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2859   def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2860                               (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2861                               "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2862   def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2863                               (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2864                               "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2866   // Vector Test Data Class SP/DP
2867   def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2868                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2869                               "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2870                               [(set v4i32: $XT,
2871                                (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
2872   def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2873                               (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2874                               "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2875                               [(set v2i64: $XT,
2876                                (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
2878   //===--------------------------------------------------------------------===//
2880   // Maximum/Minimum Type-C/Type-J DP
2881   // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2882   def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2883                                  IIC_VecFP, []>;
2884   def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2885                                  IIC_VecFP, []>;
2886   def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2887                                  IIC_VecFP, []>;
2888   def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2889                                  IIC_VecFP, []>;
2891   //===--------------------------------------------------------------------===//
2893   // Vector Byte-Reverse H/W/D/Q Word
2894   def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2895   def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2896   def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2897   def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2899   // Vector Reverse
2900   def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)),
2901             (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2902   def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)),
2903             (v4i32 (XXBRW $A))>;
2904   def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)),
2905             (v2i64 (XXBRD $A))>;
2906   def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)),
2907             (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2909   // Vector Permute
2910   def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2911                                 IIC_VecPerm, []>;
2912   def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2913                                 IIC_VecPerm, []>;
2915   // Vector Splat Immediate Byte
2916   def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2917                             "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
2919   //===--------------------------------------------------------------------===//
2920   // Vector/Scalar Load/Store Instructions
2922   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2923   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2924   let mayLoad = 1, mayStore = 0 in {
2925   // Load Vector
2926   def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2927                             "lxv $XT, $src", IIC_LdStLFD, []>;
2928   // Load DWord
2929   def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2930                        "lxsd $vD, $src", IIC_LdStLFD, []>;
2931   // Load SP from src, convert it to DP, and place in dword[0]
2932   def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2933                        "lxssp $vD, $src", IIC_LdStLFD, []>;
2935   // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2936   // "out" and "in" dag
2937   class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2938                       RegisterOperand vtype, list<dag> pattern>
2939     : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2940               !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
2942   // Load as Integer Byte/Halfword & Zero Indexed
2943   def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2944                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2945   def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2946                               [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2948   // Load Vector Halfword*8/Byte*16 Indexed
2949   def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2950   def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2952   // Load Vector Indexed
2953   def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2954                 [(set v2f64:$XT, (load xaddrX16:$src))]>;
2955   // Load Vector (Left-justified) with Length
2956   def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2957                    "lxvl $XT, $src, $rB", IIC_LdStLoad,
2958                    [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
2959   def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2960                    "lxvll $XT, $src, $rB", IIC_LdStLoad,
2961                    [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
2963   // Load Vector Word & Splat Indexed
2964   def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2965   } // mayLoad
2967   // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2968   // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2969   let mayStore = 1, mayLoad = 0 in {
2970   // Store Vector
2971   def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2972                              "stxv $XT, $dst", IIC_LdStSTFD, []>;
2973   // Store DWord
2974   def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2975                         "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2976   // Convert DP of dword[0] to SP, and Store to dst
2977   def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2978                         "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2980   // [PO S RA RB XO SX]
2981   class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2982                       RegisterOperand vtype, list<dag> pattern>
2983     : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2984               !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
2986   // Store as Integer Byte/Halfword Indexed
2987   def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2988                                [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2989   def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2990                                [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2991   let isCodeGenOnly = 1 in {
2992     def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
2993     def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
2994   }
2996   // Store Vector Halfword*8/Byte*16 Indexed
2997   def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2998   def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
3000   // Store Vector Indexed
3001   def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
3002                  [(store v2f64:$XT, xaddrX16:$dst)]>;
3004   // Store Vector (Left-justified) with Length
3005   def STXVL : XX1Form_memOp<31, 397, (outs),
3006                             (ins vsrc:$XT, memr:$dst, g8rc:$rB),
3007                             "stxvl $XT, $dst, $rB", IIC_LdStLoad,
3008                             [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
3009                               i64:$rB)]>;
3010   def STXVLL : XX1Form_memOp<31, 429, (outs),
3011                             (ins vsrc:$XT, memr:$dst, g8rc:$rB),
3012                             "stxvll $XT, $dst, $rB", IIC_LdStLoad,
3013                             [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
3014                               i64:$rB)]>;
3015   } // mayStore
3017   let Predicates = [IsLittleEndian] in {
3018   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3019            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
3020   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3021            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
3022   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3023            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
3024   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3025            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
3026   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3027            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
3028   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3029            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
3030   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3031            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
3032   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3033            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
3034   }
3036   let Predicates = [IsBigEndian] in {
3037   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3038            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
3039   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3040            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
3041   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3042            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
3043   def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3044            (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
3045   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
3046            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
3047   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
3048            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
3049   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
3050            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
3051   def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
3052            (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
3053   }
3055   // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
3056   // of f64
3057   def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
3058             (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
3059   def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
3060             (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
3062   // Patterns for which instructions from ISA 3.0 are a better match
3063   let Predicates = [IsLittleEndian, HasP9Vector] in {
3064   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3065             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
3066   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3067             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
3068   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3069             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
3070   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3071             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
3072   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3073             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
3074   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3075             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
3076   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3077             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
3078   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3079             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
3080   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
3081             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
3082   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
3083             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
3084   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
3085             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
3086   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
3087             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
3088   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
3089             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
3090   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
3091             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
3092   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
3093             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
3094   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3095             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3097   def : Pat<(v8i16 (PPCld_vec_be xoaddr:$src)),
3098             (COPY_TO_REGCLASS (LXVH8X xoaddr:$src), VRRC)>;
3099   def : Pat<(PPCst_vec_be v8i16:$rS, xoaddr:$dst),
3100             (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3102   def : Pat<(v16i8 (PPCld_vec_be xoaddr:$src)),
3103             (COPY_TO_REGCLASS (LXVB16X xoaddr:$src), VRRC)>;
3104   def : Pat<(PPCst_vec_be v16i8:$rS, xoaddr:$dst),
3105             (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3106   } // IsLittleEndian, HasP9Vector
3108   let Predicates = [IsBigEndian, HasP9Vector] in {
3109   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3110             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
3111   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3112             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
3113   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3114             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
3115   def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3116             (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
3117   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3118             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
3119   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3120             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
3121   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3122             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
3123   def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3124             (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
3125   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
3126             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
3127   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
3128             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
3129   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
3130             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
3131   def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
3132             (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
3133   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
3134             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3135   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
3136             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
3137   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
3138             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
3139   def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3140             (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
3141   } // IsBigEndian, HasP9Vector
3143   // D-Form Load/Store
3144   def : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3145   def : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3146   def : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3147   def : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
3148   def : Pat<(f128  (quadwOffsetLoad iaddrX16:$src)),
3149             (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3150   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>;
3151   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>;
3153   def : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3154   def : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3155   def : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3156   def : Pat<(quadwOffsetStore  f128:$rS, iaddrX16:$dst),
3157             (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3158   def : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
3159   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst),
3160             (STXV $rS, memrix16:$dst)>;
3161   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst),
3162             (STXV $rS, memrix16:$dst)>;
3165   def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3166   def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3167   def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3168   def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3169   def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
3170   def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
3171   def : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
3172             (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
3173   def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
3174             (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3175   def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
3176             (STXVX $rS, xoaddr:$dst)>;
3177   def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
3178             (STXVX $rS, xoaddr:$dst)>;
3179   def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
3180             (STXVX $rS, xoaddr:$dst)>;
3181   def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
3182             (STXVX $rS, xoaddr:$dst)>;
3183   def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3184             (STXVX $rS, xoaddr:$dst)>;
3185   def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
3186             (STXVX $rS, xoaddr:$dst)>;
3188   let AddedComplexity = 400 in {
3189     // LIWAX - This instruction is used for sign extending i32 -> i64.
3190     // LIWZX - This instruction will be emitted for i32, f32, and when
3191     //         zero-extending i32 to i64 (zext i32 -> i64).
3192     let Predicates = [IsLittleEndian] in {
3194       def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
3195                 (v2i64 (XXPERMDIs
3196                 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC), 2))>;
3198       def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
3199                 (v2i64 (XXPERMDIs
3200                 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
3202       def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3203                 (v4i32 (XXPERMDIs
3204                 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
3206       def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3207                 (v4f32 (XXPERMDIs
3208                 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
3209     }
3211     let Predicates = [IsBigEndian] in {
3212       def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
3213                 (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
3215       def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
3216                 (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
3218       def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3219                 (v4i32 (XXSLDWIs
3220                 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3222       def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3223                 (v4f32 (XXSLDWIs
3224                 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3225     }
3227   }
3229   // Build vectors from i8 loads
3230   def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
3231             (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
3232   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
3233             (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
3234   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
3235            (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
3236   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
3237             (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
3238   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
3239             (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
3240   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
3241             (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
3243   // Build vectors from i16 loads
3244   def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
3245             (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
3246   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
3247             (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
3248   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
3249            (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
3250   def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
3251             (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
3252   def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
3253             (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
3255   let Predicates = [IsBigEndian, HasP9Vector] in {
3256   // Scalar stores of i8
3257   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3258             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
3259   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3260             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3261   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3262             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
3263   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3264             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3265   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3266             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
3267   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3268             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3269   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3270             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
3271   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3272             (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3273   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3274             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
3275   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3276             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3277   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3278             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
3279   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3280             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3281   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3282             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
3283   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3284             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3285   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3286             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
3287   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3288             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3290   // Scalar stores of i16
3291   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3292             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3293   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3294             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3295   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3296             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3297   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3298             (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3299   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3300             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3301   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3302             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3303   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3304             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3305   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3306             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3307   } // IsBigEndian, HasP9Vector
3309   let Predicates = [IsLittleEndian, HasP9Vector] in {
3310   // Scalar stores of i8
3311   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3312             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3313   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3314             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
3315   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3316             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3317   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3318             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
3319   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3320             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3321   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3322             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
3323   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3324             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3325   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3326             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
3327   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3328             (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3329   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3330             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
3331   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3332             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3333   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3334             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
3335   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3336             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3337   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3338             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
3339   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3340             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3341   def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3342             (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
3344   // Scalar stores of i16
3345   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3346             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
3347   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3348             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
3349   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3350             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
3351   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3352             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
3353   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3354             (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
3355   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3356             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
3357   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3358             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
3359   def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3360             (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
3361   } // IsLittleEndian, HasP9Vector
3364   // Vector sign extensions
3365   def : Pat<(f64 (PPCVexts f64:$A, 1)),
3366             (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
3367   def : Pat<(f64 (PPCVexts f64:$A, 2)),
3368             (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
3370   def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
3371                           "#DFLOADf32",
3372                           [(set f32:$XT, (load iaddrX4:$src))]>;
3373   def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
3374                           "#DFLOADf64",
3375                           [(set f64:$XT, (load iaddrX4:$src))]>;
3376   def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
3377                           "#DFSTOREf32",
3378                           [(store f32:$XT, iaddrX4:$dst)]>;
3379   def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
3380                           "#DFSTOREf64",
3381                           [(store f64:$XT, iaddrX4:$dst)]>;
3383   def : Pat<(f64 (extloadf32 iaddrX4:$src)),
3384             (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>;
3385   def : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))),
3386             (f32 (DFLOADf32 iaddrX4:$src))>;
3388   def : Pat<(v4f32 (PPCldvsxlh xaddr:$src)),
3389             (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>;
3390   def : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)),
3391             (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>;
3393   let AddedComplexity = 400 in {
3394   // The following pseudoinstructions are used to ensure the utilization
3395   // of all 64 VSX registers.
3396     let Predicates = [IsLittleEndian, HasP9Vector] in {
3397       def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
3398                 (v2i64 (XXPERMDIs
3399                 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>;
3400       def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
3401                 (v2i64 (XXPERMDIs
3402                 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>;
3404       def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
3405                 (v2f64 (XXPERMDIs
3406                 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>;
3407       def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
3408                 (v2f64 (XXPERMDIs
3409                 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>;
3410       def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
3411                 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3412                              sub_64), xaddrX4:$src)>;
3413       def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
3414                 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3415                              sub_64), xaddrX4:$src)>;
3416       def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
3417                 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
3418       def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
3419                 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
3420       def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
3421                 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3422                              sub_64), iaddrX4:$src)>;
3423       def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
3424                 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
3425                             iaddrX4:$src)>;
3426       def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
3427                 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
3428       def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
3429                 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
3430     } // IsLittleEndian, HasP9Vector
3432     let Predicates = [IsBigEndian, HasP9Vector] in {
3433       def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
3434                 (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
3435       def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
3436                 (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
3438       def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
3439                 (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
3440       def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
3441                 (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
3442       def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
3443                 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3444                              sub_64), xaddrX4:$src)>;
3445       def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
3446                 (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3447                              sub_64), xaddrX4:$src)>;
3448       def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
3449                 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
3450       def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
3451                 (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
3452       def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
3453                 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3454                              sub_64), iaddrX4:$src)>;
3455       def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
3456                 (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
3457                              sub_64), iaddrX4:$src)>;
3458       def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
3459                 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
3460       def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
3461                 (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
3462     } // IsBigEndian, HasP9Vector
3463   }
3465   let Predicates = [IsBigEndian, HasP9Vector] in {
3467     // (Un)Signed DWord vector extract -> QP
3468     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3469               (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3470     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3471               (f128 (XSCVSDQP
3472                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3473     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3474               (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3475     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3476               (f128 (XSCVUDQP
3477                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3479     // (Un)Signed Word vector extract -> QP
3480     def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
3481               (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
3482     foreach Idx = [0,2,3] in {
3483       def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
3484                 (f128 (XSCVSDQP (EXTRACT_SUBREG
3485                                 (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
3486     }
3487     foreach Idx = 0-3 in {
3488       def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
3489                 (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
3490     }
3492     // (Un)Signed HWord vector extract -> QP
3493     foreach Idx = 0-7 in {
3494       def : Pat<(f128 (sint_to_fp
3495                         (i32 (sext_inreg
3496                                (vector_extract v8i16:$src, Idx), i16)))),
3497               (f128 (XSCVSDQP (EXTRACT_SUBREG
3498                                 (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
3499                                 sub_64)))>;
3500       // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
3501       def : Pat<(f128 (uint_to_fp
3502                         (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
3503                 (f128 (XSCVUDQP (EXTRACT_SUBREG
3504                                   (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
3505     }
3507     // (Un)Signed Byte vector extract -> QP
3508     foreach Idx = 0-15 in {
3509       def : Pat<(f128 (sint_to_fp
3510                         (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
3511                                          i8)))),
3512                 (f128 (XSCVSDQP (EXTRACT_SUBREG
3513                                   (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
3514       def : Pat<(f128 (uint_to_fp
3515                         (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
3516                 (f128 (XSCVUDQP
3517                         (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
3518     }
3520     // Unsiged int in vsx register -> QP
3521     def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
3522               (f128 (XSCVUDQP
3523                       (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
3524   } // IsBigEndian, HasP9Vector
3526   let Predicates = [IsLittleEndian, HasP9Vector] in {
3528     // (Un)Signed DWord vector extract -> QP
3529     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3530               (f128 (XSCVSDQP
3531                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3532     def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3533               (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3534     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3535               (f128 (XSCVUDQP
3536                       (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3537     def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3538               (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3540     // (Un)Signed Word vector extract -> QP
3541     foreach Idx = [[0,3],[1,2],[3,0]] in {
3542       def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
3543                 (f128 (XSCVSDQP (EXTRACT_SUBREG
3544                                   (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
3545                                   sub_64)))>;
3546     }
3547     def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
3548               (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
3550     foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
3551       def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
3552                 (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
3553     }
3555     // (Un)Signed HWord vector extract -> QP
3556     // The Nested foreach lists identifies the vector element and corresponding
3557     // register byte location.
3558     foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
3559       def : Pat<(f128 (sint_to_fp
3560                         (i32 (sext_inreg
3561                                (vector_extract v8i16:$src, !head(Idx)), i16)))),
3562                 (f128 (XSCVSDQP
3563                         (EXTRACT_SUBREG (VEXTSH2D
3564                                           (VEXTRACTUH !head(!tail(Idx)), $src)),
3565                                         sub_64)))>;
3566       def : Pat<(f128 (uint_to_fp
3567                         (and (i32 (vector_extract v8i16:$src, !head(Idx))),
3568                              65535))),
3569                 (f128 (XSCVUDQP (EXTRACT_SUBREG
3570                                   (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
3571     }
3573     // (Un)Signed Byte vector extract -> QP
3574     foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
3575                    [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
3576       def : Pat<(f128 (sint_to_fp
3577                         (i32 (sext_inreg
3578                                (vector_extract v16i8:$src, !head(Idx)), i8)))),
3579                 (f128 (XSCVSDQP
3580                         (EXTRACT_SUBREG
3581                           (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
3582                           sub_64)))>;
3583       def : Pat<(f128 (uint_to_fp
3584                         (and (i32 (vector_extract v16i8:$src, !head(Idx))),
3585                              255))),
3586                 (f128 (XSCVUDQP
3587                         (EXTRACT_SUBREG
3588                           (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
3589     }
3591     // Unsiged int in vsx register -> QP
3592     def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
3593               (f128 (XSCVUDQP
3594                       (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
3595   } // IsLittleEndian, HasP9Vector
3597   // Convert (Un)Signed DWord in memory -> QP
3598   def : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))),
3599             (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>;
3600   def : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))),
3601             (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>;
3602   def : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))),
3603             (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>;
3604   def : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))),
3605             (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>;
3607   // Convert Unsigned HWord in memory -> QP
3608   def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
3609             (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
3611   // Convert Unsigned Byte in memory -> QP
3612   def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
3613             (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
3615   // Truncate & Convert QP -> (Un)Signed (D)Word.
3616   def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3617   def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3618   def : Pat<(i32 (fp_to_sint f128:$src)),
3619             (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
3620   def : Pat<(i32 (fp_to_uint f128:$src)),
3621             (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
3623   // Instructions for store(fptosi).
3624   // The 8-byte version is repeated here due to availability of D-Form STXSD.
3625   def : Pat<(PPCstore_scal_int_from_vsr
3626               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8),
3627             (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3628                     xaddrX4:$dst)>;
3629   def : Pat<(PPCstore_scal_int_from_vsr
3630               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8),
3631             (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3632                    iaddrX4:$dst)>;
3633   def : Pat<(PPCstore_scal_int_from_vsr
3634               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
3635             (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3636   def : Pat<(PPCstore_scal_int_from_vsr
3637               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
3638             (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3639   def : Pat<(PPCstore_scal_int_from_vsr
3640               (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
3641             (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3642   def : Pat<(PPCstore_scal_int_from_vsr
3643               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8),
3644             (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>;
3645   def : Pat<(PPCstore_scal_int_from_vsr
3646               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8),
3647             (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>;
3648   def : Pat<(PPCstore_scal_int_from_vsr
3649               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
3650             (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3651   def : Pat<(PPCstore_scal_int_from_vsr
3652               (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
3653             (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3655   // Instructions for store(fptoui).
3656   def : Pat<(PPCstore_scal_int_from_vsr
3657               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8),
3658             (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3659                     xaddrX4:$dst)>;
3660   def : Pat<(PPCstore_scal_int_from_vsr
3661               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8),
3662             (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3663                    iaddrX4:$dst)>;
3664   def : Pat<(PPCstore_scal_int_from_vsr
3665               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
3666             (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3667   def : Pat<(PPCstore_scal_int_from_vsr
3668               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
3669             (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3670   def : Pat<(PPCstore_scal_int_from_vsr
3671               (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
3672             (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3673   def : Pat<(PPCstore_scal_int_from_vsr
3674               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8),
3675             (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>;
3676   def : Pat<(PPCstore_scal_int_from_vsr
3677               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8),
3678             (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>;
3679   def : Pat<(PPCstore_scal_int_from_vsr
3680               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
3681             (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3682   def : Pat<(PPCstore_scal_int_from_vsr
3683               (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
3684             (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3686   // Round & Convert QP -> DP/SP
3687   def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>;
3688   def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
3690   // Convert SP -> QP
3691   def : Pat<(f128 (fpextend f32:$src)),
3692             (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
3694 } // end HasP9Vector, AddedComplexity
3696 let AddedComplexity = 400 in {
3697   let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in {
3698     def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
3699               (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
3700   }
3701   let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in {
3702     def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
3703               (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
3704   }
3707 let Predicates = [HasP9Vector] in {
3708   let mayStore = 1 in {
3709     def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
3710                                           (ins spilltovsrrc:$XT, memrr:$dst),
3711                                           "#SPILLTOVSR_STX", []>;
3712     def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
3713                               "#SPILLTOVSR_ST", []>;
3714   }
3715   let mayLoad = 1 in {
3716     def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
3717                                           (ins memrr:$src),
3718                                           "#SPILLTOVSR_LDX", []>;
3719     def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
3720                               "#SPILLTOVSR_LD", []>;
3722   }
3724 // Integer extend helper dags 32 -> 64
3725 def AnyExts {
3726   dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
3727   dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
3728   dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
3729   dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
3732 def DblToFlt {
3733   dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
3734   dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
3735   dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
3736   dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
3739 def ExtDbl {
3740   dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
3741   dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
3742   dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
3743   dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
3744   dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
3745   dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
3746   dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
3747   dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
3750 def ByteToWord {
3751   dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
3752   dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
3753   dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
3754   dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
3755   dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
3756   dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
3757   dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
3758   dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
3761 def ByteToDWord {
3762   dag LE_A0 = (i64 (sext_inreg
3763               (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
3764   dag LE_A1 = (i64 (sext_inreg
3765               (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
3766   dag BE_A0 = (i64 (sext_inreg
3767               (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
3768   dag BE_A1 = (i64 (sext_inreg
3769               (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
3772 def HWordToWord {
3773   dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
3774   dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
3775   dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
3776   dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
3777   dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
3778   dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
3779   dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
3780   dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
3783 def HWordToDWord {
3784   dag LE_A0 = (i64 (sext_inreg
3785               (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
3786   dag LE_A1 = (i64 (sext_inreg
3787               (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
3788   dag BE_A0 = (i64 (sext_inreg
3789               (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
3790   dag BE_A1 = (i64 (sext_inreg
3791               (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
3794 def WordToDWord {
3795   dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
3796   dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
3797   dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
3798   dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
3801 def FltToIntLoad {
3802   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
3804 def FltToUIntLoad {
3805   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
3807 def FltToLongLoad {
3808   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
3810 def FltToLongLoadP9 {
3811   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A)))));
3813 def FltToULongLoad {
3814   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
3816 def FltToULongLoadP9 {
3817   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A)))));
3819 def FltToLong {
3820   dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
3822 def FltToULong {
3823   dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
3825 def DblToInt {
3826   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
3827   dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
3828   dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
3829   dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
3831 def DblToUInt {
3832   dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
3833   dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
3834   dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
3835   dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
3837 def DblToLong {
3838   dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
3840 def DblToULong {
3841   dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
3843 def DblToIntLoad {
3844   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
3846 def DblToIntLoadP9 {
3847   dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A)))));
3849 def DblToUIntLoad {
3850   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
3852 def DblToUIntLoadP9 {
3853   dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A)))));
3855 def DblToLongLoad {
3856   dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
3858 def DblToULongLoad {
3859   dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
3862 // FP merge dags (for f32 -> v4f32)
3863 def MrgFP {
3864   dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
3865                                (COPY_TO_REGCLASS $C, VSRC), 0));
3866   dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
3867                                (COPY_TO_REGCLASS $D, VSRC), 0));
3868   dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
3869   dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
3870   dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
3871   dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
3874 // Word-element merge dags - conversions from f64 to i32 merged into vectors.
3875 def MrgWords {
3876   // For big endian, we merge low and hi doublewords (A, B).
3877   dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
3878   dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
3879   dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
3880   dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
3881   dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
3882   dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
3884   // For little endian, we merge low and hi doublewords (B, A).
3885   dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
3886   dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
3887   dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
3888   dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
3889   dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
3890   dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
3892   // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
3893   // then merge.
3894   dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
3895                             (COPY_TO_REGCLASS f64:$C, VSRC), 0));
3896   dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
3897                             (COPY_TO_REGCLASS f64:$D, VSRC), 0));
3898   dag CVACS = (v4i32 (XVCVDPSXWS AC));
3899   dag CVBDS = (v4i32 (XVCVDPSXWS BD));
3900   dag CVACU = (v4i32 (XVCVDPUXWS AC));
3901   dag CVBDU = (v4i32 (XVCVDPUXWS BD));
3903   // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
3904   // then merge.
3905   dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
3906                             (COPY_TO_REGCLASS f64:$B, VSRC), 0));
3907   dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
3908                             (COPY_TO_REGCLASS f64:$A, VSRC), 0));
3909   dag CVDBS = (v4i32 (XVCVDPSXWS DB));
3910   dag CVCAS = (v4i32 (XVCVDPSXWS CA));
3911   dag CVDBU = (v4i32 (XVCVDPUXWS DB));
3912   dag CVCAU = (v4i32 (XVCVDPUXWS CA));
3915 // Patterns for BUILD_VECTOR nodes.
3916 let AddedComplexity = 400 in {
3918   let Predicates = [HasVSX] in {
3919     // Build vectors of floating point converted to i32.
3920     def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
3921                                    DblToInt.A, DblToInt.A)),
3922               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
3923     def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
3924                                    DblToUInt.A, DblToUInt.A)),
3925               (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
3926     def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
3927               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
3928                                (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
3929     def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
3930               (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
3931                                (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
3932     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3933               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3934                                 (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3935     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3936               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3937                                 (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3938     def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
3939               (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
3940     def : Pat<(v2f64 (PPCldsplat xoaddr:$A)),
3941               (v2f64 (LXVDSX xoaddr:$A))>;
3942     def : Pat<(v2i64 (PPCldsplat xoaddr:$A)),
3943               (v2i64 (LXVDSX xoaddr:$A))>;
3945     // Build vectors of floating point converted to i64.
3946     def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
3947               (v2i64 (XXPERMDIs
3948                        (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
3949     def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
3950               (v2i64 (XXPERMDIs
3951                        (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
3952     def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
3953               (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
3954     def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
3955               (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
3956   }
3958   let Predicates = [HasVSX, NoP9Vector] in {
3959     // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
3960     def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
3961               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3962                                 (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3963     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
3964               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3965                                 (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3966     def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
3967               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3968                                               (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3969     def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
3970               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3971                                               (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3972   }
3974   let Predicates = [IsBigEndian, HasP8Vector] in {
3975     def : Pat<DWToSPExtractConv.BVU,
3976               (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
3977                               (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
3978     def : Pat<DWToSPExtractConv.BVS,
3979               (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
3980                               (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
3981     def : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src),
3982               (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3983     def : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src),
3984               (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
3986     // Elements in a register on a BE system are in order <0, 1, 2, 3>.
3987     // The store instructions store the second word from the left.
3988     // So to align element zero, we need to modulo-left-shift by 3 words.
3989     // Similar logic applies for elements 2 and 3.
3990     foreach Idx = [ [0,3], [2,1], [3,2] ] in {
3991       def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
3992                 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3993                                        sub_64), xoaddr:$src)>;
3994       def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
3995                 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
3996                                        sub_64), xoaddr:$src)>;
3997     }
3998   }
4000   let Predicates = [HasP8Vector, IsBigEndian, NoP9Vector] in {
4001     def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
4002               (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
4003     def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
4004               (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
4005     def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
4006               (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4007                           xoaddr:$src)>;
4008     def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
4009               (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4010                           xoaddr:$src)>;
4011    }
4013   // Big endian, available on all targets with VSX
4014   let Predicates = [IsBigEndian, HasVSX] in {
4015     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
4016               (v2f64 (XXPERMDI
4017                         (COPY_TO_REGCLASS $A, VSRC),
4018                         (COPY_TO_REGCLASS $B, VSRC), 0))>;
4020     def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
4021               (VMRGEW MrgFP.AC, MrgFP.BD)>;
4022     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
4023                                    DblToFlt.B0, DblToFlt.B1)),
4024               (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
4026     // Convert 4 doubles to a vector of ints.
4027     def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
4028                                    DblToInt.C, DblToInt.D)),
4029               (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
4030     def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
4031                                    DblToUInt.C, DblToUInt.D)),
4032               (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
4033     def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
4034                                    ExtDbl.B0S, ExtDbl.B1S)),
4035               (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
4036     def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
4037                                    ExtDbl.B0U, ExtDbl.B1U)),
4038               (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
4039   }
4041   let Predicates = [IsLittleEndian, HasP8Vector] in {
4042     def : Pat<DWToSPExtractConv.BVU,
4043               (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
4044                               (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
4045     def : Pat<DWToSPExtractConv.BVS,
4046               (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
4047                               (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
4048     def : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src),
4049               (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
4050     def : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src),
4051               (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
4053     // Elements in a register on a LE system are in order <3, 2, 1, 0>.
4054     // The store instructions store the second word from the left.
4055     // So to align element 3, we need to modulo-left-shift by 3 words.
4056     // Similar logic applies for elements 0 and 1.
4057     foreach Idx = [ [0,2], [1,1], [3,3] ] in {
4058       def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
4059                 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
4060                                        sub_64), xoaddr:$src)>;
4061       def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
4062                 (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
4063                                        sub_64), xoaddr:$src)>;
4064     }
4065   }
4067   let Predicates = [HasP8Vector, IsLittleEndian, NoP9Vector] in {
4068     def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
4069               (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4070                           xoaddr:$src)>;
4071     def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
4072               (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
4073                           xoaddr:$src)>;
4074     def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
4075               (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
4076     def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
4077               (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
4078    }
4080   let Predicates = [IsLittleEndian, HasVSX] in {
4081   // Little endian, available on all targets with VSX
4082     def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
4083               (v2f64 (XXPERMDI
4084                         (COPY_TO_REGCLASS $B, VSRC),
4085                         (COPY_TO_REGCLASS $A, VSRC), 0))>;
4087     def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
4088               (VMRGEW MrgFP.AC, MrgFP.BD)>;
4089     def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
4090                                    DblToFlt.B0, DblToFlt.B1)),
4091               (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
4093     // Convert 4 doubles to a vector of ints.
4094     def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
4095                                    DblToInt.C, DblToInt.D)),
4096               (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
4097     def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
4098                                    DblToUInt.C, DblToUInt.D)),
4099               (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
4100     def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
4101                                    ExtDbl.B0S, ExtDbl.B1S)),
4102               (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
4103     def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
4104                                    ExtDbl.B0U, ExtDbl.B1U)),
4105               (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
4106   }
4108   let Predicates = [HasDirectMove] in {
4109     // Endianness-neutral constant splat on P8 and newer targets. The reason
4110     // for this pattern is that on targets with direct moves, we don't expand
4111     // BUILD_VECTOR nodes for v4i32.
4112     def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
4113                                    immSExt5NonZero:$A, immSExt5NonZero:$A)),
4114               (v4i32 (VSPLTISW imm:$A))>;
4115   }
4117   let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
4118     // Big endian integer vectors using direct moves.
4119     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
4120               (v2i64 (XXPERMDI
4121                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
4122                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
4123     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4124               (XXPERMDI
4125                 (COPY_TO_REGCLASS
4126                   (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
4127                 (COPY_TO_REGCLASS
4128                   (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
4129     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
4130               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
4131   }
4133   let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
4134     // Little endian integer vectors using direct moves.
4135     def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
4136               (v2i64 (XXPERMDI
4137                         (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
4138                         (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
4139     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4140               (XXPERMDI
4141                 (COPY_TO_REGCLASS
4142                   (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
4143                 (COPY_TO_REGCLASS
4144                   (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
4145     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
4146               (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
4147   }
4149   let Predicates = [HasP8Vector] in {
4150     def : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
4151               (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
4152     def : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
4153               (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
4154     def : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
4155               (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
4156     def : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
4157               (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
4158   }
4160   let Predicates = [HasP9Vector] in {
4161     // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
4162     def : Pat<(v4i32 (scalar_to_vector i32:$A)),
4163               (v4i32 (MTVSRWS $A))>;
4164     def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
4165               (v4i32 (MTVSRWS $A))>;
4166     def : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4167                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4168                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4169                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4170                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4171                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4172                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
4173                                    immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
4174               (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
4175     def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
4176               (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
4177     def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
4178               (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
4179     def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
4180               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
4181                                 (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>;
4182     def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
4183               (v4i32 (XXSPLTW (COPY_TO_REGCLASS
4184                                 (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>;
4185     def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
4186               (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
4187                                               (DFLOADf32 iaddrX4:$A),
4188                                               VSFRC)), 0))>;
4189     def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
4190               (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
4191                                               (DFLOADf32 iaddrX4:$A),
4192                                               VSFRC)), 0))>;
4193     def : Pat<(v4f32 (PPCldsplat xoaddr:$A)),
4194               (v4f32 (LXVWSX xoaddr:$A))>;
4195     def : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
4196               (v4i32 (LXVWSX xoaddr:$A))>;
4197   }
4199   let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
4200     def : Pat<(i64 (extractelt v2i64:$A, 1)),
4201               (i64 (MFVSRLD $A))>;
4202     // Better way to build integer vectors if we have MTVSRDD. Big endian.
4203     def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
4204               (v2i64 (MTVSRDD $rB, $rA))>;
4205     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4206               (MTVSRDD
4207                 (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
4208                 (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
4209   }
4211   let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
4212     def : Pat<(i64 (extractelt v2i64:$A, 0)),
4213               (i64 (MFVSRLD $A))>;
4214     // Better way to build integer vectors if we have MTVSRDD. Little endian.
4215     def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
4216               (v2i64 (MTVSRDD $rB, $rA))>;
4217     def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
4218               (MTVSRDD
4219                 (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
4220                 (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
4221   }
4222   // P9 Altivec instructions that can be used to build vectors.
4223   // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
4224   // with complexities of existing build vector patterns in this file.
4225   let Predicates = [HasP9Altivec, IsLittleEndian] in {
4226     def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
4227               (v2i64 (VEXTSW2D $A))>;
4228     def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
4229               (v2i64 (VEXTSH2D $A))>;
4230     def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
4231                       HWordToWord.LE_A2, HWordToWord.LE_A3)),
4232               (v4i32 (VEXTSH2W $A))>;
4233     def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
4234                       ByteToWord.LE_A2, ByteToWord.LE_A3)),
4235               (v4i32 (VEXTSB2W $A))>;
4236     def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
4237               (v2i64 (VEXTSB2D $A))>;
4238   }
4240   let Predicates = [HasP9Altivec, IsBigEndian] in {
4241     def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
4242               (v2i64 (VEXTSW2D $A))>;
4243     def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
4244               (v2i64 (VEXTSH2D $A))>;
4245     def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
4246                       HWordToWord.BE_A2, HWordToWord.BE_A3)),
4247               (v4i32 (VEXTSH2W $A))>;
4248     def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
4249                       ByteToWord.BE_A2, ByteToWord.BE_A3)),
4250               (v4i32 (VEXTSB2W $A))>;
4251     def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
4252               (v2i64 (VEXTSB2D $A))>;
4253   }
4255   let Predicates = [HasP9Altivec] in {
4256     def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)),
4257               (v2i64 (VEXTSB2D $A))>;
4258     def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)),
4259               (v2i64 (VEXTSH2D $A))>;
4260     def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)),
4261               (v2i64 (VEXTSW2D $A))>;
4262     def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)),
4263               (v4i32 (VEXTSB2W $A))>;
4264     def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)),
4265               (v4i32 (VEXTSH2W $A))>;
4266   }
4269 // Put this P9Altivec related definition here since it's possible to be 
4270 // selected to VSX instruction xvnegsp, avoid possible undef.
4271 let Predicates = [HasP9Altivec] in {
4273   def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
4274             (v4i32 (VABSDUW $A, $B))>;
4276   def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
4277             (v8i16 (VABSDUH $A, $B))>;
4279   def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
4280             (v16i8 (VABSDUB $A, $B))>;
4282   // As PPCVABSD description, the last operand indicates whether do the
4283   // sign bit flip.
4284   def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
4285             (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;