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