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]>;
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 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                         [(set v4i32:$XT, (int_ppc_vsx_lxvw4x xoaddr:$src))]>;
142  } // mayLoad
143
144  // Store indexed instructions
145  let mayStore = 1 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                         [(store v4i32:$XT, xoaddr:$dst)]>;
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  let isCodeGenOnly = 1 in
848  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
849                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
850  def XXSEL : XX4Form<60, 3,
851                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
852                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
853
854  def XXSLDWI : XX3Form_2<60, 2,
855                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
856                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
857                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
858                                                  imm32SExt16:$SHW))]>;
859  def XXSPLTW : XX2Form_2<60, 164,
860                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
861                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
862                       [(set v4i32:$XT,
863                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
864  let isCodeGenOnly = 1 in
865  def XXSPLTWs : XX2Form_2<60, 164,
866                       (outs vsrc:$XT), (ins vfrc:$XB, u2imm:$UIM),
867                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
868} // hasSideEffects
869} // UseVSXReg = 1
870
871// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
872// instruction selection into a branch sequence.
873let usesCustomInserter = 1,    // Expanded after instruction selection.
874    PPC970_Single = 1 in {
875
876  def SELECT_CC_VSRC: Pseudo<(outs vsrc:$dst),
877                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
878                             "#SELECT_CC_VSRC",
879                             []>;
880  def SELECT_VSRC: Pseudo<(outs vsrc:$dst),
881                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
882                          "#SELECT_VSRC",
883                          [(set v2f64:$dst,
884                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
885  def SELECT_CC_VSFRC: Pseudo<(outs f8rc:$dst),
886                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
887                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
888                              []>;
889  def SELECT_VSFRC: Pseudo<(outs f8rc:$dst),
890                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
891                           "#SELECT_VSFRC",
892                           [(set f64:$dst,
893                                 (select i1:$cond, f64:$T, f64:$F))]>;
894  def SELECT_CC_VSSRC: Pseudo<(outs f4rc:$dst),
895                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
896                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
897                              []>;
898  def SELECT_VSSRC: Pseudo<(outs f4rc:$dst),
899                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
900                           "#SELECT_VSSRC",
901                           [(set f32:$dst,
902                                 (select i1:$cond, f32:$T, f32:$F))]>;
903} // usesCustomInserter
904} // AddedComplexity
905
906def : InstAlias<"xvmovdp $XT, $XB",
907                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
908def : InstAlias<"xvmovsp $XT, $XB",
909                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
910
911def : InstAlias<"xxspltd $XT, $XB, 0",
912                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
913def : InstAlias<"xxspltd $XT, $XB, 1",
914                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
915def : InstAlias<"xxmrghd $XT, $XA, $XB",
916                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
917def : InstAlias<"xxmrgld $XT, $XA, $XB",
918                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
919def : InstAlias<"xxswapd $XT, $XB",
920                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
921def : InstAlias<"xxspltd $XT, $XB, 0",
922                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
923def : InstAlias<"xxspltd $XT, $XB, 1",
924                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
925def : InstAlias<"xxswapd $XT, $XB",
926                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
927
928let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
929
930def : Pat<(v4i32 (vnot_ppc v4i32:$A)),
931          (v4i32 (XXLNOR $A, $A))>;
932let Predicates = [IsBigEndian] in {
933def : Pat<(v2f64 (scalar_to_vector f64:$A)),
934          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
935
936def : Pat<(f64 (extractelt v2f64:$S, 0)),
937          (f64 (EXTRACT_SUBREG $S, sub_64))>;
938def : Pat<(f64 (extractelt v2f64:$S, 1)),
939          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
940}
941
942let Predicates = [IsLittleEndian] in {
943def : Pat<(v2f64 (scalar_to_vector f64:$A)),
944          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
945                           (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
946
947def : Pat<(f64 (extractelt v2f64:$S, 0)),
948          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
949def : Pat<(f64 (extractelt v2f64:$S, 1)),
950          (f64 (EXTRACT_SUBREG $S, sub_64))>;
951}
952
953// Additional fnmsub patterns: -a*c + b == -(a*c - b)
954def : Pat<(fma (fneg f64:$A), f64:$C, f64:$B),
955          (XSNMSUBADP $B, $C, $A)>;
956def : Pat<(fma f64:$A, (fneg f64:$C), f64:$B),
957          (XSNMSUBADP $B, $C, $A)>;
958
959def : Pat<(fma (fneg v2f64:$A), v2f64:$C, v2f64:$B),
960          (XVNMSUBADP $B, $C, $A)>;
961def : Pat<(fma v2f64:$A, (fneg v2f64:$C), v2f64:$B),
962          (XVNMSUBADP $B, $C, $A)>;
963
964def : Pat<(fma (fneg v4f32:$A), v4f32:$C, v4f32:$B),
965          (XVNMSUBASP $B, $C, $A)>;
966def : Pat<(fma v4f32:$A, (fneg v4f32:$C), v4f32:$B),
967          (XVNMSUBASP $B, $C, $A)>;
968
969def : Pat<(v2f64 (bitconvert v4f32:$A)),
970          (COPY_TO_REGCLASS $A, VSRC)>;
971def : Pat<(v2f64 (bitconvert v4i32:$A)),
972          (COPY_TO_REGCLASS $A, VSRC)>;
973def : Pat<(v2f64 (bitconvert v8i16:$A)),
974          (COPY_TO_REGCLASS $A, VSRC)>;
975def : Pat<(v2f64 (bitconvert v16i8:$A)),
976          (COPY_TO_REGCLASS $A, VSRC)>;
977
978def : Pat<(v4f32 (bitconvert v2f64:$A)),
979          (COPY_TO_REGCLASS $A, VRRC)>;
980def : Pat<(v4i32 (bitconvert v2f64:$A)),
981          (COPY_TO_REGCLASS $A, VRRC)>;
982def : Pat<(v8i16 (bitconvert v2f64:$A)),
983          (COPY_TO_REGCLASS $A, VRRC)>;
984def : Pat<(v16i8 (bitconvert v2f64:$A)),
985          (COPY_TO_REGCLASS $A, VRRC)>;
986
987def : Pat<(v2i64 (bitconvert v4f32:$A)),
988          (COPY_TO_REGCLASS $A, VSRC)>;
989def : Pat<(v2i64 (bitconvert v4i32:$A)),
990          (COPY_TO_REGCLASS $A, VSRC)>;
991def : Pat<(v2i64 (bitconvert v8i16:$A)),
992          (COPY_TO_REGCLASS $A, VSRC)>;
993def : Pat<(v2i64 (bitconvert v16i8:$A)),
994          (COPY_TO_REGCLASS $A, VSRC)>;
995
996def : Pat<(v4f32 (bitconvert v2i64:$A)),
997          (COPY_TO_REGCLASS $A, VRRC)>;
998def : Pat<(v4i32 (bitconvert v2i64:$A)),
999          (COPY_TO_REGCLASS $A, VRRC)>;
1000def : Pat<(v8i16 (bitconvert v2i64:$A)),
1001          (COPY_TO_REGCLASS $A, VRRC)>;
1002def : Pat<(v16i8 (bitconvert v2i64:$A)),
1003          (COPY_TO_REGCLASS $A, VRRC)>;
1004
1005def : Pat<(v2f64 (bitconvert v2i64:$A)),
1006          (COPY_TO_REGCLASS $A, VRRC)>;
1007def : Pat<(v2i64 (bitconvert v2f64:$A)),
1008          (COPY_TO_REGCLASS $A, VRRC)>;
1009
1010def : Pat<(v2f64 (bitconvert v1i128:$A)),
1011          (COPY_TO_REGCLASS $A, VRRC)>;
1012def : Pat<(v1i128 (bitconvert v2f64:$A)),
1013          (COPY_TO_REGCLASS $A, VRRC)>;
1014
1015// sign extension patterns
1016// To extend "in place" from v2i32 to v2i64, we have input data like:
1017// | undef | i32 | undef | i32 |
1018// but xvcvsxwdp expects the input in big-Endian format:
1019// | i32 | undef | i32 | undef |
1020// so we need to shift everything to the left by one i32 (word) before
1021// the conversion.
1022def : Pat<(sext_inreg v2i64:$C, v2i32),
1023          (XVCVDPSXDS (XVCVSXWDP (XXSLDWI $C, $C, 1)))>;
1024def : Pat<(v2f64 (sint_to_fp (sext_inreg v2i64:$C, v2i32))),
1025          (XVCVSXWDP (XXSLDWI $C, $C, 1))>;
1026
1027def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
1028          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
1029def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
1030          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
1031
1032def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
1033          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
1034def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
1035          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
1036
1037// Loads.
1038let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
1039  def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1040
1041  // Stores.
1042  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
1043            (STXVD2X $rS, xoaddr:$dst)>;
1044  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
1045            (STXVW4X $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<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1057  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1058}
1059
1060// Permutes.
1061def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1062def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
1063def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
1064def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
1065def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1066
1067// Selects.
1068def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
1069          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1070def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
1071          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1072def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
1073          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1074def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
1075          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1076def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
1077          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1078def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
1079          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1080def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
1081          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1082def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
1083          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1084def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
1085          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1086def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
1087          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1088
1089def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
1090          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1091def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
1092          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1093def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
1094          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1095def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
1096          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1097def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
1098          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
1099def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
1100          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1101def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
1102          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1103def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
1104          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1105def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
1106          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1107def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
1108          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1109
1110// Divides.
1111def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
1112          (XVDIVSP $A, $B)>;
1113def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
1114          (XVDIVDP $A, $B)>;
1115
1116// Reciprocal estimate
1117def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1118          (XVRESP $A)>;
1119def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1120          (XVREDP $A)>;
1121
1122// Recip. square root estimate
1123def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1124          (XVRSQRTESP $A)>;
1125def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1126          (XVRSQRTEDP $A)>;
1127
1128let Predicates = [IsLittleEndian] in {
1129def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1130          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1131def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1132          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1133def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1134          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1135def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1136          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1137} // IsLittleEndian
1138
1139let Predicates = [IsBigEndian] in {
1140def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1141          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1142def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1143          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1144def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1145          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1146def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1147          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1148} // IsBigEndian
1149
1150} // AddedComplexity
1151} // HasVSX
1152
1153def ScalarLoads {
1154  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
1155  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
1156  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
1157  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
1158  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
1159
1160  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
1161  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
1162  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
1163  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
1164  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
1165
1166  dag Li32 = (i32 (load xoaddr:$src));
1167}
1168
1169// The following VSX instructions were introduced in Power ISA 2.07
1170/* FIXME: if the operands are v2i64, these patterns will not match.
1171   we should define new patterns or otherwise match the same patterns
1172   when the elements are larger than i32.
1173*/
1174def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1175def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1176let Predicates = [HasP8Vector] in {
1177let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1178  let isCommutable = 1, UseVSXReg = 1 in {
1179    def XXLEQV : XX3Form<60, 186,
1180                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1181                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1182                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1183    def XXLNAND : XX3Form<60, 178,
1184                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1185                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1186                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1187                                                    v4i32:$XB)))]>;
1188  } // isCommutable, UseVSXReg
1189
1190  def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1191            (XXLEQV $A, $B)>;
1192
1193  let UseVSXReg = 1 in {
1194  def XXLORC : XX3Form<60, 170,
1195                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1196                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1197                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1198
1199  // VSX scalar loads introduced in ISA 2.07
1200  let mayLoad = 1 in {
1201    let CodeSize = 3 in
1202    def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1203                         "lxsspx $XT, $src", IIC_LdStLFD,
1204                         [(set f32:$XT, (load xoaddr:$src))]>;
1205    def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1206                          "lxsiwax $XT, $src", IIC_LdStLFD,
1207                          [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1208    def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1209                          "lxsiwzx $XT, $src", IIC_LdStLFD,
1210                          [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1211  } // mayLoad
1212
1213  // VSX scalar stores introduced in ISA 2.07
1214  let mayStore = 1 in {
1215    let CodeSize = 3 in
1216    def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1217                          "stxsspx $XT, $dst", IIC_LdStSTFD,
1218                          [(store f32:$XT, xoaddr:$dst)]>;
1219    def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1220                          "stxsiwx $XT, $dst", IIC_LdStSTFD,
1221                          [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1222  } // mayStore
1223  } // UseVSXReg = 1
1224
1225  def : Pat<(f64 (extloadf32 xoaddr:$src)),
1226            (COPY_TO_REGCLASS (LXSSPX xoaddr:$src), VSFRC)>;
1227  def : Pat<(f32 (fpround (extloadf32 xoaddr:$src))),
1228            (f32 (LXSSPX xoaddr:$src))>;
1229  def : Pat<(f64 (fpextend f32:$src)),
1230            (COPY_TO_REGCLASS $src, VSFRC)>;
1231
1232  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1233            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1234  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1235            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1236  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1237            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1238  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1239            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1240  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1241            (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1242  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1243            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1244  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1245            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1246  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1247            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1248  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1249            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1250  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1251            (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1252
1253  let UseVSXReg = 1 in {
1254  // VSX Elementary Scalar FP arithmetic (SP)
1255  let isCommutable = 1 in {
1256    def XSADDSP : XX3Form<60, 0,
1257                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1258                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1259                          [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1260    def XSMULSP : XX3Form<60, 16,
1261                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1262                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1263                          [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1264  } // isCommutable
1265
1266  def XSDIVSP : XX3Form<60, 24,
1267                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1268                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1269                        [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1270  def XSRESP : XX2Form<60, 26,
1271                        (outs vssrc:$XT), (ins vssrc:$XB),
1272                        "xsresp $XT, $XB", IIC_VecFP,
1273                        [(set f32:$XT, (PPCfre f32:$XB))]>;
1274  def XSSQRTSP : XX2Form<60, 11,
1275                        (outs vssrc:$XT), (ins vssrc:$XB),
1276                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1277                        [(set f32:$XT, (fsqrt f32:$XB))]>;
1278  def XSRSQRTESP : XX2Form<60, 10,
1279                           (outs vssrc:$XT), (ins vssrc:$XB),
1280                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
1281                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1282  def XSSUBSP : XX3Form<60, 8,
1283                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1284                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
1285                        [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1286
1287  // FMA Instructions
1288  let BaseName = "XSMADDASP" in {
1289  let isCommutable = 1 in
1290  def XSMADDASP : XX3Form<60, 1,
1291                          (outs vssrc:$XT),
1292                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1293                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1294                          [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1295                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1296                          AltVSXFMARel;
1297  let IsVSXFMAAlt = 1 in
1298  def XSMADDMSP : XX3Form<60, 9,
1299                          (outs vssrc:$XT),
1300                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1301                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1302                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1303                          AltVSXFMARel;
1304  }
1305
1306  let BaseName = "XSMSUBASP" in {
1307  let isCommutable = 1 in
1308  def XSMSUBASP : XX3Form<60, 17,
1309                          (outs vssrc:$XT),
1310                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1311                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1312                          [(set f32:$XT, (fma f32:$XA, f32:$XB,
1313                                              (fneg f32:$XTi)))]>,
1314                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1315                          AltVSXFMARel;
1316  let IsVSXFMAAlt = 1 in
1317  def XSMSUBMSP : XX3Form<60, 25,
1318                          (outs vssrc:$XT),
1319                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1320                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1321                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1322                          AltVSXFMARel;
1323  }
1324
1325  let BaseName = "XSNMADDASP" in {
1326  let isCommutable = 1 in
1327  def XSNMADDASP : XX3Form<60, 129,
1328                          (outs vssrc:$XT),
1329                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1330                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1331                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1332                                                    f32:$XTi)))]>,
1333                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1334                          AltVSXFMARel;
1335  let IsVSXFMAAlt = 1 in
1336  def XSNMADDMSP : XX3Form<60, 137,
1337                          (outs vssrc:$XT),
1338                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1339                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1340                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1341                          AltVSXFMARel;
1342  }
1343
1344  let BaseName = "XSNMSUBASP" in {
1345  let isCommutable = 1 in
1346  def XSNMSUBASP : XX3Form<60, 145,
1347                          (outs vssrc:$XT),
1348                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1349                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1350                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1351                                                    (fneg f32:$XTi))))]>,
1352                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1353                          AltVSXFMARel;
1354  let IsVSXFMAAlt = 1 in
1355  def XSNMSUBMSP : XX3Form<60, 153,
1356                          (outs vssrc:$XT),
1357                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1358                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1359                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1360                          AltVSXFMARel;
1361  }
1362
1363  // Single Precision Conversions (FP <-> INT)
1364  def XSCVSXDSP : XX2Form<60, 312,
1365                      (outs vssrc:$XT), (ins vsfrc:$XB),
1366                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1367                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1368  def XSCVUXDSP : XX2Form<60, 296,
1369                      (outs vssrc:$XT), (ins vsfrc:$XB),
1370                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1371                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1372
1373  // Conversions between vector and scalar single precision
1374  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1375                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1376  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1377                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1378  } // UseVSXReg = 1
1379
1380  let Predicates = [IsLittleEndian] in {
1381  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1382            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1383  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1384            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1385  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1386            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1387  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1388            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1389  }
1390
1391  let Predicates = [IsBigEndian] in {
1392  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1393            (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1394  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1395            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1396  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1397            (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1398  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1399            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1400  }
1401  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.Li32)),
1402            (v4i32 (XXSPLTWs (LXSIWAX xoaddr:$src), 1))>;
1403} // AddedComplexity = 400
1404} // HasP8Vector
1405
1406let UseVSXReg = 1, AddedComplexity = 400 in {
1407let Predicates = [HasDirectMove] in {
1408  // VSX direct move instructions
1409  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1410                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1411                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1412      Requires<[In64BitMode]>;
1413  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1414                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1415                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1416  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1417                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1418                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1419      Requires<[In64BitMode]>;
1420  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1421                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1422                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1423  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1424                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1425                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1426} // HasDirectMove
1427
1428let Predicates = [IsISA3_0, HasDirectMove] in {
1429  def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1430                              "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1431
1432  def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
1433                       "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1434                       []>, Requires<[In64BitMode]>;
1435
1436  def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1437                              "mfvsrld $rA, $XT", IIC_VecGeneral,
1438                              []>, Requires<[In64BitMode]>;
1439
1440} // IsISA3_0, HasDirectMove
1441} // UseVSXReg = 1
1442
1443/*  Direct moves of various widths from GPR's into VSR's. Each move lines
1444    the value up into element 0 (both BE and LE). Namely, entities smaller than
1445    a doubleword are shifted left and moved for BE. For LE, they're moved, then
1446    swapped to go into the least significant element of the VSR.
1447*/
1448def MovesToVSR {
1449  dag BE_BYTE_0 =
1450    (MTVSRD
1451      (RLDICR
1452        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1453  dag BE_HALF_0 =
1454    (MTVSRD
1455      (RLDICR
1456        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1457  dag BE_WORD_0 =
1458    (MTVSRD
1459      (RLDICR
1460        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1461  dag BE_DWORD_0 = (MTVSRD $A);
1462
1463  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1464  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1465                                        LE_MTVSRW, sub_64));
1466  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1467  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1468                                         BE_DWORD_0, sub_64));
1469  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1470}
1471
1472/*  Patterns for extracting elements out of vectors. Integer elements are
1473    extracted using direct move operations. Patterns for extracting elements
1474    whose indices are not available at compile time are also provided with
1475    various _VARIABLE_ patterns.
1476    The numbering for the DAG's is for LE, but when used on BE, the correct
1477    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1478*/
1479def VectorExtractions {
1480  // Doubleword extraction
1481  dag LE_DWORD_0 =
1482    (MFVSRD
1483      (EXTRACT_SUBREG
1484        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1485                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1486  dag LE_DWORD_1 = (MFVSRD
1487                     (EXTRACT_SUBREG
1488                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1489
1490  // Word extraction
1491  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1492  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1493  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1494                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1495  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1496
1497  // Halfword extraction
1498  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1499  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1500  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1501  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1502  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1503  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1504  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1505  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1506
1507  // Byte extraction
1508  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1509  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1510  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1511  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1512  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1513  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1514  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1515  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1516  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1517  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1518  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1519  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1520  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1521  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1522  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1523  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1524
1525  /* Variable element number (BE and LE patterns must be specified separately)
1526     This is a rather involved process.
1527
1528     Conceptually, this is how the move is accomplished:
1529     1. Identify which doubleword contains the element
1530     2. Shift in the VMX register so that the correct doubleword is correctly
1531        lined up for the MFVSRD
1532     3. Perform the move so that the element (along with some extra stuff)
1533        is in the GPR
1534     4. Right shift within the GPR so that the element is right-justified
1535
1536     Of course, the index is an element number which has a different meaning
1537     on LE/BE so the patterns have to be specified separately.
1538
1539     Note: The final result will be the element right-justified with high
1540           order bits being arbitrarily defined (namely, whatever was in the
1541           vector register to the left of the value originally).
1542  */
1543
1544  /*  LE variable byte
1545      Number 1. above:
1546      - For elements 0-7, we shift left by 8 bytes since they're on the right
1547      - For elements 8-15, we need not shift (shift left by zero bytes)
1548      This is accomplished by inverting the bits of the index and AND-ing
1549      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1550  */
1551  dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx));
1552
1553  //  Number 2. above:
1554  //  - Now that we set up the shift amount, we shift in the VMX register
1555  dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC);
1556
1557  //  Number 3. above:
1558  //  - The doubleword containing our element is moved to a GPR
1559  dag LE_MV_VBYTE = (MFVSRD
1560                      (EXTRACT_SUBREG
1561                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1562                        sub_64));
1563
1564  /*  Number 4. above:
1565      - Truncate the element number to the range 0-7 (8-15 are symmetrical
1566        and out of range values are truncated accordingly)
1567      - Multiply by 8 as we need to shift right by the number of bits, not bytes
1568      - Shift right in the GPR by the calculated value
1569  */
1570  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1571                                       sub_32);
1572  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1573                                         sub_32);
1574
1575  /*  LE variable halfword
1576      Number 1. above:
1577      - For elements 0-3, we shift left by 8 since they're on the right
1578      - For elements 4-7, we need not shift (shift left by zero bytes)
1579      Similarly to the byte pattern, we invert the bits of the index, but we
1580      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1581      Of course, the shift is still by 8 bytes, so we must multiply by 2.
1582  */
1583  dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62));
1584
1585  //  Number 2. above:
1586  //  - Now that we set up the shift amount, we shift in the VMX register
1587  dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC);
1588
1589  //  Number 3. above:
1590  //  - The doubleword containing our element is moved to a GPR
1591  dag LE_MV_VHALF = (MFVSRD
1592                      (EXTRACT_SUBREG
1593                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1594                        sub_64));
1595
1596  /*  Number 4. above:
1597      - Truncate the element number to the range 0-3 (4-7 are symmetrical
1598        and out of range values are truncated accordingly)
1599      - Multiply by 16 as we need to shift right by the number of bits
1600      - Shift right in the GPR by the calculated value
1601  */
1602  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1603                                       sub_32);
1604  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1605                                         sub_32);
1606
1607  /*  LE variable word
1608      Number 1. above:
1609      - For elements 0-1, we shift left by 8 since they're on the right
1610      - For elements 2-3, we need not shift
1611  */
1612  dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61));
1613
1614  //  Number 2. above:
1615  //  - Now that we set up the shift amount, we shift in the VMX register
1616  dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC);
1617
1618  //  Number 3. above:
1619  //  - The doubleword containing our element is moved to a GPR
1620  dag LE_MV_VWORD = (MFVSRD
1621                      (EXTRACT_SUBREG
1622                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1623                        sub_64));
1624
1625  /*  Number 4. above:
1626      - Truncate the element number to the range 0-1 (2-3 are symmetrical
1627        and out of range values are truncated accordingly)
1628      - Multiply by 32 as we need to shift right by the number of bits
1629      - Shift right in the GPR by the calculated value
1630  */
1631  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1632                                       sub_32);
1633  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1634                                         sub_32);
1635
1636  /*  LE variable doubleword
1637      Number 1. above:
1638      - For element 0, we shift left by 8 since it's on the right
1639      - For element 1, we need not shift
1640  */
1641  dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60));
1642
1643  //  Number 2. above:
1644  //  - Now that we set up the shift amount, we shift in the VMX register
1645  dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC);
1646
1647  // Number 3. above:
1648  //  - The doubleword containing our element is moved to a GPR
1649  //  - Number 4. is not needed for the doubleword as the value is 64-bits
1650  dag LE_VARIABLE_DWORD =
1651        (MFVSRD (EXTRACT_SUBREG
1652                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1653                  sub_64));
1654
1655  /*  LE variable float
1656      - Shift the vector to line up the desired element to BE Word 0
1657      - Convert 32-bit float to a 64-bit single precision float
1658  */
1659  dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61));
1660  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1661  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1662
1663  /*  LE variable double
1664      Same as the LE doubleword except there is no move.
1665  */
1666  dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1667                                  (COPY_TO_REGCLASS $S, VRRC),
1668                                  LE_VDWORD_PERM_VEC);
1669  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1670
1671  /*  BE variable byte
1672      The algorithm here is the same as the LE variable byte except:
1673      - The shift in the VMX register is by 0/8 for opposite element numbers so
1674        we simply AND the element number with 0x8
1675      - The order of elements after the move to GPR is reversed, so we invert
1676        the bits of the index prior to truncating to the range 0-7
1677  */
1678  dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8));
1679  dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC);
1680  dag BE_MV_VBYTE = (MFVSRD
1681                      (EXTRACT_SUBREG
1682                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1683                        sub_64));
1684  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1685                                       sub_32);
1686  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1687                                         sub_32);
1688
1689  /*  BE variable halfword
1690      The algorithm here is the same as the LE variable halfword except:
1691      - The shift in the VMX register is by 0/8 for opposite element numbers so
1692        we simply AND the element number with 0x4 and multiply by 2
1693      - The order of elements after the move to GPR is reversed, so we invert
1694        the bits of the index prior to truncating to the range 0-3
1695  */
1696  dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62));
1697  dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC);
1698  dag BE_MV_VHALF = (MFVSRD
1699                      (EXTRACT_SUBREG
1700                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1701                        sub_64));
1702  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1703                                       sub_32);
1704  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1705                                         sub_32);
1706
1707  /*  BE variable word
1708      The algorithm is the same as the LE variable word except:
1709      - The shift in the VMX register happens for opposite element numbers
1710      - The order of elements after the move to GPR is reversed, so we invert
1711        the bits of the index prior to truncating to the range 0-1
1712  */
1713  dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61));
1714  dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC);
1715  dag BE_MV_VWORD = (MFVSRD
1716                      (EXTRACT_SUBREG
1717                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1718                        sub_64));
1719  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1720                                       sub_32);
1721  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1722                                         sub_32);
1723
1724  /*  BE variable doubleword
1725      Same as the LE doubleword except we shift in the VMX register for opposite
1726      element indices.
1727  */
1728  dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60));
1729  dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC);
1730  dag BE_VARIABLE_DWORD =
1731        (MFVSRD (EXTRACT_SUBREG
1732                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1733                  sub_64));
1734
1735  /*  BE variable float
1736      - Shift the vector to line up the desired element to BE Word 0
1737      - Convert 32-bit float to a 64-bit single precision float
1738  */
1739  dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61));
1740  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1741  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1742
1743  /* BE variable double
1744      Same as the BE doubleword except there is no move.
1745  */
1746  dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1747                                  (COPY_TO_REGCLASS $S, VRRC),
1748                                  BE_VDWORD_PERM_VEC);
1749  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1750}
1751
1752let AddedComplexity = 400 in {
1753// v4f32 scalar <-> vector conversions (BE)
1754let Predicates = [IsBigEndian, HasP8Vector] in {
1755  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1756            (v4f32 (XSCVDPSPN $A))>;
1757  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1758            (f32 (XSCVSPDPN $S))>;
1759  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1760            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1761  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1762            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1763  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1764            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1765  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1766            (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1767} // IsBigEndian, HasP8Vector
1768
1769// Variable index vector_extract for v2f64 does not require P8Vector
1770let Predicates = [IsBigEndian, HasVSX] in
1771  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1772            (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1773
1774let Predicates = [IsBigEndian, HasDirectMove] in {
1775  // v16i8 scalar <-> vector conversions (BE)
1776  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1777            (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1778  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1779            (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1780  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1781            (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1782  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1783            (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1784  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1785            (i32 VectorExtractions.LE_BYTE_15)>;
1786  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1787            (i32 VectorExtractions.LE_BYTE_14)>;
1788  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1789            (i32 VectorExtractions.LE_BYTE_13)>;
1790  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1791            (i32 VectorExtractions.LE_BYTE_12)>;
1792  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1793            (i32 VectorExtractions.LE_BYTE_11)>;
1794  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1795            (i32 VectorExtractions.LE_BYTE_10)>;
1796  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1797            (i32 VectorExtractions.LE_BYTE_9)>;
1798  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1799            (i32 VectorExtractions.LE_BYTE_8)>;
1800  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1801            (i32 VectorExtractions.LE_BYTE_7)>;
1802  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1803            (i32 VectorExtractions.LE_BYTE_6)>;
1804  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1805            (i32 VectorExtractions.LE_BYTE_5)>;
1806  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1807            (i32 VectorExtractions.LE_BYTE_4)>;
1808  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1809            (i32 VectorExtractions.LE_BYTE_3)>;
1810  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1811            (i32 VectorExtractions.LE_BYTE_2)>;
1812  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1813            (i32 VectorExtractions.LE_BYTE_1)>;
1814  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1815            (i32 VectorExtractions.LE_BYTE_0)>;
1816  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1817            (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1818
1819  // v8i16 scalar <-> vector conversions (BE)
1820  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1821            (i32 VectorExtractions.LE_HALF_7)>;
1822  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1823            (i32 VectorExtractions.LE_HALF_6)>;
1824  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1825            (i32 VectorExtractions.LE_HALF_5)>;
1826  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1827            (i32 VectorExtractions.LE_HALF_4)>;
1828  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1829            (i32 VectorExtractions.LE_HALF_3)>;
1830  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1831            (i32 VectorExtractions.LE_HALF_2)>;
1832  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1833            (i32 VectorExtractions.LE_HALF_1)>;
1834  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1835            (i32 VectorExtractions.LE_HALF_0)>;
1836  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1837            (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1838
1839  // v4i32 scalar <-> vector conversions (BE)
1840  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1841            (i32 VectorExtractions.LE_WORD_3)>;
1842  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1843            (i32 VectorExtractions.LE_WORD_2)>;
1844  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1845            (i32 VectorExtractions.LE_WORD_1)>;
1846  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1847            (i32 VectorExtractions.LE_WORD_0)>;
1848  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1849            (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1850
1851  // v2i64 scalar <-> vector conversions (BE)
1852  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1853            (i64 VectorExtractions.LE_DWORD_1)>;
1854  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1855            (i64 VectorExtractions.LE_DWORD_0)>;
1856  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1857            (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1858} // IsBigEndian, HasDirectMove
1859
1860// v4f32 scalar <-> vector conversions (LE)
1861let Predicates = [IsLittleEndian, HasP8Vector] in {
1862  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1863            (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1864  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1865            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1866  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1867            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1868  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1869            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1870  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1871            (f32 (XSCVSPDPN $S))>;
1872  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1873            (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1874} // IsLittleEndian, HasP8Vector
1875
1876// Variable index vector_extract for v2f64 does not require P8Vector
1877let Predicates = [IsLittleEndian, HasVSX] in
1878  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1879            (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1880
1881  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1882  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1883
1884let Predicates = [IsLittleEndian, HasDirectMove] in {
1885  // v16i8 scalar <-> vector conversions (LE)
1886  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1887            (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1888  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1889            (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
1890  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1891            (v4i32 MovesToVSR.LE_WORD_0)>;
1892  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1893            (v2i64 MovesToVSR.LE_DWORD_0)>;
1894  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1895            (i32 VectorExtractions.LE_BYTE_0)>;
1896  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1897            (i32 VectorExtractions.LE_BYTE_1)>;
1898  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1899            (i32 VectorExtractions.LE_BYTE_2)>;
1900  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1901            (i32 VectorExtractions.LE_BYTE_3)>;
1902  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1903            (i32 VectorExtractions.LE_BYTE_4)>;
1904  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1905            (i32 VectorExtractions.LE_BYTE_5)>;
1906  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1907            (i32 VectorExtractions.LE_BYTE_6)>;
1908  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1909            (i32 VectorExtractions.LE_BYTE_7)>;
1910  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1911            (i32 VectorExtractions.LE_BYTE_8)>;
1912  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1913            (i32 VectorExtractions.LE_BYTE_9)>;
1914  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1915            (i32 VectorExtractions.LE_BYTE_10)>;
1916  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1917            (i32 VectorExtractions.LE_BYTE_11)>;
1918  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1919            (i32 VectorExtractions.LE_BYTE_12)>;
1920  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1921            (i32 VectorExtractions.LE_BYTE_13)>;
1922  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1923            (i32 VectorExtractions.LE_BYTE_14)>;
1924  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1925            (i32 VectorExtractions.LE_BYTE_15)>;
1926  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1927            (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
1928
1929  // v8i16 scalar <-> vector conversions (LE)
1930  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1931            (i32 VectorExtractions.LE_HALF_0)>;
1932  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1933            (i32 VectorExtractions.LE_HALF_1)>;
1934  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1935            (i32 VectorExtractions.LE_HALF_2)>;
1936  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1937            (i32 VectorExtractions.LE_HALF_3)>;
1938  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1939            (i32 VectorExtractions.LE_HALF_4)>;
1940  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1941            (i32 VectorExtractions.LE_HALF_5)>;
1942  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1943            (i32 VectorExtractions.LE_HALF_6)>;
1944  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1945            (i32 VectorExtractions.LE_HALF_7)>;
1946  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1947            (i32 VectorExtractions.LE_VARIABLE_HALF)>;
1948
1949  // v4i32 scalar <-> vector conversions (LE)
1950  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1951            (i32 VectorExtractions.LE_WORD_0)>;
1952  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1953            (i32 VectorExtractions.LE_WORD_1)>;
1954  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1955            (i32 VectorExtractions.LE_WORD_2)>;
1956  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1957            (i32 VectorExtractions.LE_WORD_3)>;
1958  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1959            (i32 VectorExtractions.LE_VARIABLE_WORD)>;
1960
1961  // v2i64 scalar <-> vector conversions (LE)
1962  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1963            (i64 VectorExtractions.LE_DWORD_0)>;
1964  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1965            (i64 VectorExtractions.LE_DWORD_1)>;
1966  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1967            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
1968} // IsLittleEndian, HasDirectMove
1969
1970let Predicates = [HasDirectMove, HasVSX] in {
1971// bitconvert f32 -> i32
1972// (convert to 32-bit fp single, shift right 1 word, move to GPR)
1973def : Pat<(i32 (bitconvert f32:$S)),
1974          (i32 (MFVSRWZ (EXTRACT_SUBREG
1975                          (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
1976                          sub_64)))>;
1977// bitconvert i32 -> f32
1978// (move to FPR, shift left 1 word, convert to 64-bit fp single)
1979def : Pat<(f32 (bitconvert i32:$A)),
1980          (f32 (XSCVSPDPN
1981                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
1982
1983// bitconvert f64 -> i64
1984// (move to GPR, nothing else needed)
1985def : Pat<(i64 (bitconvert f64:$S)),
1986          (i64 (MFVSRD $S))>;
1987
1988// bitconvert i64 -> f64
1989// (move to FPR, nothing else needed)
1990def : Pat<(f64 (bitconvert i64:$S)),
1991          (f64 (MTVSRD $S))>;
1992}
1993
1994// Materialize a zero-vector of long long
1995def : Pat<(v2i64 immAllZerosV),
1996          (v2i64 (XXLXORz))>;
1997}
1998
1999def AlignValues {
2000  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2001  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2002}
2003
2004// The following VSX instructions were introduced in Power ISA 3.0
2005def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2006let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2007
2008  // [PO VRT XO VRB XO /]
2009  class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2010                      list<dag> pattern>
2011    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2012                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2013
2014  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2015  class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2016                         list<dag> pattern>
2017    : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2018
2019  // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2020  // So we use different operand class for VRB
2021  class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2022                           RegisterOperand vbtype, list<dag> pattern>
2023    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2024                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2025
2026  let UseVSXReg = 1 in {
2027  // [PO T XO B XO BX /]
2028  class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2029                        list<dag> pattern>
2030    : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2031                      !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2032
2033  // [PO T XO B XO BX TX]
2034  class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2035                        RegisterOperand vtype, list<dag> pattern>
2036    : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2037                      !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2038
2039  // [PO T A B XO AX BX TX], src and dest register use different operand class
2040  class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2041                  RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2042                  InstrItinClass itin, list<dag> pattern>
2043    : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2044              !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2045  } // UseVSXReg = 1
2046
2047  // [PO VRT VRA VRB XO /]
2048  class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2049                      list<dag> pattern>
2050    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2051              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2052
2053  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2054  class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2055                         list<dag> pattern>
2056    : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2057
2058  //===--------------------------------------------------------------------===//
2059  // Quad-Precision Scalar Move Instructions:
2060
2061  // Copy Sign
2062  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>;
2063
2064  // Absolute/Negative-Absolute/Negate
2065  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp" , []>;
2066  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp", []>;
2067  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>;
2068
2069  //===--------------------------------------------------------------------===//
2070  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2071
2072  // Add/Divide/Multiply/Subtract
2073  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp" , []>;
2074  def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>;
2075  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp" , []>;
2076  def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>;
2077  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp" , []>;
2078  def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>;
2079  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" , []>;
2080  def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>;
2081
2082  // Square-Root
2083  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp" , []>;
2084  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>;
2085
2086  // (Negative) Multiply-{Add/Subtract}
2087  def XSMADDQP  : X_VT5_VA5_VB5   <63, 388, "xsmaddqp"  , []>;
2088  def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>;
2089  def XSMSUBQP  : X_VT5_VA5_VB5   <63, 420, "xsmsubqp"  , []>;
2090  def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>;
2091  def XSNMADDQP : X_VT5_VA5_VB5   <63, 452, "xsnmaddqp" , []>;
2092  def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>;
2093  def XSNMSUBQP : X_VT5_VA5_VB5   <63, 484, "xsnmsubqp" , []>;
2094  def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>;
2095
2096  //===--------------------------------------------------------------------===//
2097  // Quad/Double-Precision Compare Instructions:
2098
2099  // [PO BF // VRA VRB XO /]
2100  class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2101                      list<dag> pattern>
2102    : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2103               !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2104    let Pattern = pattern;
2105  }
2106
2107  // QP Compare Ordered/Unordered
2108  def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2109  def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2110
2111  // DP/QP Compare Exponents
2112  def XSCMPEXPDP : XX3Form_1<60, 59,
2113                             (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2114                             "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>,
2115                   UseVSXReg;
2116  def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2117
2118  // DP Compare ==, >=, >, !=
2119  // Use vsrc for XT, because the entire register of XT is set.
2120  // XT.dword[1] = 0x0000_0000_0000_0000
2121  def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2122                                  IIC_FPCompare, []>;
2123  def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2124                                  IIC_FPCompare, []>;
2125  def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2126                                  IIC_FPCompare, []>;
2127  def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc,
2128                                  IIC_FPCompare, []>;
2129  let UseVSXReg = 1 in {
2130  // Vector Compare Not Equal
2131  def XVCMPNEDP  : XX3Form_Rc<60, 123,
2132                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2133                              "xvcmpnedp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2134  let Defs = [CR6] in
2135  def XVCMPNEDPo : XX3Form_Rc<60, 123,
2136                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2137                              "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2138                              isDOT;
2139  def XVCMPNESP  : XX3Form_Rc<60,  91,
2140                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2141                              "xvcmpnesp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2142  let Defs = [CR6] in
2143  def XVCMPNESPo : XX3Form_Rc<60,  91,
2144                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2145                              "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2146                              isDOT;
2147  } // UseVSXReg = 1
2148
2149  //===--------------------------------------------------------------------===//
2150  // Quad-Precision Floating-Point Conversion Instructions:
2151
2152  // Convert DP -> QP
2153  def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, []>;
2154
2155  // Round & Convert QP -> DP (dword[1] is set to zero)
2156  def XSCVQPDP  : X_VT5_XO5_VB5   <63, 20, 836, "xscvqpdp" , []>;
2157  def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>;
2158
2159  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2160  def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2161  def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2162  def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2163  def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2164
2165  // Convert (Un)Signed DWord -> QP
2166  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2167  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2168
2169  let UseVSXReg = 1 in {
2170  //===--------------------------------------------------------------------===//
2171  // Round to Floating-Point Integer Instructions
2172
2173  // (Round &) Convert DP <-> HP
2174  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2175  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2176  // but we still use vsfrc for it.
2177  def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2178  def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2179
2180  // Vector HP -> SP
2181  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2182  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2183                                 [(set v4f32:$XT,
2184                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2185
2186  } // UseVSXReg = 1
2187
2188  // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2189  // seperate pattern so that it can convert the input register class from
2190  // VRRC(v8i16) to VSRC.
2191  def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2192            (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2193
2194  class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2195                                list<dag> pattern>
2196    : Z23Form_1<opcode, xo,
2197                (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2198                !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2199    let RC = ex;
2200  }
2201
2202  // Round to Quad-Precision Integer [with Inexact]
2203  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2204  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2205
2206  // Round Quad-Precision to Double-Extended Precision (fp80)
2207  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2208
2209  //===--------------------------------------------------------------------===//
2210  // Insert/Extract Instructions
2211
2212  // Insert Exponent DP/QP
2213  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2214  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2215                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg;
2216  // vB NOTE: only vB.dword[0] is used, that's why we don't use
2217  //          X_VT5_VA5_VB5 form
2218  def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2219                          "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2220
2221  // Extract Exponent/Significand DP/QP
2222  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2223  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2224
2225  def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2226  def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2227
2228  // Vector Insert Word
2229  let UseVSXReg = 1 in {
2230  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2231  def XXINSERTW   :
2232    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2233                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2234                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2235                     [(set v4i32:$XT, (PPCxxinsert v4i32:$XTi, v4i32:$XB,
2236                                                   imm32SExt16:$UIM))]>,
2237                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2238
2239  // Vector Extract Unsigned Word
2240  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2241                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2242                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2243  } // UseVSXReg = 1
2244
2245  // Vector Insert Exponent DP/SP
2246  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2247    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2248  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2249    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2250
2251  // Vector Extract Exponent/Significand DP/SP
2252  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2253                                 [(set v2i64: $XT,
2254                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2255  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2256                                 [(set v4i32: $XT,
2257                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2258  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2259                                 [(set v2i64: $XT,
2260                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2261  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2262                                 [(set v4i32: $XT,
2263                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2264
2265  let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2266  // Extra patterns expanding to vector Extract Word/Insert Word
2267  def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2268            (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2269  def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2270            (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2271  } // AddedComplexity = 400, HasP9Vector
2272
2273  //===--------------------------------------------------------------------===//
2274
2275  // Test Data Class SP/DP/QP
2276  let UseVSXReg = 1 in {
2277  def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2278                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2279                              "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2280  def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2281                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2282                              "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2283  } // UseVSXReg = 1
2284  def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2285                              (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2286                              "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2287
2288  // Vector Test Data Class SP/DP
2289  let UseVSXReg = 1 in {
2290  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2291                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2292                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2293                              [(set v4i32: $XT,
2294                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>;
2295  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2296                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2297                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2298                              [(set v2i64: $XT,
2299                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>;
2300  } // UseVSXReg = 1
2301
2302  //===--------------------------------------------------------------------===//
2303
2304  // Maximum/Minimum Type-C/Type-J DP
2305  // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2306  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2307                                 IIC_VecFP, []>;
2308  def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2309                                 IIC_VecFP, []>;
2310  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2311                                 IIC_VecFP, []>;
2312  def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2313                                 IIC_VecFP, []>;
2314
2315  //===--------------------------------------------------------------------===//
2316
2317  // Vector Byte-Reverse H/W/D/Q Word
2318  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2319  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2320  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2321  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2322
2323  // Vector Permute
2324  def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2325                                IIC_VecPerm, []>;
2326  def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2327                                IIC_VecPerm, []>;
2328
2329  // Vector Splat Immediate Byte
2330  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2331                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg;
2332
2333  //===--------------------------------------------------------------------===//
2334  // Vector/Scalar Load/Store Instructions
2335
2336  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2337  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2338  let mayLoad = 1 in {
2339  // Load Vector
2340  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2341                            "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg;
2342  // Load DWord
2343  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2344                       "lxsd $vD, $src", IIC_LdStLFD, []>;
2345  // Load SP from src, convert it to DP, and place in dword[0]
2346  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2347                       "lxssp $vD, $src", IIC_LdStLFD, []>;
2348
2349  // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2350  // "out" and "in" dag
2351  class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2352                      RegisterOperand vtype, list<dag> pattern>
2353    : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2354              !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg;
2355
2356  // Load as Integer Byte/Halfword & Zero Indexed
2357  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2358                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2359  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2360                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2361
2362  // Load Vector Halfword*8/Byte*16 Indexed
2363  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2364  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2365
2366  // Load Vector Indexed
2367  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2368                [(set v2f64:$XT, (load xoaddr:$src))]>;
2369
2370  // Load Vector (Left-justified) with Length
2371  def LXVL : XX1Form<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2372                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
2373                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>,
2374                    UseVSXReg;
2375  def LXVLL : XX1Form<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2376                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
2377                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>,
2378                    UseVSXReg;
2379
2380  // Load Vector Word & Splat Indexed
2381  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2382  } // mayLoad
2383
2384  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2385  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2386  let mayStore = 1 in {
2387  // Store Vector
2388  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2389                             "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg;
2390  // Store DWord
2391  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2392                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2393  // Convert DP of dword[0] to SP, and Store to dst
2394  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2395                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2396
2397  // [PO S RA RB XO SX]
2398  class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2399                      RegisterOperand vtype, list<dag> pattern>
2400    : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2401              !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg;
2402
2403  // Store as Integer Byte/Halfword Indexed
2404  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2405                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2406  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2407                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2408  let isCodeGenOnly = 1 in {
2409    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vrrc, []>;
2410    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vrrc, []>;
2411  }
2412
2413  // Store Vector Halfword*8/Byte*16 Indexed
2414  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2415  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2416
2417  // Store Vector Indexed
2418  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
2419                 [(store v2f64:$XT, xoaddr:$dst)]>;
2420
2421  // Store Vector (Left-justified) with Length
2422  def STXVL : XX1Form<31, 397, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2423                   "stxvl $XT, $dst, $rB", IIC_LdStLoad,
2424                   [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, i64:$rB)]>,
2425                    UseVSXReg;
2426  def STXVLL : XX1Form<31, 429, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2427                   "stxvll $XT, $dst, $rB", IIC_LdStLoad,
2428                   [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, i64:$rB)]>,
2429                    UseVSXReg;
2430  } // mayStore
2431
2432  // Patterns for which instructions from ISA 3.0 are a better match
2433  let Predicates = [IsLittleEndian, HasP9Vector] in {
2434  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2435            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2436  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2437            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2438  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2439            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2440  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2441            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2442  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2443            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2444  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2445            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2446  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2447            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2448  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2449            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2450  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2451            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2452  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2453            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2454  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2455            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2456  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2457            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2458  } // IsLittleEndian, HasP9Vector
2459
2460  let Predicates = [IsBigEndian, HasP9Vector] in {
2461  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2462            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2463  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2464            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2465  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2466            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2467  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2468            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2469  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2470            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2471  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2472            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2473  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2474            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2475  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2476            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2477  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2478            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2479  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2480            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2481  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2482            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2483  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2484            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2485  } // IsLittleEndian, HasP9Vector
2486
2487  def : Pat<(v2f64 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2488  def : Pat<(v2i64 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2489  def : Pat<(v4f32 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2490  def : Pat<(v4i32 (load xoaddr:$src)), (LXVX xoaddr:$src)>;
2491  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
2492  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
2493  def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2494  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2495  def : Pat<(store v4f32:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2496  def : Pat<(store v4i32:$rS, xoaddr:$dst), (STXVX $rS, xoaddr:$dst)>;
2497  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
2498            (STXVX $rS, xoaddr:$dst)>;
2499  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
2500            (STXVX $rS, xoaddr:$dst)>;
2501
2502  def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
2503            (v4i32 (LXVWSX xoaddr:$src))>;
2504  def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
2505            (v4f32 (LXVWSX xoaddr:$src))>;
2506  def : Pat<(v4f32 (scalar_to_vector (f32 (fpround (extloadf32 xoaddr:$src))))),
2507            (v4f32 (LXVWSX xoaddr:$src))>;
2508
2509  // Build vectors from i8 loads
2510  def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
2511            (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
2512  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
2513            (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
2514  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
2515           (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
2516  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
2517            (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
2518  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
2519            (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
2520  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
2521            (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
2522
2523  // Build vectors from i16 loads
2524  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
2525            (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
2526  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
2527            (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
2528  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
2529           (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
2530  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
2531            (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
2532  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
2533            (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
2534
2535  let Predicates = [IsBigEndian, HasP9Vector] in {
2536  // Scalar stores of i8
2537  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2538            (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2539  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2540            (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2541  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2542            (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2543  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2544            (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2545  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2546            (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2547  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2548            (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2549  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2550            (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2551  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2552            (STXSIBXv $S, xoaddr:$dst)>;
2553  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2554            (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2555  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2556            (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2557  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2558            (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2559  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2560            (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2561  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2562            (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2563  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2564            (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2565  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2566            (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2567  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2568            (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2569
2570  // Scalar stores of i16
2571  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2572            (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2573  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2574            (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2575  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2576            (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2577  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2578            (STXSIHXv $S, xoaddr:$dst)>;
2579  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2580            (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2581  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2582            (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2583  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2584            (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2585  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2586            (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2587  } // IsBigEndian, HasP9Vector
2588
2589  let Predicates = [IsLittleEndian, HasP9Vector] in {
2590  // Scalar stores of i8
2591  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2592            (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2593  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2594            (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2595  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2596            (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2597  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2598            (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2599  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2600            (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2601  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2602            (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2603  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2604            (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2605  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2606            (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2607  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2608            (STXSIBXv $S, xoaddr:$dst)>;
2609  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2610            (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2611  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2612            (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2613  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2614            (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2615  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2616            (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2617  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2618            (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2619  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2620            (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2621  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2622            (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2623
2624  // Scalar stores of i16
2625  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2626            (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2627  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2628            (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2629  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2630            (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2631  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2632            (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2633  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2634            (STXSIHXv $S, xoaddr:$dst)>;
2635  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2636            (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2637  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2638            (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2639  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2640            (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2641  } // IsLittleEndian, HasP9Vector
2642
2643
2644  // Vector sign extensions
2645  def : Pat<(f64 (PPCVexts f64:$A, 1)),
2646            (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
2647  def : Pat<(f64 (PPCVexts f64:$A, 2)),
2648            (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
2649
2650  let isPseudo = 1 in {
2651    def DFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrix:$src),
2652                            "#DFLOADf32",
2653                            [(set f32:$XT, (load iaddr:$src))]>;
2654    def DFLOADf64  : Pseudo<(outs vsfrc:$XT), (ins memrix:$src),
2655                            "#DFLOADf64",
2656                            [(set f64:$XT, (load iaddr:$src))]>;
2657    def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst),
2658                            "#DFSTOREf32",
2659                            [(store f32:$XT, iaddr:$dst)]>;
2660    def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
2661                            "#DFSTOREf64",
2662                            [(store f64:$XT, iaddr:$dst)]>;
2663  }
2664  def : Pat<(f64 (extloadf32 iaddr:$src)),
2665            (COPY_TO_REGCLASS (DFLOADf32 iaddr:$src), VSFRC)>;
2666  def : Pat<(f32 (fpround (extloadf32 iaddr:$src))),
2667            (f32 (DFLOADf32 iaddr:$src))>;
2668} // end HasP9Vector, AddedComplexity
2669
2670// Integer extend helper dags 32 -> 64
2671def AnyExts {
2672  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
2673  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
2674  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
2675  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
2676}
2677
2678def DblToFlt {
2679  dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
2680  dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
2681  dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
2682  dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
2683}
2684def FltToIntLoad {
2685  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
2686}
2687def FltToUIntLoad {
2688  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
2689}
2690def FltToLongLoad {
2691  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
2692}
2693def FltToULongLoad {
2694  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
2695}
2696def FltToLong {
2697  dag A = (i64 (PPCmfvsr (PPCfctidz (fpextend f32:$A))));
2698}
2699def FltToULong {
2700  dag A = (i64 (PPCmfvsr (PPCfctiduz (fpextend f32:$A))));
2701}
2702def DblToInt {
2703  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
2704}
2705def DblToUInt {
2706  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
2707}
2708def DblToLong {
2709  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
2710}
2711def DblToULong {
2712  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
2713}
2714def DblToIntLoad {
2715  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
2716}
2717def DblToUIntLoad {
2718  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
2719}
2720def DblToLongLoad {
2721  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
2722}
2723def DblToULongLoad {
2724  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
2725}
2726
2727// FP merge dags (for f32 -> v4f32)
2728def MrgFP {
2729  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
2730                               (COPY_TO_REGCLASS $C, VSRC), 0));
2731  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
2732                               (COPY_TO_REGCLASS $D, VSRC), 0));
2733  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
2734  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
2735  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
2736  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
2737}
2738
2739// Patterns for BUILD_VECTOR nodes.
2740def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
2741let AddedComplexity = 400 in {
2742
2743  let Predicates = [HasVSX] in {
2744    // Build vectors of floating point converted to i32.
2745    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
2746                                   DblToInt.A, DblToInt.A)),
2747              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
2748    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
2749                                   DblToUInt.A, DblToUInt.A)),
2750              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
2751    def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
2752              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
2753                               (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
2754    def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
2755              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
2756                               (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
2757    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
2758              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2759                                (XSCVDPSXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>;
2760    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
2761              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2762                                (XSCVDPUXWSs (LXSSPX xoaddr:$A)), VSRC), 1))>;
2763    def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
2764              (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
2765
2766    // Build vectors of floating point converted to i64.
2767    def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
2768              (v2i64 (XXPERMDIs
2769                       (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
2770    def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
2771              (v2i64 (XXPERMDIs
2772                       (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
2773    def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
2774              (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
2775    def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
2776              (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
2777  }
2778
2779  let Predicates = [HasVSX, NoP9Vector] in {
2780    // Load-and-splat with fp-to-int conversion (using X-Form VSX loads).
2781    def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
2782              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2783                                (XSCVDPSXWS (LXSDX xoaddr:$A)), VSRC), 1))>;
2784    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
2785              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2786                                (XSCVDPUXWS (LXSDX xoaddr:$A)), VSRC), 1))>;
2787    def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
2788              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
2789                                              (LXSSPX xoaddr:$A), VSFRC)), 0))>;
2790    def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
2791              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
2792                                              (LXSSPX xoaddr:$A), VSFRC)), 0))>;
2793  }
2794
2795  // Big endian, available on all targets with VSX
2796  let Predicates = [IsBigEndian, HasVSX] in {
2797    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2798              (v2f64 (XXPERMDI
2799                        (COPY_TO_REGCLASS $A, VSRC),
2800                        (COPY_TO_REGCLASS $B, VSRC), 0))>;
2801
2802    def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
2803              (VMRGEW MrgFP.AC, MrgFP.BD)>;
2804    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2805                                   DblToFlt.B0, DblToFlt.B1)),
2806              (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
2807  }
2808
2809  let Predicates = [IsLittleEndian, HasVSX] in {
2810  // Little endian, available on all targets with VSX
2811    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
2812              (v2f64 (XXPERMDI
2813                        (COPY_TO_REGCLASS $B, VSRC),
2814                        (COPY_TO_REGCLASS $A, VSRC), 0))>;
2815
2816    def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
2817              (VMRGEW MrgFP.AC, MrgFP.BD)>;
2818    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
2819                                   DblToFlt.B0, DblToFlt.B1)),
2820              (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
2821  }
2822
2823  let Predicates = [HasDirectMove] in {
2824    // Endianness-neutral constant splat on P8 and newer targets. The reason
2825    // for this pattern is that on targets with direct moves, we don't expand
2826    // BUILD_VECTOR nodes for v4i32.
2827    def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
2828                                   immSExt5NonZero:$A, immSExt5NonZero:$A)),
2829              (v4i32 (VSPLTISW imm:$A))>;
2830  }
2831
2832  let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
2833    // Big endian integer vectors using direct moves.
2834    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
2835              (v2i64 (XXPERMDI
2836                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
2837                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
2838    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2839              (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC),
2840                                   (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 0),
2841                      (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC),
2842                                   (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 0))>;
2843    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2844              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
2845  }
2846
2847  let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
2848    // Little endian integer vectors using direct moves.
2849    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
2850              (v2i64 (XXPERMDI
2851                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
2852                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
2853    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2854              (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC),
2855                                   (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 0),
2856                      (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC),
2857                                   (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 0))>;
2858    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2859              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
2860  }
2861
2862  let Predicates = [HasP9Vector] in {
2863    // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
2864    def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2865              (v4i32 (MTVSRWS $A))>;
2866    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
2867              (v4i32 (MTVSRWS $A))>;
2868    def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2869                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2870                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2871                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2872                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
2873                                   immAnyExt8:$A)),
2874              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
2875    def : Pat<(v16i8 immAllOnesV),
2876              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
2877    def : Pat<(v8i16 immAllOnesV),
2878              (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
2879    def : Pat<(v4i32 immAllOnesV),
2880              (v4i32 (XXSPLTIB 255))>;
2881    def : Pat<(v2i64 immAllOnesV),
2882              (v2i64 (XXSPLTIB 255))>;
2883    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
2884              (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
2885    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
2886              (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
2887    def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
2888              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2889                                (XSCVDPSXWS (DFLOADf64 iaddr:$A)), VSRC), 1))>;
2890    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
2891              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
2892                                (XSCVDPUXWS (DFLOADf64 iaddr:$A)), VSRC), 1))>;
2893    def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
2894              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
2895                                              (DFLOADf32 iaddr:$A),
2896                                              VSFRC)), 0))>;
2897    def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
2898              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
2899                                              (DFLOADf32 iaddr:$A),
2900                                              VSFRC)), 0))>;
2901  }
2902
2903  let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
2904    def : Pat<(i64 (extractelt v2i64:$A, 1)),
2905              (i64 (MFVSRLD $A))>;
2906    // Better way to build integer vectors if we have MTVSRDD. Big endian.
2907    def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
2908              (v2i64 (MTVSRDD $rB, $rA))>;
2909    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2910              (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.A, AnyExts.C), VSRC),
2911                      (COPY_TO_REGCLASS (MTVSRDD AnyExts.B, AnyExts.D), VSRC))>;
2912  }
2913
2914  let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
2915    def : Pat<(i64 (extractelt v2i64:$A, 0)),
2916              (i64 (MFVSRLD $A))>;
2917    // Better way to build integer vectors if we have MTVSRDD. Little endian.
2918    def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
2919              (v2i64 (MTVSRDD $rB, $rA))>;
2920    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
2921              (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.D, AnyExts.B), VSRC),
2922                      (COPY_TO_REGCLASS (MTVSRDD AnyExts.C, AnyExts.A), VSRC))>;
2923  }
2924}
2925