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