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