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