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