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