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