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