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
1043def : Pat<(v2i64 (bitconvert f128:$A)),
1044          (COPY_TO_REGCLASS $A, VRRC)>;
1045def : Pat<(v4i32 (bitconvert f128:$A)),
1046          (COPY_TO_REGCLASS $A, VRRC)>;
1047def : Pat<(v8i16 (bitconvert f128:$A)),
1048          (COPY_TO_REGCLASS $A, VRRC)>;
1049def : Pat<(v16i8 (bitconvert f128:$A)),
1050          (COPY_TO_REGCLASS $A, VRRC)>;
1051
1052def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
1053          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
1054def : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
1055          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
1056
1057def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
1058          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
1059def : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
1060          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
1061
1062// Loads.
1063let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
1064  def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1065
1066  // Stores.
1067  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
1068            (STXVD2X $rS, xoaddr:$dst)>;
1069  def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1070}
1071let Predicates = [IsBigEndian, HasVSX, HasOnlySwappingMemOps] in {
1072  def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1073  def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1074  def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1075  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1076  def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1077  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
1078  def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
1079  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
1080            (STXVW4X $rS, xoaddr:$dst)>;
1081}
1082
1083// Permutes.
1084def : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1085def : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
1086def : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
1087def : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
1088def : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
1089
1090// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
1091// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
1092def : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), (XXPERMDI $src, $src, 2)>;
1093
1094// Selects.
1095def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
1096          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1097def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
1098          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1099def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
1100          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1101def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
1102          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1103def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
1104          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1105def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
1106          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1107def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
1108          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1109def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
1110          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1111def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
1112          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1113def : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
1114          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1115
1116def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
1117          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1118def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
1119          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1120def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
1121          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1122def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
1123          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1124def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
1125          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
1126def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
1127          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1128def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
1129          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1130def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
1131          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1132def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
1133          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1134def : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
1135          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1136
1137// Divides.
1138def : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
1139          (XVDIVSP $A, $B)>;
1140def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
1141          (XVDIVDP $A, $B)>;
1142
1143// Reciprocal estimate
1144def : Pat<(int_ppc_vsx_xvresp v4f32:$A),
1145          (XVRESP $A)>;
1146def : Pat<(int_ppc_vsx_xvredp v2f64:$A),
1147          (XVREDP $A)>;
1148
1149// Recip. square root estimate
1150def : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
1151          (XVRSQRTESP $A)>;
1152def : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
1153          (XVRSQRTEDP $A)>;
1154
1155// Vector selection
1156def : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
1157          (COPY_TO_REGCLASS
1158                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
1159                        (COPY_TO_REGCLASS $vB, VSRC),
1160                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
1161def : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
1162          (COPY_TO_REGCLASS
1163                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
1164                        (COPY_TO_REGCLASS $vB, VSRC),
1165                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
1166def : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
1167          (XXSEL $vC, $vB, $vA)>;
1168def : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
1169          (XXSEL $vC, $vB, $vA)>;
1170def : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
1171          (XXSEL $vC, $vB, $vA)>;
1172def : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
1173          (XXSEL $vC, $vB, $vA)>;
1174
1175let Predicates = [IsLittleEndian] in {
1176def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1177          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1178def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1179          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1180def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1181          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1182def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1183          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1184} // IsLittleEndian
1185
1186let Predicates = [IsBigEndian] in {
1187def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1188          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1189def : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1190          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1191def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1192          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
1193def : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1194          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1195} // IsBigEndian
1196
1197} // AddedComplexity
1198} // HasVSX
1199
1200def ScalarLoads {
1201  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
1202  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
1203  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
1204  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
1205  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
1206
1207  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
1208  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
1209  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
1210  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
1211  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
1212
1213  dag Li32 = (i32 (load xoaddr:$src));
1214}
1215
1216// The following VSX instructions were introduced in Power ISA 2.07
1217/* FIXME: if the operands are v2i64, these patterns will not match.
1218   we should define new patterns or otherwise match the same patterns
1219   when the elements are larger than i32.
1220*/
1221def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
1222def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
1223def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
1224let Predicates = [HasP8Vector] in {
1225let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1226  let isCommutable = 1, UseVSXReg = 1 in {
1227    def XXLEQV : XX3Form<60, 186,
1228                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1229                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1230                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1231    def XXLNAND : XX3Form<60, 178,
1232                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1233                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1234                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1235                                                    v4i32:$XB)))]>;
1236  } // isCommutable, UseVSXReg
1237
1238  def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1239            (XXLEQV $A, $B)>;
1240
1241  let UseVSXReg = 1 in {
1242  def XXLORC : XX3Form<60, 170,
1243                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1244                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1245                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1246
1247  // VSX scalar loads introduced in ISA 2.07
1248  let mayLoad = 1, mayStore = 0 in {
1249    let CodeSize = 3 in
1250    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1251                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
1252    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1253                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
1254    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1255                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
1256
1257    // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it
1258    // would cause these Pseudos are not expanded in expandPostRAPseudos()
1259    let isPseudo = 1 in {
1260      // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
1261      let CodeSize = 3 in
1262      def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
1263                              "#XFLOADf32",
1264                              [(set f32:$XT, (load xoaddr:$src))]>;
1265      // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
1266      def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1267                         "#LIWAX",
1268                         [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1269      // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
1270      def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1271                         "#LIWZX",
1272                         [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1273    }
1274  } // mayLoad
1275
1276  // VSX scalar stores introduced in ISA 2.07
1277  let mayStore = 1, mayLoad = 0 in {
1278    let CodeSize = 3 in
1279    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1280                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
1281    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1282                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
1283
1284    // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it
1285    // would cause these Pseudos are not expanded in expandPostRAPseudos()
1286    let isPseudo = 1 in {
1287      // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
1288      let CodeSize = 3 in
1289      def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
1290                              "#XFSTOREf32",
1291                              [(store f32:$XT, xoaddr:$dst)]>;
1292      // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
1293      def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1294                         "#STIWX",
1295                        [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1296    }
1297  } // mayStore
1298  } // UseVSXReg = 1
1299
1300  def : Pat<(f64 (extloadf32 xoaddr:$src)),
1301            (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
1302  def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
1303            (f32 (XFLOADf32 xoaddr:$src))>;
1304  def : Pat<(f64 (fpextend f32:$src)),
1305            (COPY_TO_REGCLASS $src, VSFRC)>;
1306
1307  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1308            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1309  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1310            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1311  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1312            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1313  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1314            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1315  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1316            (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1317  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1318            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1319  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1320            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1321  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1322            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1323  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1324            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1325  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1326            (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1327
1328  let UseVSXReg = 1 in {
1329  // VSX Elementary Scalar FP arithmetic (SP)
1330  let isCommutable = 1 in {
1331    def XSADDSP : XX3Form<60, 0,
1332                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1333                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1334                          [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1335    def XSMULSP : XX3Form<60, 16,
1336                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1337                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1338                          [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1339  } // isCommutable
1340
1341  def XSDIVSP : XX3Form<60, 24,
1342                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1343                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1344                        [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1345  def XSRESP : XX2Form<60, 26,
1346                        (outs vssrc:$XT), (ins vssrc:$XB),
1347                        "xsresp $XT, $XB", IIC_VecFP,
1348                        [(set f32:$XT, (PPCfre f32:$XB))]>;
1349  def XSRSP : XX2Form<60, 281,
1350                        (outs vssrc:$XT), (ins vsfrc:$XB),
1351                        "xsrsp $XT, $XB", IIC_VecFP, []>;
1352  def XSSQRTSP : XX2Form<60, 11,
1353                        (outs vssrc:$XT), (ins vssrc:$XB),
1354                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1355                        [(set f32:$XT, (fsqrt f32:$XB))]>;
1356  def XSRSQRTESP : XX2Form<60, 10,
1357                           (outs vssrc:$XT), (ins vssrc:$XB),
1358                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
1359                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1360  def XSSUBSP : XX3Form<60, 8,
1361                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1362                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
1363                        [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1364
1365  // FMA Instructions
1366  let BaseName = "XSMADDASP" in {
1367  let isCommutable = 1 in
1368  def XSMADDASP : XX3Form<60, 1,
1369                          (outs vssrc:$XT),
1370                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1371                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1372                          [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1373                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1374                          AltVSXFMARel;
1375  let IsVSXFMAAlt = 1 in
1376  def XSMADDMSP : XX3Form<60, 9,
1377                          (outs vssrc:$XT),
1378                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1379                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1380                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1381                          AltVSXFMARel;
1382  }
1383
1384  let BaseName = "XSMSUBASP" in {
1385  let isCommutable = 1 in
1386  def XSMSUBASP : XX3Form<60, 17,
1387                          (outs vssrc:$XT),
1388                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1389                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1390                          [(set f32:$XT, (fma f32:$XA, f32:$XB,
1391                                              (fneg f32:$XTi)))]>,
1392                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1393                          AltVSXFMARel;
1394  let IsVSXFMAAlt = 1 in
1395  def XSMSUBMSP : XX3Form<60, 25,
1396                          (outs vssrc:$XT),
1397                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1398                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1399                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1400                          AltVSXFMARel;
1401  }
1402
1403  let BaseName = "XSNMADDASP" in {
1404  let isCommutable = 1 in
1405  def XSNMADDASP : XX3Form<60, 129,
1406                          (outs vssrc:$XT),
1407                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1408                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1409                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1410                                                    f32:$XTi)))]>,
1411                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1412                          AltVSXFMARel;
1413  let IsVSXFMAAlt = 1 in
1414  def XSNMADDMSP : XX3Form<60, 137,
1415                          (outs vssrc:$XT),
1416                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1417                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1418                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1419                          AltVSXFMARel;
1420  }
1421
1422  let BaseName = "XSNMSUBASP" in {
1423  let isCommutable = 1 in
1424  def XSNMSUBASP : XX3Form<60, 145,
1425                          (outs vssrc:$XT),
1426                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1427                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1428                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1429                                                    (fneg f32:$XTi))))]>,
1430                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1431                          AltVSXFMARel;
1432  let IsVSXFMAAlt = 1 in
1433  def XSNMSUBMSP : XX3Form<60, 153,
1434                          (outs vssrc:$XT),
1435                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1436                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1437                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1438                          AltVSXFMARel;
1439  }
1440
1441  // Single Precision Conversions (FP <-> INT)
1442  def XSCVSXDSP : XX2Form<60, 312,
1443                      (outs vssrc:$XT), (ins vsfrc:$XB),
1444                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1445                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1446  def XSCVUXDSP : XX2Form<60, 296,
1447                      (outs vssrc:$XT), (ins vsfrc:$XB),
1448                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1449                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1450
1451  // Conversions between vector and scalar single precision
1452  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1453                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1454  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1455                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1456  } // UseVSXReg = 1
1457
1458  let Predicates = [IsLittleEndian] in {
1459  def : Pat<(f32 (PPCfcfids
1460                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1461            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1462  def : Pat<(f32 (PPCfcfids
1463                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1464            (f32 (XSCVSXDSP (COPY_TO_REGCLASS
1465                              (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1466  def : Pat<(f32 (PPCfcfidus
1467                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1468            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1469  def : Pat<(f32 (PPCfcfidus
1470                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1471            (f32 (XSCVUXDSP (COPY_TO_REGCLASS
1472                              (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1473  }
1474
1475  let Predicates = [IsBigEndian] in {
1476  def : Pat<(f32 (PPCfcfids
1477                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1478            (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1479  def : Pat<(f32 (PPCfcfids
1480                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1481            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1482  def : Pat<(f32 (PPCfcfidus
1483                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 0)))))),
1484            (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1485  def : Pat<(f32 (PPCfcfidus
1486                   (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S, 1)))))),
1487            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1488  }
1489
1490  // Instructions for converting float to i64 feeding a store.
1491  let Predicates = [NoP9Vector] in {
1492  def : Pat<(PPCstore_scal_int_from_vsr
1493              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
1494            (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
1495  def : Pat<(PPCstore_scal_int_from_vsr
1496              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
1497            (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
1498  }
1499
1500  // Instructions for converting float to i32 feeding a store.
1501  def : Pat<(PPCstore_scal_int_from_vsr
1502              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
1503            (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
1504  def : Pat<(PPCstore_scal_int_from_vsr
1505              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
1506            (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
1507
1508} // AddedComplexity = 400
1509} // HasP8Vector
1510
1511let UseVSXReg = 1, AddedComplexity = 400 in {
1512let Predicates = [HasDirectMove] in {
1513  // VSX direct move instructions
1514  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1515                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1516                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1517      Requires<[In64BitMode]>;
1518  let isCodeGenOnly = 1 in
1519  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vrrc:$XT),
1520                             "mfvsrd $rA, $XT", IIC_VecGeneral,
1521                             []>,
1522      Requires<[In64BitMode]>;
1523  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1524                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1525                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1526  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1527                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1528                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1529      Requires<[In64BitMode]>;
1530  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1531                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1532                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1533  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1534                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1535                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1536} // HasDirectMove
1537
1538let Predicates = [IsISA3_0, HasDirectMove] in {
1539  def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1540                              "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1541
1542  def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1543                       "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1544                       []>, Requires<[In64BitMode]>;
1545
1546  def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1547                              "mfvsrld $rA, $XT", IIC_VecGeneral,
1548                              []>, Requires<[In64BitMode]>;
1549
1550} // IsISA3_0, HasDirectMove
1551} // UseVSXReg = 1
1552
1553// We want to parse this from asm, but we don't want to emit this as it would
1554// be emitted with a VSX reg. So leave Emit = 0 here.
1555def : InstAlias<"mfvrd $rA, $XT",
1556                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
1557def : InstAlias<"mffprd $rA, $src",
1558                (MFVSRD g8rc:$rA, f8rc:$src)>;
1559
1560/*  Direct moves of various widths from GPR's into VSR's. Each move lines
1561    the value up into element 0 (both BE and LE). Namely, entities smaller than
1562    a doubleword are shifted left and moved for BE. For LE, they're moved, then
1563    swapped to go into the least significant element of the VSR.
1564*/
1565def MovesToVSR {
1566  dag BE_BYTE_0 =
1567    (MTVSRD
1568      (RLDICR
1569        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1570  dag BE_HALF_0 =
1571    (MTVSRD
1572      (RLDICR
1573        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1574  dag BE_WORD_0 =
1575    (MTVSRD
1576      (RLDICR
1577        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1578  dag BE_DWORD_0 = (MTVSRD $A);
1579
1580  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1581  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1582                                        LE_MTVSRW, sub_64));
1583  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1584  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1585                                         BE_DWORD_0, sub_64));
1586  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1587}
1588
1589/*  Patterns for extracting elements out of vectors. Integer elements are
1590    extracted using direct move operations. Patterns for extracting elements
1591    whose indices are not available at compile time are also provided with
1592    various _VARIABLE_ patterns.
1593    The numbering for the DAG's is for LE, but when used on BE, the correct
1594    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1595*/
1596def VectorExtractions {
1597  // Doubleword extraction
1598  dag LE_DWORD_0 =
1599    (MFVSRD
1600      (EXTRACT_SUBREG
1601        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1602                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1603  dag LE_DWORD_1 = (MFVSRD
1604                     (EXTRACT_SUBREG
1605                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1606
1607  // Word extraction
1608  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1609  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1610  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1611                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1612  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1613
1614  // Halfword extraction
1615  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1616  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1617  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1618  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1619  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1620  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1621  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1622  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1623
1624  // Byte extraction
1625  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1626  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1627  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1628  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1629  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1630  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1631  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1632  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1633  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1634  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1635  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1636  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1637  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1638  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1639  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1640  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1641
1642  /* Variable element number (BE and LE patterns must be specified separately)
1643     This is a rather involved process.
1644
1645     Conceptually, this is how the move is accomplished:
1646     1. Identify which doubleword contains the element
1647     2. Shift in the VMX register so that the correct doubleword is correctly
1648        lined up for the MFVSRD
1649     3. Perform the move so that the element (along with some extra stuff)
1650        is in the GPR
1651     4. Right shift within the GPR so that the element is right-justified
1652
1653     Of course, the index is an element number which has a different meaning
1654     on LE/BE so the patterns have to be specified separately.
1655
1656     Note: The final result will be the element right-justified with high
1657           order bits being arbitrarily defined (namely, whatever was in the
1658           vector register to the left of the value originally).
1659  */
1660
1661  /*  LE variable byte
1662      Number 1. above:
1663      - For elements 0-7, we shift left by 8 bytes since they're on the right
1664      - For elements 8-15, we need not shift (shift left by zero bytes)
1665      This is accomplished by inverting the bits of the index and AND-ing
1666      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1667  */
1668  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
1669
1670  //  Number 2. above:
1671  //  - Now that we set up the shift amount, we shift in the VMX register
1672  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
1673
1674  //  Number 3. above:
1675  //  - The doubleword containing our element is moved to a GPR
1676  dag LE_MV_VBYTE = (MFVSRD
1677                      (EXTRACT_SUBREG
1678                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1679                        sub_64));
1680
1681  /*  Number 4. above:
1682      - Truncate the element number to the range 0-7 (8-15 are symmetrical
1683        and out of range values are truncated accordingly)
1684      - Multiply by 8 as we need to shift right by the number of bits, not bytes
1685      - Shift right in the GPR by the calculated value
1686  */
1687  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1688                                       sub_32);
1689  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1690                                         sub_32);
1691
1692  /*  LE variable halfword
1693      Number 1. above:
1694      - For elements 0-3, we shift left by 8 since they're on the right
1695      - For elements 4-7, we need not shift (shift left by zero bytes)
1696      Similarly to the byte pattern, we invert the bits of the index, but we
1697      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1698      Of course, the shift is still by 8 bytes, so we must multiply by 2.
1699  */
1700  dag LE_VHALF_PERM_VEC =
1701    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
1702
1703  //  Number 2. above:
1704  //  - Now that we set up the shift amount, we shift in the VMX register
1705  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
1706
1707  //  Number 3. above:
1708  //  - The doubleword containing our element is moved to a GPR
1709  dag LE_MV_VHALF = (MFVSRD
1710                      (EXTRACT_SUBREG
1711                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1712                        sub_64));
1713
1714  /*  Number 4. above:
1715      - Truncate the element number to the range 0-3 (4-7 are symmetrical
1716        and out of range values are truncated accordingly)
1717      - Multiply by 16 as we need to shift right by the number of bits
1718      - Shift right in the GPR by the calculated value
1719  */
1720  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1721                                       sub_32);
1722  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1723                                         sub_32);
1724
1725  /*  LE variable word
1726      Number 1. above:
1727      - For elements 0-1, we shift left by 8 since they're on the right
1728      - For elements 2-3, we need not shift
1729  */
1730  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1731                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
1732
1733  //  Number 2. above:
1734  //  - Now that we set up the shift amount, we shift in the VMX register
1735  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
1736
1737  //  Number 3. above:
1738  //  - The doubleword containing our element is moved to a GPR
1739  dag LE_MV_VWORD = (MFVSRD
1740                      (EXTRACT_SUBREG
1741                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1742                        sub_64));
1743
1744  /*  Number 4. above:
1745      - Truncate the element number to the range 0-1 (2-3 are symmetrical
1746        and out of range values are truncated accordingly)
1747      - Multiply by 32 as we need to shift right by the number of bits
1748      - Shift right in the GPR by the calculated value
1749  */
1750  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1751                                       sub_32);
1752  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1753                                         sub_32);
1754
1755  /*  LE variable doubleword
1756      Number 1. above:
1757      - For element 0, we shift left by 8 since it's on the right
1758      - For element 1, we need not shift
1759  */
1760  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1761                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
1762
1763  //  Number 2. above:
1764  //  - Now that we set up the shift amount, we shift in the VMX register
1765  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
1766
1767  // Number 3. above:
1768  //  - The doubleword containing our element is moved to a GPR
1769  //  - Number 4. is not needed for the doubleword as the value is 64-bits
1770  dag LE_VARIABLE_DWORD =
1771        (MFVSRD (EXTRACT_SUBREG
1772                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1773                  sub_64));
1774
1775  /*  LE variable float
1776      - Shift the vector to line up the desired element to BE Word 0
1777      - Convert 32-bit float to a 64-bit single precision float
1778  */
1779  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
1780                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
1781  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1782  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1783
1784  /*  LE variable double
1785      Same as the LE doubleword except there is no move.
1786  */
1787  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1788                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1789                                         LE_VDWORD_PERM_VEC));
1790  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1791
1792  /*  BE variable byte
1793      The algorithm here is the same as the LE variable byte except:
1794      - The shift in the VMX register is by 0/8 for opposite element numbers so
1795        we simply AND the element number with 0x8
1796      - The order of elements after the move to GPR is reversed, so we invert
1797        the bits of the index prior to truncating to the range 0-7
1798  */
1799  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDIo8 $Idx, 8)));
1800  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
1801  dag BE_MV_VBYTE = (MFVSRD
1802                      (EXTRACT_SUBREG
1803                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1804                        sub_64));
1805  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1806                                       sub_32);
1807  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1808                                         sub_32);
1809
1810  /*  BE variable halfword
1811      The algorithm here is the same as the LE variable halfword except:
1812      - The shift in the VMX register is by 0/8 for opposite element numbers so
1813        we simply AND the element number with 0x4 and multiply by 2
1814      - The order of elements after the move to GPR is reversed, so we invert
1815        the bits of the index prior to truncating to the range 0-3
1816  */
1817  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
1818                                       (RLDICR (ANDIo8 $Idx, 4), 1, 62)));
1819  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
1820  dag BE_MV_VHALF = (MFVSRD
1821                      (EXTRACT_SUBREG
1822                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1823                        sub_64));
1824  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1825                                       sub_32);
1826  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1827                                         sub_32);
1828
1829  /*  BE variable word
1830      The algorithm is the same as the LE variable word except:
1831      - The shift in the VMX register happens for opposite element numbers
1832      - The order of elements after the move to GPR is reversed, so we invert
1833        the bits of the index prior to truncating to the range 0-1
1834  */
1835  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1836                                       (RLDICR (ANDIo8 $Idx, 2), 2, 61)));
1837  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
1838  dag BE_MV_VWORD = (MFVSRD
1839                      (EXTRACT_SUBREG
1840                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1841                        sub_64));
1842  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1843                                       sub_32);
1844  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1845                                         sub_32);
1846
1847  /*  BE variable doubleword
1848      Same as the LE doubleword except we shift in the VMX register for opposite
1849      element indices.
1850  */
1851  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
1852                                        (RLDICR (ANDIo8 $Idx, 1), 3, 60)));
1853  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
1854  dag BE_VARIABLE_DWORD =
1855        (MFVSRD (EXTRACT_SUBREG
1856                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1857                  sub_64));
1858
1859  /*  BE variable float
1860      - Shift the vector to line up the desired element to BE Word 0
1861      - Convert 32-bit float to a 64-bit single precision float
1862  */
1863  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
1864  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1865  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1866
1867  /* BE variable double
1868      Same as the BE doubleword except there is no move.
1869  */
1870  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1871                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
1872                                         BE_VDWORD_PERM_VEC));
1873  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1874}
1875
1876def NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">;
1877let AddedComplexity = 400 in {
1878// v4f32 scalar <-> vector conversions (BE)
1879let Predicates = [IsBigEndian, HasP8Vector] in {
1880  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1881            (v4f32 (XSCVDPSPN $A))>;
1882  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1883            (f32 (XSCVSPDPN $S))>;
1884  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1885            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1886  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1887            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1888  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1889            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1890  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1891            (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1892} // IsBigEndian, HasP8Vector
1893
1894// Variable index vector_extract for v2f64 does not require P8Vector
1895let Predicates = [IsBigEndian, HasVSX] in
1896  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1897            (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1898
1899let Predicates = [IsBigEndian, HasDirectMove] in {
1900  // v16i8 scalar <-> vector conversions (BE)
1901  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1902            (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1903  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1904            (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1905  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1906            (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1907  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1908            (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1909
1910  // v2i64 scalar <-> vector conversions (BE)
1911  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1912            (i64 VectorExtractions.LE_DWORD_1)>;
1913  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1914            (i64 VectorExtractions.LE_DWORD_0)>;
1915  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1916            (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1917} // IsBigEndian, HasDirectMove
1918
1919let Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in {
1920  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1921            (i32 VectorExtractions.LE_BYTE_15)>;
1922  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1923            (i32 VectorExtractions.LE_BYTE_14)>;
1924  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1925            (i32 VectorExtractions.LE_BYTE_13)>;
1926  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1927            (i32 VectorExtractions.LE_BYTE_12)>;
1928  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1929            (i32 VectorExtractions.LE_BYTE_11)>;
1930  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1931            (i32 VectorExtractions.LE_BYTE_10)>;
1932  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1933            (i32 VectorExtractions.LE_BYTE_9)>;
1934  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1935            (i32 VectorExtractions.LE_BYTE_8)>;
1936  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1937            (i32 VectorExtractions.LE_BYTE_7)>;
1938  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1939            (i32 VectorExtractions.LE_BYTE_6)>;
1940  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1941            (i32 VectorExtractions.LE_BYTE_5)>;
1942  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1943            (i32 VectorExtractions.LE_BYTE_4)>;
1944  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1945            (i32 VectorExtractions.LE_BYTE_3)>;
1946  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1947            (i32 VectorExtractions.LE_BYTE_2)>;
1948  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1949            (i32 VectorExtractions.LE_BYTE_1)>;
1950  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1951            (i32 VectorExtractions.LE_BYTE_0)>;
1952  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1953            (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1954
1955  // v8i16 scalar <-> vector conversions (BE)
1956  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1957            (i32 VectorExtractions.LE_HALF_7)>;
1958  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1959            (i32 VectorExtractions.LE_HALF_6)>;
1960  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1961            (i32 VectorExtractions.LE_HALF_5)>;
1962  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1963            (i32 VectorExtractions.LE_HALF_4)>;
1964  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1965            (i32 VectorExtractions.LE_HALF_3)>;
1966  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1967            (i32 VectorExtractions.LE_HALF_2)>;
1968  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1969            (i32 VectorExtractions.LE_HALF_1)>;
1970  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1971            (i32 VectorExtractions.LE_HALF_0)>;
1972  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1973            (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1974
1975  // v4i32 scalar <-> vector conversions (BE)
1976  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1977            (i32 VectorExtractions.LE_WORD_3)>;
1978  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1979            (i32 VectorExtractions.LE_WORD_2)>;
1980  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1981            (i32 VectorExtractions.LE_WORD_1)>;
1982  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1983            (i32 VectorExtractions.LE_WORD_0)>;
1984  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1985            (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1986} // IsBigEndian, HasDirectMove, NoP9Altivec
1987
1988// v4f32 scalar <-> vector conversions (LE)
1989let Predicates = [IsLittleEndian, HasP8Vector] in {
1990  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1991            (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1992  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1993            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1994  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1995            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1996  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1997            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1998  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1999            (f32 (XSCVSPDPN $S))>;
2000  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
2001            (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
2002} // IsLittleEndian, HasP8Vector
2003
2004// Variable index vector_extract for v2f64 does not require P8Vector
2005let Predicates = [IsLittleEndian, HasVSX] in
2006  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
2007            (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
2008
2009def : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
2010            (STXVD2X $rS, xoaddr:$dst)>;
2011def : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
2012            (STXVW4X $rS, xoaddr:$dst)>;
2013def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
2014def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
2015
2016// Variable index unsigned vector_extract on Power9
2017let Predicates = [HasP9Altivec, IsLittleEndian] in {
2018  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
2019            (VEXTUBRX $Idx, $S)>;
2020
2021  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2022            (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2023  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2024            (VEXTUHRX (LI8 0), $S)>;
2025  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2026            (VEXTUHRX (LI8 2), $S)>;
2027  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2028            (VEXTUHRX (LI8 4), $S)>;
2029  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2030            (VEXTUHRX (LI8 6), $S)>;
2031  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2032            (VEXTUHRX (LI8 8), $S)>;
2033  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2034            (VEXTUHRX (LI8 10), $S)>;
2035  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2036            (VEXTUHRX (LI8 12), $S)>;
2037  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2038            (VEXTUHRX (LI8 14), $S)>;
2039
2040  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2041            (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2042  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2043            (VEXTUWRX (LI8 0), $S)>;
2044  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2045            (VEXTUWRX (LI8 4), $S)>;
2046  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2047  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2048            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2049	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2050  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2051            (VEXTUWRX (LI8 12), $S)>;
2052
2053  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2054            (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2055  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2056            (EXTSW (VEXTUWRX (LI8 0), $S))>;
2057  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2058            (EXTSW (VEXTUWRX (LI8 4), $S))>;
2059  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2060  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2061            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2062	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2063  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2064            (EXTSW (VEXTUWRX (LI8 12), $S))>;
2065
2066  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2067            (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
2068  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2069            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
2070  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2071            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
2072  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2073            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
2074  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2075            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
2076  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2077            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
2078  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2079            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
2080  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2081            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
2082  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2083            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
2084  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2085            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
2086  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2087            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
2088  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2089            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
2090  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2091            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
2092  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2093            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
2094  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2095            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
2096  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2097            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
2098  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2099            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
2100
2101  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2102            (i32 (EXTRACT_SUBREG (VEXTUHRX
2103	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2104  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2105            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
2106  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2107            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
2108  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2109            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
2110  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2111            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
2112  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2113            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
2114  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2115            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
2116  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2117            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
2118  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2119            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
2120
2121  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2122            (i32 (EXTRACT_SUBREG (VEXTUWRX
2123	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2124  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2125            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
2126  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2127            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
2128  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2129  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2130            (i32 VectorExtractions.LE_WORD_2)>;
2131  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2132            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
2133}
2134
2135let Predicates = [HasP9Altivec, IsBigEndian] in {
2136  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
2137            (VEXTUBLX $Idx, $S)>;
2138
2139  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2140            (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2141  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2142            (VEXTUHLX (LI8 0), $S)>;
2143  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2144            (VEXTUHLX (LI8 2), $S)>;
2145  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2146            (VEXTUHLX (LI8 4), $S)>;
2147  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2148            (VEXTUHLX (LI8 6), $S)>;
2149  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2150            (VEXTUHLX (LI8 8), $S)>;
2151  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2152            (VEXTUHLX (LI8 10), $S)>;
2153  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2154            (VEXTUHLX (LI8 12), $S)>;
2155  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2156            (VEXTUHLX (LI8 14), $S)>;
2157
2158  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2159            (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2160  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2161            (VEXTUWLX (LI8 0), $S)>;
2162
2163  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2164  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2165            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2166	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2167  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2168            (VEXTUWLX (LI8 8), $S)>;
2169  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2170            (VEXTUWLX (LI8 12), $S)>;
2171
2172  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2173            (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2174  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2175            (EXTSW (VEXTUWLX (LI8 0), $S))>;
2176  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2177  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2178            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2179	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2180  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2181            (EXTSW (VEXTUWLX (LI8 8), $S))>;
2182  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2183            (EXTSW (VEXTUWLX (LI8 12), $S))>;
2184
2185  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2186            (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
2187  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2188            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
2189  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2190            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
2191  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2192            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
2193  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2194            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
2195  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2196            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
2197  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2198            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
2199  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2200            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
2201  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2202            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
2203  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2204            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
2205  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2206            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
2207  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2208            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
2209  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2210            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
2211  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2212            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
2213  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2214            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
2215  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2216            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
2217  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2218            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
2219
2220  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2221            (i32 (EXTRACT_SUBREG (VEXTUHLX
2222	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2223  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2224            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
2225  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2226            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
2227  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2228            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
2229  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2230            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
2231  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2232            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
2233  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2234            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
2235  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2236            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
2237  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2238            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
2239
2240  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2241            (i32 (EXTRACT_SUBREG (VEXTUWLX
2242	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2243  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2244            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
2245  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2246  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2247            (i32 VectorExtractions.LE_WORD_2)>;
2248  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2249            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
2250  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2251            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
2252}
2253
2254let Predicates = [IsLittleEndian, HasDirectMove] in {
2255  // v16i8 scalar <-> vector conversions (LE)
2256  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
2257            (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2258  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
2259            (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2260  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2261            (v4i32 MovesToVSR.LE_WORD_0)>;
2262  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
2263            (v2i64 MovesToVSR.LE_DWORD_0)>;
2264  // v2i64 scalar <-> vector conversions (LE)
2265  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
2266            (i64 VectorExtractions.LE_DWORD_0)>;
2267  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
2268            (i64 VectorExtractions.LE_DWORD_1)>;
2269  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
2270            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
2271} // IsLittleEndian, HasDirectMove
2272
2273let Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in {
2274  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2275            (i32 VectorExtractions.LE_BYTE_0)>;
2276  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2277            (i32 VectorExtractions.LE_BYTE_1)>;
2278  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2279            (i32 VectorExtractions.LE_BYTE_2)>;
2280  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2281            (i32 VectorExtractions.LE_BYTE_3)>;
2282  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2283            (i32 VectorExtractions.LE_BYTE_4)>;
2284  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2285            (i32 VectorExtractions.LE_BYTE_5)>;
2286  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2287            (i32 VectorExtractions.LE_BYTE_6)>;
2288  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2289            (i32 VectorExtractions.LE_BYTE_7)>;
2290  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2291            (i32 VectorExtractions.LE_BYTE_8)>;
2292  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2293            (i32 VectorExtractions.LE_BYTE_9)>;
2294  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2295            (i32 VectorExtractions.LE_BYTE_10)>;
2296  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2297            (i32 VectorExtractions.LE_BYTE_11)>;
2298  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2299            (i32 VectorExtractions.LE_BYTE_12)>;
2300  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2301            (i32 VectorExtractions.LE_BYTE_13)>;
2302  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2303            (i32 VectorExtractions.LE_BYTE_14)>;
2304  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2305            (i32 VectorExtractions.LE_BYTE_15)>;
2306  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2307            (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
2308
2309  // v8i16 scalar <-> vector conversions (LE)
2310  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2311            (i32 VectorExtractions.LE_HALF_0)>;
2312  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2313            (i32 VectorExtractions.LE_HALF_1)>;
2314  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2315            (i32 VectorExtractions.LE_HALF_2)>;
2316  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2317            (i32 VectorExtractions.LE_HALF_3)>;
2318  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2319            (i32 VectorExtractions.LE_HALF_4)>;
2320  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2321            (i32 VectorExtractions.LE_HALF_5)>;
2322  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2323            (i32 VectorExtractions.LE_HALF_6)>;
2324  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
2325            (i32 VectorExtractions.LE_HALF_7)>;
2326  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2327            (i32 VectorExtractions.LE_VARIABLE_HALF)>;
2328
2329  // v4i32 scalar <-> vector conversions (LE)
2330  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2331            (i32 VectorExtractions.LE_WORD_0)>;
2332  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2333            (i32 VectorExtractions.LE_WORD_1)>;
2334  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2335            (i32 VectorExtractions.LE_WORD_2)>;
2336  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2337            (i32 VectorExtractions.LE_WORD_3)>;
2338  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2339            (i32 VectorExtractions.LE_VARIABLE_WORD)>;
2340} // IsLittleEndian, HasDirectMove, NoP9Altivec
2341
2342let Predicates = [HasDirectMove, HasVSX] in {
2343// bitconvert f32 -> i32
2344// (convert to 32-bit fp single, shift right 1 word, move to GPR)
2345def : Pat<(i32 (bitconvert f32:$S)),
2346          (i32 (MFVSRWZ (EXTRACT_SUBREG
2347                          (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
2348                          sub_64)))>;
2349// bitconvert i32 -> f32
2350// (move to FPR, shift left 1 word, convert to 64-bit fp single)
2351def : Pat<(f32 (bitconvert i32:$A)),
2352          (f32 (XSCVSPDPN
2353                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
2354
2355// bitconvert f64 -> i64
2356// (move to GPR, nothing else needed)
2357def : Pat<(i64 (bitconvert f64:$S)),
2358          (i64 (MFVSRD $S))>;
2359
2360// bitconvert i64 -> f64
2361// (move to FPR, nothing else needed)
2362def : Pat<(f64 (bitconvert i64:$S)),
2363          (f64 (MTVSRD $S))>;
2364}
2365
2366// Materialize a zero-vector of long long
2367def : Pat<(v2i64 immAllZerosV),
2368          (v2i64 (XXLXORz))>;
2369}
2370
2371def AlignValues {
2372  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2373  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2374}
2375
2376// The following VSX instructions were introduced in Power ISA 3.0
2377def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2378let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2379
2380  // [PO VRT XO VRB XO /]
2381  class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2382                      list<dag> pattern>
2383    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2384                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2385
2386  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2387  class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2388                         list<dag> pattern>
2389    : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2390
2391  // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2392  // So we use different operand class for VRB
2393  class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2394                           RegisterOperand vbtype, list<dag> pattern>
2395    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2396                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2397
2398  // [PO VRT XO VRB XO /]
2399  class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2400                      list<dag> pattern>
2401    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
2402                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2403
2404  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2405  class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2406                         list<dag> pattern>
2407    : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isDOT;
2408
2409  let UseVSXReg = 1 in {
2410  // [PO T XO B XO BX /]
2411  class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2412                        list<dag> pattern>
2413    : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2414                      !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2415
2416  // [PO T XO B XO BX TX]
2417  class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2418                        RegisterOperand vtype, list<dag> pattern>
2419    : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2420                      !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2421
2422  // [PO T A B XO AX BX TX], src and dest register use different operand class
2423  class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2424                  RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2425                  InstrItinClass itin, list<dag> pattern>
2426    : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2427              !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2428  } // UseVSXReg = 1
2429
2430  // [PO VRT VRA VRB XO /]
2431  class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2432                      list<dag> pattern>
2433    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2434              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2435
2436  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2437  class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2438                         list<dag> pattern>
2439    : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2440
2441  // [PO VRT VRA VRB XO /]
2442  class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
2443                          list<dag> pattern>
2444    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
2445              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
2446              RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
2447
2448  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2449  class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
2450                          list<dag> pattern>
2451    : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isDOT;
2452
2453  //===--------------------------------------------------------------------===//
2454  // Quad-Precision Scalar Move Instructions:
2455
2456  // Copy Sign
2457  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
2458                                [(set f128:$vT,
2459                                      (fcopysign f128:$vB, f128:$vA))]>;
2460
2461  // Absolute/Negative-Absolute/Negate
2462  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
2463                                [(set f128:$vT, (fabs f128:$vB))]>;
2464  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
2465                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
2466  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
2467                                [(set f128:$vT, (fneg f128:$vB))]>;
2468
2469  //===--------------------------------------------------------------------===//
2470  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2471
2472  // Add/Divide/Multiply/Subtract
2473  let isCommutable = 1 in {
2474  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
2475                                   [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>;
2476  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
2477                                  [(set f128:$vT,
2478                                  (int_ppc_addf128_round_to_odd
2479                                  f128:$vA, f128:$vB))]>;
2480  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
2481                                   [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>;
2482  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
2483                                  [(set f128:$vT,
2484                                  (int_ppc_mulf128_round_to_odd
2485                                  f128:$vA, f128:$vB))]>;
2486  }
2487
2488  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
2489                                   [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>;
2490  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
2491                                  [(set f128:$vT,
2492                                  (int_ppc_subf128_round_to_odd
2493                                  f128:$vA, f128:$vB))]>;
2494  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
2495                                   [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>;
2496  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
2497                                  [(set f128:$vT,
2498                                  (int_ppc_divf128_round_to_odd
2499                                  f128:$vA, f128:$vB))]>;
2500
2501  // Square-Root
2502  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
2503                                   [(set f128:$vT, (fsqrt f128:$vB))]>;
2504  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
2505                                  [(set f128:$vT,
2506                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
2507
2508  // (Negative) Multiply-{Add/Subtract}
2509  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
2510                                    [(set f128:$vT,
2511                                          (fma f128:$vA, f128:$vB,
2512                                               f128:$vTi))]>;
2513
2514  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
2515                                      [(set f128:$vT,
2516                                      (int_ppc_fmaf128_round_to_odd
2517                                      f128:$vA,f128:$vB,f128:$vTi))]>;
2518
2519  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
2520                                       [(set f128:$vT,
2521                                             (fma f128:$vA, f128:$vB,
2522                                                  (fneg f128:$vTi)))]>;
2523  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
2524                                      [(set f128:$vT,
2525                                      (int_ppc_fmaf128_round_to_odd
2526                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
2527  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
2528                                     [(set f128:$vT,
2529                                           (fneg (fma f128:$vA, f128:$vB,
2530                                                      f128:$vTi)))]>;
2531  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
2532                                      [(set f128:$vT,
2533                                      (fneg (int_ppc_fmaf128_round_to_odd
2534                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
2535  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
2536                                     [(set f128:$vT,
2537                                           (fneg (fma f128:$vA, f128:$vB,
2538                                                      (fneg f128:$vTi))))]>;
2539  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
2540                                      [(set f128:$vT,
2541                                      (fneg (int_ppc_fmaf128_round_to_odd
2542                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
2543
2544  // Additional fnmsub patterns: -a*c + b == -(a*c - b)
2545  def : Pat<(fma (fneg f128:$A), f128:$C, f128:$B), (XSNMSUBQP $B, $C, $A)>;
2546  def : Pat<(fma f128:$A, (fneg f128:$C), f128:$B), (XSNMSUBQP $B, $C, $A)>;
2547
2548  //===--------------------------------------------------------------------===//
2549  // Quad/Double-Precision Compare Instructions:
2550
2551  // [PO BF // VRA VRB XO /]
2552  class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2553                      list<dag> pattern>
2554    : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2555               !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2556    let Pattern = pattern;
2557  }
2558
2559  // QP Compare Ordered/Unordered
2560  def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2561  def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2562
2563  // DP/QP Compare Exponents
2564  def XSCMPEXPDP : XX3Form_1<60, 59,
2565                             (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2566                             "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>,
2567                   UseVSXReg;
2568  def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2569
2570  // DP Compare ==, >=, >, !=
2571  // Use vsrc for XT, because the entire register of XT is set.
2572  // XT.dword[1] = 0x0000_0000_0000_0000
2573  def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2574                                  IIC_FPCompare, []>;
2575  def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2576                                  IIC_FPCompare, []>;
2577  def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2578                                  IIC_FPCompare, []>;
2579
2580  //===--------------------------------------------------------------------===//
2581  // Quad-Precision Floating-Point Conversion Instructions:
2582
2583  // Convert DP -> QP
2584  def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
2585                                     [(set f128:$vT, (fpextend f64:$vB))]>;
2586
2587  // Round & Convert QP -> DP (dword[1] is set to zero)
2588  def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
2589  def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
2590                                        [(set f64:$vT,
2591                                        (int_ppc_truncf128_round_to_odd
2592                                        f128:$vB))]>;
2593
2594  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2595  def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2596  def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2597  def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2598  def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2599
2600  // Convert (Un)Signed DWord -> QP.
2601  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2602  def : Pat<(f128 (sint_to_fp i64:$src)),
2603            (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
2604  def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))),
2605            (f128 (XSCVSDQP $src))>;
2606  def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))),
2607            (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
2608
2609  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2610  def : Pat<(f128 (uint_to_fp i64:$src)),
2611            (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
2612  def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))),
2613            (f128 (XSCVUDQP $src))>;
2614
2615  // Convert (Un)Signed Word -> QP.
2616  def : Pat<(f128 (sint_to_fp i32:$src)),
2617            (f128 (XSCVSDQP (MTVSRWA $src)))>;
2618  def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
2619            (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
2620  def : Pat<(f128 (uint_to_fp i32:$src)),
2621            (f128 (XSCVUDQP (MTVSRWZ $src)))>;
2622  def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))),
2623            (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
2624
2625  let UseVSXReg = 1 in {
2626  //===--------------------------------------------------------------------===//
2627  // Round to Floating-Point Integer Instructions
2628
2629  // (Round &) Convert DP <-> HP
2630  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2631  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2632  // but we still use vsfrc for it.
2633  def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2634  def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2635
2636  // Vector HP -> SP
2637  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2638  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2639                                 [(set v4f32:$XT,
2640                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2641
2642  } // UseVSXReg = 1
2643
2644  // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2645  // separate pattern so that it can convert the input register class from
2646  // VRRC(v8i16) to VSRC.
2647  def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2648            (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2649
2650  class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2651                                list<dag> pattern>
2652    : Z23Form_8<opcode, xo,
2653                (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2654                !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2655    let RC = ex;
2656  }
2657
2658  // Round to Quad-Precision Integer [with Inexact]
2659  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2660  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2661
2662  // Use current rounding mode
2663  def : Pat<(f128 (fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
2664  // Round to nearest, ties away from zero
2665  def : Pat<(f128 (fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
2666  // Round towards Zero
2667  def : Pat<(f128 (ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
2668  // Round towards +Inf
2669  def : Pat<(f128 (fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
2670  // Round towards -Inf
2671  def : Pat<(f128 (ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
2672
2673  // Use current rounding mode, [with Inexact]
2674  def : Pat<(f128 (frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
2675
2676  // Round Quad-Precision to Double-Extended Precision (fp80)
2677  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2678
2679  //===--------------------------------------------------------------------===//
2680  // Insert/Extract Instructions
2681
2682  // Insert Exponent DP/QP
2683  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2684  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2685                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg;
2686  // vB NOTE: only vB.dword[0] is used, that's why we don't use
2687  //          X_VT5_VA5_VB5 form
2688  def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2689                          "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2690
2691  def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
2692            (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
2693
2694  // Extract Exponent/Significand DP/QP
2695  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2696  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2697
2698  def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2699  def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2700
2701  def : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
2702            (i64 (MFVSRD (EXTRACT_SUBREG
2703                           (v2i64 (XSXEXPQP $vA)), sub_64)))>;
2704
2705  // Vector Insert Word
2706  let UseVSXReg = 1 in {
2707  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2708  def XXINSERTW   :
2709    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2710                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2711                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2712                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
2713                                                   imm32SExt16:$UIM))]>,
2714                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2715
2716  // Vector Extract Unsigned Word
2717  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2718                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2719                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2720  } // UseVSXReg = 1
2721
2722  // Vector Insert Exponent DP/SP
2723  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2724    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2725  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2726    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2727
2728  // Vector Extract Exponent/Significand DP/SP
2729  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2730                                 [(set v2i64: $XT,
2731                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2732  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2733                                 [(set v4i32: $XT,
2734                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2735  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2736                                 [(set v2i64: $XT,
2737                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2738  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2739                                 [(set v4i32: $XT,
2740                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2741
2742  let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2743  // Extra patterns expanding to vector Extract Word/Insert Word
2744  def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2745            (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2746  def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2747            (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2748  } // AddedComplexity = 400, HasP9Vector
2749
2750  //===--------------------------------------------------------------------===//
2751
2752  // Test Data Class SP/DP/QP
2753  let UseVSXReg = 1 in {
2754  def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2755                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2756                              "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2757  def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2758                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2759                              "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2760  } // UseVSXReg = 1
2761  def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2762                              (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2763                              "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2764
2765  // Vector Test Data Class SP/DP
2766  let UseVSXReg = 1 in {
2767  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2768                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2769                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2770                              [(set v4i32: $XT,
2771                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>;
2772  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2773                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2774                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2775                              [(set v2i64: $XT,
2776                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>;
2777  } // UseVSXReg = 1
2778
2779  //===--------------------------------------------------------------------===//
2780
2781  // Maximum/Minimum Type-C/Type-J DP
2782  // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2783  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2784                                 IIC_VecFP, []>;
2785  def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2786                                 IIC_VecFP, []>;
2787  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2788                                 IIC_VecFP, []>;
2789  def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2790                                 IIC_VecFP, []>;
2791
2792  //===--------------------------------------------------------------------===//
2793
2794  // Vector Byte-Reverse H/W/D/Q Word
2795  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2796  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2797  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2798  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2799
2800  // Vector Reverse
2801  def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)),
2802            (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2803  def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)),
2804            (v4i32 (XXBRW $A))>;
2805  def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)),
2806            (v2i64 (XXBRD $A))>;
2807  def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)),
2808            (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2809
2810  // Vector Permute
2811  def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2812                                IIC_VecPerm, []>;
2813  def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2814                                IIC_VecPerm, []>;
2815
2816  // Vector Splat Immediate Byte
2817  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2818                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg;
2819
2820  //===--------------------------------------------------------------------===//
2821  // Vector/Scalar Load/Store Instructions
2822
2823  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2824  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2825  let mayLoad = 1, mayStore = 0 in {
2826  // Load Vector
2827  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2828                            "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg;
2829  // Load DWord
2830  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2831                       "lxsd $vD, $src", IIC_LdStLFD, []>;
2832  // Load SP from src, convert it to DP, and place in dword[0]
2833  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2834                       "lxssp $vD, $src", IIC_LdStLFD, []>;
2835
2836  // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2837  // "out" and "in" dag
2838  class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2839                      RegisterOperand vtype, list<dag> pattern>
2840    : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2841              !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg;
2842
2843  // Load as Integer Byte/Halfword & Zero Indexed
2844  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2845                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2846  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2847                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2848
2849  // Load Vector Halfword*8/Byte*16 Indexed
2850  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2851  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2852
2853  // Load Vector Indexed
2854  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2855                [(set v2f64:$XT, (load xaddr:$src))]>;
2856  // Load Vector (Left-justified) with Length
2857  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2858                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
2859                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>,
2860                    UseVSXReg;
2861  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2862                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
2863                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>,
2864                    UseVSXReg;
2865
2866  // Load Vector Word & Splat Indexed
2867  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2868  } // mayLoad
2869
2870  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2871  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2872  let mayStore = 1, mayLoad = 0 in {
2873  // Store Vector
2874  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2875                             "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg;
2876  // Store DWord
2877  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2878                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2879  // Convert DP of dword[0] to SP, and Store to dst
2880  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2881                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2882
2883  // [PO S RA RB XO SX]
2884  class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2885                      RegisterOperand vtype, list<dag> pattern>
2886    : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2887              !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg;
2888
2889  // Store as Integer Byte/Halfword Indexed
2890  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2891                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2892  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2893                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2894  let isCodeGenOnly = 1 in {
2895    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vrrc, []>;
2896    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vrrc, []>;
2897  }
2898
2899  // Store Vector Halfword*8/Byte*16 Indexed
2900  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2901  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2902
2903  // Store Vector Indexed
2904  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
2905                 [(store v2f64:$XT, xaddr:$dst)]>;
2906
2907  // Store Vector (Left-justified) with Length
2908  def STXVL : XX1Form_memOp<31, 397, (outs),
2909                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2910                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
2911                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
2912                              i64:$rB)]>,
2913                            UseVSXReg;
2914  def STXVLL : XX1Form_memOp<31, 429, (outs),
2915                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2916                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
2917                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
2918                              i64:$rB)]>,
2919                            UseVSXReg;
2920  } // mayStore
2921
2922  let Predicates = [IsLittleEndian] in {
2923  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2924           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
2925  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2926           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
2927  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2928           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
2929  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2930           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
2931  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2932           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
2933  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2934           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
2935  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2936           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
2937  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2938           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
2939  }
2940
2941  let Predicates = [IsBigEndian] in {
2942  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2943           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
2944  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2945           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
2946  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2947           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
2948  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2949           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
2950  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
2951           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
2952  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
2953           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
2954  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
2955           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
2956  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
2957           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
2958  }
2959
2960  // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
2961  // of f64
2962  def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
2963            (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
2964  def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
2965            (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
2966
2967  // Patterns for which instructions from ISA 3.0 are a better match
2968  let Predicates = [IsLittleEndian, HasP9Vector] in {
2969  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
2970            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2971  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
2972            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2973  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
2974            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2975  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
2976            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2977  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
2978            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
2979  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
2980            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
2981  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
2982            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
2983  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
2984            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
2985  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2986            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2987  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2988            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2989  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2990            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2991  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2992            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2993  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2994            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2995  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2996            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2997  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2998            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2999  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3000            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3001  } // IsLittleEndian, HasP9Vector
3002
3003  let Predicates = [IsBigEndian, HasP9Vector] in {
3004  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3005            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
3006  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3007            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
3008  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3009            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
3010  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3011            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
3012  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
3013            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
3014  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
3015            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
3016  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
3017            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
3018  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
3019            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
3020  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
3021            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
3022  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
3023            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
3024  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
3025            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
3026  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
3027            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
3028  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
3029            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
3030  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
3031            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
3032  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
3033            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
3034  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
3035            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
3036  } // IsLittleEndian, HasP9Vector
3037
3038  // D-Form Load/Store
3039  def : Pat<(v4i32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3040  def : Pat<(v4f32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3041  def : Pat<(v2i64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3042  def : Pat<(v2f64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
3043  def : Pat<(f128  (quadwOffsetLoad iqaddr:$src)),
3044            (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
3045  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iqaddr:$src)), (LXV memrix16:$src)>;
3046  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iqaddr:$src)), (LXV memrix16:$src)>;
3047
3048  def : Pat<(quadwOffsetStore v4f32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3049  def : Pat<(quadwOffsetStore v4i32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3050  def : Pat<(quadwOffsetStore v2f64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3051  def : Pat<(quadwOffsetStore  f128:$rS, iqaddr:$dst),
3052            (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
3053  def : Pat<(quadwOffsetStore v2i64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
3054  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iqaddr:$dst),
3055            (STXV $rS, memrix16:$dst)>;
3056  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iqaddr:$dst),
3057            (STXV $rS, memrix16:$dst)>;
3058
3059
3060  def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3061  def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3062  def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3063  def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
3064  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
3065  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
3066  def : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
3067            (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
3068  def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
3069            (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
3070  def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
3071            (STXVX $rS, xoaddr:$dst)>;
3072  def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
3073            (STXVX $rS, xoaddr:$dst)>;
3074  def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
3075            (STXVX $rS, xoaddr:$dst)>;
3076  def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
3077            (STXVX $rS, xoaddr:$dst)>;
3078  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
3079            (STXVX $rS, xoaddr:$dst)>;
3080  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
3081            (STXVX $rS, xoaddr:$dst)>;
3082
3083  let AddedComplexity = 400 in {
3084    // LIWAX - This instruction is used for sign extending i32 -> i64.
3085    // LIWZX - This instruction will be emitted for i32, f32, and when
3086    //         zero-extending i32 to i64 (zext i32 -> i64).
3087    let Predicates = [IsLittleEndian] in {
3088
3089      def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
3090                (v2i64 (XXPERMDIs
3091                (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC), 2))>;
3092
3093      def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
3094                (v2i64 (XXPERMDIs
3095                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
3096
3097      def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3098                (v4i32 (XXPERMDIs
3099                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
3100
3101      def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3102                (v4f32 (XXPERMDIs
3103                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
3104    }
3105
3106    let Predicates = [IsBigEndian] in {
3107      def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
3108                (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
3109
3110      def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
3111                (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
3112
3113      def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
3114                (v4i32 (XXSLDWIs
3115                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3116
3117      def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
3118                (v4f32 (XXSLDWIs
3119                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
3120    }
3121
3122  }
3123
3124  // Build vectors from i8 loads
3125  def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
3126            (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
3127  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
3128            (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
3129  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
3130           (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
3131  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
3132            (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
3133  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
3134            (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
3135  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
3136            (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
3137
3138  // Build vectors from i16 loads
3139  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
3140            (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
3141  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
3142            (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
3143  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
3144           (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
3145  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
3146            (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
3147  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
3148            (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
3149
3150  let Predicates = [IsBigEndian, HasP9Vector] in {
3151  // Scalar stores of i8
3152  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3153            (STXSIBXv (v16i8 (VSLDOI $S, $S, 9)), xoaddr:$dst)>;
3154  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3155            (STXSIBXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3156  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3157            (STXSIBXv (v16i8 (VSLDOI $S, $S, 11)), xoaddr:$dst)>;
3158  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3159            (STXSIBXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3160  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3161            (STXSIBXv (v16i8 (VSLDOI $S, $S, 13)), xoaddr:$dst)>;
3162  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3163            (STXSIBXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3164  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3165            (STXSIBXv (v16i8 (VSLDOI $S, $S, 15)), xoaddr:$dst)>;
3166  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3167            (STXSIBXv $S, xoaddr:$dst)>;
3168  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3169            (STXSIBXv (v16i8 (VSLDOI $S, $S, 1)), xoaddr:$dst)>;
3170  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3171            (STXSIBXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3172  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3173            (STXSIBXv (v16i8 (VSLDOI $S, $S, 3)), xoaddr:$dst)>;
3174  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3175            (STXSIBXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3176  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3177            (STXSIBXv (v16i8 (VSLDOI $S, $S, 5)), xoaddr:$dst)>;
3178  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3179            (STXSIBXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3180  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3181            (STXSIBXv (v16i8 (VSLDOI $S, $S, 7)), xoaddr:$dst)>;
3182  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3183            (STXSIBXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3184
3185  // Scalar stores of i16
3186  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3187            (STXSIHXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3188  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3189            (STXSIHXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3190  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3191            (STXSIHXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3192  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3193            (STXSIHXv $S, xoaddr:$dst)>;
3194  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3195            (STXSIHXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3196  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3197            (STXSIHXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3198  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3199            (STXSIHXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3200  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3201            (STXSIHXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3202  } // IsBigEndian, HasP9Vector
3203
3204  let Predicates = [IsLittleEndian, HasP9Vector] in {
3205  // Scalar stores of i8
3206  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
3207            (STXSIBXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3208  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
3209            (STXSIBXv (v16i8 (VSLDOI $S, $S, 7)), xoaddr:$dst)>;
3210  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
3211            (STXSIBXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3212  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
3213            (STXSIBXv (v16i8 (VSLDOI $S, $S, 5)), xoaddr:$dst)>;
3214  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3215            (STXSIBXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3216  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3217            (STXSIBXv (v16i8 (VSLDOI $S, $S, 3)), xoaddr:$dst)>;
3218  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3219            (STXSIBXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3220  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3221            (STXSIBXv (v16i8 (VSLDOI $S, $S, 1)), xoaddr:$dst)>;
3222  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3223            (STXSIBXv $S, xoaddr:$dst)>;
3224  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3225            (STXSIBXv (v16i8 (VSLDOI $S, $S, 15)), xoaddr:$dst)>;
3226  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3227            (STXSIBXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3228  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3229            (STXSIBXv (v16i8 (VSLDOI $S, $S, 13)), xoaddr:$dst)>;
3230  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3231            (STXSIBXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3232  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3233            (STXSIBXv (v16i8 (VSLDOI $S, $S, 11)), xoaddr:$dst)>;
3234  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3235            (STXSIBXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3236  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3237            (STXSIBXv (v16i8 (VSLDOI $S, $S, 9)), xoaddr:$dst)>;
3238
3239  // Scalar stores of i16
3240  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3241            (STXSIHXv (v16i8 (VSLDOI $S, $S, 8)), xoaddr:$dst)>;
3242  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3243            (STXSIHXv (v16i8 (VSLDOI $S, $S, 6)), xoaddr:$dst)>;
3244  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3245            (STXSIHXv (v16i8 (VSLDOI $S, $S, 4)), xoaddr:$dst)>;
3246  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3247            (STXSIHXv (v16i8 (VSLDOI $S, $S, 2)), xoaddr:$dst)>;
3248  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3249            (STXSIHXv $S, xoaddr:$dst)>;
3250  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3251            (STXSIHXv (v16i8 (VSLDOI $S, $S, 14)), xoaddr:$dst)>;
3252  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3253            (STXSIHXv (v16i8 (VSLDOI $S, $S, 12)), xoaddr:$dst)>;
3254  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3255            (STXSIHXv (v16i8 (VSLDOI $S, $S, 10)), xoaddr:$dst)>;
3256  } // IsLittleEndian, HasP9Vector
3257
3258
3259  // Vector sign extensions
3260  def : Pat<(f64 (PPCVexts f64:$A, 1)),
3261            (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
3262  def : Pat<(f64 (PPCVexts f64:$A, 2)),
3263            (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
3264
3265  let isPseudo = 1 in {
3266    def DFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrix:$src),
3267                            "#DFLOADf32",
3268                            [(set f32:$XT, (load ixaddr:$src))]>;
3269    def DFLOADf64  : Pseudo<(outs vsfrc:$XT), (ins memrix:$src),
3270                            "#DFLOADf64",
3271                            [(set f64:$XT, (load ixaddr:$src))]>;
3272    def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst),
3273                            "#DFSTOREf32",
3274                            [(store f32:$XT, ixaddr:$dst)]>;
3275    def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
3276                            "#DFSTOREf64",
3277                            [(store f64:$XT, ixaddr:$dst)]>;
3278  }
3279  def : Pat<(f64 (extloadf32 ixaddr:$src)),
3280            (COPY_TO_REGCLASS (DFLOADf32 ixaddr:$src), VSFRC)>;
3281  def : Pat<(f32 (fpround (f64 (extloadf32 ixaddr:$src)))),
3282            (f32 (DFLOADf32 ixaddr:$src))>;
3283
3284
3285  let AddedComplexity = 400 in {
3286  // The following pseudoinstructions are used to ensure the utilization
3287  // of all 64 VSX registers.
3288    let Predicates = [IsLittleEndian, HasP9Vector] in {
3289      def : Pat<(v2i64 (scalar_to_vector (i64 (load ixaddr:$src)))),
3290                (v2i64 (XXPERMDIs
3291                (COPY_TO_REGCLASS (DFLOADf64 ixaddr:$src), VSRC), 2))>;
3292      def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddr:$src)))),
3293                (v2i64 (XXPERMDIs
3294		(COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC), 2))>;
3295
3296      def : Pat<(v2f64 (scalar_to_vector (f64 (load ixaddr:$src)))),
3297                (v2f64 (XXPERMDIs
3298                (COPY_TO_REGCLASS (DFLOADf64 ixaddr:$src), VSRC), 2))>;
3299      def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddr:$src)))),
3300                (v2f64 (XXPERMDIs
3301                (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC), 2))>;
3302    }
3303
3304    let Predicates = [IsBigEndian, HasP9Vector] in {
3305      def : Pat<(v2i64 (scalar_to_vector (i64 (load ixaddr:$src)))),
3306                (v2i64 (COPY_TO_REGCLASS (DFLOADf64 ixaddr:$src), VSRC))>;
3307      def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddr:$src)))),
3308                (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC))>;
3309
3310      def : Pat<(v2f64 (scalar_to_vector (f64 (load ixaddr:$src)))),
3311                (v2f64 (COPY_TO_REGCLASS (DFLOADf64 ixaddr:$src), VSRC))>;
3312      def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddr:$src)))),
3313                (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC))>;
3314    }
3315  }
3316
3317  let Predicates = [IsBigEndian, HasP9Vector] in {
3318
3319    // (Un)Signed DWord vector extract -> QP
3320    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3321              (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3322    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3323              (f128 (XSCVSDQP
3324                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3325    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3326              (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3327    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3328              (f128 (XSCVUDQP
3329                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3330
3331    // (Un)Signed Word vector extract -> QP
3332    def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
3333              (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
3334    foreach Idx = [0,2,3] in {
3335      def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
3336                (f128 (XSCVSDQP (EXTRACT_SUBREG
3337                                (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
3338    }
3339    foreach Idx = 0-3 in {
3340      def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
3341                (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
3342    }
3343
3344    // (Un)Signed HWord vector extract -> QP
3345    foreach Idx = 0-7 in {
3346      def : Pat<(f128 (sint_to_fp
3347                        (i32 (sext_inreg
3348                               (vector_extract v8i16:$src, Idx), i16)))),
3349              (f128 (XSCVSDQP (EXTRACT_SUBREG
3350                                (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
3351                                sub_64)))>;
3352      // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
3353      def : Pat<(f128 (uint_to_fp
3354                        (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
3355                (f128 (XSCVUDQP (EXTRACT_SUBREG
3356                                  (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
3357    }
3358
3359    // (Un)Signed Byte vector extract -> QP
3360    foreach Idx = 0-15 in {
3361      def : Pat<(f128 (sint_to_fp
3362                        (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
3363                                         i8)))),
3364                (f128 (XSCVSDQP (EXTRACT_SUBREG
3365                                  (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
3366      def : Pat<(f128 (uint_to_fp
3367                        (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
3368                (f128 (XSCVUDQP
3369                        (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
3370    }
3371
3372    // Unsiged int in vsx register -> QP
3373    def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
3374              (f128 (XSCVUDQP
3375                      (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
3376  } // IsBigEndian, HasP9Vector
3377
3378  let Predicates = [IsLittleEndian, HasP9Vector] in {
3379
3380    // (Un)Signed DWord vector extract -> QP
3381    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3382              (f128 (XSCVSDQP
3383                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3384    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3385              (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3386    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
3387              (f128 (XSCVUDQP
3388                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
3389    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
3390              (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
3391
3392    // (Un)Signed Word vector extract -> QP
3393    foreach Idx = [[0,3],[1,2],[3,0]] in {
3394      def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
3395                (f128 (XSCVSDQP (EXTRACT_SUBREG
3396                                  (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
3397                                  sub_64)))>;
3398    }
3399    def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
3400              (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
3401
3402    foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
3403      def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
3404                (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
3405    }
3406
3407    // (Un)Signed HWord vector extract -> QP
3408    // The Nested foreach lists identifies the vector element and corresponding
3409    // register byte location.
3410    foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
3411      def : Pat<(f128 (sint_to_fp
3412                        (i32 (sext_inreg
3413                               (vector_extract v8i16:$src, !head(Idx)), i16)))),
3414                (f128 (XSCVSDQP
3415                        (EXTRACT_SUBREG (VEXTSH2D
3416                                          (VEXTRACTUH !head(!tail(Idx)), $src)),
3417                                        sub_64)))>;
3418      def : Pat<(f128 (uint_to_fp
3419                        (and (i32 (vector_extract v8i16:$src, !head(Idx))),
3420                             65535))),
3421                (f128 (XSCVUDQP (EXTRACT_SUBREG
3422                                  (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
3423    }
3424
3425    // (Un)Signed Byte vector extract -> QP
3426    foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
3427                   [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
3428      def : Pat<(f128 (sint_to_fp
3429                        (i32 (sext_inreg
3430                               (vector_extract v16i8:$src, !head(Idx)), i8)))),
3431                (f128 (XSCVSDQP
3432                        (EXTRACT_SUBREG
3433                          (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
3434                          sub_64)))>;
3435      def : Pat<(f128 (uint_to_fp
3436                        (and (i32 (vector_extract v16i8:$src, !head(Idx))),
3437                             255))),
3438                (f128 (XSCVUDQP
3439                        (EXTRACT_SUBREG
3440                          (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
3441    }
3442
3443    // Unsiged int in vsx register -> QP
3444    def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
3445              (f128 (XSCVUDQP
3446                      (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
3447  } // IsLittleEndian, HasP9Vector
3448
3449  // Convert (Un)Signed DWord in memory -> QP
3450  def : Pat<(f128 (sint_to_fp (i64 (load xaddr:$src)))),
3451            (f128 (XSCVSDQP (LXSDX xaddr:$src)))>;
3452  def : Pat<(f128 (sint_to_fp (i64 (load ixaddr:$src)))),
3453            (f128 (XSCVSDQP (LXSD ixaddr:$src)))>;
3454  def : Pat<(f128 (uint_to_fp (i64 (load xaddr:$src)))),
3455            (f128 (XSCVUDQP (LXSDX xaddr:$src)))>;
3456  def : Pat<(f128 (uint_to_fp (i64 (load ixaddr:$src)))),
3457            (f128 (XSCVUDQP (LXSD ixaddr:$src)))>;
3458
3459  // Convert Unsigned HWord in memory -> QP
3460  def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
3461            (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
3462
3463  // Convert Unsigned Byte in memory -> QP
3464  def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
3465            (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
3466
3467  // Truncate & Convert QP -> (Un)Signed (D)Word.
3468  def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
3469  def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
3470  def : Pat<(i32 (fp_to_sint f128:$src)),
3471            (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
3472  def : Pat<(i32 (fp_to_uint f128:$src)),
3473            (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
3474
3475  // Instructions for store(fptosi).
3476  // The 8-byte version is repeated here due to availability of D-Form STXSD.
3477  def : Pat<(PPCstore_scal_int_from_vsr
3478              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddr:$dst, 8),
3479            (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3480                    xaddr:$dst)>;
3481  def : Pat<(PPCstore_scal_int_from_vsr
3482              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), ixaddr:$dst, 8),
3483            (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
3484                   ixaddr:$dst)>;
3485  def : Pat<(PPCstore_scal_int_from_vsr
3486              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
3487            (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3488  def : Pat<(PPCstore_scal_int_from_vsr
3489              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
3490            (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3491  def : Pat<(PPCstore_scal_int_from_vsr
3492              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
3493            (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
3494  def : Pat<(PPCstore_scal_int_from_vsr
3495              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddr:$dst, 8),
3496            (STXSDX (XSCVDPSXDS f64:$src), xaddr:$dst)>;
3497  def : Pat<(PPCstore_scal_int_from_vsr
3498              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), ixaddr:$dst, 8),
3499            (STXSD (XSCVDPSXDS f64:$src), ixaddr:$dst)>;
3500  def : Pat<(PPCstore_scal_int_from_vsr
3501              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
3502            (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3503  def : Pat<(PPCstore_scal_int_from_vsr
3504              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
3505            (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
3506
3507  // Instructions for store(fptoui).
3508  def : Pat<(PPCstore_scal_int_from_vsr
3509              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddr:$dst, 8),
3510            (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3511                    xaddr:$dst)>;
3512  def : Pat<(PPCstore_scal_int_from_vsr
3513              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), ixaddr:$dst, 8),
3514            (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
3515                   ixaddr:$dst)>;
3516  def : Pat<(PPCstore_scal_int_from_vsr
3517              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
3518            (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3519  def : Pat<(PPCstore_scal_int_from_vsr
3520              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
3521            (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3522  def : Pat<(PPCstore_scal_int_from_vsr
3523              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
3524            (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
3525  def : Pat<(PPCstore_scal_int_from_vsr
3526              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddr:$dst, 8),
3527            (STXSDX (XSCVDPUXDS f64:$src), xaddr:$dst)>;
3528  def : Pat<(PPCstore_scal_int_from_vsr
3529              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), ixaddr:$dst, 8),
3530            (STXSD (XSCVDPUXDS f64:$src), ixaddr:$dst)>;
3531  def : Pat<(PPCstore_scal_int_from_vsr
3532              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
3533            (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3534  def : Pat<(PPCstore_scal_int_from_vsr
3535              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
3536            (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
3537
3538  // Round & Convert QP -> DP/SP
3539  def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>;
3540  def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
3541
3542  // Convert SP -> QP
3543  def : Pat<(f128 (fpextend f32:$src)),
3544            (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
3545
3546} // end HasP9Vector, AddedComplexity
3547
3548let AddedComplexity = 400 in {
3549  let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in {
3550    def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
3551              (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
3552  }
3553  let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in {
3554    def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
3555              (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
3556  }
3557}
3558
3559let Predicates = [HasP9Vector] in {
3560  let isPseudo = 1 in {
3561    let mayStore = 1 in {
3562      def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
3563                                            (ins spilltovsrrc:$XT, memrr:$dst),
3564                                            "#SPILLTOVSR_STX", []>;
3565      def SPILLTOVSR_ST : Pseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
3566                                "#SPILLTOVSR_ST", []>;
3567    }
3568    let mayLoad = 1 in {
3569      def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
3570                                            (ins memrr:$src),
3571                                            "#SPILLTOVSR_LDX", []>;
3572      def SPILLTOVSR_LD : Pseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
3573                                "#SPILLTOVSR_LD", []>;
3574
3575    }
3576  }
3577}
3578// Integer extend helper dags 32 -> 64
3579def AnyExts {
3580  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
3581  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
3582  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
3583  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
3584}
3585
3586def DblToFlt {
3587  dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
3588  dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
3589  dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
3590  dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
3591}
3592
3593def ExtDbl {
3594  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
3595  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
3596  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
3597  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
3598  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
3599  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
3600  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
3601  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
3602}
3603
3604def ByteToWord {
3605  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
3606  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
3607  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
3608  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
3609  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
3610  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
3611  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
3612  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
3613}
3614
3615def ByteToDWord {
3616  dag LE_A0 = (i64 (sext_inreg
3617              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
3618  dag LE_A1 = (i64 (sext_inreg
3619              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
3620  dag BE_A0 = (i64 (sext_inreg
3621              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
3622  dag BE_A1 = (i64 (sext_inreg
3623              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
3624}
3625
3626def HWordToWord {
3627  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
3628  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
3629  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
3630  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
3631  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
3632  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
3633  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
3634  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
3635}
3636
3637def HWordToDWord {
3638  dag LE_A0 = (i64 (sext_inreg
3639              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
3640  dag LE_A1 = (i64 (sext_inreg
3641              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
3642  dag BE_A0 = (i64 (sext_inreg
3643              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
3644  dag BE_A1 = (i64 (sext_inreg
3645              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
3646}
3647
3648def WordToDWord {
3649  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
3650  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
3651  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
3652  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
3653}
3654
3655def FltToIntLoad {
3656  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
3657}
3658def FltToUIntLoad {
3659  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
3660}
3661def FltToLongLoad {
3662  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
3663}
3664def FltToLongLoadP9 {
3665  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ixaddr:$A)))));
3666}
3667def FltToULongLoad {
3668  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
3669}
3670def FltToULongLoadP9 {
3671  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ixaddr:$A)))));
3672}
3673def FltToLong {
3674  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
3675}
3676def FltToULong {
3677  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
3678}
3679def DblToInt {
3680  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
3681  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
3682  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
3683  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
3684}
3685def DblToUInt {
3686  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
3687  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
3688  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
3689  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
3690}
3691def DblToLong {
3692  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
3693}
3694def DblToULong {
3695  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
3696}
3697def DblToIntLoad {
3698  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
3699}
3700def DblToIntLoadP9 {
3701  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ixaddr:$A)))));
3702}
3703def DblToUIntLoad {
3704  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
3705}
3706def DblToUIntLoadP9 {
3707  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ixaddr:$A)))));
3708}
3709def DblToLongLoad {
3710  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
3711}
3712def DblToULongLoad {
3713  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
3714}
3715
3716// FP merge dags (for f32 -> v4f32)
3717def MrgFP {
3718  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
3719                               (COPY_TO_REGCLASS $C, VSRC), 0));
3720  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
3721                               (COPY_TO_REGCLASS $D, VSRC), 0));
3722  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
3723  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
3724  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
3725  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
3726}
3727
3728// Word-element merge dags - conversions from f64 to i32 merged into vectors.
3729def MrgWords {
3730  // For big endian, we merge low and hi doublewords (A, B).
3731  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
3732  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
3733  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
3734  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
3735  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
3736  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
3737
3738  // For little endian, we merge low and hi doublewords (B, A).
3739  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
3740  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
3741  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
3742  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
3743  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
3744  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
3745
3746  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
3747  // then merge.
3748  dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
3749                            (COPY_TO_REGCLASS f64:$C, VSRC), 0));
3750  dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
3751                            (COPY_TO_REGCLASS f64:$D, VSRC), 0));
3752  dag CVACS = (v4i32 (XVCVDPSXWS AC));
3753  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
3754  dag CVACU = (v4i32 (XVCVDPUXWS AC));
3755  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
3756
3757  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
3758  // then merge.
3759  dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
3760                            (COPY_TO_REGCLASS f64:$B, VSRC), 0));
3761  dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
3762                            (COPY_TO_REGCLASS f64:$A, VSRC), 0));
3763  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
3764  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
3765  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
3766  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
3767}
3768
3769// Patterns for BUILD_VECTOR nodes.
3770let AddedComplexity = 400 in {
3771
3772  let Predicates = [HasVSX] in {
3773    // Build vectors of floating point converted to i32.
3774    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
3775                                   DblToInt.A, DblToInt.A)),
3776              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
3777    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
3778                                   DblToUInt.A, DblToUInt.A)),
3779              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
3780    def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
3781              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
3782                               (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
3783    def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
3784              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
3785                               (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
3786    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3787              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3788                                (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3789    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3790              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3791                                (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3792    def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
3793              (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
3794
3795    // Build vectors of floating point converted to i64.
3796    def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
3797              (v2i64 (XXPERMDIs
3798                       (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
3799    def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
3800              (v2i64 (XXPERMDIs
3801                       (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
3802    def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
3803              (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
3804    def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
3805              (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
3806  }
3807
3808  let Predicates = [HasVSX, NoP9Vector] in {
3809    // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
3810    def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
3811              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3812                                (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3813    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
3814              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3815                                (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3816    def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
3817              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3818                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3819    def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
3820              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3821                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3822  }
3823
3824  // Big endian, available on all targets with VSX
3825  let Predicates = [IsBigEndian, HasVSX] in {
3826    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
3827              (v2f64 (XXPERMDI
3828                        (COPY_TO_REGCLASS $A, VSRC),
3829                        (COPY_TO_REGCLASS $B, VSRC), 0))>;
3830
3831    def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
3832              (VMRGEW MrgFP.AC, MrgFP.BD)>;
3833    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
3834                                   DblToFlt.B0, DblToFlt.B1)),
3835              (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
3836
3837    // Convert 4 doubles to a vector of ints.
3838    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
3839                                   DblToInt.C, DblToInt.D)),
3840              (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
3841    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
3842                                   DblToUInt.C, DblToUInt.D)),
3843              (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
3844    def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
3845                                   ExtDbl.B0S, ExtDbl.B1S)),
3846              (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
3847    def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
3848                                   ExtDbl.B0U, ExtDbl.B1U)),
3849              (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
3850  }
3851
3852  let Predicates = [IsLittleEndian, HasVSX] in {
3853  // Little endian, available on all targets with VSX
3854    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
3855              (v2f64 (XXPERMDI
3856                        (COPY_TO_REGCLASS $B, VSRC),
3857                        (COPY_TO_REGCLASS $A, VSRC), 0))>;
3858
3859    def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
3860              (VMRGEW MrgFP.AC, MrgFP.BD)>;
3861    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
3862                                   DblToFlt.B0, DblToFlt.B1)),
3863              (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
3864
3865    // Convert 4 doubles to a vector of ints.
3866    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
3867                                   DblToInt.C, DblToInt.D)),
3868              (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
3869    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
3870                                   DblToUInt.C, DblToUInt.D)),
3871              (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
3872    def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
3873                                   ExtDbl.B0S, ExtDbl.B1S)),
3874              (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
3875    def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
3876                                   ExtDbl.B0U, ExtDbl.B1U)),
3877              (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
3878  }
3879
3880  let Predicates = [HasDirectMove] in {
3881    // Endianness-neutral constant splat on P8 and newer targets. The reason
3882    // for this pattern is that on targets with direct moves, we don't expand
3883    // BUILD_VECTOR nodes for v4i32.
3884    def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
3885                                   immSExt5NonZero:$A, immSExt5NonZero:$A)),
3886              (v4i32 (VSPLTISW imm:$A))>;
3887  }
3888
3889  let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
3890    // Big endian integer vectors using direct moves.
3891    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3892              (v2i64 (XXPERMDI
3893                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
3894                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
3895    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3896              (XXPERMDI
3897                (COPY_TO_REGCLASS
3898                  (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
3899                (COPY_TO_REGCLASS
3900                  (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
3901    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3902              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3903  }
3904
3905  let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
3906    // Little endian integer vectors using direct moves.
3907    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3908              (v2i64 (XXPERMDI
3909                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
3910                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
3911    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3912              (XXPERMDI
3913                (COPY_TO_REGCLASS
3914                  (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
3915                (COPY_TO_REGCLASS
3916                  (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
3917    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3918              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3919  }
3920
3921  let Predicates = [HasP9Vector] in {
3922    // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
3923    def : Pat<(v4i32 (scalar_to_vector i32:$A)),
3924              (v4i32 (MTVSRWS $A))>;
3925    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3926              (v4i32 (MTVSRWS $A))>;
3927    def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3928                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3929                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3930                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3931                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3932                                   immAnyExt8:$A)),
3933              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
3934    def : Pat<(v16i8 immAllOnesV),
3935              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
3936    def : Pat<(v8i16 immAllOnesV),
3937              (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
3938    def : Pat<(v4i32 immAllOnesV),
3939              (v4i32 (XXSPLTIB 255))>;
3940    def : Pat<(v2i64 immAllOnesV),
3941              (v2i64 (XXSPLTIB 255))>;
3942    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3943              (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
3944    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3945              (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
3946    def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
3947              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3948                                (XSCVDPSXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>;
3949    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
3950              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3951                                (XSCVDPUXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>;
3952    def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
3953              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3954                                              (DFLOADf32 ixaddr:$A),
3955                                              VSFRC)), 0))>;
3956    def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
3957              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3958                                              (DFLOADf32 ixaddr:$A),
3959                                              VSFRC)), 0))>;
3960  }
3961
3962  let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
3963    def : Pat<(i64 (extractelt v2i64:$A, 1)),
3964              (i64 (MFVSRLD $A))>;
3965    // Better way to build integer vectors if we have MTVSRDD. Big endian.
3966    def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
3967              (v2i64 (MTVSRDD $rB, $rA))>;
3968    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3969              (MTVSRDD
3970                (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
3971                (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
3972  }
3973
3974  let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
3975    def : Pat<(i64 (extractelt v2i64:$A, 0)),
3976              (i64 (MFVSRLD $A))>;
3977    // Better way to build integer vectors if we have MTVSRDD. Little endian.
3978    def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
3979              (v2i64 (MTVSRDD $rB, $rA))>;
3980    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3981              (MTVSRDD
3982                (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
3983                (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
3984  }
3985  // P9 Altivec instructions that can be used to build vectors.
3986  // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
3987  // with complexities of existing build vector patterns in this file.
3988  let Predicates = [HasP9Altivec, IsLittleEndian] in {
3989    def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
3990              (v2i64 (VEXTSW2D $A))>;
3991    def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
3992              (v2i64 (VEXTSH2D $A))>;
3993    def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
3994                      HWordToWord.LE_A2, HWordToWord.LE_A3)),
3995              (v4i32 (VEXTSH2W $A))>;
3996    def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
3997                      ByteToWord.LE_A2, ByteToWord.LE_A3)),
3998              (v4i32 (VEXTSB2W $A))>;
3999    def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
4000              (v2i64 (VEXTSB2D $A))>;
4001  }
4002
4003  let Predicates = [HasP9Altivec, IsBigEndian] in {
4004    def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
4005              (v2i64 (VEXTSW2D $A))>;
4006    def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
4007              (v2i64 (VEXTSH2D $A))>;
4008    def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
4009                      HWordToWord.BE_A2, HWordToWord.BE_A3)),
4010              (v4i32 (VEXTSH2W $A))>;
4011    def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
4012                      ByteToWord.BE_A2, ByteToWord.BE_A3)),
4013              (v4i32 (VEXTSB2W $A))>;
4014    def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
4015              (v2i64 (VEXTSB2D $A))>;
4016  }
4017
4018  let Predicates = [HasP9Altivec] in {
4019    def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)),
4020              (v2i64 (VEXTSB2D $A))>;
4021    def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)),
4022              (v2i64 (VEXTSH2D $A))>;
4023    def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)),
4024              (v2i64 (VEXTSW2D $A))>;
4025    def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)),
4026              (v4i32 (VEXTSB2W $A))>;
4027    def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)),
4028              (v4i32 (VEXTSH2W $A))>;
4029  }
4030}
4031
4032