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