1//===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file describes the VSX extension to the PowerPC instruction set.
11//
12//===----------------------------------------------------------------------===//
13
14// *********************************** NOTE ***********************************
15// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing  **
16// ** which VMX and VSX instructions are lane-sensitive and which are not.   **
17// ** A lane-sensitive instruction relies, implicitly or explicitly, on      **
18// ** whether lanes are numbered from left to right.  An instruction like    **
19// ** VADDFP is not lane-sensitive, because each lane of the result vector   **
20// ** relies only on the corresponding lane of the source vectors.  However, **
21// ** an instruction like VMULESB is lane-sensitive, because "even" and      **
22// ** "odd" lanes are different for big-endian and little-endian numbering.  **
23// **                                                                        **
24// ** When adding new VMX and VSX instructions, please consider whether they **
25// ** are lane-sensitive.  If so, they must be added to a switch statement   **
26// ** in PPCVSXSwapRemoval::gatherVectorInstructions().                      **
27// ****************************************************************************
28
29def PPCRegVSRCAsmOperand : AsmOperandClass {
30  let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
31}
32def vsrc : RegisterOperand<VSRC> {
33  let ParserMatchClass = PPCRegVSRCAsmOperand;
34}
35
36def PPCRegVSFRCAsmOperand : AsmOperandClass {
37  let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
38}
39def vsfrc : RegisterOperand<VSFRC> {
40  let ParserMatchClass = PPCRegVSFRCAsmOperand;
41}
42
43def PPCRegVSSRCAsmOperand : AsmOperandClass {
44  let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
45}
46def vssrc : RegisterOperand<VSSRC> {
47  let ParserMatchClass = PPCRegVSSRCAsmOperand;
48}
49
50def PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass {
51  let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber";
52}
53
54def spilltovsrrc : RegisterOperand<SPILLTOVSRRC> {
55  let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand;
56}
57// Little-endian-specific nodes.
58def SDT_PPClxvd2x : SDTypeProfile<1, 1, [
59  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
60]>;
61def SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
62  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
63]>;
64def SDT_PPCxxswapd : SDTypeProfile<1, 1, [
65  SDTCisSameAs<0, 1>
66]>;
67def SDTVecConv : SDTypeProfile<1, 2, [
68  SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>
69]>;
70
71def PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
72                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
73def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
74                        [SDNPHasChain, SDNPMayStore]>;
75def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
76def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
77def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
78def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
79def PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
80def PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
81def PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
82
83multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
84                    string asmstr, InstrItinClass itin, Intrinsic Int,
85                    ValueType OutTy, ValueType InTy> {
86  let BaseName = asmbase in {
87    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
88                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
89                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
90    let Defs = [CR6] in
91    def o    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
92                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
93                       [(set InTy:$XT,
94                                (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>,
95                       isDOT;
96  }
97}
98
99// Instruction form with a single input register for instructions such as
100// XXPERMDI. The reason for defining this is that specifying multiple chained
101// operands (such as loads) to an instruction will perform both chained
102// operations rather than coalescing them into a single register - even though
103// the source memory location is the same. This simply forces the instruction
104// to use the same register for both inputs.
105// For example, an output DAG such as this:
106//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
107// would result in two load instructions emitted and used as separate inputs
108// to the XXPERMDI instruction.
109class XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
110                 InstrItinClass itin, list<dag> pattern>
111  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
112    let XB = XA;
113}
114
115def HasVSX : Predicate<"PPCSubTarget->hasVSX()">;
116def IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">;
117def IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">;
118def HasOnlySwappingMemOps : Predicate<"!PPCSubTarget->hasP9Vector()">;
119
120let Predicates = [HasVSX] in {
121let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
122let UseVSXReg = 1 in {
123let hasSideEffects = 0 in { // VSX instructions don't have side effects.
124let Uses = [RM] in {
125
126  // Load indexed instructions
127  let mayLoad = 1, mayStore = 0 in {
128    let CodeSize = 3 in
129    def LXSDX : XX1Form<31, 588,
130                        (outs vsfrc:$XT), (ins memrr:$src),
131                        "lxsdx $XT, $src", IIC_LdStLFD,
132                        [(set f64:$XT, (load xoaddr:$src))]>;
133
134    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
135    let isPseudo = 1, CodeSize = 3 in
136      def XFLOADf64  : Pseudo<(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<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<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<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<31, 716,
161                        (outs), (ins vsfrc:$XT, memrr:$dst),
162                        "stxsdx $XT, $dst", IIC_LdStSTFD,
163                        [(store f64:$XT, xoaddr:$dst)]>;
164
165    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
166    let isPseudo = 1, CodeSize = 3 in
167      def XFSTOREf64 : Pseudo<(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<31, 972,
175                         (outs), (ins vsrc:$XT, memrr:$dst),
176                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
177                         []>;
178
179    def STXVW4X : XX1Form<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()">;
1203let Predicates = [HasP8Vector] in {
1204let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1205  let isCommutable = 1, UseVSXReg = 1 in {
1206    def XXLEQV : XX3Form<60, 186,
1207                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1208                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
1209                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
1210    def XXLNAND : XX3Form<60, 178,
1211                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1212                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
1213                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
1214                                                    v4i32:$XB)))]>;
1215  } // isCommutable, UseVSXReg
1216
1217  def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
1218            (XXLEQV $A, $B)>;
1219
1220  let UseVSXReg = 1 in {
1221  def XXLORC : XX3Form<60, 170,
1222                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1223                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
1224                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
1225
1226  // VSX scalar loads introduced in ISA 2.07
1227  let mayLoad = 1, mayStore = 0 in {
1228    let CodeSize = 3 in
1229    def LXSSPX : XX1Form<31, 524, (outs vssrc:$XT), (ins memrr:$src),
1230                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
1231    def LXSIWAX : XX1Form<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
1232                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
1233    def LXSIWZX : XX1Form<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
1234                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
1235
1236    // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it
1237    // would cause these Pseudos are not expanded in expandPostRAPseudos()
1238    let isPseudo = 1 in {
1239      // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
1240      let CodeSize = 3 in
1241      def XFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrr:$src),
1242                              "#XFLOADf32",
1243                              [(set f32:$XT, (load xoaddr:$src))]>;
1244      // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
1245      def LIWAX : Pseudo<(outs vsfrc:$XT), (ins memrr:$src),
1246                         "#LIWAX",
1247                         [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
1248      // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
1249      def LIWZX : Pseudo<(outs vsfrc:$XT), (ins memrr:$src),
1250                         "#LIWZX",
1251                         [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
1252    }
1253  } // mayLoad
1254
1255  // VSX scalar stores introduced in ISA 2.07
1256  let mayStore = 1, mayLoad = 0 in {
1257    let CodeSize = 3 in
1258    def STXSSPX : XX1Form<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
1259                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
1260    def STXSIWX : XX1Form<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
1261                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
1262
1263    // Please note let isPseudo = 1 is not part of class Pseudo<>. Missing it
1264    // would cause these Pseudos are not expanded in expandPostRAPseudos()
1265    let isPseudo = 1 in {
1266      // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
1267      let CodeSize = 3 in
1268      def XFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrr:$dst),
1269                              "#XFSTOREf32",
1270                              [(store f32:$XT, xoaddr:$dst)]>;
1271      // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
1272      def STIWX : Pseudo<(outs), (ins vsfrc:$XT, memrr:$dst),
1273                         "#STIWX",
1274                        [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
1275    }
1276  } // mayStore
1277  } // UseVSXReg = 1
1278
1279  def : Pat<(f64 (extloadf32 xoaddr:$src)),
1280            (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
1281  def : Pat<(f32 (fpround (extloadf32 xoaddr:$src))),
1282            (f32 (XFLOADf32 xoaddr:$src))>;
1283  def : Pat<(f64 (fpextend f32:$src)),
1284            (COPY_TO_REGCLASS $src, VSFRC)>;
1285
1286  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
1287            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1288  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
1289            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1290  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
1291            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1292  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
1293            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1294  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
1295            (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
1296  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
1297            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
1298  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
1299            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
1300  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
1301            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
1302  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
1303            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
1304  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
1305            (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
1306
1307  let UseVSXReg = 1 in {
1308  // VSX Elementary Scalar FP arithmetic (SP)
1309  let isCommutable = 1 in {
1310    def XSADDSP : XX3Form<60, 0,
1311                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1312                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
1313                          [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
1314    def XSMULSP : XX3Form<60, 16,
1315                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1316                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
1317                          [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
1318  } // isCommutable
1319
1320  def XSDIVSP : XX3Form<60, 24,
1321                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1322                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
1323                        [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
1324  def XSRESP : XX2Form<60, 26,
1325                        (outs vssrc:$XT), (ins vssrc:$XB),
1326                        "xsresp $XT, $XB", IIC_VecFP,
1327                        [(set f32:$XT, (PPCfre f32:$XB))]>;
1328  def XSSQRTSP : XX2Form<60, 11,
1329                        (outs vssrc:$XT), (ins vssrc:$XB),
1330                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
1331                        [(set f32:$XT, (fsqrt f32:$XB))]>;
1332  def XSRSQRTESP : XX2Form<60, 10,
1333                           (outs vssrc:$XT), (ins vssrc:$XB),
1334                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
1335                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
1336  def XSSUBSP : XX3Form<60, 8,
1337                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
1338                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
1339                        [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
1340
1341  // FMA Instructions
1342  let BaseName = "XSMADDASP" in {
1343  let isCommutable = 1 in
1344  def XSMADDASP : XX3Form<60, 1,
1345                          (outs vssrc:$XT),
1346                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1347                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
1348                          [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
1349                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1350                          AltVSXFMARel;
1351  let IsVSXFMAAlt = 1 in
1352  def XSMADDMSP : XX3Form<60, 9,
1353                          (outs vssrc:$XT),
1354                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1355                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1356                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1357                          AltVSXFMARel;
1358  }
1359
1360  let BaseName = "XSMSUBASP" in {
1361  let isCommutable = 1 in
1362  def XSMSUBASP : XX3Form<60, 17,
1363                          (outs vssrc:$XT),
1364                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1365                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
1366                          [(set f32:$XT, (fma f32:$XA, f32:$XB,
1367                                              (fneg f32:$XTi)))]>,
1368                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1369                          AltVSXFMARel;
1370  let IsVSXFMAAlt = 1 in
1371  def XSMSUBMSP : XX3Form<60, 25,
1372                          (outs vssrc:$XT),
1373                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1374                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1375                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1376                          AltVSXFMARel;
1377  }
1378
1379  let BaseName = "XSNMADDASP" in {
1380  let isCommutable = 1 in
1381  def XSNMADDASP : XX3Form<60, 129,
1382                          (outs vssrc:$XT),
1383                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1384                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
1385                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1386                                                    f32:$XTi)))]>,
1387                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1388                          AltVSXFMARel;
1389  let IsVSXFMAAlt = 1 in
1390  def XSNMADDMSP : XX3Form<60, 137,
1391                          (outs vssrc:$XT),
1392                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1393                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
1394                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1395                          AltVSXFMARel;
1396  }
1397
1398  let BaseName = "XSNMSUBASP" in {
1399  let isCommutable = 1 in
1400  def XSNMSUBASP : XX3Form<60, 145,
1401                          (outs vssrc:$XT),
1402                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1403                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
1404                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
1405                                                    (fneg f32:$XTi))))]>,
1406                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1407                          AltVSXFMARel;
1408  let IsVSXFMAAlt = 1 in
1409  def XSNMSUBMSP : XX3Form<60, 153,
1410                          (outs vssrc:$XT),
1411                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
1412                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
1413                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
1414                          AltVSXFMARel;
1415  }
1416
1417  // Single Precision Conversions (FP <-> INT)
1418  def XSCVSXDSP : XX2Form<60, 312,
1419                      (outs vssrc:$XT), (ins vsfrc:$XB),
1420                      "xscvsxdsp $XT, $XB", IIC_VecFP,
1421                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
1422  def XSCVUXDSP : XX2Form<60, 296,
1423                      (outs vssrc:$XT), (ins vsfrc:$XB),
1424                      "xscvuxdsp $XT, $XB", IIC_VecFP,
1425                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
1426
1427  // Conversions between vector and scalar single precision
1428  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
1429                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
1430  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
1431                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
1432  } // UseVSXReg = 1
1433
1434  let Predicates = [IsLittleEndian] in {
1435  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1436            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1437  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1438            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1439  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1440            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1441  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1442            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
1443  }
1444
1445  let Predicates = [IsBigEndian] in {
1446  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1447            (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1448  def : Pat<(f32 (PPCfcfids (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1449            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1450  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
1451            (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S, VSFRC)))>;
1452  def : Pat<(f32 (PPCfcfidus (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
1453            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
1454  }
1455  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.Li32)),
1456            (v4i32 (XXSPLTWs (LIWAX xoaddr:$src), 1))>;
1457} // AddedComplexity = 400
1458} // HasP8Vector
1459
1460let UseVSXReg = 1, AddedComplexity = 400 in {
1461let Predicates = [HasDirectMove] in {
1462  // VSX direct move instructions
1463  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
1464                              "mfvsrd $rA, $XT", IIC_VecGeneral,
1465                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
1466      Requires<[In64BitMode]>;
1467  let isCodeGenOnly = 1 in
1468  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vrrc:$XT),
1469                             "mfvsrd $rA, $XT", IIC_VecGeneral,
1470                             []>,
1471      Requires<[In64BitMode]>;
1472  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
1473                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
1474                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
1475  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
1476                              "mtvsrd $XT, $rA", IIC_VecGeneral,
1477                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
1478      Requires<[In64BitMode]>;
1479  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
1480                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
1481                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
1482  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
1483                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
1484                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
1485} // HasDirectMove
1486
1487let Predicates = [IsISA3_0, HasDirectMove] in {
1488  def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
1489                              "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
1490
1491  def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
1492                       "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
1493                       []>, Requires<[In64BitMode]>;
1494
1495  def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
1496                              "mfvsrld $rA, $XT", IIC_VecGeneral,
1497                              []>, Requires<[In64BitMode]>;
1498
1499} // IsISA3_0, HasDirectMove
1500} // UseVSXReg = 1
1501
1502// We want to parse this from asm, but we don't want to emit this as it would
1503// be emitted with a VSX reg. So leave Emit = 0 here.
1504def : InstAlias<"mfvrd $rA, $XT",
1505                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
1506def : InstAlias<"mffprd $rA, $src",
1507                (MFVSRD g8rc:$rA, f8rc:$src)>;
1508
1509/*  Direct moves of various widths from GPR's into VSR's. Each move lines
1510    the value up into element 0 (both BE and LE). Namely, entities smaller than
1511    a doubleword are shifted left and moved for BE. For LE, they're moved, then
1512    swapped to go into the least significant element of the VSR.
1513*/
1514def MovesToVSR {
1515  dag BE_BYTE_0 =
1516    (MTVSRD
1517      (RLDICR
1518        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
1519  dag BE_HALF_0 =
1520    (MTVSRD
1521      (RLDICR
1522        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
1523  dag BE_WORD_0 =
1524    (MTVSRD
1525      (RLDICR
1526        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
1527  dag BE_DWORD_0 = (MTVSRD $A);
1528
1529  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
1530  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1531                                        LE_MTVSRW, sub_64));
1532  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
1533  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
1534                                         BE_DWORD_0, sub_64));
1535  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
1536}
1537
1538/*  Patterns for extracting elements out of vectors. Integer elements are
1539    extracted using direct move operations. Patterns for extracting elements
1540    whose indices are not available at compile time are also provided with
1541    various _VARIABLE_ patterns.
1542    The numbering for the DAG's is for LE, but when used on BE, the correct
1543    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
1544*/
1545def VectorExtractions {
1546  // Doubleword extraction
1547  dag LE_DWORD_0 =
1548    (MFVSRD
1549      (EXTRACT_SUBREG
1550        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
1551                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
1552  dag LE_DWORD_1 = (MFVSRD
1553                     (EXTRACT_SUBREG
1554                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1555
1556  // Word extraction
1557  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
1558  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
1559  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
1560                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
1561  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
1562
1563  // Halfword extraction
1564  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
1565  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
1566  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
1567  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
1568  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
1569  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
1570  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
1571  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
1572
1573  // Byte extraction
1574  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
1575  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
1576  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
1577  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
1578  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
1579  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
1580  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
1581  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
1582  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
1583  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
1584  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
1585  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
1586  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
1587  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
1588  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
1589  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
1590
1591  /* Variable element number (BE and LE patterns must be specified separately)
1592     This is a rather involved process.
1593
1594     Conceptually, this is how the move is accomplished:
1595     1. Identify which doubleword contains the element
1596     2. Shift in the VMX register so that the correct doubleword is correctly
1597        lined up for the MFVSRD
1598     3. Perform the move so that the element (along with some extra stuff)
1599        is in the GPR
1600     4. Right shift within the GPR so that the element is right-justified
1601
1602     Of course, the index is an element number which has a different meaning
1603     on LE/BE so the patterns have to be specified separately.
1604
1605     Note: The final result will be the element right-justified with high
1606           order bits being arbitrarily defined (namely, whatever was in the
1607           vector register to the left of the value originally).
1608  */
1609
1610  /*  LE variable byte
1611      Number 1. above:
1612      - For elements 0-7, we shift left by 8 bytes since they're on the right
1613      - For elements 8-15, we need not shift (shift left by zero bytes)
1614      This is accomplished by inverting the bits of the index and AND-ing
1615      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
1616  */
1617  dag LE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDC8 (LI8 8), $Idx));
1618
1619  //  Number 2. above:
1620  //  - Now that we set up the shift amount, we shift in the VMX register
1621  dag LE_VBYTE_PERMUTE = (VPERM $S, $S, LE_VBYTE_PERM_VEC);
1622
1623  //  Number 3. above:
1624  //  - The doubleword containing our element is moved to a GPR
1625  dag LE_MV_VBYTE = (MFVSRD
1626                      (EXTRACT_SUBREG
1627                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
1628                        sub_64));
1629
1630  /*  Number 4. above:
1631      - Truncate the element number to the range 0-7 (8-15 are symmetrical
1632        and out of range values are truncated accordingly)
1633      - Multiply by 8 as we need to shift right by the number of bits, not bytes
1634      - Shift right in the GPR by the calculated value
1635  */
1636  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
1637                                       sub_32);
1638  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
1639                                         sub_32);
1640
1641  /*  LE variable halfword
1642      Number 1. above:
1643      - For elements 0-3, we shift left by 8 since they're on the right
1644      - For elements 4-7, we need not shift (shift left by zero bytes)
1645      Similarly to the byte pattern, we invert the bits of the index, but we
1646      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
1647      Of course, the shift is still by 8 bytes, so we must multiply by 2.
1648  */
1649  dag LE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62));
1650
1651  //  Number 2. above:
1652  //  - Now that we set up the shift amount, we shift in the VMX register
1653  dag LE_VHALF_PERMUTE = (VPERM $S, $S, LE_VHALF_PERM_VEC);
1654
1655  //  Number 3. above:
1656  //  - The doubleword containing our element is moved to a GPR
1657  dag LE_MV_VHALF = (MFVSRD
1658                      (EXTRACT_SUBREG
1659                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
1660                        sub_64));
1661
1662  /*  Number 4. above:
1663      - Truncate the element number to the range 0-3 (4-7 are symmetrical
1664        and out of range values are truncated accordingly)
1665      - Multiply by 16 as we need to shift right by the number of bits
1666      - Shift right in the GPR by the calculated value
1667  */
1668  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
1669                                       sub_32);
1670  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
1671                                         sub_32);
1672
1673  /*  LE variable word
1674      Number 1. above:
1675      - For elements 0-1, we shift left by 8 since they're on the right
1676      - For elements 2-3, we need not shift
1677  */
1678  dag LE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61));
1679
1680  //  Number 2. above:
1681  //  - Now that we set up the shift amount, we shift in the VMX register
1682  dag LE_VWORD_PERMUTE = (VPERM $S, $S, LE_VWORD_PERM_VEC);
1683
1684  //  Number 3. above:
1685  //  - The doubleword containing our element is moved to a GPR
1686  dag LE_MV_VWORD = (MFVSRD
1687                      (EXTRACT_SUBREG
1688                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
1689                        sub_64));
1690
1691  /*  Number 4. above:
1692      - Truncate the element number to the range 0-1 (2-3 are symmetrical
1693        and out of range values are truncated accordingly)
1694      - Multiply by 32 as we need to shift right by the number of bits
1695      - Shift right in the GPR by the calculated value
1696  */
1697  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
1698                                       sub_32);
1699  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
1700                                         sub_32);
1701
1702  /*  LE variable doubleword
1703      Number 1. above:
1704      - For element 0, we shift left by 8 since it's on the right
1705      - For element 1, we need not shift
1706  */
1707  dag LE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60));
1708
1709  //  Number 2. above:
1710  //  - Now that we set up the shift amount, we shift in the VMX register
1711  dag LE_VDWORD_PERMUTE = (VPERM $S, $S, LE_VDWORD_PERM_VEC);
1712
1713  // Number 3. above:
1714  //  - The doubleword containing our element is moved to a GPR
1715  //  - Number 4. is not needed for the doubleword as the value is 64-bits
1716  dag LE_VARIABLE_DWORD =
1717        (MFVSRD (EXTRACT_SUBREG
1718                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
1719                  sub_64));
1720
1721  /*  LE variable float
1722      - Shift the vector to line up the desired element to BE Word 0
1723      - Convert 32-bit float to a 64-bit single precision float
1724  */
1725  dag LE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR (XOR8 (LI8 3), $Idx), 2, 61));
1726  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
1727  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
1728
1729  /*  LE variable double
1730      Same as the LE doubleword except there is no move.
1731  */
1732  dag LE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1733                                  (COPY_TO_REGCLASS $S, VRRC),
1734                                  LE_VDWORD_PERM_VEC);
1735  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
1736
1737  /*  BE variable byte
1738      The algorithm here is the same as the LE variable byte except:
1739      - The shift in the VMX register is by 0/8 for opposite element numbers so
1740        we simply AND the element number with 0x8
1741      - The order of elements after the move to GPR is reversed, so we invert
1742        the bits of the index prior to truncating to the range 0-7
1743  */
1744  dag BE_VBYTE_PERM_VEC = (LVSL ZERO8, (ANDIo8 $Idx, 8));
1745  dag BE_VBYTE_PERMUTE = (VPERM $S, $S, BE_VBYTE_PERM_VEC);
1746  dag BE_MV_VBYTE = (MFVSRD
1747                      (EXTRACT_SUBREG
1748                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
1749                        sub_64));
1750  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
1751                                       sub_32);
1752  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
1753                                         sub_32);
1754
1755  /*  BE variable halfword
1756      The algorithm here is the same as the LE variable halfword except:
1757      - The shift in the VMX register is by 0/8 for opposite element numbers so
1758        we simply AND the element number with 0x4 and multiply by 2
1759      - The order of elements after the move to GPR is reversed, so we invert
1760        the bits of the index prior to truncating to the range 0-3
1761  */
1762  dag BE_VHALF_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 4), 1, 62));
1763  dag BE_VHALF_PERMUTE = (VPERM $S, $S, BE_VHALF_PERM_VEC);
1764  dag BE_MV_VHALF = (MFVSRD
1765                      (EXTRACT_SUBREG
1766                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
1767                        sub_64));
1768  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
1769                                       sub_32);
1770  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
1771                                         sub_32);
1772
1773  /*  BE variable word
1774      The algorithm is the same as the LE variable word except:
1775      - The shift in the VMX register happens for opposite element numbers
1776      - The order of elements after the move to GPR is reversed, so we invert
1777        the bits of the index prior to truncating to the range 0-1
1778  */
1779  dag BE_VWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 2), 2, 61));
1780  dag BE_VWORD_PERMUTE = (VPERM $S, $S, BE_VWORD_PERM_VEC);
1781  dag BE_MV_VWORD = (MFVSRD
1782                      (EXTRACT_SUBREG
1783                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
1784                        sub_64));
1785  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
1786                                       sub_32);
1787  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
1788                                         sub_32);
1789
1790  /*  BE variable doubleword
1791      Same as the LE doubleword except we shift in the VMX register for opposite
1792      element indices.
1793  */
1794  dag BE_VDWORD_PERM_VEC = (LVSL ZERO8, (RLDICR (ANDIo8 $Idx, 1), 3, 60));
1795  dag BE_VDWORD_PERMUTE = (VPERM $S, $S, BE_VDWORD_PERM_VEC);
1796  dag BE_VARIABLE_DWORD =
1797        (MFVSRD (EXTRACT_SUBREG
1798                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
1799                  sub_64));
1800
1801  /*  BE variable float
1802      - Shift the vector to line up the desired element to BE Word 0
1803      - Convert 32-bit float to a 64-bit single precision float
1804  */
1805  dag BE_VFLOAT_PERM_VEC = (LVSL ZERO8, (RLDICR $Idx, 2, 61));
1806  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
1807  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
1808
1809  /* BE variable double
1810      Same as the BE doubleword except there is no move.
1811  */
1812  dag BE_VDOUBLE_PERMUTE = (VPERM (COPY_TO_REGCLASS $S, VRRC),
1813                                  (COPY_TO_REGCLASS $S, VRRC),
1814                                  BE_VDWORD_PERM_VEC);
1815  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
1816}
1817
1818def NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">;
1819let AddedComplexity = 400 in {
1820// v4f32 scalar <-> vector conversions (BE)
1821let Predicates = [IsBigEndian, HasP8Vector] in {
1822  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1823            (v4f32 (XSCVDPSPN $A))>;
1824  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1825            (f32 (XSCVSPDPN $S))>;
1826  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1827            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1828  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1829            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1830  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1831            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1832  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1833            (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
1834} // IsBigEndian, HasP8Vector
1835
1836// Variable index vector_extract for v2f64 does not require P8Vector
1837let Predicates = [IsBigEndian, HasVSX] in
1838  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1839            (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
1840
1841let Predicates = [IsBigEndian, HasDirectMove] in {
1842  // v16i8 scalar <-> vector conversions (BE)
1843  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
1844            (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
1845  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
1846            (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
1847  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
1848            (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
1849  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
1850            (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
1851
1852  // v2i64 scalar <-> vector conversions (BE)
1853  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
1854            (i64 VectorExtractions.LE_DWORD_1)>;
1855  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
1856            (i64 VectorExtractions.LE_DWORD_0)>;
1857  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
1858            (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
1859} // IsBigEndian, HasDirectMove
1860
1861let Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in {
1862  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
1863            (i32 VectorExtractions.LE_BYTE_15)>;
1864  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
1865            (i32 VectorExtractions.LE_BYTE_14)>;
1866  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
1867            (i32 VectorExtractions.LE_BYTE_13)>;
1868  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
1869            (i32 VectorExtractions.LE_BYTE_12)>;
1870  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
1871            (i32 VectorExtractions.LE_BYTE_11)>;
1872  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
1873            (i32 VectorExtractions.LE_BYTE_10)>;
1874  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
1875            (i32 VectorExtractions.LE_BYTE_9)>;
1876  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
1877            (i32 VectorExtractions.LE_BYTE_8)>;
1878  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
1879            (i32 VectorExtractions.LE_BYTE_7)>;
1880  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
1881            (i32 VectorExtractions.LE_BYTE_6)>;
1882  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
1883            (i32 VectorExtractions.LE_BYTE_5)>;
1884  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
1885            (i32 VectorExtractions.LE_BYTE_4)>;
1886  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
1887            (i32 VectorExtractions.LE_BYTE_3)>;
1888  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
1889            (i32 VectorExtractions.LE_BYTE_2)>;
1890  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
1891            (i32 VectorExtractions.LE_BYTE_1)>;
1892  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
1893            (i32 VectorExtractions.LE_BYTE_0)>;
1894  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
1895            (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
1896
1897  // v8i16 scalar <-> vector conversions (BE)
1898  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
1899            (i32 VectorExtractions.LE_HALF_7)>;
1900  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
1901            (i32 VectorExtractions.LE_HALF_6)>;
1902  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
1903            (i32 VectorExtractions.LE_HALF_5)>;
1904  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
1905            (i32 VectorExtractions.LE_HALF_4)>;
1906  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
1907            (i32 VectorExtractions.LE_HALF_3)>;
1908  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
1909            (i32 VectorExtractions.LE_HALF_2)>;
1910  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
1911            (i32 VectorExtractions.LE_HALF_1)>;
1912  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
1913            (i32 VectorExtractions.LE_HALF_0)>;
1914  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
1915            (i32 VectorExtractions.BE_VARIABLE_HALF)>;
1916
1917  // v4i32 scalar <-> vector conversions (BE)
1918  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
1919            (i32 VectorExtractions.LE_WORD_3)>;
1920  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
1921            (i32 VectorExtractions.LE_WORD_2)>;
1922  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
1923            (i32 VectorExtractions.LE_WORD_1)>;
1924  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
1925            (i32 VectorExtractions.LE_WORD_0)>;
1926  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
1927            (i32 VectorExtractions.BE_VARIABLE_WORD)>;
1928} // IsBigEndian, HasDirectMove, NoP9Altivec
1929
1930// v4f32 scalar <-> vector conversions (LE)
1931let Predicates = [IsLittleEndian, HasP8Vector] in {
1932  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
1933            (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
1934  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
1935            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
1936  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
1937            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
1938  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
1939            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
1940  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
1941            (f32 (XSCVSPDPN $S))>;
1942  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
1943            (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
1944} // IsLittleEndian, HasP8Vector
1945
1946// Variable index vector_extract for v2f64 does not require P8Vector
1947let Predicates = [IsLittleEndian, HasVSX] in
1948  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
1949            (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
1950
1951def : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
1952def : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
1953
1954// Variable index unsigned vector_extract on Power9
1955let Predicates = [HasP9Altivec, IsLittleEndian] in {
1956  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
1957            (VEXTUBRX $Idx, $S)>;
1958
1959  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
1960            (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
1961  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
1962            (VEXTUHRX (LI8 0), $S)>;
1963  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
1964            (VEXTUHRX (LI8 2), $S)>;
1965  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
1966            (VEXTUHRX (LI8 4), $S)>;
1967  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
1968            (VEXTUHRX (LI8 6), $S)>;
1969  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
1970            (VEXTUHRX (LI8 8), $S)>;
1971  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
1972            (VEXTUHRX (LI8 10), $S)>;
1973  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
1974            (VEXTUHRX (LI8 12), $S)>;
1975  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
1976            (VEXTUHRX (LI8 14), $S)>;
1977
1978  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
1979            (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
1980  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
1981            (VEXTUWRX (LI8 0), $S)>;
1982  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
1983            (VEXTUWRX (LI8 4), $S)>;
1984  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
1985  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
1986            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1987	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
1988  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
1989            (VEXTUWRX (LI8 12), $S)>;
1990
1991  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
1992            (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
1993  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
1994            (EXTSW (VEXTUWRX (LI8 0), $S))>;
1995  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
1996            (EXTSW (VEXTUWRX (LI8 4), $S))>;
1997  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
1998  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
1999            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2000	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2001  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2002            (EXTSW (VEXTUWRX (LI8 12), $S))>;
2003
2004  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2005            (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
2006  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2007            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
2008  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2009            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
2010  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2011            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
2012  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2013            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
2014  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2015            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
2016  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2017            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
2018  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2019            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
2020  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2021            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
2022  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2023            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
2024  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2025            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
2026  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2027            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
2028  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2029            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
2030  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2031            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
2032  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2033            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
2034  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2035            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
2036  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2037            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
2038
2039  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2040            (i32 (EXTRACT_SUBREG (VEXTUHRX
2041	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2042  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2043            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
2044  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2045            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
2046  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2047            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
2048  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2049            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
2050  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2051            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
2052  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2053            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
2054  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2055            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
2056  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2057            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
2058
2059  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2060            (i32 (EXTRACT_SUBREG (VEXTUWRX
2061	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2062  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2063            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
2064  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2065            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
2066  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
2067  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2068            (i32 VectorExtractions.LE_WORD_2)>;
2069  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2070            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
2071}
2072
2073let Predicates = [HasP9Altivec, IsBigEndian] in {
2074  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
2075            (VEXTUBLX $Idx, $S)>;
2076
2077  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
2078            (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
2079  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
2080            (VEXTUHLX (LI8 0), $S)>;
2081  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
2082            (VEXTUHLX (LI8 2), $S)>;
2083  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
2084            (VEXTUHLX (LI8 4), $S)>;
2085  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
2086            (VEXTUHLX (LI8 6), $S)>;
2087  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
2088            (VEXTUHLX (LI8 8), $S)>;
2089  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
2090            (VEXTUHLX (LI8 10), $S)>;
2091  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
2092            (VEXTUHLX (LI8 12), $S)>;
2093  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
2094            (VEXTUHLX (LI8 14), $S)>;
2095
2096  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2097            (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
2098  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
2099            (VEXTUWLX (LI8 0), $S)>;
2100
2101  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2102  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
2103            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2104	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
2105  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
2106            (VEXTUWLX (LI8 8), $S)>;
2107  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
2108            (VEXTUWLX (LI8 12), $S)>;
2109
2110  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
2111            (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
2112  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
2113            (EXTSW (VEXTUWLX (LI8 0), $S))>;
2114  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2115  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
2116            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
2117	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
2118  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
2119            (EXTSW (VEXTUWLX (LI8 8), $S))>;
2120  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
2121            (EXTSW (VEXTUWLX (LI8 12), $S))>;
2122
2123  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2124            (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
2125  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2126            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
2127  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2128            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
2129  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2130            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
2131  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2132            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
2133  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2134            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
2135  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2136            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
2137  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2138            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
2139  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2140            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
2141  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2142            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
2143  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2144            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
2145  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2146            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
2147  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2148            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
2149  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2150            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
2151  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2152            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
2153  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2154            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
2155  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2156            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
2157
2158  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2159            (i32 (EXTRACT_SUBREG (VEXTUHLX
2160	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
2161  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2162            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
2163  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2164            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
2165  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2166            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
2167  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2168            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
2169  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2170            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
2171  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2172            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
2173  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2174            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
2175  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2176            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
2177
2178  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2179            (i32 (EXTRACT_SUBREG (VEXTUWLX
2180	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
2181  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2182            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
2183  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
2184  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2185            (i32 VectorExtractions.LE_WORD_2)>;
2186  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2187            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
2188  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2189            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
2190}
2191
2192let Predicates = [IsLittleEndian, HasDirectMove] in {
2193  // v16i8 scalar <-> vector conversions (LE)
2194  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
2195            (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2196  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
2197            (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
2198  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
2199            (v4i32 MovesToVSR.LE_WORD_0)>;
2200  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
2201            (v2i64 MovesToVSR.LE_DWORD_0)>;
2202  // v2i64 scalar <-> vector conversions (LE)
2203  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
2204            (i64 VectorExtractions.LE_DWORD_0)>;
2205  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
2206            (i64 VectorExtractions.LE_DWORD_1)>;
2207  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
2208            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
2209} // IsLittleEndian, HasDirectMove
2210
2211let Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in {
2212  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
2213            (i32 VectorExtractions.LE_BYTE_0)>;
2214  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
2215            (i32 VectorExtractions.LE_BYTE_1)>;
2216  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
2217            (i32 VectorExtractions.LE_BYTE_2)>;
2218  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
2219            (i32 VectorExtractions.LE_BYTE_3)>;
2220  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
2221            (i32 VectorExtractions.LE_BYTE_4)>;
2222  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
2223            (i32 VectorExtractions.LE_BYTE_5)>;
2224  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
2225            (i32 VectorExtractions.LE_BYTE_6)>;
2226  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
2227            (i32 VectorExtractions.LE_BYTE_7)>;
2228  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
2229            (i32 VectorExtractions.LE_BYTE_8)>;
2230  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
2231            (i32 VectorExtractions.LE_BYTE_9)>;
2232  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
2233            (i32 VectorExtractions.LE_BYTE_10)>;
2234  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
2235            (i32 VectorExtractions.LE_BYTE_11)>;
2236  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
2237            (i32 VectorExtractions.LE_BYTE_12)>;
2238  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
2239            (i32 VectorExtractions.LE_BYTE_13)>;
2240  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
2241            (i32 VectorExtractions.LE_BYTE_14)>;
2242  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
2243            (i32 VectorExtractions.LE_BYTE_15)>;
2244  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
2245            (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
2246
2247  // v8i16 scalar <-> vector conversions (LE)
2248  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
2249            (i32 VectorExtractions.LE_HALF_0)>;
2250  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
2251            (i32 VectorExtractions.LE_HALF_1)>;
2252  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
2253            (i32 VectorExtractions.LE_HALF_2)>;
2254  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
2255            (i32 VectorExtractions.LE_HALF_3)>;
2256  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
2257            (i32 VectorExtractions.LE_HALF_4)>;
2258  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
2259            (i32 VectorExtractions.LE_HALF_5)>;
2260  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
2261            (i32 VectorExtractions.LE_HALF_6)>;
2262  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
2263            (i32 VectorExtractions.LE_HALF_7)>;
2264  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
2265            (i32 VectorExtractions.LE_VARIABLE_HALF)>;
2266
2267  // v4i32 scalar <-> vector conversions (LE)
2268  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
2269            (i32 VectorExtractions.LE_WORD_0)>;
2270  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
2271            (i32 VectorExtractions.LE_WORD_1)>;
2272  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
2273            (i32 VectorExtractions.LE_WORD_2)>;
2274  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
2275            (i32 VectorExtractions.LE_WORD_3)>;
2276  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
2277            (i32 VectorExtractions.LE_VARIABLE_WORD)>;
2278} // IsLittleEndian, HasDirectMove, NoP9Altivec
2279
2280let Predicates = [HasDirectMove, HasVSX] in {
2281// bitconvert f32 -> i32
2282// (convert to 32-bit fp single, shift right 1 word, move to GPR)
2283def : Pat<(i32 (bitconvert f32:$S)),
2284          (i32 (MFVSRWZ (EXTRACT_SUBREG
2285                          (XXSLDWI (XSCVDPSPN $S),(XSCVDPSPN $S), 3),
2286                          sub_64)))>;
2287// bitconvert i32 -> f32
2288// (move to FPR, shift left 1 word, convert to 64-bit fp single)
2289def : Pat<(f32 (bitconvert i32:$A)),
2290          (f32 (XSCVSPDPN
2291                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
2292
2293// bitconvert f64 -> i64
2294// (move to GPR, nothing else needed)
2295def : Pat<(i64 (bitconvert f64:$S)),
2296          (i64 (MFVSRD $S))>;
2297
2298// bitconvert i64 -> f64
2299// (move to FPR, nothing else needed)
2300def : Pat<(f64 (bitconvert i64:$S)),
2301          (f64 (MTVSRD $S))>;
2302}
2303
2304// Materialize a zero-vector of long long
2305def : Pat<(v2i64 immAllZerosV),
2306          (v2i64 (XXLXORz))>;
2307}
2308
2309def AlignValues {
2310  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
2311  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
2312}
2313
2314// The following VSX instructions were introduced in Power ISA 3.0
2315def HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
2316let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2317
2318  // [PO VRT XO VRB XO /]
2319  class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2320                      list<dag> pattern>
2321    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
2322                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2323
2324  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
2325  class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2326                         list<dag> pattern>
2327    : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
2328
2329  // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
2330  // So we use different operand class for VRB
2331  class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
2332                           RegisterOperand vbtype, list<dag> pattern>
2333    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
2334                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
2335
2336  let UseVSXReg = 1 in {
2337  // [PO T XO B XO BX /]
2338  class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2339                        list<dag> pattern>
2340    : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
2341                      !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
2342
2343  // [PO T XO B XO BX TX]
2344  class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
2345                        RegisterOperand vtype, list<dag> pattern>
2346    : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
2347                      !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
2348
2349  // [PO T A B XO AX BX TX], src and dest register use different operand class
2350  class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
2351                  RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
2352                  InstrItinClass itin, list<dag> pattern>
2353    : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
2354              !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
2355  } // UseVSXReg = 1
2356
2357  // [PO VRT VRA VRB XO /]
2358  class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2359                      list<dag> pattern>
2360    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
2361              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
2362
2363  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
2364  class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
2365                         list<dag> pattern>
2366    : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
2367
2368  //===--------------------------------------------------------------------===//
2369  // Quad-Precision Scalar Move Instructions:
2370
2371  // Copy Sign
2372  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp", []>;
2373
2374  // Absolute/Negative-Absolute/Negate
2375  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp" , []>;
2376  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp", []>;
2377  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp" , []>;
2378
2379  //===--------------------------------------------------------------------===//
2380  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
2381
2382  // Add/Divide/Multiply/Subtract
2383  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp" , []>;
2384  def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>;
2385  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp" , []>;
2386  def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>;
2387  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp" , []>;
2388  def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>;
2389  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" , []>;
2390  def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>;
2391
2392  // Square-Root
2393  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp" , []>;
2394  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>;
2395
2396  // (Negative) Multiply-{Add/Subtract}
2397  def XSMADDQP  : X_VT5_VA5_VB5   <63, 388, "xsmaddqp"  , []>;
2398  def XSMADDQPO : X_VT5_VA5_VB5_Ro<63, 388, "xsmaddqpo" , []>;
2399  def XSMSUBQP  : X_VT5_VA5_VB5   <63, 420, "xsmsubqp"  , []>;
2400  def XSMSUBQPO : X_VT5_VA5_VB5_Ro<63, 420, "xsmsubqpo" , []>;
2401  def XSNMADDQP : X_VT5_VA5_VB5   <63, 452, "xsnmaddqp" , []>;
2402  def XSNMADDQPO: X_VT5_VA5_VB5_Ro<63, 452, "xsnmaddqpo", []>;
2403  def XSNMSUBQP : X_VT5_VA5_VB5   <63, 484, "xsnmsubqp" , []>;
2404  def XSNMSUBQPO: X_VT5_VA5_VB5_Ro<63, 484, "xsnmsubqpo", []>;
2405
2406  //===--------------------------------------------------------------------===//
2407  // Quad/Double-Precision Compare Instructions:
2408
2409  // [PO BF // VRA VRB XO /]
2410  class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
2411                      list<dag> pattern>
2412    : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
2413               !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
2414    let Pattern = pattern;
2415  }
2416
2417  // QP Compare Ordered/Unordered
2418  def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
2419  def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
2420
2421  // DP/QP Compare Exponents
2422  def XSCMPEXPDP : XX3Form_1<60, 59,
2423                             (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
2424                             "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>,
2425                   UseVSXReg;
2426  def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
2427
2428  // DP Compare ==, >=, >, !=
2429  // Use vsrc for XT, because the entire register of XT is set.
2430  // XT.dword[1] = 0x0000_0000_0000_0000
2431  def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
2432                                  IIC_FPCompare, []>;
2433  def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
2434                                  IIC_FPCompare, []>;
2435  def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
2436                                  IIC_FPCompare, []>;
2437  def XSCMPNEDP : XX3_XT5_XA5_XB5<60, 27, "xscmpnedp", vsrc, vsfrc, vsfrc,
2438                                  IIC_FPCompare, []>;
2439  let UseVSXReg = 1 in {
2440  // Vector Compare Not Equal
2441  def XVCMPNEDP  : XX3Form_Rc<60, 123,
2442                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2443                              "xvcmpnedp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2444  let Defs = [CR6] in
2445  def XVCMPNEDPo : XX3Form_Rc<60, 123,
2446                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2447                              "xvcmpnedp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2448                              isDOT;
2449  def XVCMPNESP  : XX3Form_Rc<60,  91,
2450                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2451                              "xvcmpnesp  $XT, $XA, $XB", IIC_VecFPCompare, []>;
2452  let Defs = [CR6] in
2453  def XVCMPNESPo : XX3Form_Rc<60,  91,
2454                              (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2455                              "xvcmpnesp. $XT, $XA, $XB", IIC_VecFPCompare, []>,
2456                              isDOT;
2457  } // UseVSXReg = 1
2458
2459  //===--------------------------------------------------------------------===//
2460  // Quad-Precision Floating-Point Conversion Instructions:
2461
2462  // Convert DP -> QP
2463  def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc, []>;
2464
2465  // Round & Convert QP -> DP (dword[1] is set to zero)
2466  def XSCVQPDP  : X_VT5_XO5_VB5   <63, 20, 836, "xscvqpdp" , []>;
2467  def XSCVQPDPO : X_VT5_XO5_VB5_Ro<63, 20, 836, "xscvqpdpo", []>;
2468
2469  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
2470  def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
2471  def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
2472  def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
2473  def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
2474
2475  // Convert (Un)Signed DWord -> QP
2476  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
2477  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
2478
2479  let UseVSXReg = 1 in {
2480  //===--------------------------------------------------------------------===//
2481  // Round to Floating-Point Integer Instructions
2482
2483  // (Round &) Convert DP <-> HP
2484  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
2485  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
2486  // but we still use vsfrc for it.
2487  def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
2488  def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
2489
2490  // Vector HP -> SP
2491  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
2492  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
2493                                 [(set v4f32:$XT,
2494                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
2495
2496  } // UseVSXReg = 1
2497
2498  // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
2499  // separate pattern so that it can convert the input register class from
2500  // VRRC(v8i16) to VSRC.
2501  def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
2502            (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
2503
2504  class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
2505                                list<dag> pattern>
2506    : Z23Form_1<opcode, xo,
2507                (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
2508                !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
2509    let RC = ex;
2510  }
2511
2512  // Round to Quad-Precision Integer [with Inexact]
2513  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
2514  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
2515
2516  // Round Quad-Precision to Double-Extended Precision (fp80)
2517  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
2518
2519  //===--------------------------------------------------------------------===//
2520  // Insert/Extract Instructions
2521
2522  // Insert Exponent DP/QP
2523  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
2524  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
2525                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>, UseVSXReg;
2526  // vB NOTE: only vB.dword[0] is used, that's why we don't use
2527  //          X_VT5_VA5_VB5 form
2528  def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
2529                          "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
2530
2531  // Extract Exponent/Significand DP/QP
2532  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
2533  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
2534
2535  def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
2536  def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
2537
2538  // Vector Insert Word
2539  let UseVSXReg = 1 in {
2540  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
2541  def XXINSERTW   :
2542    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
2543                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
2544                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
2545                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
2546                                                   imm32SExt16:$UIM))]>,
2547                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
2548
2549  // Vector Extract Unsigned Word
2550  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
2551                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
2552                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
2553  } // UseVSXReg = 1
2554
2555  // Vector Insert Exponent DP/SP
2556  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
2557    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
2558  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
2559    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
2560
2561  // Vector Extract Exponent/Significand DP/SP
2562  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
2563                                 [(set v2i64: $XT,
2564                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
2565  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
2566                                 [(set v4i32: $XT,
2567                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
2568  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
2569                                 [(set v2i64: $XT,
2570                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
2571  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
2572                                 [(set v4i32: $XT,
2573                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
2574
2575  let AddedComplexity = 400, Predicates = [HasP9Vector] in {
2576  // Extra patterns expanding to vector Extract Word/Insert Word
2577  def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
2578            (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
2579  def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
2580            (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
2581  } // AddedComplexity = 400, HasP9Vector
2582
2583  //===--------------------------------------------------------------------===//
2584
2585  // Test Data Class SP/DP/QP
2586  let UseVSXReg = 1 in {
2587  def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
2588                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2589                              "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
2590  def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
2591                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
2592                              "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
2593  } // UseVSXReg = 1
2594  def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
2595                              (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
2596                              "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
2597
2598  // Vector Test Data Class SP/DP
2599  let UseVSXReg = 1 in {
2600  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
2601                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2602                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
2603                              [(set v4i32: $XT,
2604                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, imm:$DCMX))]>;
2605  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
2606                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
2607                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
2608                              [(set v2i64: $XT,
2609                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, imm:$DCMX))]>;
2610  } // UseVSXReg = 1
2611
2612  //===--------------------------------------------------------------------===//
2613
2614  // Maximum/Minimum Type-C/Type-J DP
2615  // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
2616  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
2617                                 IIC_VecFP, []>;
2618  def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
2619                                 IIC_VecFP, []>;
2620  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
2621                                 IIC_VecFP, []>;
2622  def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
2623                                 IIC_VecFP, []>;
2624
2625  //===--------------------------------------------------------------------===//
2626
2627  // Vector Byte-Reverse H/W/D/Q Word
2628  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2629  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
2630  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
2631  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
2632
2633  // Vector Reverse
2634  def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)),
2635            (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2636  def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)),
2637            (v4i32 (XXBRW $A))>;
2638  def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)),
2639            (v2i64 (XXBRD $A))>;
2640  def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)),
2641            (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2642
2643  // Vector Permute
2644  def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
2645                                IIC_VecPerm, []>;
2646  def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
2647                                IIC_VecPerm, []>;
2648
2649  // Vector Splat Immediate Byte
2650  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
2651                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>, UseVSXReg;
2652
2653  //===--------------------------------------------------------------------===//
2654  // Vector/Scalar Load/Store Instructions
2655
2656  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2657  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2658  let mayLoad = 1, mayStore = 0 in {
2659  // Load Vector
2660  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
2661                            "lxv $XT, $src", IIC_LdStLFD, []>, UseVSXReg;
2662  // Load DWord
2663  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
2664                       "lxsd $vD, $src", IIC_LdStLFD, []>;
2665  // Load SP from src, convert it to DP, and place in dword[0]
2666  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
2667                       "lxssp $vD, $src", IIC_LdStLFD, []>;
2668
2669  // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
2670  // "out" and "in" dag
2671  class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2672                      RegisterOperand vtype, list<dag> pattern>
2673    : XX1Form<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
2674              !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>, UseVSXReg;
2675
2676  // Load as Integer Byte/Halfword & Zero Indexed
2677  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
2678                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
2679  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
2680                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
2681
2682  // Load Vector Halfword*8/Byte*16 Indexed
2683  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
2684  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
2685
2686  // Load Vector Indexed
2687  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
2688                [(set v2f64:$XT, (load xaddr:$src))]>;
2689  // Load Vector (Left-justified) with Length
2690  def LXVL : XX1Form<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2691                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
2692                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>,
2693                    UseVSXReg;
2694  def LXVLL : XX1Form<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
2695                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
2696                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>,
2697                    UseVSXReg;
2698
2699  // Load Vector Word & Splat Indexed
2700  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
2701  } // mayLoad
2702
2703  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
2704  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
2705  let mayStore = 1, mayLoad = 0 in {
2706  // Store Vector
2707  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
2708                             "stxv $XT, $dst", IIC_LdStSTFD, []>, UseVSXReg;
2709  // Store DWord
2710  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
2711                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
2712  // Convert DP of dword[0] to SP, and Store to dst
2713  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
2714                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
2715
2716  // [PO S RA RB XO SX]
2717  class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
2718                      RegisterOperand vtype, list<dag> pattern>
2719    : XX1Form<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
2720              !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>, UseVSXReg;
2721
2722  // Store as Integer Byte/Halfword Indexed
2723  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
2724                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
2725  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
2726                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
2727  let isCodeGenOnly = 1 in {
2728    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vrrc, []>;
2729    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vrrc, []>;
2730  }
2731
2732  // Store Vector Halfword*8/Byte*16 Indexed
2733  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
2734  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
2735
2736  // Store Vector Indexed
2737  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
2738                 [(store v2f64:$XT, xaddr:$dst)]>;
2739
2740  // Store Vector (Left-justified) with Length
2741  def STXVL : XX1Form<31, 397, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2742                   "stxvl $XT, $dst, $rB", IIC_LdStLoad,
2743                   [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst, i64:$rB)]>,
2744                    UseVSXReg;
2745  def STXVLL : XX1Form<31, 429, (outs), (ins vsrc:$XT, memr:$dst, g8rc:$rB),
2746                   "stxvll $XT, $dst, $rB", IIC_LdStLoad,
2747                   [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst, i64:$rB)]>,
2748                    UseVSXReg;
2749  } // mayStore
2750
2751  let Predicates = [IsLittleEndian] in {
2752  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))),
2753           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
2754  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))),
2755           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
2756  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))),
2757           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
2758  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))),
2759           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
2760  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))),
2761           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
2762  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))),
2763           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
2764  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))),
2765           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
2766  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))),
2767           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
2768  }
2769
2770  let Predicates = [IsBigEndian] in {
2771  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))),
2772           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
2773  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))),
2774           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
2775  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))),
2776           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
2777  def: Pat<(f32 (PPCfcfids (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))),
2778           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
2779  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 0))))),
2780           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
2781  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 1))))),
2782           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
2783  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 2))))),
2784           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
2785  def: Pat<(f64 (PPCfcfid (PPCmtvsra (i32 (extractelt v4i32:$A, 3))))),
2786           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
2787  }
2788
2789  // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
2790  // of f64
2791  def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
2792            (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
2793  def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
2794            (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
2795
2796  // Patterns for which instructions from ISA 3.0 are a better match
2797  let Predicates = [IsLittleEndian, HasP9Vector] in {
2798  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2799            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2800  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2801            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2802  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2803            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2804  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2805            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2806  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2807            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
2808  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2809            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
2810  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2811            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
2812  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2813            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
2814  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2815            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2816  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2817            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2818  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2819            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2820  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2821            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2822  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2823            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2824  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2825            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2826  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2827            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2828  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2829            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2830  } // IsLittleEndian, HasP9Vector
2831
2832  let Predicates = [IsBigEndian, HasP9Vector] in {
2833  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2834            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
2835  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2836            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
2837  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2838            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
2839  def : Pat<(f32 (PPCfcfidus (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2840            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
2841  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 0))))),
2842            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
2843  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 1))))),
2844            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
2845  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 2))))),
2846            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
2847  def : Pat<(f64 (PPCfcfidu (PPCmtvsrz (i32 (extractelt v4i32:$A, 3))))),
2848            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
2849  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
2850            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
2851  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
2852            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
2853  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
2854            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
2855  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
2856            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
2857  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
2858            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
2859  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
2860            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
2861  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
2862            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
2863  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
2864            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
2865  } // IsLittleEndian, HasP9Vector
2866
2867  // D-Form Load/Store
2868  def : Pat<(v4i32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
2869  def : Pat<(v4f32 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
2870  def : Pat<(v2i64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
2871  def : Pat<(v2f64 (quadwOffsetLoad iqaddr:$src)), (LXV memrix16:$src)>;
2872  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iqaddr:$src)), (LXV memrix16:$src)>;
2873  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iqaddr:$src)), (LXV memrix16:$src)>;
2874
2875  def : Pat<(quadwOffsetStore v4f32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
2876  def : Pat<(quadwOffsetStore v4i32:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
2877  def : Pat<(quadwOffsetStore v2f64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
2878  def : Pat<(quadwOffsetStore v2i64:$rS, iqaddr:$dst), (STXV $rS, memrix16:$dst)>;
2879  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iqaddr:$dst),
2880            (STXV $rS, memrix16:$dst)>;
2881  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iqaddr:$dst),
2882            (STXV $rS, memrix16:$dst)>;
2883
2884
2885  def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
2886  def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
2887  def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
2888  def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
2889  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
2890  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
2891  def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
2892            (STXVX $rS, xoaddr:$dst)>;
2893  def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
2894            (STXVX $rS, xoaddr:$dst)>;
2895  def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
2896            (STXVX $rS, xoaddr:$dst)>;
2897  def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
2898            (STXVX $rS, xoaddr:$dst)>;
2899  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
2900            (STXVX $rS, xoaddr:$dst)>;
2901  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
2902            (STXVX $rS, xoaddr:$dst)>;
2903  def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
2904            (v4i32 (LXVWSX xoaddr:$src))>;
2905  def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
2906            (v4f32 (LXVWSX xoaddr:$src))>;
2907  def : Pat<(v4f32 (scalar_to_vector (f32 (fpround (extloadf32 xoaddr:$src))))),
2908            (v4f32 (LXVWSX xoaddr:$src))>;
2909
2910  // Build vectors from i8 loads
2911  def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
2912            (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
2913  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
2914            (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
2915  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
2916           (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
2917  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
2918            (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
2919  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
2920            (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
2921  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
2922            (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
2923
2924  // Build vectors from i16 loads
2925  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
2926            (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
2927  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
2928            (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
2929  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
2930           (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
2931  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
2932            (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
2933  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
2934            (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
2935
2936  let Predicates = [IsBigEndian, HasP9Vector] in {
2937  // Scalar stores of i8
2938  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2939            (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
2940  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2941            (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2942  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2943            (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
2944  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2945            (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2946  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
2947            (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
2948  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
2949            (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2950  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
2951            (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
2952  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
2953            (STXSIBXv $S, xoaddr:$dst)>;
2954  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
2955            (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
2956  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
2957            (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2958  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
2959            (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
2960  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
2961            (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2962  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
2963            (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
2964  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
2965            (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2966  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
2967            (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2968  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
2969            (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2970
2971  // Scalar stores of i16
2972  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
2973            (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
2974  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
2975            (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
2976  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
2977            (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
2978  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
2979            (STXSIHXv $S, xoaddr:$dst)>;
2980  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
2981            (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
2982  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
2983            (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
2984  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
2985            (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2986  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
2987            (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2988  } // IsBigEndian, HasP9Vector
2989
2990  let Predicates = [IsLittleEndian, HasP9Vector] in {
2991  // Scalar stores of i8
2992  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
2993            (STXSIBXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
2994  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
2995            (STXSIBXv (VSLDOI $S, $S, 7), xoaddr:$dst)>;
2996  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
2997            (STXSIBXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
2998  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
2999            (STXSIBXv (VSLDOI $S, $S, 5), xoaddr:$dst)>;
3000  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
3001            (STXSIBXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
3002  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
3003            (STXSIBXv (VSLDOI $S, $S, 3), xoaddr:$dst)>;
3004  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
3005            (STXSIBXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
3006  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
3007            (STXSIBXv (VSLDOI $S, $S, 1), xoaddr:$dst)>;
3008  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
3009            (STXSIBXv $S, xoaddr:$dst)>;
3010  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
3011            (STXSIBXv (VSLDOI $S, $S, 15), xoaddr:$dst)>;
3012  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
3013            (STXSIBXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
3014  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
3015            (STXSIBXv (VSLDOI $S, $S, 13), xoaddr:$dst)>;
3016  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
3017            (STXSIBXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
3018  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
3019            (STXSIBXv (VSLDOI $S, $S, 11), xoaddr:$dst)>;
3020  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
3021            (STXSIBXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
3022  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
3023            (STXSIBXv (VSLDOI $S, $S, 9), xoaddr:$dst)>;
3024
3025  // Scalar stores of i16
3026  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
3027            (STXSIHXv (VSLDOI $S, $S, 8), xoaddr:$dst)>;
3028  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
3029            (STXSIHXv (VSLDOI $S, $S, 6), xoaddr:$dst)>;
3030  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
3031            (STXSIHXv (VSLDOI $S, $S, 4), xoaddr:$dst)>;
3032  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
3033            (STXSIHXv (VSLDOI $S, $S, 2), xoaddr:$dst)>;
3034  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
3035            (STXSIHXv $S, xoaddr:$dst)>;
3036  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
3037            (STXSIHXv (VSLDOI $S, $S, 14), xoaddr:$dst)>;
3038  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
3039            (STXSIHXv (VSLDOI $S, $S, 12), xoaddr:$dst)>;
3040  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
3041            (STXSIHXv (VSLDOI $S, $S, 10), xoaddr:$dst)>;
3042  } // IsLittleEndian, HasP9Vector
3043
3044
3045  // Vector sign extensions
3046  def : Pat<(f64 (PPCVexts f64:$A, 1)),
3047            (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
3048  def : Pat<(f64 (PPCVexts f64:$A, 2)),
3049            (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
3050
3051  let isPseudo = 1 in {
3052    def DFLOADf32  : Pseudo<(outs vssrc:$XT), (ins memrix:$src),
3053                            "#DFLOADf32",
3054                            [(set f32:$XT, (load ixaddr:$src))]>;
3055    def DFLOADf64  : Pseudo<(outs vsfrc:$XT), (ins memrix:$src),
3056                            "#DFLOADf64",
3057                            [(set f64:$XT, (load ixaddr:$src))]>;
3058    def DFSTOREf32 : Pseudo<(outs), (ins vssrc:$XT, memrix:$dst),
3059                            "#DFSTOREf32",
3060                            [(store f32:$XT, ixaddr:$dst)]>;
3061    def DFSTOREf64 : Pseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
3062                            "#DFSTOREf64",
3063                            [(store f64:$XT, ixaddr:$dst)]>;
3064  }
3065  def : Pat<(f64 (extloadf32 ixaddr:$src)),
3066            (COPY_TO_REGCLASS (DFLOADf32 ixaddr:$src), VSFRC)>;
3067  def : Pat<(f32 (fpround (extloadf32 ixaddr:$src))),
3068            (f32 (DFLOADf32 ixaddr:$src))>;
3069} // end HasP9Vector, AddedComplexity
3070
3071let Predicates = [HasP9Vector] in {
3072  let isPseudo = 1 in {
3073    let mayStore = 1 in {
3074      def SPILLTOVSR_STX : Pseudo<(outs), (ins spilltovsrrc:$XT, memrr:$dst),
3075                                "#SPILLTOVSR_STX", []>;
3076      def SPILLTOVSR_ST : Pseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
3077                                "#SPILLTOVSR_ST", []>;
3078    }
3079    let mayLoad = 1 in {
3080      def SPILLTOVSR_LDX : Pseudo<(outs spilltovsrrc:$XT), (ins memrr:$src),
3081                                "#SPILLTOVSR_LDX", []>;
3082      def SPILLTOVSR_LD : Pseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
3083                                "#SPILLTOVSR_LD", []>;
3084
3085    }
3086  }
3087}
3088// Integer extend helper dags 32 -> 64
3089def AnyExts {
3090  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
3091  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
3092  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
3093  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
3094}
3095
3096def DblToFlt {
3097  dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
3098  dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
3099  dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
3100  dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
3101}
3102
3103def ByteToWord {
3104  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
3105  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
3106  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
3107  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
3108  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
3109  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
3110  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
3111  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
3112}
3113
3114def ByteToDWord {
3115  dag LE_A0 = (i64 (sext_inreg
3116              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
3117  dag LE_A1 = (i64 (sext_inreg
3118              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
3119  dag BE_A0 = (i64 (sext_inreg
3120              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
3121  dag BE_A1 = (i64 (sext_inreg
3122              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
3123}
3124
3125def HWordToWord {
3126  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
3127  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
3128  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
3129  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
3130  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
3131  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
3132  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
3133  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
3134}
3135
3136def HWordToDWord {
3137  dag LE_A0 = (i64 (sext_inreg
3138              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
3139  dag LE_A1 = (i64 (sext_inreg
3140              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
3141  dag BE_A0 = (i64 (sext_inreg
3142              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
3143  dag BE_A1 = (i64 (sext_inreg
3144              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
3145}
3146
3147def WordToDWord {
3148  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
3149  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
3150  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
3151  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
3152}
3153
3154def FltToIntLoad {
3155  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
3156}
3157def FltToUIntLoad {
3158  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
3159}
3160def FltToLongLoad {
3161  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
3162}
3163def FltToLongLoadP9 {
3164  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 ixaddr:$A)))));
3165}
3166def FltToULongLoad {
3167  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
3168}
3169def FltToULongLoadP9 {
3170  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 ixaddr:$A)))));
3171}
3172def FltToLong {
3173  dag A = (i64 (PPCmfvsr (PPCfctidz (fpextend f32:$A))));
3174}
3175def FltToULong {
3176  dag A = (i64 (PPCmfvsr (PPCfctiduz (fpextend f32:$A))));
3177}
3178def DblToInt {
3179  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
3180}
3181def DblToUInt {
3182  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
3183}
3184def DblToLong {
3185  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
3186}
3187def DblToULong {
3188  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
3189}
3190def DblToIntLoad {
3191  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
3192}
3193def DblToIntLoadP9 {
3194  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load ixaddr:$A)))));
3195}
3196def DblToUIntLoad {
3197  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
3198}
3199def DblToUIntLoadP9 {
3200  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load ixaddr:$A)))));
3201}
3202def DblToLongLoad {
3203  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
3204}
3205def DblToULongLoad {
3206  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
3207}
3208
3209// FP merge dags (for f32 -> v4f32)
3210def MrgFP {
3211  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
3212                               (COPY_TO_REGCLASS $C, VSRC), 0));
3213  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
3214                               (COPY_TO_REGCLASS $D, VSRC), 0));
3215  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
3216  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
3217  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
3218  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
3219}
3220
3221// Patterns for BUILD_VECTOR nodes.
3222def NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
3223let AddedComplexity = 400 in {
3224
3225  let Predicates = [HasVSX] in {
3226    // Build vectors of floating point converted to i32.
3227    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
3228                                   DblToInt.A, DblToInt.A)),
3229              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
3230    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
3231                                   DblToUInt.A, DblToUInt.A)),
3232              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
3233    def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
3234              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
3235                               (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
3236    def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
3237              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
3238                               (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
3239    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3240              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3241                                (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3242    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3243              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3244                                (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
3245    def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
3246              (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
3247
3248    // Build vectors of floating point converted to i64.
3249    def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
3250              (v2i64 (XXPERMDIs
3251                       (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
3252    def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
3253              (v2i64 (XXPERMDIs
3254                       (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
3255    def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
3256              (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
3257    def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
3258              (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
3259  }
3260
3261  let Predicates = [HasVSX, NoP9Vector] in {
3262    // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
3263    def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
3264              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3265                                (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3266    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
3267              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3268                                (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
3269    def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
3270              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3271                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3272    def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
3273              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3274                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
3275  }
3276
3277  // Big endian, available on all targets with VSX
3278  let Predicates = [IsBigEndian, HasVSX] in {
3279    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
3280              (v2f64 (XXPERMDI
3281                        (COPY_TO_REGCLASS $A, VSRC),
3282                        (COPY_TO_REGCLASS $B, VSRC), 0))>;
3283
3284    def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
3285              (VMRGEW MrgFP.AC, MrgFP.BD)>;
3286    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
3287                                   DblToFlt.B0, DblToFlt.B1)),
3288              (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
3289  }
3290
3291  let Predicates = [IsLittleEndian, HasVSX] in {
3292  // Little endian, available on all targets with VSX
3293    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
3294              (v2f64 (XXPERMDI
3295                        (COPY_TO_REGCLASS $B, VSRC),
3296                        (COPY_TO_REGCLASS $A, VSRC), 0))>;
3297
3298    def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
3299              (VMRGEW MrgFP.AC, MrgFP.BD)>;
3300    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
3301                                   DblToFlt.B0, DblToFlt.B1)),
3302              (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
3303  }
3304
3305  let Predicates = [HasDirectMove] in {
3306    // Endianness-neutral constant splat on P8 and newer targets. The reason
3307    // for this pattern is that on targets with direct moves, we don't expand
3308    // BUILD_VECTOR nodes for v4i32.
3309    def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
3310                                   immSExt5NonZero:$A, immSExt5NonZero:$A)),
3311              (v4i32 (VSPLTISW imm:$A))>;
3312  }
3313
3314  let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
3315    // Big endian integer vectors using direct moves.
3316    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3317              (v2i64 (XXPERMDI
3318                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
3319                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
3320    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3321              (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC),
3322                                   (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC), 0),
3323                      (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC),
3324                                   (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC), 0))>;
3325    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3326              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3327  }
3328
3329  let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
3330    // Little endian integer vectors using direct moves.
3331    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
3332              (v2i64 (XXPERMDI
3333                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
3334                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
3335    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3336              (VMRGOW (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $D), VSRC),
3337                                   (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC), 0),
3338                      (XXPERMDI (COPY_TO_REGCLASS (MTVSRWZ $C), VSRC),
3339                                   (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 0))>;
3340    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3341              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
3342  }
3343
3344  let Predicates = [HasP9Vector] in {
3345    // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
3346    def : Pat<(v4i32 (scalar_to_vector i32:$A)),
3347              (v4i32 (MTVSRWS $A))>;
3348    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
3349              (v4i32 (MTVSRWS $A))>;
3350    def : Pat<(v16i8 (build_vector immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3351                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3352                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3353                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3354                                   immAnyExt8:$A, immAnyExt8:$A, immAnyExt8:$A,
3355                                   immAnyExt8:$A)),
3356              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
3357    def : Pat<(v16i8 immAllOnesV),
3358              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
3359    def : Pat<(v8i16 immAllOnesV),
3360              (v8i16 (COPY_TO_REGCLASS (XXSPLTIB 255), VSRC))>;
3361    def : Pat<(v4i32 immAllOnesV),
3362              (v4i32 (XXSPLTIB 255))>;
3363    def : Pat<(v2i64 immAllOnesV),
3364              (v2i64 (XXSPLTIB 255))>;
3365    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
3366              (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
3367    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
3368              (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
3369    def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
3370              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3371                                (XSCVDPSXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>;
3372    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
3373              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
3374                                (XSCVDPUXWS (DFLOADf64 ixaddr:$A)), VSRC), 1))>;
3375    def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
3376              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
3377                                              (DFLOADf32 ixaddr:$A),
3378                                              VSFRC)), 0))>;
3379    def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
3380              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
3381                                              (DFLOADf32 ixaddr:$A),
3382                                              VSFRC)), 0))>;
3383  }
3384
3385  let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
3386    def : Pat<(i64 (extractelt v2i64:$A, 1)),
3387              (i64 (MFVSRLD $A))>;
3388    // Better way to build integer vectors if we have MTVSRDD. Big endian.
3389    def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
3390              (v2i64 (MTVSRDD $rB, $rA))>;
3391    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3392              (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.A, AnyExts.C), VSRC),
3393                      (COPY_TO_REGCLASS (MTVSRDD AnyExts.B, AnyExts.D), VSRC))>;
3394  }
3395
3396  let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
3397    def : Pat<(i64 (extractelt v2i64:$A, 0)),
3398              (i64 (MFVSRLD $A))>;
3399    // Better way to build integer vectors if we have MTVSRDD. Little endian.
3400    def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
3401              (v2i64 (MTVSRDD $rB, $rA))>;
3402    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
3403              (VMRGOW (COPY_TO_REGCLASS (MTVSRDD AnyExts.D, AnyExts.B), VSRC),
3404                      (COPY_TO_REGCLASS (MTVSRDD AnyExts.C, AnyExts.A), VSRC))>;
3405  }
3406  // P9 Altivec instructions that can be used to build vectors.
3407  // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
3408  // with complexities of existing build vector patterns in this file.
3409  let Predicates = [HasP9Altivec, IsLittleEndian] in {
3410    def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
3411              (v2i64 (VEXTSW2D $A))>;
3412    def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
3413              (v2i64 (VEXTSH2D $A))>;
3414    def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
3415                      HWordToWord.LE_A2, HWordToWord.LE_A3)),
3416              (v4i32 (VEXTSH2W $A))>;
3417    def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
3418                      ByteToWord.LE_A2, ByteToWord.LE_A3)),
3419              (v4i32 (VEXTSB2W $A))>;
3420    def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
3421              (v2i64 (VEXTSB2D $A))>;
3422  }
3423
3424  let Predicates = [HasP9Altivec, IsBigEndian] in {
3425    def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
3426              (v2i64 (VEXTSW2D $A))>;
3427    def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
3428              (v2i64 (VEXTSH2D $A))>;
3429    def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
3430                      HWordToWord.BE_A2, HWordToWord.BE_A3)),
3431              (v4i32 (VEXTSH2W $A))>;
3432    def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
3433                      ByteToWord.BE_A2, ByteToWord.BE_A3)),
3434              (v4i32 (VEXTSB2W $A))>;
3435    def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
3436              (v2i64 (VEXTSB2D $A))>;
3437  }
3438
3439  let Predicates = [HasP9Altivec] in {
3440    def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)),
3441              (v2i64 (VEXTSB2D $A))>;
3442    def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)),
3443              (v2i64 (VEXTSH2D $A))>;
3444    def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)),
3445              (v2i64 (VEXTSW2D $A))>;
3446    def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)),
3447              (v4i32 (VEXTSB2W $A))>;
3448    def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)),
3449              (v4i32 (VEXTSH2W $A))>;
3450  }
3451}
3452