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