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