xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrVSX.td (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
10b57cec5SDimitry Andric//===- PPCInstrVSX.td - The PowerPC VSX Extension --*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This file describes the VSX extension to the PowerPC instruction set.
100b57cec5SDimitry Andric//
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric// *********************************** NOTE ***********************************
140b57cec5SDimitry Andric// ** For POWER8 Little Endian, the VSX swap optimization relies on knowing  **
150b57cec5SDimitry Andric// ** which VMX and VSX instructions are lane-sensitive and which are not.   **
160b57cec5SDimitry Andric// ** A lane-sensitive instruction relies, implicitly or explicitly, on      **
170b57cec5SDimitry Andric// ** whether lanes are numbered from left to right.  An instruction like    **
180b57cec5SDimitry Andric// ** VADDFP is not lane-sensitive, because each lane of the result vector   **
190b57cec5SDimitry Andric// ** relies only on the corresponding lane of the source vectors.  However, **
200b57cec5SDimitry Andric// ** an instruction like VMULESB is lane-sensitive, because "even" and      **
210b57cec5SDimitry Andric// ** "odd" lanes are different for big-endian and little-endian numbering.  **
220b57cec5SDimitry Andric// **                                                                        **
230b57cec5SDimitry Andric// ** When adding new VMX and VSX instructions, please consider whether they **
240b57cec5SDimitry Andric// ** are lane-sensitive.  If so, they must be added to a switch statement   **
250b57cec5SDimitry Andric// ** in PPCVSXSwapRemoval::gatherVectorInstructions().                      **
260b57cec5SDimitry Andric// ****************************************************************************
270b57cec5SDimitry Andric
280b57cec5SDimitry Andricdef PPCRegVSRCAsmOperand : AsmOperandClass {
290b57cec5SDimitry Andric  let Name = "RegVSRC"; let PredicateMethod = "isVSRegNumber";
300b57cec5SDimitry Andric}
310b57cec5SDimitry Andricdef vsrc : RegisterOperand<VSRC> {
320b57cec5SDimitry Andric  let ParserMatchClass = PPCRegVSRCAsmOperand;
330b57cec5SDimitry Andric}
340b57cec5SDimitry Andric
350b57cec5SDimitry Andricdef PPCRegVSFRCAsmOperand : AsmOperandClass {
360b57cec5SDimitry Andric  let Name = "RegVSFRC"; let PredicateMethod = "isVSRegNumber";
370b57cec5SDimitry Andric}
380b57cec5SDimitry Andricdef vsfrc : RegisterOperand<VSFRC> {
390b57cec5SDimitry Andric  let ParserMatchClass = PPCRegVSFRCAsmOperand;
400b57cec5SDimitry Andric}
410b57cec5SDimitry Andric
420b57cec5SDimitry Andricdef PPCRegVSSRCAsmOperand : AsmOperandClass {
430b57cec5SDimitry Andric  let Name = "RegVSSRC"; let PredicateMethod = "isVSRegNumber";
440b57cec5SDimitry Andric}
450b57cec5SDimitry Andricdef vssrc : RegisterOperand<VSSRC> {
460b57cec5SDimitry Andric  let ParserMatchClass = PPCRegVSSRCAsmOperand;
470b57cec5SDimitry Andric}
480b57cec5SDimitry Andric
490b57cec5SDimitry Andricdef PPCRegSPILLTOVSRRCAsmOperand : AsmOperandClass {
500b57cec5SDimitry Andric  let Name = "RegSPILLTOVSRRC"; let PredicateMethod = "isVSRegNumber";
510b57cec5SDimitry Andric}
520b57cec5SDimitry Andric
530b57cec5SDimitry Andricdef spilltovsrrc : RegisterOperand<SPILLTOVSRRC> {
540b57cec5SDimitry Andric  let ParserMatchClass = PPCRegSPILLTOVSRRCAsmOperand;
550b57cec5SDimitry Andric}
560b57cec5SDimitry Andric
570b57cec5SDimitry Andricdef SDT_PPCldvsxlh : SDTypeProfile<1, 1, [
580b57cec5SDimitry Andric  SDTCisVT<0, v4f32>, SDTCisPtrTy<1>
590b57cec5SDimitry Andric]>;
600b57cec5SDimitry Andric
618bcb0991SDimitry Andricdef SDT_PPCfpexth : SDTypeProfile<1, 2, [
628bcb0991SDimitry Andric  SDTCisVT<0, v2f64>, SDTCisVT<1, v4f32>, SDTCisPtrTy<2>
638bcb0991SDimitry Andric]>;
648bcb0991SDimitry Andric
658bcb0991SDimitry Andricdef SDT_PPCldsplat : SDTypeProfile<1, 1, [
668bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
670b57cec5SDimitry Andric]>;
680b57cec5SDimitry Andric
690b57cec5SDimitry Andric// Little-endian-specific nodes.
700b57cec5SDimitry Andricdef SDT_PPClxvd2x : SDTypeProfile<1, 1, [
710b57cec5SDimitry Andric  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
720b57cec5SDimitry Andric]>;
730b57cec5SDimitry Andricdef SDT_PPCstxvd2x : SDTypeProfile<0, 2, [
740b57cec5SDimitry Andric  SDTCisVT<0, v2f64>, SDTCisPtrTy<1>
750b57cec5SDimitry Andric]>;
760b57cec5SDimitry Andricdef SDT_PPCxxswapd : SDTypeProfile<1, 1, [
770b57cec5SDimitry Andric  SDTCisSameAs<0, 1>
780b57cec5SDimitry Andric]>;
790b57cec5SDimitry Andricdef SDTVecConv : SDTypeProfile<1, 2, [
800b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>
810b57cec5SDimitry Andric]>;
820b57cec5SDimitry Andricdef SDTVabsd : SDTypeProfile<1, 3, [
830b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<3, i32>
840b57cec5SDimitry Andric]>;
858bcb0991SDimitry Andricdef SDT_PPCld_vec_be : SDTypeProfile<1, 1, [
868bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
878bcb0991SDimitry Andric]>;
888bcb0991SDimitry Andricdef SDT_PPCst_vec_be : SDTypeProfile<0, 2, [
898bcb0991SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
908bcb0991SDimitry Andric]>;
910b57cec5SDimitry Andric
920b57cec5SDimitry Andricdef PPClxvd2x  : SDNode<"PPCISD::LXVD2X", SDT_PPClxvd2x,
930b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
940b57cec5SDimitry Andricdef PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
950b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayStore]>;
968bcb0991SDimitry Andricdef PPCld_vec_be  : SDNode<"PPCISD::LOAD_VEC_BE", SDT_PPCld_vec_be,
978bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
988bcb0991SDimitry Andricdef PPCst_vec_be : SDNode<"PPCISD::STORE_VEC_BE", SDT_PPCst_vec_be,
998bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayStore]>;
1000b57cec5SDimitry Andricdef PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd, [SDNPHasChain]>;
1010b57cec5SDimitry Andricdef PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
1020b57cec5SDimitry Andricdef PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
1030b57cec5SDimitry Andricdef PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
1040b57cec5SDimitry Andricdef PPCsvec2fp : SDNode<"PPCISD::SINT_VEC_TO_FP", SDTVecConv, []>;
1050b57cec5SDimitry Andricdef PPCuvec2fp: SDNode<"PPCISD::UINT_VEC_TO_FP", SDTVecConv, []>;
1060b57cec5SDimitry Andricdef PPCswapNoChain : SDNode<"PPCISD::SWAP_NO_CHAIN", SDT_PPCxxswapd>;
1070b57cec5SDimitry Andricdef PPCvabsd : SDNode<"PPCISD::VABSD", SDTVabsd, []>;
1080b57cec5SDimitry Andric
1098bcb0991SDimitry Andricdef PPCfpexth : SDNode<"PPCISD::FP_EXTEND_HALF", SDT_PPCfpexth, []>;
1100b57cec5SDimitry Andricdef PPCldvsxlh : SDNode<"PPCISD::LD_VSX_LH", SDT_PPCldvsxlh,
1110b57cec5SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1128bcb0991SDimitry Andricdef PPCldsplat : SDNode<"PPCISD::LD_SPLAT", SDT_PPCldsplat,
1138bcb0991SDimitry Andric                        [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andricmulticlass XX3Form_Rcr<bits<6> opcode, bits<7> xo, string asmbase,
1160b57cec5SDimitry Andric                    string asmstr, InstrItinClass itin, Intrinsic Int,
1170b57cec5SDimitry Andric                    ValueType OutTy, ValueType InTy> {
1180b57cec5SDimitry Andric  let BaseName = asmbase in {
1190b57cec5SDimitry Andric    def NAME : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1200b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
1210b57cec5SDimitry Andric                       [(set OutTy:$XT, (Int InTy:$XA, InTy:$XB))]>;
1220b57cec5SDimitry Andric    let Defs = [CR6] in
123*480093f4SDimitry Andric    def _rec    : XX3Form_Rc<opcode, xo, (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
1240b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1250b57cec5SDimitry Andric                       [(set InTy:$XT,
1260b57cec5SDimitry Andric                                (InTy (PPCvcmp_o InTy:$XA, InTy:$XB, xo)))]>,
127*480093f4SDimitry Andric                       isRecordForm;
1280b57cec5SDimitry Andric  }
1290b57cec5SDimitry Andric}
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric// Instruction form with a single input register for instructions such as
1320b57cec5SDimitry Andric// XXPERMDI. The reason for defining this is that specifying multiple chained
1330b57cec5SDimitry Andric// operands (such as loads) to an instruction will perform both chained
1340b57cec5SDimitry Andric// operations rather than coalescing them into a single register - even though
1350b57cec5SDimitry Andric// the source memory location is the same. This simply forces the instruction
1360b57cec5SDimitry Andric// to use the same register for both inputs.
1370b57cec5SDimitry Andric// For example, an output DAG such as this:
1380b57cec5SDimitry Andric//   (XXPERMDI (LXSIBZX xoaddr:$src), (LXSIBZX xoaddr:$src ), 0))
1390b57cec5SDimitry Andric// would result in two load instructions emitted and used as separate inputs
1400b57cec5SDimitry Andric// to the XXPERMDI instruction.
1410b57cec5SDimitry Andricclass XX3Form_2s<bits<6> opcode, bits<5> xo, dag OOL, dag IOL, string asmstr,
1420b57cec5SDimitry Andric                 InstrItinClass itin, list<dag> pattern>
1430b57cec5SDimitry Andric  : XX3Form_2<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
1440b57cec5SDimitry Andric    let XB = XA;
1450b57cec5SDimitry Andric}
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andricdef HasVSX : Predicate<"PPCSubTarget->hasVSX()">;
1480b57cec5SDimitry Andricdef IsLittleEndian : Predicate<"PPCSubTarget->isLittleEndian()">;
1490b57cec5SDimitry Andricdef IsBigEndian : Predicate<"!PPCSubTarget->isLittleEndian()">;
1500b57cec5SDimitry Andricdef HasOnlySwappingMemOps : Predicate<"!PPCSubTarget->hasP9Vector()">;
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andriclet Predicates = [HasVSX] in {
1530b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
1540b57cec5SDimitry Andriclet hasSideEffects = 0 in { // VSX instructions don't have side effects.
1550b57cec5SDimitry Andric
1560b57cec5SDimitry Andric  // Load indexed instructions
1570b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
1580b57cec5SDimitry Andric    let CodeSize = 3 in
1590b57cec5SDimitry Andric    def LXSDX : XX1Form_memOp<31, 588,
1600b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
1610b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
1620b57cec5SDimitry Andric                        []>;
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
1650b57cec5SDimitry Andric    let CodeSize = 3 in
1660b57cec5SDimitry Andric      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1670b57cec5SDimitry Andric                              "#XFLOADf64",
1680b57cec5SDimitry Andric                              [(set f64:$XT, (load xoaddr:$src))]>;
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
1710b57cec5SDimitry Andric    def LXVD2X : XX1Form_memOp<31, 844,
1720b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
1730b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
1740b57cec5SDimitry Andric                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric    def LXVDSX : XX1Form_memOp<31, 332,
1770b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
1780b57cec5SDimitry Andric                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
1810b57cec5SDimitry Andric    def LXVW4X : XX1Form_memOp<31, 780,
1820b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
1830b57cec5SDimitry Andric                         "lxvw4x $XT, $src", IIC_LdStLFD,
1840b57cec5SDimitry Andric                         []>;
1850b57cec5SDimitry Andric  } // mayLoad
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric  // Store indexed instructions
1880b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
1890b57cec5SDimitry Andric    let CodeSize = 3 in
1900b57cec5SDimitry Andric    def STXSDX : XX1Form_memOp<31, 716,
1910b57cec5SDimitry Andric                        (outs), (ins vsfrc:$XT, memrr:$dst),
1920b57cec5SDimitry Andric                        "stxsdx $XT, $dst", IIC_LdStSTFD,
1930b57cec5SDimitry Andric                        []>;
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
1960b57cec5SDimitry Andric    let CodeSize = 3 in
1970b57cec5SDimitry Andric      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1980b57cec5SDimitry Andric                              "#XFSTOREf64",
1990b57cec5SDimitry Andric                              [(store f64:$XT, xoaddr:$dst)]>;
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
2020b57cec5SDimitry Andric    // The behaviour of this instruction is endianness-specific so we provide no
2030b57cec5SDimitry Andric    // pattern to match it without considering endianness.
2040b57cec5SDimitry Andric    def STXVD2X : XX1Form_memOp<31, 972,
2050b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
2060b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
2070b57cec5SDimitry Andric                         []>;
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric    def STXVW4X : XX1Form_memOp<31, 908,
2100b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
2110b57cec5SDimitry Andric                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
2120b57cec5SDimitry Andric                         []>;
2130b57cec5SDimitry Andric    }
2140b57cec5SDimitry Andric  } // mayStore
2150b57cec5SDimitry Andric
216*480093f4SDimitry Andric  let Uses = [RM] in {
2170b57cec5SDimitry Andric  // Add/Mul Instructions
2180b57cec5SDimitry Andric  let isCommutable = 1 in {
2190b57cec5SDimitry Andric    def XSADDDP : XX3Form<60, 32,
2200b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
2210b57cec5SDimitry Andric                          "xsadddp $XT, $XA, $XB", IIC_VecFP,
2220b57cec5SDimitry Andric                          [(set f64:$XT, (fadd f64:$XA, f64:$XB))]>;
2230b57cec5SDimitry Andric    def XSMULDP : XX3Form<60, 48,
2240b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
2250b57cec5SDimitry Andric                          "xsmuldp $XT, $XA, $XB", IIC_VecFP,
2260b57cec5SDimitry Andric                          [(set f64:$XT, (fmul f64:$XA, f64:$XB))]>;
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andric    def XVADDDP : XX3Form<60, 96,
2290b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2300b57cec5SDimitry Andric                          "xvadddp $XT, $XA, $XB", IIC_VecFP,
2310b57cec5SDimitry Andric                          [(set v2f64:$XT, (fadd v2f64:$XA, v2f64:$XB))]>;
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric    def XVADDSP : XX3Form<60, 64,
2340b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2350b57cec5SDimitry Andric                          "xvaddsp $XT, $XA, $XB", IIC_VecFP,
2360b57cec5SDimitry Andric                          [(set v4f32:$XT, (fadd v4f32:$XA, v4f32:$XB))]>;
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric    def XVMULDP : XX3Form<60, 112,
2390b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2400b57cec5SDimitry Andric                          "xvmuldp $XT, $XA, $XB", IIC_VecFP,
2410b57cec5SDimitry Andric                          [(set v2f64:$XT, (fmul v2f64:$XA, v2f64:$XB))]>;
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric    def XVMULSP : XX3Form<60, 80,
2440b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2450b57cec5SDimitry Andric                          "xvmulsp $XT, $XA, $XB", IIC_VecFP,
2460b57cec5SDimitry Andric                          [(set v4f32:$XT, (fmul v4f32:$XA, v4f32:$XB))]>;
2470b57cec5SDimitry Andric  }
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric  // Subtract Instructions
2500b57cec5SDimitry Andric  def XSSUBDP : XX3Form<60, 40,
2510b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
2520b57cec5SDimitry Andric                        "xssubdp $XT, $XA, $XB", IIC_VecFP,
2530b57cec5SDimitry Andric                        [(set f64:$XT, (fsub f64:$XA, f64:$XB))]>;
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric  def XVSUBDP : XX3Form<60, 104,
2560b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2570b57cec5SDimitry Andric                        "xvsubdp $XT, $XA, $XB", IIC_VecFP,
2580b57cec5SDimitry Andric                        [(set v2f64:$XT, (fsub v2f64:$XA, v2f64:$XB))]>;
2590b57cec5SDimitry Andric  def XVSUBSP : XX3Form<60, 72,
2600b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
2610b57cec5SDimitry Andric                        "xvsubsp $XT, $XA, $XB", IIC_VecFP,
2620b57cec5SDimitry Andric                        [(set v4f32:$XT, (fsub v4f32:$XA, v4f32:$XB))]>;
2630b57cec5SDimitry Andric
2640b57cec5SDimitry Andric  // FMA Instructions
2650b57cec5SDimitry Andric  let BaseName = "XSMADDADP" in {
2660b57cec5SDimitry Andric  let isCommutable = 1 in
2670b57cec5SDimitry Andric  def XSMADDADP : XX3Form<60, 33,
2680b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
2690b57cec5SDimitry Andric                          "xsmaddadp $XT, $XA, $XB", IIC_VecFP,
2700b57cec5SDimitry Andric                          [(set f64:$XT, (fma f64:$XA, f64:$XB, f64:$XTi))]>,
2710b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
2720b57cec5SDimitry Andric                          AltVSXFMARel;
2730b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
2740b57cec5SDimitry Andric  def XSMADDMDP : XX3Form<60, 41,
2750b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
2760b57cec5SDimitry Andric                          "xsmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
2770b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
2780b57cec5SDimitry Andric                          AltVSXFMARel;
2790b57cec5SDimitry Andric  }
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric  let BaseName = "XSMSUBADP" in {
2820b57cec5SDimitry Andric  let isCommutable = 1 in
2830b57cec5SDimitry Andric  def XSMSUBADP : XX3Form<60, 49,
2840b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
2850b57cec5SDimitry Andric                          "xsmsubadp $XT, $XA, $XB", IIC_VecFP,
2860b57cec5SDimitry Andric                          [(set f64:$XT, (fma f64:$XA, f64:$XB, (fneg f64:$XTi)))]>,
2870b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
2880b57cec5SDimitry Andric                          AltVSXFMARel;
2890b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
2900b57cec5SDimitry Andric  def XSMSUBMDP : XX3Form<60, 57,
2910b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
2920b57cec5SDimitry Andric                          "xsmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
2930b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
2940b57cec5SDimitry Andric                          AltVSXFMARel;
2950b57cec5SDimitry Andric  }
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric  let BaseName = "XSNMADDADP" in {
2980b57cec5SDimitry Andric  let isCommutable = 1 in
2990b57cec5SDimitry Andric  def XSNMADDADP : XX3Form<60, 161,
3000b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
3010b57cec5SDimitry Andric                          "xsnmaddadp $XT, $XA, $XB", IIC_VecFP,
3020b57cec5SDimitry Andric                          [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, f64:$XTi)))]>,
3030b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3040b57cec5SDimitry Andric                          AltVSXFMARel;
3050b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
3060b57cec5SDimitry Andric  def XSNMADDMDP : XX3Form<60, 169,
3070b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
3080b57cec5SDimitry Andric                          "xsnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
3090b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3100b57cec5SDimitry Andric                          AltVSXFMARel;
3110b57cec5SDimitry Andric  }
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andric  let BaseName = "XSNMSUBADP" in {
3140b57cec5SDimitry Andric  let isCommutable = 1 in
3150b57cec5SDimitry Andric  def XSNMSUBADP : XX3Form<60, 177,
3160b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
3170b57cec5SDimitry Andric                          "xsnmsubadp $XT, $XA, $XB", IIC_VecFP,
3180b57cec5SDimitry Andric                          [(set f64:$XT, (fneg (fma f64:$XA, f64:$XB, (fneg f64:$XTi))))]>,
3190b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3200b57cec5SDimitry Andric                          AltVSXFMARel;
3210b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
3220b57cec5SDimitry Andric  def XSNMSUBMDP : XX3Form<60, 185,
3230b57cec5SDimitry Andric                          (outs vsfrc:$XT), (ins vsfrc:$XTi, vsfrc:$XA, vsfrc:$XB),
3240b57cec5SDimitry Andric                          "xsnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
3250b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3260b57cec5SDimitry Andric                          AltVSXFMARel;
3270b57cec5SDimitry Andric  }
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andric  let BaseName = "XVMADDADP" in {
3300b57cec5SDimitry Andric  let isCommutable = 1 in
3310b57cec5SDimitry Andric  def XVMADDADP : XX3Form<60, 97,
3320b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3330b57cec5SDimitry Andric                          "xvmaddadp $XT, $XA, $XB", IIC_VecFP,
3340b57cec5SDimitry Andric                          [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi))]>,
3350b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3360b57cec5SDimitry Andric                          AltVSXFMARel;
3370b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
3380b57cec5SDimitry Andric  def XVMADDMDP : XX3Form<60, 105,
3390b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3400b57cec5SDimitry Andric                          "xvmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
3410b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3420b57cec5SDimitry Andric                          AltVSXFMARel;
3430b57cec5SDimitry Andric  }
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andric  let BaseName = "XVMADDASP" in {
3460b57cec5SDimitry Andric  let isCommutable = 1 in
3470b57cec5SDimitry Andric  def XVMADDASP : XX3Form<60, 65,
3480b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3490b57cec5SDimitry Andric                          "xvmaddasp $XT, $XA, $XB", IIC_VecFP,
3500b57cec5SDimitry Andric                          [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi))]>,
3510b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3520b57cec5SDimitry Andric                          AltVSXFMARel;
3530b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
3540b57cec5SDimitry Andric  def XVMADDMSP : XX3Form<60, 73,
3550b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3560b57cec5SDimitry Andric                          "xvmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
3570b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3580b57cec5SDimitry Andric                          AltVSXFMARel;
3590b57cec5SDimitry Andric  }
3600b57cec5SDimitry Andric
3610b57cec5SDimitry Andric  let BaseName = "XVMSUBADP" in {
3620b57cec5SDimitry Andric  let isCommutable = 1 in
3630b57cec5SDimitry Andric  def XVMSUBADP : XX3Form<60, 113,
3640b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3650b57cec5SDimitry Andric                          "xvmsubadp $XT, $XA, $XB", IIC_VecFP,
3660b57cec5SDimitry Andric                          [(set v2f64:$XT, (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi)))]>,
3670b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3680b57cec5SDimitry Andric                          AltVSXFMARel;
3690b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
3700b57cec5SDimitry Andric  def XVMSUBMDP : XX3Form<60, 121,
3710b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3720b57cec5SDimitry Andric                          "xvmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
3730b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3740b57cec5SDimitry Andric                          AltVSXFMARel;
3750b57cec5SDimitry Andric  }
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andric  let BaseName = "XVMSUBASP" in {
3780b57cec5SDimitry Andric  let isCommutable = 1 in
3790b57cec5SDimitry Andric  def XVMSUBASP : XX3Form<60, 81,
3800b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3810b57cec5SDimitry Andric                          "xvmsubasp $XT, $XA, $XB", IIC_VecFP,
3820b57cec5SDimitry Andric                          [(set v4f32:$XT, (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi)))]>,
3830b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3840b57cec5SDimitry Andric                          AltVSXFMARel;
3850b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
3860b57cec5SDimitry Andric  def XVMSUBMSP : XX3Form<60, 89,
3870b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3880b57cec5SDimitry Andric                          "xvmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
3890b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
3900b57cec5SDimitry Andric                          AltVSXFMARel;
3910b57cec5SDimitry Andric  }
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric  let BaseName = "XVNMADDADP" in {
3940b57cec5SDimitry Andric  let isCommutable = 1 in
3950b57cec5SDimitry Andric  def XVNMADDADP : XX3Form<60, 225,
3960b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
3970b57cec5SDimitry Andric                          "xvnmaddadp $XT, $XA, $XB", IIC_VecFP,
3980b57cec5SDimitry Andric                          [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, v2f64:$XTi)))]>,
3990b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4000b57cec5SDimitry Andric                          AltVSXFMARel;
4010b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4020b57cec5SDimitry Andric  def XVNMADDMDP : XX3Form<60, 233,
4030b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4040b57cec5SDimitry Andric                          "xvnmaddmdp $XT, $XA, $XB", IIC_VecFP, []>,
4050b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4060b57cec5SDimitry Andric                          AltVSXFMARel;
4070b57cec5SDimitry Andric  }
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric  let BaseName = "XVNMADDASP" in {
4100b57cec5SDimitry Andric  let isCommutable = 1 in
4110b57cec5SDimitry Andric  def XVNMADDASP : XX3Form<60, 193,
4120b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4130b57cec5SDimitry Andric                          "xvnmaddasp $XT, $XA, $XB", IIC_VecFP,
4140b57cec5SDimitry Andric                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, v4f32:$XTi)))]>,
4150b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4160b57cec5SDimitry Andric                          AltVSXFMARel;
4170b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4180b57cec5SDimitry Andric  def XVNMADDMSP : XX3Form<60, 201,
4190b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4200b57cec5SDimitry Andric                          "xvnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
4210b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4220b57cec5SDimitry Andric                          AltVSXFMARel;
4230b57cec5SDimitry Andric  }
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andric  let BaseName = "XVNMSUBADP" in {
4260b57cec5SDimitry Andric  let isCommutable = 1 in
4270b57cec5SDimitry Andric  def XVNMSUBADP : XX3Form<60, 241,
4280b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4290b57cec5SDimitry Andric                          "xvnmsubadp $XT, $XA, $XB", IIC_VecFP,
4300b57cec5SDimitry Andric                          [(set v2f64:$XT, (fneg (fma v2f64:$XA, v2f64:$XB, (fneg v2f64:$XTi))))]>,
4310b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4320b57cec5SDimitry Andric                          AltVSXFMARel;
4330b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4340b57cec5SDimitry Andric  def XVNMSUBMDP : XX3Form<60, 249,
4350b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4360b57cec5SDimitry Andric                          "xvnmsubmdp $XT, $XA, $XB", IIC_VecFP, []>,
4370b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4380b57cec5SDimitry Andric                          AltVSXFMARel;
4390b57cec5SDimitry Andric  }
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric  let BaseName = "XVNMSUBASP" in {
4420b57cec5SDimitry Andric  let isCommutable = 1 in
4430b57cec5SDimitry Andric  def XVNMSUBASP : XX3Form<60, 209,
4440b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4450b57cec5SDimitry Andric                          "xvnmsubasp $XT, $XA, $XB", IIC_VecFP,
4460b57cec5SDimitry Andric                          [(set v4f32:$XT, (fneg (fma v4f32:$XA, v4f32:$XB, (fneg v4f32:$XTi))))]>,
4470b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4480b57cec5SDimitry Andric                          AltVSXFMARel;
4490b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
4500b57cec5SDimitry Andric  def XVNMSUBMSP : XX3Form<60, 217,
4510b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XTi, vsrc:$XA, vsrc:$XB),
4520b57cec5SDimitry Andric                          "xvnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
4530b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
4540b57cec5SDimitry Andric                          AltVSXFMARel;
4550b57cec5SDimitry Andric  }
4560b57cec5SDimitry Andric
4570b57cec5SDimitry Andric  // Division Instructions
4580b57cec5SDimitry Andric  def XSDIVDP : XX3Form<60, 56,
4590b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
4600b57cec5SDimitry Andric                        "xsdivdp $XT, $XA, $XB", IIC_FPDivD,
4610b57cec5SDimitry Andric                        [(set f64:$XT, (fdiv f64:$XA, f64:$XB))]>;
4620b57cec5SDimitry Andric  def XSSQRTDP : XX2Form<60, 75,
4630b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
4640b57cec5SDimitry Andric                        "xssqrtdp $XT, $XB", IIC_FPSqrtD,
4650b57cec5SDimitry Andric                        [(set f64:$XT, (fsqrt f64:$XB))]>;
4660b57cec5SDimitry Andric
4670b57cec5SDimitry Andric  def XSREDP : XX2Form<60, 90,
4680b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XB),
4690b57cec5SDimitry Andric                        "xsredp $XT, $XB", IIC_VecFP,
4700b57cec5SDimitry Andric                        [(set f64:$XT, (PPCfre f64:$XB))]>;
4710b57cec5SDimitry Andric  def XSRSQRTEDP : XX2Form<60, 74,
4720b57cec5SDimitry Andric                           (outs vsfrc:$XT), (ins vsfrc:$XB),
4730b57cec5SDimitry Andric                           "xsrsqrtedp $XT, $XB", IIC_VecFP,
4740b57cec5SDimitry Andric                           [(set f64:$XT, (PPCfrsqrte f64:$XB))]>;
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric  def XSTDIVDP : XX3Form_1<60, 61,
4770b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
4780b57cec5SDimitry Andric                         "xstdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
4790b57cec5SDimitry Andric  def XSTSQRTDP : XX2Form_1<60, 106,
4800b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsfrc:$XB),
4810b57cec5SDimitry Andric                          "xstsqrtdp $crD, $XB", IIC_FPCompare, []>;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andric  def XVDIVDP : XX3Form<60, 120,
4840b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4850b57cec5SDimitry Andric                        "xvdivdp $XT, $XA, $XB", IIC_FPDivD,
4860b57cec5SDimitry Andric                        [(set v2f64:$XT, (fdiv v2f64:$XA, v2f64:$XB))]>;
4870b57cec5SDimitry Andric  def XVDIVSP : XX3Form<60, 88,
4880b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
4890b57cec5SDimitry Andric                        "xvdivsp $XT, $XA, $XB", IIC_FPDivS,
4900b57cec5SDimitry Andric                        [(set v4f32:$XT, (fdiv v4f32:$XA, v4f32:$XB))]>;
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andric  def XVSQRTDP : XX2Form<60, 203,
4930b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
4940b57cec5SDimitry Andric                        "xvsqrtdp $XT, $XB", IIC_FPSqrtD,
4950b57cec5SDimitry Andric                        [(set v2f64:$XT, (fsqrt v2f64:$XB))]>;
4960b57cec5SDimitry Andric  def XVSQRTSP : XX2Form<60, 139,
4970b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
4980b57cec5SDimitry Andric                        "xvsqrtsp $XT, $XB", IIC_FPSqrtS,
4990b57cec5SDimitry Andric                        [(set v4f32:$XT, (fsqrt v4f32:$XB))]>;
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andric  def XVTDIVDP : XX3Form_1<60, 125,
5020b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
5030b57cec5SDimitry Andric                         "xvtdivdp $crD, $XA, $XB", IIC_FPCompare, []>;
5040b57cec5SDimitry Andric  def XVTDIVSP : XX3Form_1<60, 93,
5050b57cec5SDimitry Andric                         (outs crrc:$crD), (ins vsrc:$XA, vsrc:$XB),
5060b57cec5SDimitry Andric                         "xvtdivsp $crD, $XA, $XB", IIC_FPCompare, []>;
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andric  def XVTSQRTDP : XX2Form_1<60, 234,
5090b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
5100b57cec5SDimitry Andric                          "xvtsqrtdp $crD, $XB", IIC_FPCompare, []>;
5110b57cec5SDimitry Andric  def XVTSQRTSP : XX2Form_1<60, 170,
5120b57cec5SDimitry Andric                          (outs crrc:$crD), (ins vsrc:$XB),
5130b57cec5SDimitry Andric                          "xvtsqrtsp $crD, $XB", IIC_FPCompare, []>;
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric  def XVREDP : XX2Form<60, 218,
5160b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
5170b57cec5SDimitry Andric                        "xvredp $XT, $XB", IIC_VecFP,
5180b57cec5SDimitry Andric                        [(set v2f64:$XT, (PPCfre v2f64:$XB))]>;
5190b57cec5SDimitry Andric  def XVRESP : XX2Form<60, 154,
5200b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XB),
5210b57cec5SDimitry Andric                        "xvresp $XT, $XB", IIC_VecFP,
5220b57cec5SDimitry Andric                        [(set v4f32:$XT, (PPCfre v4f32:$XB))]>;
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric  def XVRSQRTEDP : XX2Form<60, 202,
5250b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
5260b57cec5SDimitry Andric                           "xvrsqrtedp $XT, $XB", IIC_VecFP,
5270b57cec5SDimitry Andric                           [(set v2f64:$XT, (PPCfrsqrte v2f64:$XB))]>;
5280b57cec5SDimitry Andric  def XVRSQRTESP : XX2Form<60, 138,
5290b57cec5SDimitry Andric                           (outs vsrc:$XT), (ins vsrc:$XB),
5300b57cec5SDimitry Andric                           "xvrsqrtesp $XT, $XB", IIC_VecFP,
5310b57cec5SDimitry Andric                           [(set v4f32:$XT, (PPCfrsqrte v4f32:$XB))]>;
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric  // Compare Instructions
5340b57cec5SDimitry Andric  def XSCMPODP : XX3Form_1<60, 43,
5350b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
5360b57cec5SDimitry Andric                           "xscmpodp $crD, $XA, $XB", IIC_FPCompare, []>;
5370b57cec5SDimitry Andric  def XSCMPUDP : XX3Form_1<60, 35,
5380b57cec5SDimitry Andric                           (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
5390b57cec5SDimitry Andric                           "xscmpudp $crD, $XA, $XB", IIC_FPCompare, []>;
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric  defm XVCMPEQDP : XX3Form_Rcr<60, 99,
5420b57cec5SDimitry Andric                             "xvcmpeqdp", "$XT, $XA, $XB", IIC_VecFPCompare,
5430b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqdp, v2i64, v2f64>;
5440b57cec5SDimitry Andric  defm XVCMPEQSP : XX3Form_Rcr<60, 67,
5450b57cec5SDimitry Andric                             "xvcmpeqsp", "$XT, $XA, $XB", IIC_VecFPCompare,
5460b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpeqsp, v4i32, v4f32>;
5470b57cec5SDimitry Andric  defm XVCMPGEDP : XX3Form_Rcr<60, 115,
5480b57cec5SDimitry Andric                             "xvcmpgedp", "$XT, $XA, $XB", IIC_VecFPCompare,
5490b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgedp, v2i64, v2f64>;
5500b57cec5SDimitry Andric  defm XVCMPGESP : XX3Form_Rcr<60, 83,
5510b57cec5SDimitry Andric                             "xvcmpgesp", "$XT, $XA, $XB", IIC_VecFPCompare,
5520b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgesp, v4i32, v4f32>;
5530b57cec5SDimitry Andric  defm XVCMPGTDP : XX3Form_Rcr<60, 107,
5540b57cec5SDimitry Andric                             "xvcmpgtdp", "$XT, $XA, $XB", IIC_VecFPCompare,
5550b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtdp, v2i64, v2f64>;
5560b57cec5SDimitry Andric  defm XVCMPGTSP : XX3Form_Rcr<60, 75,
5570b57cec5SDimitry Andric                             "xvcmpgtsp", "$XT, $XA, $XB", IIC_VecFPCompare,
5580b57cec5SDimitry Andric                             int_ppc_vsx_xvcmpgtsp, v4i32, v4f32>;
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andric  // Move Instructions
5610b57cec5SDimitry Andric  def XSABSDP : XX2Form<60, 345,
5620b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
5630b57cec5SDimitry Andric                      "xsabsdp $XT, $XB", IIC_VecFP,
5640b57cec5SDimitry Andric                      [(set f64:$XT, (fabs f64:$XB))]>;
5650b57cec5SDimitry Andric  def XSNABSDP : XX2Form<60, 361,
5660b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
5670b57cec5SDimitry Andric                      "xsnabsdp $XT, $XB", IIC_VecFP,
5680b57cec5SDimitry Andric                      [(set f64:$XT, (fneg (fabs f64:$XB)))]>;
5690b57cec5SDimitry Andric  def XSNEGDP : XX2Form<60, 377,
5700b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
5710b57cec5SDimitry Andric                      "xsnegdp $XT, $XB", IIC_VecFP,
5720b57cec5SDimitry Andric                      [(set f64:$XT, (fneg f64:$XB))]>;
5730b57cec5SDimitry Andric  def XSCPSGNDP : XX3Form<60, 176,
5740b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
5750b57cec5SDimitry Andric                      "xscpsgndp $XT, $XA, $XB", IIC_VecFP,
5760b57cec5SDimitry Andric                      [(set f64:$XT, (fcopysign f64:$XB, f64:$XA))]>;
5770b57cec5SDimitry Andric
5780b57cec5SDimitry Andric  def XVABSDP : XX2Form<60, 473,
5790b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
5800b57cec5SDimitry Andric                      "xvabsdp $XT, $XB", IIC_VecFP,
5810b57cec5SDimitry Andric                      [(set v2f64:$XT, (fabs v2f64:$XB))]>;
5820b57cec5SDimitry Andric
5830b57cec5SDimitry Andric  def XVABSSP : XX2Form<60, 409,
5840b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
5850b57cec5SDimitry Andric                      "xvabssp $XT, $XB", IIC_VecFP,
5860b57cec5SDimitry Andric                      [(set v4f32:$XT, (fabs v4f32:$XB))]>;
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andric  def XVCPSGNDP : XX3Form<60, 240,
5890b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
5900b57cec5SDimitry Andric                      "xvcpsgndp $XT, $XA, $XB", IIC_VecFP,
5910b57cec5SDimitry Andric                      [(set v2f64:$XT, (fcopysign v2f64:$XB, v2f64:$XA))]>;
5920b57cec5SDimitry Andric  def XVCPSGNSP : XX3Form<60, 208,
5930b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
5940b57cec5SDimitry Andric                      "xvcpsgnsp $XT, $XA, $XB", IIC_VecFP,
5950b57cec5SDimitry Andric                      [(set v4f32:$XT, (fcopysign v4f32:$XB, v4f32:$XA))]>;
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric  def XVNABSDP : XX2Form<60, 489,
5980b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
5990b57cec5SDimitry Andric                      "xvnabsdp $XT, $XB", IIC_VecFP,
6000b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg (fabs v2f64:$XB)))]>;
6010b57cec5SDimitry Andric  def XVNABSSP : XX2Form<60, 425,
6020b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6030b57cec5SDimitry Andric                      "xvnabssp $XT, $XB", IIC_VecFP,
6040b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg (fabs v4f32:$XB)))]>;
6050b57cec5SDimitry Andric
6060b57cec5SDimitry Andric  def XVNEGDP : XX2Form<60, 505,
6070b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6080b57cec5SDimitry Andric                      "xvnegdp $XT, $XB", IIC_VecFP,
6090b57cec5SDimitry Andric                      [(set v2f64:$XT, (fneg v2f64:$XB))]>;
6100b57cec5SDimitry Andric  def XVNEGSP : XX2Form<60, 441,
6110b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6120b57cec5SDimitry Andric                      "xvnegsp $XT, $XB", IIC_VecFP,
6130b57cec5SDimitry Andric                      [(set v4f32:$XT, (fneg v4f32:$XB))]>;
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andric  // Conversion Instructions
6160b57cec5SDimitry Andric  def XSCVDPSP : XX2Form<60, 265,
6170b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6180b57cec5SDimitry Andric                      "xscvdpsp $XT, $XB", IIC_VecFP, []>;
6190b57cec5SDimitry Andric  def XSCVDPSXDS : XX2Form<60, 344,
6200b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6210b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
6220b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctidz f64:$XB))]>;
6230b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
6240b57cec5SDimitry Andric  def XSCVDPSXDSs : XX2Form<60, 344,
6250b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
6260b57cec5SDimitry Andric                      "xscvdpsxds $XT, $XB", IIC_VecFP,
6270b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctidz f32:$XB))]>;
6280b57cec5SDimitry Andric  def XSCVDPSXWS : XX2Form<60, 88,
6290b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6300b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
6310b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctiwz f64:$XB))]>;
6320b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
6330b57cec5SDimitry Andric  def XSCVDPSXWSs : XX2Form<60, 88,
6340b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
6350b57cec5SDimitry Andric                      "xscvdpsxws $XT, $XB", IIC_VecFP,
6360b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctiwz f32:$XB))]>;
6370b57cec5SDimitry Andric  def XSCVDPUXDS : XX2Form<60, 328,
6380b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6390b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
6400b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctiduz f64:$XB))]>;
6410b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
6420b57cec5SDimitry Andric  def XSCVDPUXDSs : XX2Form<60, 328,
6430b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
6440b57cec5SDimitry Andric                      "xscvdpuxds $XT, $XB", IIC_VecFP,
6450b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctiduz f32:$XB))]>;
6460b57cec5SDimitry Andric  def XSCVDPUXWS : XX2Form<60, 72,
6470b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6480b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
6490b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfctiwuz f64:$XB))]>;
6500b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
6510b57cec5SDimitry Andric  def XSCVDPUXWSs : XX2Form<60, 72,
6520b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vssrc:$XB),
6530b57cec5SDimitry Andric                      "xscvdpuxws $XT, $XB", IIC_VecFP,
6540b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfctiwuz f32:$XB))]>;
6550b57cec5SDimitry Andric  def XSCVSPDP : XX2Form<60, 329,
6560b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6570b57cec5SDimitry Andric                      "xscvspdp $XT, $XB", IIC_VecFP, []>;
6580b57cec5SDimitry Andric  def XSCVSXDDP : XX2Form<60, 376,
6590b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6600b57cec5SDimitry Andric                      "xscvsxddp $XT, $XB", IIC_VecFP,
6610b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfcfid f64:$XB))]>;
6620b57cec5SDimitry Andric  def XSCVUXDDP : XX2Form<60, 360,
6630b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
6640b57cec5SDimitry Andric                      "xscvuxddp $XT, $XB", IIC_VecFP,
6650b57cec5SDimitry Andric                      [(set f64:$XT, (PPCfcfidu f64:$XB))]>;
6660b57cec5SDimitry Andric
6670b57cec5SDimitry Andric  def XVCVDPSP : XX2Form<60, 393,
6680b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6690b57cec5SDimitry Andric                      "xvcvdpsp $XT, $XB", IIC_VecFP,
6700b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvdpsp v2f64:$XB))]>;
6710b57cec5SDimitry Andric  def XVCVDPSXDS : XX2Form<60, 472,
6720b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6730b57cec5SDimitry Andric                      "xvcvdpsxds $XT, $XB", IIC_VecFP,
6740b57cec5SDimitry Andric                      [(set v2i64:$XT, (fp_to_sint v2f64:$XB))]>;
6750b57cec5SDimitry Andric  def XVCVDPSXWS : XX2Form<60, 216,
6760b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6770b57cec5SDimitry Andric                      "xvcvdpsxws $XT, $XB", IIC_VecFP,
6780b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpsxws v2f64:$XB))]>;
6790b57cec5SDimitry Andric  def XVCVDPUXDS : XX2Form<60, 456,
6800b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6810b57cec5SDimitry Andric                      "xvcvdpuxds $XT, $XB", IIC_VecFP,
6820b57cec5SDimitry Andric                      [(set v2i64:$XT, (fp_to_uint v2f64:$XB))]>;
6830b57cec5SDimitry Andric  def XVCVDPUXWS : XX2Form<60, 200,
6840b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6850b57cec5SDimitry Andric                      "xvcvdpuxws $XT, $XB", IIC_VecFP,
6860b57cec5SDimitry Andric                      [(set v4i32:$XT, (int_ppc_vsx_xvcvdpuxws v2f64:$XB))]>;
6870b57cec5SDimitry Andric
6880b57cec5SDimitry Andric  def XVCVSPDP : XX2Form<60, 457,
6890b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6900b57cec5SDimitry Andric                      "xvcvspdp $XT, $XB", IIC_VecFP,
6910b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvspdp v4f32:$XB))]>;
6920b57cec5SDimitry Andric  def XVCVSPSXDS : XX2Form<60, 408,
6930b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6940b57cec5SDimitry Andric                      "xvcvspsxds $XT, $XB", IIC_VecFP, []>;
6950b57cec5SDimitry Andric  def XVCVSPSXWS : XX2Form<60, 152,
6960b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
6970b57cec5SDimitry Andric                      "xvcvspsxws $XT, $XB", IIC_VecFP,
6980b57cec5SDimitry Andric                      [(set v4i32:$XT, (fp_to_sint v4f32:$XB))]>;
6990b57cec5SDimitry Andric  def XVCVSPUXDS : XX2Form<60, 392,
7000b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7010b57cec5SDimitry Andric                      "xvcvspuxds $XT, $XB", IIC_VecFP, []>;
7020b57cec5SDimitry Andric  def XVCVSPUXWS : XX2Form<60, 136,
7030b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7040b57cec5SDimitry Andric                      "xvcvspuxws $XT, $XB", IIC_VecFP,
7050b57cec5SDimitry Andric                      [(set v4i32:$XT, (fp_to_uint v4f32:$XB))]>;
7060b57cec5SDimitry Andric  def XVCVSXDDP : XX2Form<60, 504,
7070b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7080b57cec5SDimitry Andric                      "xvcvsxddp $XT, $XB", IIC_VecFP,
7090b57cec5SDimitry Andric                      [(set v2f64:$XT, (sint_to_fp v2i64:$XB))]>;
7100b57cec5SDimitry Andric  def XVCVSXDSP : XX2Form<60, 440,
7110b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7120b57cec5SDimitry Andric                      "xvcvsxdsp $XT, $XB", IIC_VecFP,
7130b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvsxdsp v2i64:$XB))]>;
7140b57cec5SDimitry Andric  def XVCVSXWDP : XX2Form<60, 248,
7150b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7160b57cec5SDimitry Andric                      "xvcvsxwdp $XT, $XB", IIC_VecFP,
7170b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvsxwdp v4i32:$XB))]>;
7180b57cec5SDimitry Andric  def XVCVSXWSP : XX2Form<60, 184,
7190b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7200b57cec5SDimitry Andric                      "xvcvsxwsp $XT, $XB", IIC_VecFP,
7210b57cec5SDimitry Andric                      [(set v4f32:$XT, (sint_to_fp v4i32:$XB))]>;
7220b57cec5SDimitry Andric  def XVCVUXDDP : XX2Form<60, 488,
7230b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7240b57cec5SDimitry Andric                      "xvcvuxddp $XT, $XB", IIC_VecFP,
7250b57cec5SDimitry Andric                      [(set v2f64:$XT, (uint_to_fp v2i64:$XB))]>;
7260b57cec5SDimitry Andric  def XVCVUXDSP : XX2Form<60, 424,
7270b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7280b57cec5SDimitry Andric                      "xvcvuxdsp $XT, $XB", IIC_VecFP,
7290b57cec5SDimitry Andric                      [(set v4f32:$XT, (int_ppc_vsx_xvcvuxdsp v2i64:$XB))]>;
7300b57cec5SDimitry Andric  def XVCVUXWDP : XX2Form<60, 232,
7310b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7320b57cec5SDimitry Andric                      "xvcvuxwdp $XT, $XB", IIC_VecFP,
7330b57cec5SDimitry Andric                      [(set v2f64:$XT, (int_ppc_vsx_xvcvuxwdp v4i32:$XB))]>;
7340b57cec5SDimitry Andric  def XVCVUXWSP : XX2Form<60, 168,
7350b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7360b57cec5SDimitry Andric                      "xvcvuxwsp $XT, $XB", IIC_VecFP,
7370b57cec5SDimitry Andric                      [(set v4f32:$XT, (uint_to_fp v4i32:$XB))]>;
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric  // Rounding Instructions
7400b57cec5SDimitry Andric  def XSRDPI : XX2Form<60, 73,
7410b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7420b57cec5SDimitry Andric                      "xsrdpi $XT, $XB", IIC_VecFP,
7430b57cec5SDimitry Andric                      [(set f64:$XT, (fround f64:$XB))]>;
7440b57cec5SDimitry Andric  def XSRDPIC : XX2Form<60, 107,
7450b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7460b57cec5SDimitry Andric                      "xsrdpic $XT, $XB", IIC_VecFP,
7470b57cec5SDimitry Andric                      [(set f64:$XT, (fnearbyint f64:$XB))]>;
7480b57cec5SDimitry Andric  def XSRDPIM : XX2Form<60, 121,
7490b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7500b57cec5SDimitry Andric                      "xsrdpim $XT, $XB", IIC_VecFP,
7510b57cec5SDimitry Andric                      [(set f64:$XT, (ffloor f64:$XB))]>;
7520b57cec5SDimitry Andric  def XSRDPIP : XX2Form<60, 105,
7530b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7540b57cec5SDimitry Andric                      "xsrdpip $XT, $XB", IIC_VecFP,
7550b57cec5SDimitry Andric                      [(set f64:$XT, (fceil f64:$XB))]>;
7560b57cec5SDimitry Andric  def XSRDPIZ : XX2Form<60, 89,
7570b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XB),
7580b57cec5SDimitry Andric                      "xsrdpiz $XT, $XB", IIC_VecFP,
7590b57cec5SDimitry Andric                      [(set f64:$XT, (ftrunc f64:$XB))]>;
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andric  def XVRDPI : XX2Form<60, 201,
7620b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7630b57cec5SDimitry Andric                      "xvrdpi $XT, $XB", IIC_VecFP,
7640b57cec5SDimitry Andric                      [(set v2f64:$XT, (fround v2f64:$XB))]>;
7650b57cec5SDimitry Andric  def XVRDPIC : XX2Form<60, 235,
7660b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7670b57cec5SDimitry Andric                      "xvrdpic $XT, $XB", IIC_VecFP,
7680b57cec5SDimitry Andric                      [(set v2f64:$XT, (fnearbyint v2f64:$XB))]>;
7690b57cec5SDimitry Andric  def XVRDPIM : XX2Form<60, 249,
7700b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7710b57cec5SDimitry Andric                      "xvrdpim $XT, $XB", IIC_VecFP,
7720b57cec5SDimitry Andric                      [(set v2f64:$XT, (ffloor v2f64:$XB))]>;
7730b57cec5SDimitry Andric  def XVRDPIP : XX2Form<60, 233,
7740b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7750b57cec5SDimitry Andric                      "xvrdpip $XT, $XB", IIC_VecFP,
7760b57cec5SDimitry Andric                      [(set v2f64:$XT, (fceil v2f64:$XB))]>;
7770b57cec5SDimitry Andric  def XVRDPIZ : XX2Form<60, 217,
7780b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7790b57cec5SDimitry Andric                      "xvrdpiz $XT, $XB", IIC_VecFP,
7800b57cec5SDimitry Andric                      [(set v2f64:$XT, (ftrunc v2f64:$XB))]>;
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andric  def XVRSPI : XX2Form<60, 137,
7830b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7840b57cec5SDimitry Andric                      "xvrspi $XT, $XB", IIC_VecFP,
7850b57cec5SDimitry Andric                      [(set v4f32:$XT, (fround v4f32:$XB))]>;
7860b57cec5SDimitry Andric  def XVRSPIC : XX2Form<60, 171,
7870b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7880b57cec5SDimitry Andric                      "xvrspic $XT, $XB", IIC_VecFP,
7890b57cec5SDimitry Andric                      [(set v4f32:$XT, (fnearbyint v4f32:$XB))]>;
7900b57cec5SDimitry Andric  def XVRSPIM : XX2Form<60, 185,
7910b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7920b57cec5SDimitry Andric                      "xvrspim $XT, $XB", IIC_VecFP,
7930b57cec5SDimitry Andric                      [(set v4f32:$XT, (ffloor v4f32:$XB))]>;
7940b57cec5SDimitry Andric  def XVRSPIP : XX2Form<60, 169,
7950b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
7960b57cec5SDimitry Andric                      "xvrspip $XT, $XB", IIC_VecFP,
7970b57cec5SDimitry Andric                      [(set v4f32:$XT, (fceil v4f32:$XB))]>;
7980b57cec5SDimitry Andric  def XVRSPIZ : XX2Form<60, 153,
7990b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XB),
8000b57cec5SDimitry Andric                      "xvrspiz $XT, $XB", IIC_VecFP,
8010b57cec5SDimitry Andric                      [(set v4f32:$XT, (ftrunc v4f32:$XB))]>;
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric  // Max/Min Instructions
8040b57cec5SDimitry Andric  let isCommutable = 1 in {
8050b57cec5SDimitry Andric  def XSMAXDP : XX3Form<60, 160,
8060b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
8070b57cec5SDimitry Andric                        "xsmaxdp $XT, $XA, $XB", IIC_VecFP,
8080b57cec5SDimitry Andric                        [(set vsfrc:$XT,
8090b57cec5SDimitry Andric                              (int_ppc_vsx_xsmaxdp vsfrc:$XA, vsfrc:$XB))]>;
8100b57cec5SDimitry Andric  def XSMINDP : XX3Form<60, 168,
8110b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
8120b57cec5SDimitry Andric                        "xsmindp $XT, $XA, $XB", IIC_VecFP,
8130b57cec5SDimitry Andric                        [(set vsfrc:$XT,
8140b57cec5SDimitry Andric                              (int_ppc_vsx_xsmindp vsfrc:$XA, vsfrc:$XB))]>;
8150b57cec5SDimitry Andric
8160b57cec5SDimitry Andric  def XVMAXDP : XX3Form<60, 224,
8170b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8180b57cec5SDimitry Andric                        "xvmaxdp $XT, $XA, $XB", IIC_VecFP,
8190b57cec5SDimitry Andric                        [(set vsrc:$XT,
8200b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxdp vsrc:$XA, vsrc:$XB))]>;
8210b57cec5SDimitry Andric  def XVMINDP : XX3Form<60, 232,
8220b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8230b57cec5SDimitry Andric                        "xvmindp $XT, $XA, $XB", IIC_VecFP,
8240b57cec5SDimitry Andric                        [(set vsrc:$XT,
8250b57cec5SDimitry Andric                              (int_ppc_vsx_xvmindp vsrc:$XA, vsrc:$XB))]>;
8260b57cec5SDimitry Andric
8270b57cec5SDimitry Andric  def XVMAXSP : XX3Form<60, 192,
8280b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8290b57cec5SDimitry Andric                        "xvmaxsp $XT, $XA, $XB", IIC_VecFP,
8300b57cec5SDimitry Andric                        [(set vsrc:$XT,
8310b57cec5SDimitry Andric                              (int_ppc_vsx_xvmaxsp vsrc:$XA, vsrc:$XB))]>;
8320b57cec5SDimitry Andric  def XVMINSP : XX3Form<60, 200,
8330b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8340b57cec5SDimitry Andric                        "xvminsp $XT, $XA, $XB", IIC_VecFP,
8350b57cec5SDimitry Andric                        [(set vsrc:$XT,
8360b57cec5SDimitry Andric                              (int_ppc_vsx_xvminsp vsrc:$XA, vsrc:$XB))]>;
8370b57cec5SDimitry Andric  } // isCommutable
8380b57cec5SDimitry Andric} // Uses = [RM]
8390b57cec5SDimitry Andric
8400b57cec5SDimitry Andric  // Logical Instructions
8410b57cec5SDimitry Andric  let isCommutable = 1 in
8420b57cec5SDimitry Andric  def XXLAND : XX3Form<60, 130,
8430b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8440b57cec5SDimitry Andric                       "xxland $XT, $XA, $XB", IIC_VecGeneral,
8450b57cec5SDimitry Andric                       [(set v4i32:$XT, (and v4i32:$XA, v4i32:$XB))]>;
8460b57cec5SDimitry Andric  def XXLANDC : XX3Form<60, 138,
8470b57cec5SDimitry Andric                        (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8480b57cec5SDimitry Andric                        "xxlandc $XT, $XA, $XB", IIC_VecGeneral,
8490b57cec5SDimitry Andric                        [(set v4i32:$XT, (and v4i32:$XA,
8500b57cec5SDimitry Andric                                              (vnot_ppc v4i32:$XB)))]>;
8510b57cec5SDimitry Andric  let isCommutable = 1 in {
8520b57cec5SDimitry Andric  def XXLNOR : XX3Form<60, 162,
8530b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8540b57cec5SDimitry Andric                       "xxlnor $XT, $XA, $XB", IIC_VecGeneral,
8550b57cec5SDimitry Andric                       [(set v4i32:$XT, (vnot_ppc (or v4i32:$XA,
8560b57cec5SDimitry Andric                                                   v4i32:$XB)))]>;
8570b57cec5SDimitry Andric  def XXLOR : XX3Form<60, 146,
8580b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8590b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral,
8600b57cec5SDimitry Andric                      [(set v4i32:$XT, (or v4i32:$XA, v4i32:$XB))]>;
8610b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
8620b57cec5SDimitry Andric  def XXLORf: XX3Form<60, 146,
8630b57cec5SDimitry Andric                      (outs vsfrc:$XT), (ins vsfrc:$XA, vsfrc:$XB),
8640b57cec5SDimitry Andric                      "xxlor $XT, $XA, $XB", IIC_VecGeneral, []>;
8650b57cec5SDimitry Andric  def XXLXOR : XX3Form<60, 154,
8660b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8670b57cec5SDimitry Andric                       "xxlxor $XT, $XA, $XB", IIC_VecGeneral,
8680b57cec5SDimitry Andric                       [(set v4i32:$XT, (xor v4i32:$XA, v4i32:$XB))]>;
8690b57cec5SDimitry Andric  } // isCommutable
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
8720b57cec5SDimitry Andric      isReMaterializable = 1 in {
8738bcb0991SDimitry Andric    def XXLXORz : XX3Form_SameOp<60, 154, (outs vsrc:$XT), (ins),
8740b57cec5SDimitry Andric                       "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
8750b57cec5SDimitry Andric                       [(set v4i32:$XT, (v4i32 immAllZerosV))]>;
8768bcb0991SDimitry Andric    def XXLXORdpz : XX3Form_SameOp<60, 154,
8770b57cec5SDimitry Andric                         (outs vsfrc:$XT), (ins),
8780b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
8790b57cec5SDimitry Andric                         [(set f64:$XT, (fpimm0))]>;
8808bcb0991SDimitry Andric    def XXLXORspz : XX3Form_SameOp<60, 154,
8810b57cec5SDimitry Andric                         (outs vssrc:$XT), (ins),
8820b57cec5SDimitry Andric                         "xxlxor $XT, $XT, $XT", IIC_VecGeneral,
8830b57cec5SDimitry Andric                         [(set f32:$XT, (fpimm0))]>;
8840b57cec5SDimitry Andric  }
8850b57cec5SDimitry Andric
8860b57cec5SDimitry Andric  // Permutation Instructions
8870b57cec5SDimitry Andric  def XXMRGHW : XX3Form<60, 18,
8880b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8890b57cec5SDimitry Andric                       "xxmrghw $XT, $XA, $XB", IIC_VecPerm, []>;
8900b57cec5SDimitry Andric  def XXMRGLW : XX3Form<60, 50,
8910b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
8920b57cec5SDimitry Andric                       "xxmrglw $XT, $XA, $XB", IIC_VecPerm, []>;
8930b57cec5SDimitry Andric
8940b57cec5SDimitry Andric  def XXPERMDI : XX3Form_2<60, 10,
8950b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$DM),
8960b57cec5SDimitry Andric                       "xxpermdi $XT, $XA, $XB, $DM", IIC_VecPerm,
8970b57cec5SDimitry Andric                       [(set v2i64:$XT, (PPCxxpermdi v2i64:$XA, v2i64:$XB,
8980b57cec5SDimitry Andric                         imm32SExt16:$DM))]>;
8990b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
9000b57cec5SDimitry Andric  def XXPERMDIs : XX3Form_2s<60, 10, (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$DM),
9010b57cec5SDimitry Andric                             "xxpermdi $XT, $XA, $XA, $DM", IIC_VecPerm, []>;
9020b57cec5SDimitry Andric  def XXSEL : XX4Form<60, 3,
9030b57cec5SDimitry Andric                      (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, vsrc:$XC),
9040b57cec5SDimitry Andric                      "xxsel $XT, $XA, $XB, $XC", IIC_VecPerm, []>;
9050b57cec5SDimitry Andric
9060b57cec5SDimitry Andric  def XXSLDWI : XX3Form_2<60, 2,
9070b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB, u2imm:$SHW),
9080b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XB, $SHW", IIC_VecPerm,
9090b57cec5SDimitry Andric                       [(set v4i32:$XT, (PPCvecshl v4i32:$XA, v4i32:$XB,
9100b57cec5SDimitry Andric                                                  imm32SExt16:$SHW))]>;
9110b57cec5SDimitry Andric
9120b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
9130b57cec5SDimitry Andric  def XXSLDWIs : XX3Form_2s<60, 2,
9140b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XA, u2imm:$SHW),
9150b57cec5SDimitry Andric                       "xxsldwi $XT, $XA, $XA, $SHW", IIC_VecPerm, []>;
9160b57cec5SDimitry Andric
9170b57cec5SDimitry Andric  def XXSPLTW : XX2Form_2<60, 164,
9180b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XB, u2imm:$UIM),
9190b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm,
9200b57cec5SDimitry Andric                       [(set v4i32:$XT,
9210b57cec5SDimitry Andric                             (PPCxxsplt v4i32:$XB, imm32SExt16:$UIM))]>;
9220b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
9230b57cec5SDimitry Andric  def XXSPLTWs : XX2Form_2<60, 164,
9240b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsfrc:$XB, u2imm:$UIM),
9250b57cec5SDimitry Andric                       "xxspltw $XT, $XB, $UIM", IIC_VecPerm, []>;
9260b57cec5SDimitry Andric
9270b57cec5SDimitry Andric} // hasSideEffects
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andric// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
9300b57cec5SDimitry Andric// instruction selection into a branch sequence.
9310b57cec5SDimitry Andriclet PPC970_Single = 1 in {
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andric  def SELECT_CC_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
9340b57cec5SDimitry Andric                             (ins crrc:$cond, vsrc:$T, vsrc:$F, i32imm:$BROPC),
9350b57cec5SDimitry Andric                             "#SELECT_CC_VSRC",
9360b57cec5SDimitry Andric                             []>;
9370b57cec5SDimitry Andric  def SELECT_VSRC: PPCCustomInserterPseudo<(outs vsrc:$dst),
9380b57cec5SDimitry Andric                          (ins crbitrc:$cond, vsrc:$T, vsrc:$F),
9390b57cec5SDimitry Andric                          "#SELECT_VSRC",
9400b57cec5SDimitry Andric                          [(set v2f64:$dst,
9410b57cec5SDimitry Andric                                (select i1:$cond, v2f64:$T, v2f64:$F))]>;
9420b57cec5SDimitry Andric  def SELECT_CC_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
9430b57cec5SDimitry Andric                              (ins crrc:$cond, f8rc:$T, f8rc:$F,
9440b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSFRC",
9450b57cec5SDimitry Andric                              []>;
9460b57cec5SDimitry Andric  def SELECT_VSFRC: PPCCustomInserterPseudo<(outs f8rc:$dst),
9470b57cec5SDimitry Andric                           (ins crbitrc:$cond, f8rc:$T, f8rc:$F),
9480b57cec5SDimitry Andric                           "#SELECT_VSFRC",
9490b57cec5SDimitry Andric                           [(set f64:$dst,
9500b57cec5SDimitry Andric                                 (select i1:$cond, f64:$T, f64:$F))]>;
9510b57cec5SDimitry Andric  def SELECT_CC_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
9520b57cec5SDimitry Andric                              (ins crrc:$cond, f4rc:$T, f4rc:$F,
9530b57cec5SDimitry Andric                               i32imm:$BROPC), "#SELECT_CC_VSSRC",
9540b57cec5SDimitry Andric                              []>;
9550b57cec5SDimitry Andric  def SELECT_VSSRC: PPCCustomInserterPseudo<(outs f4rc:$dst),
9560b57cec5SDimitry Andric                           (ins crbitrc:$cond, f4rc:$T, f4rc:$F),
9570b57cec5SDimitry Andric                           "#SELECT_VSSRC",
9580b57cec5SDimitry Andric                           [(set f32:$dst,
9590b57cec5SDimitry Andric                                 (select i1:$cond, f32:$T, f32:$F))]>;
9600b57cec5SDimitry Andric}
9610b57cec5SDimitry Andric} // AddedComplexity
9620b57cec5SDimitry Andric
9630b57cec5SDimitry Andricdef : InstAlias<"xvmovdp $XT, $XB",
9640b57cec5SDimitry Andric                (XVCPSGNDP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
9650b57cec5SDimitry Andricdef : InstAlias<"xvmovsp $XT, $XB",
9660b57cec5SDimitry Andric                (XVCPSGNSP vsrc:$XT, vsrc:$XB, vsrc:$XB)>;
9670b57cec5SDimitry Andric
9680b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 0",
9690b57cec5SDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 0)>;
9700b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 1",
9710b57cec5SDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 3)>;
9720b57cec5SDimitry Andricdef : InstAlias<"xxmrghd $XT, $XA, $XB",
9730b57cec5SDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 0)>;
9740b57cec5SDimitry Andricdef : InstAlias<"xxmrgld $XT, $XA, $XB",
9750b57cec5SDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XA, vsrc:$XB, 3)>;
9760b57cec5SDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
9770b57cec5SDimitry Andric                (XXPERMDI vsrc:$XT, vsrc:$XB, vsrc:$XB, 2)>;
9780b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 0",
9790b57cec5SDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 0)>;
9800b57cec5SDimitry Andricdef : InstAlias<"xxspltd $XT, $XB, 1",
9810b57cec5SDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 3)>;
9820b57cec5SDimitry Andricdef : InstAlias<"xxswapd $XT, $XB",
9830b57cec5SDimitry Andric                (XXPERMDIs vsrc:$XT, vsfrc:$XB, 2)>;
9840b57cec5SDimitry Andric
9850b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
9860b57cec5SDimitry Andric
9870b57cec5SDimitry Andricdef : Pat<(v4i32 (vnot_ppc v4i32:$A)),
9880b57cec5SDimitry Andric          (v4i32 (XXLNOR $A, $A))>;
9890b57cec5SDimitry Andricdef : Pat<(v4i32 (or (and (vnot_ppc v4i32:$C), v4i32:$A),
9900b57cec5SDimitry Andric                     (and v4i32:$B, v4i32:$C))),
9910b57cec5SDimitry Andric          (v4i32 (XXSEL $A, $B, $C))>;
9920b57cec5SDimitry Andric
9930b57cec5SDimitry Andriclet Predicates = [IsBigEndian] in {
9940b57cec5SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)),
9950b57cec5SDimitry Andric          (v2f64 (SUBREG_TO_REG (i64 1), $A, sub_64))>;
9960b57cec5SDimitry Andric
9970b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
9980b57cec5SDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
9990b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
10000b57cec5SDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
10010b57cec5SDimitry Andric}
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andriclet Predicates = [IsLittleEndian] in {
10040b57cec5SDimitry Andricdef : Pat<(v2f64 (scalar_to_vector f64:$A)),
10050b57cec5SDimitry Andric          (v2f64 (XXPERMDI (SUBREG_TO_REG (i64 1), $A, sub_64),
10060b57cec5SDimitry Andric                           (SUBREG_TO_REG (i64 1), $A, sub_64), 0))>;
10070b57cec5SDimitry Andric
10080b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 0)),
10090b57cec5SDimitry Andric          (f64 (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64))>;
10100b57cec5SDimitry Andricdef : Pat<(f64 (extractelt v2f64:$S, 1)),
10110b57cec5SDimitry Andric          (f64 (EXTRACT_SUBREG $S, sub_64))>;
10120b57cec5SDimitry Andric}
10130b57cec5SDimitry Andric
10148bcb0991SDimitry Andric// Additional fnmsub patterns: -a*b + c == -(a*b - c)
10158bcb0991SDimitry Andricdef : Pat<(fma (fneg f64:$A), f64:$B, f64:$C),
10168bcb0991SDimitry Andric          (XSNMSUBADP $C, $A, $B)>;
10178bcb0991SDimitry Andricdef : Pat<(fma f64:$A, (fneg f64:$B), f64:$C),
10188bcb0991SDimitry Andric          (XSNMSUBADP $C, $A, $B)>;
10190b57cec5SDimitry Andric
10208bcb0991SDimitry Andricdef : Pat<(fma (fneg v2f64:$A), v2f64:$B, v2f64:$C),
10218bcb0991SDimitry Andric          (XVNMSUBADP $C, $A, $B)>;
10228bcb0991SDimitry Andricdef : Pat<(fma v2f64:$A, (fneg v2f64:$B), v2f64:$C),
10238bcb0991SDimitry Andric          (XVNMSUBADP $C, $A, $B)>;
10240b57cec5SDimitry Andric
10258bcb0991SDimitry Andricdef : Pat<(fma (fneg v4f32:$A), v4f32:$B, v4f32:$C),
10268bcb0991SDimitry Andric          (XVNMSUBASP $C, $A, $B)>;
10278bcb0991SDimitry Andricdef : Pat<(fma v4f32:$A, (fneg v4f32:$B), v4f32:$C),
10288bcb0991SDimitry Andric          (XVNMSUBASP $C, $A, $B)>;
10290b57cec5SDimitry Andric
10300b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v4f32:$A)),
10310b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10320b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v4i32:$A)),
10330b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10340b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v8i16:$A)),
10350b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10360b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v16i8:$A)),
10370b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10380b57cec5SDimitry Andric
10390b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert v2f64:$A)),
10400b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10410b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert v2f64:$A)),
10420b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10430b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert v2f64:$A)),
10440b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10450b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert v2f64:$A)),
10460b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10470b57cec5SDimitry Andric
10480b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v4f32:$A)),
10490b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10500b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v4i32:$A)),
10510b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10520b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v8i16:$A)),
10530b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10540b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v16i8:$A)),
10550b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VSRC)>;
10560b57cec5SDimitry Andric
10570b57cec5SDimitry Andricdef : Pat<(v4f32 (bitconvert v2i64:$A)),
10580b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10590b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert v2i64:$A)),
10600b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10610b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert v2i64:$A)),
10620b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10630b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert v2i64:$A)),
10640b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10650b57cec5SDimitry Andric
10660b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v2i64:$A)),
10670b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10680b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert v2f64:$A)),
10690b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10700b57cec5SDimitry Andric
10710b57cec5SDimitry Andricdef : Pat<(v2f64 (bitconvert v1i128:$A)),
10720b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10730b57cec5SDimitry Andricdef : Pat<(v1i128 (bitconvert v2f64:$A)),
10740b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10750b57cec5SDimitry Andric
10760b57cec5SDimitry Andricdef : Pat<(v2i64 (bitconvert f128:$A)),
10770b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10780b57cec5SDimitry Andricdef : Pat<(v4i32 (bitconvert f128:$A)),
10790b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10800b57cec5SDimitry Andricdef : Pat<(v8i16 (bitconvert f128:$A)),
10810b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10820b57cec5SDimitry Andricdef : Pat<(v16i8 (bitconvert f128:$A)),
10830b57cec5SDimitry Andric          (COPY_TO_REGCLASS $A, VRRC)>;
10840b57cec5SDimitry Andric
10850b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 0)),
10860b57cec5SDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGHW $C, $C))))>;
10870b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCsvec2fp v4i32:$C, 1)),
10880b57cec5SDimitry Andric          (v2f64 (XVCVSXWDP (v2i64 (XXMRGLW $C, $C))))>;
10890b57cec5SDimitry Andric
10900b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 0)),
10910b57cec5SDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGHW $C, $C))))>;
10920b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCuvec2fp v4i32:$C, 1)),
10930b57cec5SDimitry Andric          (v2f64 (XVCVUXWDP (v2i64 (XXMRGLW $C, $C))))>;
10940b57cec5SDimitry Andric
10958bcb0991SDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 0)), (XVCVSPDP (XXMRGHW $C, $C))>;
10968bcb0991SDimitry Andricdef : Pat<(v2f64 (PPCfpexth v4f32:$C, 1)), (XVCVSPDP (XXMRGLW $C, $C))>;
10970b57cec5SDimitry Andric
10980b57cec5SDimitry Andric// Loads.
10990b57cec5SDimitry Andriclet Predicates = [HasVSX, HasOnlySwappingMemOps] in {
11000b57cec5SDimitry Andric  def : Pat<(v2f64 (PPClxvd2x xoaddr:$src)), (LXVD2X xoaddr:$src)>;
11010b57cec5SDimitry Andric
11020b57cec5SDimitry Andric  // Stores.
11030b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
11040b57cec5SDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
11050b57cec5SDimitry Andric  def : Pat<(PPCstxvd2x v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
11060b57cec5SDimitry Andric}
11078bcb0991SDimitry Andric
11088bcb0991SDimitry Andric// Load vector big endian order
11098bcb0991SDimitry Andriclet Predicates = [IsLittleEndian, HasVSX] in {
11108bcb0991SDimitry Andric  def : Pat<(v2f64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
11118bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
11128bcb0991SDimitry Andric  def : Pat<(v4f32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
11138bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v4f32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
11148bcb0991SDimitry Andric  def : Pat<(v2i64 (PPCld_vec_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
11158bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
11168bcb0991SDimitry Andric  def : Pat<(v4i32 (PPCld_vec_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
11178bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v4i32:$rS, xoaddr:$dst), (STXVW4X $rS, xoaddr:$dst)>;
11188bcb0991SDimitry Andric}
11198bcb0991SDimitry Andric
11200b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasVSX, HasOnlySwappingMemOps] in {
11210b57cec5SDimitry Andric  def : Pat<(v2f64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
11220b57cec5SDimitry Andric  def : Pat<(v2i64 (load xoaddr:$src)), (LXVD2X xoaddr:$src)>;
11230b57cec5SDimitry Andric  def : Pat<(v4i32 (load xoaddr:$src)), (LXVW4X xoaddr:$src)>;
11240b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVW4X xoaddr:$src)>;
11250b57cec5SDimitry Andric  def : Pat<(store v2f64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
11260b57cec5SDimitry Andric  def : Pat<(store v2i64:$rS, xoaddr:$dst), (STXVD2X $rS, xoaddr:$dst)>;
11270b57cec5SDimitry Andric  def : Pat<(store v4i32:$XT, xoaddr:$dst), (STXVW4X $XT, xoaddr:$dst)>;
11280b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
11290b57cec5SDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
11300b57cec5SDimitry Andric}
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric// Permutes.
11330b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCxxswapd v2f64:$src)), (XXPERMDI $src, $src, 2)>;
11340b57cec5SDimitry Andricdef : Pat<(v2i64 (PPCxxswapd v2i64:$src)), (XXPERMDI $src, $src, 2)>;
11350b57cec5SDimitry Andricdef : Pat<(v4f32 (PPCxxswapd v4f32:$src)), (XXPERMDI $src, $src, 2)>;
11360b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCxxswapd v4i32:$src)), (XXPERMDI $src, $src, 2)>;
11370b57cec5SDimitry Andricdef : Pat<(v2f64 (PPCswapNoChain v2f64:$src)), (XXPERMDI $src, $src, 2)>;
11380b57cec5SDimitry Andric
11390b57cec5SDimitry Andric// PPCvecshl XT, XA, XA, 2 can be selected to both XXSLDWI XT,XA,XA,2 and
11400b57cec5SDimitry Andric// XXSWAPD XT,XA (i.e. XXPERMDI XT,XA,XA,2), the later one is more profitable.
11410b57cec5SDimitry Andricdef : Pat<(v4i32 (PPCvecshl v4i32:$src, v4i32:$src, 2)), (XXPERMDI $src, $src, 2)>;
11420b57cec5SDimitry Andric
11430b57cec5SDimitry Andric// Selects.
11440b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLT)),
11450b57cec5SDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
11460b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULT)),
11470b57cec5SDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
11480b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETLE)),
11490b57cec5SDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
11500b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETULE)),
11510b57cec5SDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
11520b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETEQ)),
11530b57cec5SDimitry Andric          (SELECT_VSRC (CREQV $lhs, $rhs), $tval, $fval)>;
11540b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGE)),
11550b57cec5SDimitry Andric          (SELECT_VSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
11560b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGE)),
11570b57cec5SDimitry Andric          (SELECT_VSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
11580b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETGT)),
11590b57cec5SDimitry Andric          (SELECT_VSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
11600b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETUGT)),
11610b57cec5SDimitry Andric          (SELECT_VSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
11620b57cec5SDimitry Andricdef : Pat<(v2f64 (selectcc i1:$lhs, i1:$rhs, v2f64:$tval, v2f64:$fval, SETNE)),
11630b57cec5SDimitry Andric          (SELECT_VSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
11640b57cec5SDimitry Andric
11650b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
11660b57cec5SDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
11670b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
11680b57cec5SDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
11690b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
11700b57cec5SDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
11710b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
11720b57cec5SDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
11730b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
11740b57cec5SDimitry Andric          (SELECT_VSFRC (CREQV $lhs, $rhs), $tval, $fval)>;
11750b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
11760b57cec5SDimitry Andric          (SELECT_VSFRC (CRORC  $rhs, $lhs), $tval, $fval)>;
11770b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
11780b57cec5SDimitry Andric          (SELECT_VSFRC (CRORC  $lhs, $rhs), $tval, $fval)>;
11790b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
11800b57cec5SDimitry Andric          (SELECT_VSFRC (CRANDC $rhs, $lhs), $tval, $fval)>;
11810b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
11820b57cec5SDimitry Andric          (SELECT_VSFRC (CRANDC $lhs, $rhs), $tval, $fval)>;
11830b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
11840b57cec5SDimitry Andric          (SELECT_VSFRC (CRXOR $lhs, $rhs), $tval, $fval)>;
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andric// Divides.
11870b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvdivsp v4f32:$A, v4f32:$B),
11880b57cec5SDimitry Andric          (XVDIVSP $A, $B)>;
11890b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvdivdp v2f64:$A, v2f64:$B),
11900b57cec5SDimitry Andric          (XVDIVDP $A, $B)>;
11910b57cec5SDimitry Andric
11920b57cec5SDimitry Andric// Reciprocal estimate
11930b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvresp v4f32:$A),
11940b57cec5SDimitry Andric          (XVRESP $A)>;
11950b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvredp v2f64:$A),
11960b57cec5SDimitry Andric          (XVREDP $A)>;
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andric// Recip. square root estimate
11990b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtesp v4f32:$A),
12000b57cec5SDimitry Andric          (XVRSQRTESP $A)>;
12010b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_xvrsqrtedp v2f64:$A),
12020b57cec5SDimitry Andric          (XVRSQRTEDP $A)>;
12030b57cec5SDimitry Andric
12040b57cec5SDimitry Andric// Vector selection
12050b57cec5SDimitry Andricdef : Pat<(v16i8 (vselect v16i8:$vA, v16i8:$vB, v16i8:$vC)),
12060b57cec5SDimitry Andric          (COPY_TO_REGCLASS
12070b57cec5SDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
12080b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
12090b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
12100b57cec5SDimitry Andricdef : Pat<(v8i16 (vselect v8i16:$vA, v8i16:$vB, v8i16:$vC)),
12110b57cec5SDimitry Andric          (COPY_TO_REGCLASS
12120b57cec5SDimitry Andric                 (XXSEL (COPY_TO_REGCLASS $vC, VSRC),
12130b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $vB, VSRC),
12140b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $vA, VSRC)), VRRC)>;
12150b57cec5SDimitry Andricdef : Pat<(vselect v4i32:$vA, v4i32:$vB, v4i32:$vC),
12160b57cec5SDimitry Andric          (XXSEL $vC, $vB, $vA)>;
12170b57cec5SDimitry Andricdef : Pat<(vselect v2i64:$vA, v2i64:$vB, v2i64:$vC),
12180b57cec5SDimitry Andric          (XXSEL $vC, $vB, $vA)>;
12190b57cec5SDimitry Andricdef : Pat<(vselect v4i32:$vA, v4f32:$vB, v4f32:$vC),
12200b57cec5SDimitry Andric          (XXSEL $vC, $vB, $vA)>;
12210b57cec5SDimitry Andricdef : Pat<(vselect v2i64:$vA, v2f64:$vB, v2f64:$vC),
12220b57cec5SDimitry Andric          (XXSEL $vC, $vB, $vA)>;
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andricdef : Pat<(v4f32 (fmaxnum v4f32:$src1, v4f32:$src2)),
12250b57cec5SDimitry Andric          (v4f32 (XVMAXSP $src1, $src2))>;
12260b57cec5SDimitry Andricdef : Pat<(v4f32 (fminnum v4f32:$src1, v4f32:$src2)),
12270b57cec5SDimitry Andric          (v4f32 (XVMINSP $src1, $src2))>;
12280b57cec5SDimitry Andricdef : Pat<(v2f64 (fmaxnum v2f64:$src1, v2f64:$src2)),
12290b57cec5SDimitry Andric          (v2f64 (XVMAXDP $src1, $src2))>;
12300b57cec5SDimitry Andricdef : Pat<(v2f64 (fminnum v2f64:$src1, v2f64:$src2)),
12310b57cec5SDimitry Andric          (v2f64 (XVMINDP $src1, $src2))>;
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andriclet Predicates = [IsLittleEndian] in {
12340b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
12350b57cec5SDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
12360b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
12370b57cec5SDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
12380b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
12390b57cec5SDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
12400b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
12410b57cec5SDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (f64 (COPY_TO_REGCLASS $S, VSRC)), VSFRC)))>;
12420b57cec5SDimitry Andric} // IsLittleEndian
12430b57cec5SDimitry Andric
12440b57cec5SDimitry Andriclet Predicates = [IsBigEndian] in {
12450b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
12460b57cec5SDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
12470b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfid (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
12480b57cec5SDimitry Andric          (f64 (XSCVSXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
12490b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 0))))),
12500b57cec5SDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS $S, VSFRC)))>;
12510b57cec5SDimitry Andricdef : Pat<(f64 (PPCfcfidu (PPCmtvsra (i64 (vector_extract v2i64:$S, 1))))),
12520b57cec5SDimitry Andric          (f64 (XSCVUXDDP (COPY_TO_REGCLASS (XXPERMDI $S, $S, 2), VSFRC)))>;
12530b57cec5SDimitry Andric} // IsBigEndian
12540b57cec5SDimitry Andric
12550b57cec5SDimitry Andric} // AddedComplexity
12560b57cec5SDimitry Andric} // HasVSX
12570b57cec5SDimitry Andric
1258*480093f4SDimitry Andricdef FpMinMax {
1259*480093f4SDimitry Andric  dag F32Min = (COPY_TO_REGCLASS (XSMINDP (COPY_TO_REGCLASS $A, VSFRC),
1260*480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1261*480093f4SDimitry Andric                                 VSSRC);
1262*480093f4SDimitry Andric  dag F32Max = (COPY_TO_REGCLASS (XSMAXDP (COPY_TO_REGCLASS $A, VSFRC),
1263*480093f4SDimitry Andric                                          (COPY_TO_REGCLASS $B, VSFRC)),
1264*480093f4SDimitry Andric                                 VSSRC);
1265*480093f4SDimitry Andric}
1266*480093f4SDimitry Andric
1267*480093f4SDimitry Andriclet AddedComplexity = 400, Predicates = [HasVSX] in {
1268*480093f4SDimitry Andric  // f32 Min.
1269*480093f4SDimitry Andric  def : Pat<(f32 (fminnum_ieee f32:$A, f32:$B)),
1270*480093f4SDimitry Andric            (f32 FpMinMax.F32Min)>;
1271*480093f4SDimitry Andric  def : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), f32:$B)),
1272*480093f4SDimitry Andric            (f32 FpMinMax.F32Min)>;
1273*480093f4SDimitry Andric  def : Pat<(f32 (fminnum_ieee f32:$A, (fcanonicalize f32:$B))),
1274*480093f4SDimitry Andric            (f32 FpMinMax.F32Min)>;
1275*480093f4SDimitry Andric  def : Pat<(f32 (fminnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
1276*480093f4SDimitry Andric            (f32 FpMinMax.F32Min)>;
1277*480093f4SDimitry Andric  // F32 Max.
1278*480093f4SDimitry Andric  def : Pat<(f32 (fmaxnum_ieee f32:$A, f32:$B)),
1279*480093f4SDimitry Andric            (f32 FpMinMax.F32Max)>;
1280*480093f4SDimitry Andric  def : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), f32:$B)),
1281*480093f4SDimitry Andric            (f32 FpMinMax.F32Max)>;
1282*480093f4SDimitry Andric  def : Pat<(f32 (fmaxnum_ieee f32:$A, (fcanonicalize f32:$B))),
1283*480093f4SDimitry Andric            (f32 FpMinMax.F32Max)>;
1284*480093f4SDimitry Andric  def : Pat<(f32 (fmaxnum_ieee (fcanonicalize f32:$A), (fcanonicalize f32:$B))),
1285*480093f4SDimitry Andric            (f32 FpMinMax.F32Max)>;
1286*480093f4SDimitry Andric
1287*480093f4SDimitry Andric  // f64 Min.
1288*480093f4SDimitry Andric  def : Pat<(f64 (fminnum_ieee f64:$A, f64:$B)),
1289*480093f4SDimitry Andric            (f64 (XSMINDP $A, $B))>;
1290*480093f4SDimitry Andric  def : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), f64:$B)),
1291*480093f4SDimitry Andric            (f64 (XSMINDP $A, $B))>;
1292*480093f4SDimitry Andric  def : Pat<(f64 (fminnum_ieee f64:$A, (fcanonicalize f64:$B))),
1293*480093f4SDimitry Andric            (f64 (XSMINDP $A, $B))>;
1294*480093f4SDimitry Andric  def : Pat<(f64 (fminnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
1295*480093f4SDimitry Andric            (f64 (XSMINDP $A, $B))>;
1296*480093f4SDimitry Andric  // f64 Max.
1297*480093f4SDimitry Andric  def : Pat<(f64 (fmaxnum_ieee f64:$A, f64:$B)),
1298*480093f4SDimitry Andric            (f64 (XSMAXDP $A, $B))>;
1299*480093f4SDimitry Andric  def : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), f64:$B)),
1300*480093f4SDimitry Andric            (f64 (XSMAXDP $A, $B))>;
1301*480093f4SDimitry Andric  def : Pat<(f64 (fmaxnum_ieee f64:$A, (fcanonicalize f64:$B))),
1302*480093f4SDimitry Andric            (f64 (XSMAXDP $A, $B))>;
1303*480093f4SDimitry Andric  def : Pat<(f64 (fmaxnum_ieee (fcanonicalize f64:$A), (fcanonicalize f64:$B))),
1304*480093f4SDimitry Andric            (f64 (XSMAXDP $A, $B))>;
1305*480093f4SDimitry Andric}
1306*480093f4SDimitry Andric
13070b57cec5SDimitry Andricdef ScalarLoads {
13080b57cec5SDimitry Andric  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
13090b57cec5SDimitry Andric  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
13100b57cec5SDimitry Andric  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
13110b57cec5SDimitry Andric  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
13120b57cec5SDimitry Andric  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andric  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
13150b57cec5SDimitry Andric  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
13160b57cec5SDimitry Andric  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
13170b57cec5SDimitry Andric  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
13180b57cec5SDimitry Andric  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
13190b57cec5SDimitry Andric
13200b57cec5SDimitry Andric  dag Li32 = (i32 (load xoaddr:$src));
13210b57cec5SDimitry Andric}
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andricdef DWToSPExtractConv {
13240b57cec5SDimitry Andric  dag El0US1 = (f32 (PPCfcfidus
13250b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
13260b57cec5SDimitry Andric  dag El1US1 = (f32 (PPCfcfidus
13270b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
13280b57cec5SDimitry Andric  dag El0US2 = (f32 (PPCfcfidus
13290b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
13300b57cec5SDimitry Andric  dag El1US2 = (f32 (PPCfcfidus
13310b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
13320b57cec5SDimitry Andric  dag El0SS1 = (f32 (PPCfcfids
13330b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
13340b57cec5SDimitry Andric  dag El1SS1 = (f32 (PPCfcfids
13350b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
13360b57cec5SDimitry Andric  dag El0SS2 = (f32 (PPCfcfids
13370b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
13380b57cec5SDimitry Andric  dag El1SS2 = (f32 (PPCfcfids
13390b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
13400b57cec5SDimitry Andric  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
13410b57cec5SDimitry Andric  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
13420b57cec5SDimitry Andric}
13430b57cec5SDimitry Andric
13440b57cec5SDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07
13450b57cec5SDimitry Andric/* FIXME: if the operands are v2i64, these patterns will not match.
13460b57cec5SDimitry Andric   we should define new patterns or otherwise match the same patterns
13470b57cec5SDimitry Andric   when the elements are larger than i32.
13480b57cec5SDimitry Andric*/
13490b57cec5SDimitry Andricdef HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
13500b57cec5SDimitry Andricdef HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
13510b57cec5SDimitry Andricdef NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
13520b57cec5SDimitry Andriclet Predicates = [HasP8Vector] in {
13530b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
13540b57cec5SDimitry Andric  let isCommutable = 1 in {
13550b57cec5SDimitry Andric    def XXLEQV : XX3Form<60, 186,
13560b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
13570b57cec5SDimitry Andric                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
13580b57cec5SDimitry Andric                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
13590b57cec5SDimitry Andric    def XXLNAND : XX3Form<60, 178,
13600b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
13610b57cec5SDimitry Andric                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
13620b57cec5SDimitry Andric                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
13630b57cec5SDimitry Andric                                                    v4i32:$XB)))]>;
13640b57cec5SDimitry Andric  } // isCommutable
13650b57cec5SDimitry Andric
13660b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
13670b57cec5SDimitry Andric            (XXLEQV $A, $B)>;
13680b57cec5SDimitry Andric
13698bcb0991SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
13708bcb0991SDimitry Andric      isReMaterializable = 1 in {
13718bcb0991SDimitry Andric    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
13728bcb0991SDimitry Andric                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
13738bcb0991SDimitry Andric                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
13748bcb0991SDimitry Andric  }
13758bcb0991SDimitry Andric
13760b57cec5SDimitry Andric  def XXLORC : XX3Form<60, 170,
13770b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
13780b57cec5SDimitry Andric                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
13790b57cec5SDimitry Andric                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
13800b57cec5SDimitry Andric
13810b57cec5SDimitry Andric  // VSX scalar loads introduced in ISA 2.07
1382*480093f4SDimitry Andric  let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in {
13830b57cec5SDimitry Andric    let CodeSize = 3 in
13840b57cec5SDimitry Andric    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
13850b57cec5SDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
13860b57cec5SDimitry Andric    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
13870b57cec5SDimitry Andric                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
13880b57cec5SDimitry Andric    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
13890b57cec5SDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
13900b57cec5SDimitry Andric
13910b57cec5SDimitry Andric    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
13920b57cec5SDimitry Andric    let CodeSize = 3 in
13930b57cec5SDimitry Andric    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
13940b57cec5SDimitry Andric                            "#XFLOADf32",
13950b57cec5SDimitry Andric                            [(set f32:$XT, (load xoaddr:$src))]>;
13960b57cec5SDimitry Andric    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
13970b57cec5SDimitry Andric    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
13980b57cec5SDimitry Andric                       "#LIWAX",
13990b57cec5SDimitry Andric                       [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
14000b57cec5SDimitry Andric    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
14010b57cec5SDimitry Andric    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
14020b57cec5SDimitry Andric                       "#LIWZX",
14030b57cec5SDimitry Andric                       [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
14040b57cec5SDimitry Andric  } // mayLoad
14050b57cec5SDimitry Andric
14060b57cec5SDimitry Andric  // VSX scalar stores introduced in ISA 2.07
1407*480093f4SDimitry Andric  let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
14080b57cec5SDimitry Andric    let CodeSize = 3 in
14090b57cec5SDimitry Andric    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
14100b57cec5SDimitry Andric                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
14110b57cec5SDimitry Andric    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
14120b57cec5SDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
14130b57cec5SDimitry Andric
14140b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
14150b57cec5SDimitry Andric    let CodeSize = 3 in
14160b57cec5SDimitry Andric    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
14170b57cec5SDimitry Andric                            "#XFSTOREf32",
14180b57cec5SDimitry Andric                            [(store f32:$XT, xoaddr:$dst)]>;
14190b57cec5SDimitry Andric    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
14200b57cec5SDimitry Andric    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
14210b57cec5SDimitry Andric                       "#STIWX",
14220b57cec5SDimitry Andric                      [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
14230b57cec5SDimitry Andric  } // mayStore
14240b57cec5SDimitry Andric
14250b57cec5SDimitry Andric  def : Pat<(f64 (extloadf32 xoaddr:$src)),
14260b57cec5SDimitry Andric            (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
14270b57cec5SDimitry Andric  def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
14280b57cec5SDimitry Andric            (f32 (XFLOADf32 xoaddr:$src))>;
14290b57cec5SDimitry Andric  def : Pat<(f64 (fpextend f32:$src)),
14300b57cec5SDimitry Andric            (COPY_TO_REGCLASS $src, VSFRC)>;
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
14330b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
14340b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
14350b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
14360b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
14370b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
14380b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
14390b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
14400b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
14410b57cec5SDimitry Andric            (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
14420b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
14430b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
14440b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
14450b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
14460b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
14470b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
14480b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
14490b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
14500b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
14510b57cec5SDimitry Andric            (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
14520b57cec5SDimitry Andric
14530b57cec5SDimitry Andric  // VSX Elementary Scalar FP arithmetic (SP)
14540b57cec5SDimitry Andric  let isCommutable = 1 in {
14550b57cec5SDimitry Andric    def XSADDSP : XX3Form<60, 0,
14560b57cec5SDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14570b57cec5SDimitry Andric                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
14580b57cec5SDimitry Andric                          [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
14590b57cec5SDimitry Andric    def XSMULSP : XX3Form<60, 16,
14600b57cec5SDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14610b57cec5SDimitry Andric                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
14620b57cec5SDimitry Andric                          [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
14630b57cec5SDimitry Andric  } // isCommutable
14640b57cec5SDimitry Andric  def XSSUBSP : XX3Form<60, 8,
14650b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14660b57cec5SDimitry Andric                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
14670b57cec5SDimitry Andric                        [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
14680b57cec5SDimitry Andric  def XSDIVSP : XX3Form<60, 24,
14690b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14700b57cec5SDimitry Andric                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
14710b57cec5SDimitry Andric                        [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
14720b57cec5SDimitry Andric  def XSRESP : XX2Form<60, 26,
14730b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
14740b57cec5SDimitry Andric                        "xsresp $XT, $XB", IIC_VecFP,
14750b57cec5SDimitry Andric                        [(set f32:$XT, (PPCfre f32:$XB))]>;
14760b57cec5SDimitry Andric  def XSRSP : XX2Form<60, 281,
14770b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vsfrc:$XB),
14780b57cec5SDimitry Andric                        "xsrsp $XT, $XB", IIC_VecFP, []>;
14790b57cec5SDimitry Andric  def XSSQRTSP : XX2Form<60, 11,
14800b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
14810b57cec5SDimitry Andric                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
14820b57cec5SDimitry Andric                        [(set f32:$XT, (fsqrt f32:$XB))]>;
14830b57cec5SDimitry Andric  def XSRSQRTESP : XX2Form<60, 10,
14840b57cec5SDimitry Andric                           (outs vssrc:$XT), (ins vssrc:$XB),
14850b57cec5SDimitry Andric                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
14860b57cec5SDimitry Andric                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andric  // FMA Instructions
14890b57cec5SDimitry Andric  let BaseName = "XSMADDASP" in {
14900b57cec5SDimitry Andric  let isCommutable = 1 in
14910b57cec5SDimitry Andric  def XSMADDASP : XX3Form<60, 1,
14920b57cec5SDimitry Andric                          (outs vssrc:$XT),
14930b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14940b57cec5SDimitry Andric                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
14950b57cec5SDimitry Andric                          [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
14960b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14970b57cec5SDimitry Andric                          AltVSXFMARel;
14980b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
14990b57cec5SDimitry Andric  def XSMADDMSP : XX3Form<60, 9,
15000b57cec5SDimitry Andric                          (outs vssrc:$XT),
15010b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15020b57cec5SDimitry Andric                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
15030b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15040b57cec5SDimitry Andric                          AltVSXFMARel;
15050b57cec5SDimitry Andric  }
15060b57cec5SDimitry Andric
15070b57cec5SDimitry Andric  let BaseName = "XSMSUBASP" in {
15080b57cec5SDimitry Andric  let isCommutable = 1 in
15090b57cec5SDimitry Andric  def XSMSUBASP : XX3Form<60, 17,
15100b57cec5SDimitry Andric                          (outs vssrc:$XT),
15110b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15120b57cec5SDimitry Andric                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
15130b57cec5SDimitry Andric                          [(set f32:$XT, (fma f32:$XA, f32:$XB,
15140b57cec5SDimitry Andric                                              (fneg f32:$XTi)))]>,
15150b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15160b57cec5SDimitry Andric                          AltVSXFMARel;
15170b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
15180b57cec5SDimitry Andric  def XSMSUBMSP : XX3Form<60, 25,
15190b57cec5SDimitry Andric                          (outs vssrc:$XT),
15200b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15210b57cec5SDimitry Andric                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
15220b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15230b57cec5SDimitry Andric                          AltVSXFMARel;
15240b57cec5SDimitry Andric  }
15250b57cec5SDimitry Andric
15260b57cec5SDimitry Andric  let BaseName = "XSNMADDASP" in {
15270b57cec5SDimitry Andric  let isCommutable = 1 in
15280b57cec5SDimitry Andric  def XSNMADDASP : XX3Form<60, 129,
15290b57cec5SDimitry Andric                          (outs vssrc:$XT),
15300b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15310b57cec5SDimitry Andric                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
15320b57cec5SDimitry Andric                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
15330b57cec5SDimitry Andric                                                    f32:$XTi)))]>,
15340b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15350b57cec5SDimitry Andric                          AltVSXFMARel;
15360b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
15370b57cec5SDimitry Andric  def XSNMADDMSP : XX3Form<60, 137,
15380b57cec5SDimitry Andric                          (outs vssrc:$XT),
15390b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15400b57cec5SDimitry Andric                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
15410b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15420b57cec5SDimitry Andric                          AltVSXFMARel;
15430b57cec5SDimitry Andric  }
15440b57cec5SDimitry Andric
15450b57cec5SDimitry Andric  let BaseName = "XSNMSUBASP" in {
15460b57cec5SDimitry Andric  let isCommutable = 1 in
15470b57cec5SDimitry Andric  def XSNMSUBASP : XX3Form<60, 145,
15480b57cec5SDimitry Andric                          (outs vssrc:$XT),
15490b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15500b57cec5SDimitry Andric                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
15510b57cec5SDimitry Andric                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
15520b57cec5SDimitry Andric                                                    (fneg f32:$XTi))))]>,
15530b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15540b57cec5SDimitry Andric                          AltVSXFMARel;
15550b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
15560b57cec5SDimitry Andric  def XSNMSUBMSP : XX3Form<60, 153,
15570b57cec5SDimitry Andric                          (outs vssrc:$XT),
15580b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15590b57cec5SDimitry Andric                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
15600b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15610b57cec5SDimitry Andric                          AltVSXFMARel;
15620b57cec5SDimitry Andric  }
15630b57cec5SDimitry Andric
15648bcb0991SDimitry Andric  // Additional xsnmsubasp patterns: -a*b + c == -(a*b - c)
15658bcb0991SDimitry Andric  def : Pat<(fma (fneg f32:$A), f32:$B, f32:$C),
15668bcb0991SDimitry Andric            (XSNMSUBASP $C, $A, $B)>;
15678bcb0991SDimitry Andric  def : Pat<(fma f32:$A, (fneg f32:$B), f32:$C),
15688bcb0991SDimitry Andric            (XSNMSUBASP $C, $A, $B)>;
15698bcb0991SDimitry Andric
15700b57cec5SDimitry Andric  // Single Precision Conversions (FP <-> INT)
15710b57cec5SDimitry Andric  def XSCVSXDSP : XX2Form<60, 312,
15720b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
15730b57cec5SDimitry Andric                      "xscvsxdsp $XT, $XB", IIC_VecFP,
15740b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
15750b57cec5SDimitry Andric  def XSCVUXDSP : XX2Form<60, 296,
15760b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
15770b57cec5SDimitry Andric                      "xscvuxdsp $XT, $XB", IIC_VecFP,
15780b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
15790b57cec5SDimitry Andric
15800b57cec5SDimitry Andric  // Conversions between vector and scalar single precision
15810b57cec5SDimitry Andric  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
15820b57cec5SDimitry Andric                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
15830b57cec5SDimitry Andric  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
15840b57cec5SDimitry Andric                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
15850b57cec5SDimitry Andric
15860b57cec5SDimitry Andric  let Predicates = [IsLittleEndian] in {
15870b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0SS1,
15880b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
15890b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1SS1,
15900b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS
15910b57cec5SDimitry Andric                              (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
15920b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0US1,
15930b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
15940b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1US1,
15950b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS
15960b57cec5SDimitry Andric                              (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
15970b57cec5SDimitry Andric  }
15980b57cec5SDimitry Andric
15990b57cec5SDimitry Andric  let Predicates = [IsBigEndian] in {
16000b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0SS1,
16010b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
16020b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1SS1,
16030b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
16040b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0US1,
16050b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
16060b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1US1,
16070b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
16080b57cec5SDimitry Andric  }
16090b57cec5SDimitry Andric
16100b57cec5SDimitry Andric  // Instructions for converting float to i64 feeding a store.
16110b57cec5SDimitry Andric  let Predicates = [NoP9Vector] in {
16120b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
16130b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
16140b57cec5SDimitry Andric            (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
16150b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
16160b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
16170b57cec5SDimitry Andric            (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
16180b57cec5SDimitry Andric  }
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andric  // Instructions for converting float to i32 feeding a store.
16210b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
16220b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
16230b57cec5SDimitry Andric            (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
16240b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
16250b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
16260b57cec5SDimitry Andric            (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
16270b57cec5SDimitry Andric
16280b57cec5SDimitry Andric  def : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
16290b57cec5SDimitry Andric            (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
16300b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
16310b57cec5SDimitry Andric  def : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
16320b57cec5SDimitry Andric            (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
16330b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
16340b57cec5SDimitry Andric  def : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
16350b57cec5SDimitry Andric            (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
16360b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
16370b57cec5SDimitry Andric  def : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
16380b57cec5SDimitry Andric            (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
16390b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
16400b57cec5SDimitry Andric} // AddedComplexity = 400
16410b57cec5SDimitry Andric} // HasP8Vector
16420b57cec5SDimitry Andric
16430b57cec5SDimitry Andriclet AddedComplexity = 400 in {
16440b57cec5SDimitry Andriclet Predicates = [HasDirectMove] in {
16450b57cec5SDimitry Andric  // VSX direct move instructions
16460b57cec5SDimitry Andric  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
16470b57cec5SDimitry Andric                              "mfvsrd $rA, $XT", IIC_VecGeneral,
16480b57cec5SDimitry Andric                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
16490b57cec5SDimitry Andric      Requires<[In64BitMode]>;
16500b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
16510b57cec5SDimitry Andric  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
16520b57cec5SDimitry Andric                             "mfvsrd $rA, $XT", IIC_VecGeneral,
16530b57cec5SDimitry Andric                             []>,
16540b57cec5SDimitry Andric      Requires<[In64BitMode]>;
16550b57cec5SDimitry Andric  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
16560b57cec5SDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
16570b57cec5SDimitry Andric                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
16588bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16598bcb0991SDimitry Andric  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
16608bcb0991SDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
16618bcb0991SDimitry Andric                               []>;
16620b57cec5SDimitry Andric  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
16630b57cec5SDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
16640b57cec5SDimitry Andric                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
16650b57cec5SDimitry Andric      Requires<[In64BitMode]>;
16668bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16678bcb0991SDimitry Andric  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
16688bcb0991SDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
16698bcb0991SDimitry Andric                              []>,
16708bcb0991SDimitry Andric      Requires<[In64BitMode]>;
16710b57cec5SDimitry Andric  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
16720b57cec5SDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
16730b57cec5SDimitry Andric                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
16748bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16758bcb0991SDimitry Andric  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
16768bcb0991SDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
16778bcb0991SDimitry Andric                               []>;
16780b57cec5SDimitry Andric  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
16790b57cec5SDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
16800b57cec5SDimitry Andric                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
16818bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16828bcb0991SDimitry Andric  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
16838bcb0991SDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
16848bcb0991SDimitry Andric                               []>;
16850b57cec5SDimitry Andric} // HasDirectMove
16860b57cec5SDimitry Andric
16870b57cec5SDimitry Andriclet Predicates = [IsISA3_0, HasDirectMove] in {
16880b57cec5SDimitry Andric  def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
16890b57cec5SDimitry Andric                              "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
16900b57cec5SDimitry Andric
16910b57cec5SDimitry Andric  def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
16920b57cec5SDimitry Andric                       "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
16930b57cec5SDimitry Andric                       []>, Requires<[In64BitMode]>;
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andric  def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
16960b57cec5SDimitry Andric                              "mfvsrld $rA, $XT", IIC_VecGeneral,
16970b57cec5SDimitry Andric                              []>, Requires<[In64BitMode]>;
16980b57cec5SDimitry Andric
16990b57cec5SDimitry Andric} // IsISA3_0, HasDirectMove
17000b57cec5SDimitry Andric} // AddedComplexity = 400
17010b57cec5SDimitry Andric
17020b57cec5SDimitry Andric// We want to parse this from asm, but we don't want to emit this as it would
17030b57cec5SDimitry Andric// be emitted with a VSX reg. So leave Emit = 0 here.
17040b57cec5SDimitry Andricdef : InstAlias<"mfvrd $rA, $XT",
17050b57cec5SDimitry Andric                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
17060b57cec5SDimitry Andricdef : InstAlias<"mffprd $rA, $src",
17070b57cec5SDimitry Andric                (MFVSRD g8rc:$rA, f8rc:$src)>;
17088bcb0991SDimitry Andricdef : InstAlias<"mtvrd $XT, $rA",
17098bcb0991SDimitry Andric                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
17108bcb0991SDimitry Andricdef : InstAlias<"mtfprd $dst, $rA",
17118bcb0991SDimitry Andric                (MTVSRD f8rc:$dst, g8rc:$rA)>;
17128bcb0991SDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT",
17138bcb0991SDimitry Andric                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
17148bcb0991SDimitry Andricdef : InstAlias<"mffprwz $rA, $src",
17158bcb0991SDimitry Andric                (MFVSRWZ gprc:$rA, f8rc:$src)>;
17168bcb0991SDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA",
17178bcb0991SDimitry Andric                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
17188bcb0991SDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA",
17198bcb0991SDimitry Andric                (MTVSRWA f8rc:$dst, gprc:$rA)>;
17208bcb0991SDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA",
17218bcb0991SDimitry Andric                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
17228bcb0991SDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA",
17238bcb0991SDimitry Andric                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
17240b57cec5SDimitry Andric
17250b57cec5SDimitry Andric/*  Direct moves of various widths from GPR's into VSR's. Each move lines
17260b57cec5SDimitry Andric    the value up into element 0 (both BE and LE). Namely, entities smaller than
17270b57cec5SDimitry Andric    a doubleword are shifted left and moved for BE. For LE, they're moved, then
17280b57cec5SDimitry Andric    swapped to go into the least significant element of the VSR.
17290b57cec5SDimitry Andric*/
17300b57cec5SDimitry Andricdef MovesToVSR {
17310b57cec5SDimitry Andric  dag BE_BYTE_0 =
17320b57cec5SDimitry Andric    (MTVSRD
17330b57cec5SDimitry Andric      (RLDICR
17340b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
17350b57cec5SDimitry Andric  dag BE_HALF_0 =
17360b57cec5SDimitry Andric    (MTVSRD
17370b57cec5SDimitry Andric      (RLDICR
17380b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
17390b57cec5SDimitry Andric  dag BE_WORD_0 =
17400b57cec5SDimitry Andric    (MTVSRD
17410b57cec5SDimitry Andric      (RLDICR
17420b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
17430b57cec5SDimitry Andric  dag BE_DWORD_0 = (MTVSRD $A);
17440b57cec5SDimitry Andric
17450b57cec5SDimitry Andric  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
17460b57cec5SDimitry Andric  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
17470b57cec5SDimitry Andric                                        LE_MTVSRW, sub_64));
17480b57cec5SDimitry Andric  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
17490b57cec5SDimitry Andric  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
17500b57cec5SDimitry Andric                                         BE_DWORD_0, sub_64));
17510b57cec5SDimitry Andric  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
17520b57cec5SDimitry Andric}
17530b57cec5SDimitry Andric
17540b57cec5SDimitry Andric/*  Patterns for extracting elements out of vectors. Integer elements are
17550b57cec5SDimitry Andric    extracted using direct move operations. Patterns for extracting elements
17560b57cec5SDimitry Andric    whose indices are not available at compile time are also provided with
17570b57cec5SDimitry Andric    various _VARIABLE_ patterns.
17580b57cec5SDimitry Andric    The numbering for the DAG's is for LE, but when used on BE, the correct
17590b57cec5SDimitry Andric    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
17600b57cec5SDimitry Andric*/
17610b57cec5SDimitry Andricdef VectorExtractions {
17620b57cec5SDimitry Andric  // Doubleword extraction
17630b57cec5SDimitry Andric  dag LE_DWORD_0 =
17640b57cec5SDimitry Andric    (MFVSRD
17650b57cec5SDimitry Andric      (EXTRACT_SUBREG
17660b57cec5SDimitry Andric        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
17670b57cec5SDimitry Andric                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
17680b57cec5SDimitry Andric  dag LE_DWORD_1 = (MFVSRD
17690b57cec5SDimitry Andric                     (EXTRACT_SUBREG
17700b57cec5SDimitry Andric                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
17710b57cec5SDimitry Andric
17720b57cec5SDimitry Andric  // Word extraction
17730b57cec5SDimitry Andric  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
17740b57cec5SDimitry Andric  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
17750b57cec5SDimitry Andric  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
17760b57cec5SDimitry Andric                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
17770b57cec5SDimitry Andric  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
17780b57cec5SDimitry Andric
17790b57cec5SDimitry Andric  // Halfword extraction
17800b57cec5SDimitry Andric  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
17810b57cec5SDimitry Andric  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
17820b57cec5SDimitry Andric  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
17830b57cec5SDimitry Andric  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
17840b57cec5SDimitry Andric  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
17850b57cec5SDimitry Andric  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
17860b57cec5SDimitry Andric  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
17870b57cec5SDimitry Andric  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
17880b57cec5SDimitry Andric
17890b57cec5SDimitry Andric  // Byte extraction
17900b57cec5SDimitry Andric  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
17910b57cec5SDimitry Andric  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
17920b57cec5SDimitry Andric  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
17930b57cec5SDimitry Andric  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
17940b57cec5SDimitry Andric  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
17950b57cec5SDimitry Andric  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
17960b57cec5SDimitry Andric  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
17970b57cec5SDimitry Andric  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
17980b57cec5SDimitry Andric  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
17990b57cec5SDimitry Andric  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
18000b57cec5SDimitry Andric  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
18010b57cec5SDimitry Andric  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
18020b57cec5SDimitry Andric  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
18030b57cec5SDimitry Andric  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
18040b57cec5SDimitry Andric  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
18050b57cec5SDimitry Andric  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric  /* Variable element number (BE and LE patterns must be specified separately)
18080b57cec5SDimitry Andric     This is a rather involved process.
18090b57cec5SDimitry Andric
18100b57cec5SDimitry Andric     Conceptually, this is how the move is accomplished:
18110b57cec5SDimitry Andric     1. Identify which doubleword contains the element
18120b57cec5SDimitry Andric     2. Shift in the VMX register so that the correct doubleword is correctly
18130b57cec5SDimitry Andric        lined up for the MFVSRD
18140b57cec5SDimitry Andric     3. Perform the move so that the element (along with some extra stuff)
18150b57cec5SDimitry Andric        is in the GPR
18160b57cec5SDimitry Andric     4. Right shift within the GPR so that the element is right-justified
18170b57cec5SDimitry Andric
18180b57cec5SDimitry Andric     Of course, the index is an element number which has a different meaning
18190b57cec5SDimitry Andric     on LE/BE so the patterns have to be specified separately.
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andric     Note: The final result will be the element right-justified with high
18220b57cec5SDimitry Andric           order bits being arbitrarily defined (namely, whatever was in the
18230b57cec5SDimitry Andric           vector register to the left of the value originally).
18240b57cec5SDimitry Andric  */
18250b57cec5SDimitry Andric
18260b57cec5SDimitry Andric  /*  LE variable byte
18270b57cec5SDimitry Andric      Number 1. above:
18280b57cec5SDimitry Andric      - For elements 0-7, we shift left by 8 bytes since they're on the right
18290b57cec5SDimitry Andric      - For elements 8-15, we need not shift (shift left by zero bytes)
18300b57cec5SDimitry Andric      This is accomplished by inverting the bits of the index and AND-ing
18310b57cec5SDimitry Andric      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
18320b57cec5SDimitry Andric  */
18330b57cec5SDimitry Andric  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
18340b57cec5SDimitry Andric
18350b57cec5SDimitry Andric  //  Number 2. above:
18360b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
18370b57cec5SDimitry Andric  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
18380b57cec5SDimitry Andric
18390b57cec5SDimitry Andric  //  Number 3. above:
18400b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
18410b57cec5SDimitry Andric  dag LE_MV_VBYTE = (MFVSRD
18420b57cec5SDimitry Andric                      (EXTRACT_SUBREG
18430b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
18440b57cec5SDimitry Andric                        sub_64));
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andric  /*  Number 4. above:
18470b57cec5SDimitry Andric      - Truncate the element number to the range 0-7 (8-15 are symmetrical
18480b57cec5SDimitry Andric        and out of range values are truncated accordingly)
18490b57cec5SDimitry Andric      - Multiply by 8 as we need to shift right by the number of bits, not bytes
18500b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
18510b57cec5SDimitry Andric  */
18520b57cec5SDimitry Andric  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
18530b57cec5SDimitry Andric                                       sub_32);
18540b57cec5SDimitry Andric  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
18550b57cec5SDimitry Andric                                         sub_32);
18560b57cec5SDimitry Andric
18570b57cec5SDimitry Andric  /*  LE variable halfword
18580b57cec5SDimitry Andric      Number 1. above:
18590b57cec5SDimitry Andric      - For elements 0-3, we shift left by 8 since they're on the right
18600b57cec5SDimitry Andric      - For elements 4-7, we need not shift (shift left by zero bytes)
18610b57cec5SDimitry Andric      Similarly to the byte pattern, we invert the bits of the index, but we
18620b57cec5SDimitry Andric      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
18630b57cec5SDimitry Andric      Of course, the shift is still by 8 bytes, so we must multiply by 2.
18640b57cec5SDimitry Andric  */
18650b57cec5SDimitry Andric  dag LE_VHALF_PERM_VEC =
18660b57cec5SDimitry Andric    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
18670b57cec5SDimitry Andric
18680b57cec5SDimitry Andric  //  Number 2. above:
18690b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
18700b57cec5SDimitry Andric  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
18710b57cec5SDimitry Andric
18720b57cec5SDimitry Andric  //  Number 3. above:
18730b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
18740b57cec5SDimitry Andric  dag LE_MV_VHALF = (MFVSRD
18750b57cec5SDimitry Andric                      (EXTRACT_SUBREG
18760b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
18770b57cec5SDimitry Andric                        sub_64));
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andric  /*  Number 4. above:
18800b57cec5SDimitry Andric      - Truncate the element number to the range 0-3 (4-7 are symmetrical
18810b57cec5SDimitry Andric        and out of range values are truncated accordingly)
18820b57cec5SDimitry Andric      - Multiply by 16 as we need to shift right by the number of bits
18830b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
18840b57cec5SDimitry Andric  */
18850b57cec5SDimitry Andric  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
18860b57cec5SDimitry Andric                                       sub_32);
18870b57cec5SDimitry Andric  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
18880b57cec5SDimitry Andric                                         sub_32);
18890b57cec5SDimitry Andric
18900b57cec5SDimitry Andric  /*  LE variable word
18910b57cec5SDimitry Andric      Number 1. above:
18920b57cec5SDimitry Andric      - For elements 0-1, we shift left by 8 since they're on the right
18930b57cec5SDimitry Andric      - For elements 2-3, we need not shift
18940b57cec5SDimitry Andric  */
18950b57cec5SDimitry Andric  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
18960b57cec5SDimitry Andric                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
18970b57cec5SDimitry Andric
18980b57cec5SDimitry Andric  //  Number 2. above:
18990b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
19000b57cec5SDimitry Andric  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
19010b57cec5SDimitry Andric
19020b57cec5SDimitry Andric  //  Number 3. above:
19030b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
19040b57cec5SDimitry Andric  dag LE_MV_VWORD = (MFVSRD
19050b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19060b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
19070b57cec5SDimitry Andric                        sub_64));
19080b57cec5SDimitry Andric
19090b57cec5SDimitry Andric  /*  Number 4. above:
19100b57cec5SDimitry Andric      - Truncate the element number to the range 0-1 (2-3 are symmetrical
19110b57cec5SDimitry Andric        and out of range values are truncated accordingly)
19120b57cec5SDimitry Andric      - Multiply by 32 as we need to shift right by the number of bits
19130b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
19140b57cec5SDimitry Andric  */
19150b57cec5SDimitry Andric  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
19160b57cec5SDimitry Andric                                       sub_32);
19170b57cec5SDimitry Andric  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
19180b57cec5SDimitry Andric                                         sub_32);
19190b57cec5SDimitry Andric
19200b57cec5SDimitry Andric  /*  LE variable doubleword
19210b57cec5SDimitry Andric      Number 1. above:
19220b57cec5SDimitry Andric      - For element 0, we shift left by 8 since it's on the right
19230b57cec5SDimitry Andric      - For element 1, we need not shift
19240b57cec5SDimitry Andric  */
19250b57cec5SDimitry Andric  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
19260b57cec5SDimitry Andric                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
19270b57cec5SDimitry Andric
19280b57cec5SDimitry Andric  //  Number 2. above:
19290b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
19300b57cec5SDimitry Andric  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
19310b57cec5SDimitry Andric
19320b57cec5SDimitry Andric  // Number 3. above:
19330b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
19340b57cec5SDimitry Andric  //  - Number 4. is not needed for the doubleword as the value is 64-bits
19350b57cec5SDimitry Andric  dag LE_VARIABLE_DWORD =
19360b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
19370b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
19380b57cec5SDimitry Andric                  sub_64));
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric  /*  LE variable float
19410b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
19420b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
19430b57cec5SDimitry Andric  */
19440b57cec5SDimitry Andric  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
19450b57cec5SDimitry Andric                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
19460b57cec5SDimitry Andric  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
19470b57cec5SDimitry Andric  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
19480b57cec5SDimitry Andric
19490b57cec5SDimitry Andric  /*  LE variable double
19500b57cec5SDimitry Andric      Same as the LE doubleword except there is no move.
19510b57cec5SDimitry Andric  */
19520b57cec5SDimitry Andric  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
19530b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
19540b57cec5SDimitry Andric                                         LE_VDWORD_PERM_VEC));
19550b57cec5SDimitry Andric  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
19560b57cec5SDimitry Andric
19570b57cec5SDimitry Andric  /*  BE variable byte
19580b57cec5SDimitry Andric      The algorithm here is the same as the LE variable byte except:
19590b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
19600b57cec5SDimitry Andric        we simply AND the element number with 0x8
19610b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
19620b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-7
19630b57cec5SDimitry Andric  */
1964*480093f4SDimitry Andric  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDI8_rec $Idx, 8)));
19650b57cec5SDimitry Andric  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
19660b57cec5SDimitry Andric  dag BE_MV_VBYTE = (MFVSRD
19670b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19680b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
19690b57cec5SDimitry Andric                        sub_64));
19700b57cec5SDimitry Andric  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
19710b57cec5SDimitry Andric                                       sub_32);
19720b57cec5SDimitry Andric  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
19730b57cec5SDimitry Andric                                         sub_32);
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andric  /*  BE variable halfword
19760b57cec5SDimitry Andric      The algorithm here is the same as the LE variable halfword except:
19770b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
19780b57cec5SDimitry Andric        we simply AND the element number with 0x4 and multiply by 2
19790b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
19800b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-3
19810b57cec5SDimitry Andric  */
19820b57cec5SDimitry Andric  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
1983*480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 4), 1, 62)));
19840b57cec5SDimitry Andric  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
19850b57cec5SDimitry Andric  dag BE_MV_VHALF = (MFVSRD
19860b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19870b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
19880b57cec5SDimitry Andric                        sub_64));
19890b57cec5SDimitry Andric  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
19900b57cec5SDimitry Andric                                       sub_32);
19910b57cec5SDimitry Andric  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
19920b57cec5SDimitry Andric                                         sub_32);
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andric  /*  BE variable word
19950b57cec5SDimitry Andric      The algorithm is the same as the LE variable word except:
19960b57cec5SDimitry Andric      - The shift in the VMX register happens for opposite element numbers
19970b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
19980b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-1
19990b57cec5SDimitry Andric  */
20000b57cec5SDimitry Andric  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2001*480093f4SDimitry Andric                                       (RLDICR (ANDI8_rec $Idx, 2), 2, 61)));
20020b57cec5SDimitry Andric  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
20030b57cec5SDimitry Andric  dag BE_MV_VWORD = (MFVSRD
20040b57cec5SDimitry Andric                      (EXTRACT_SUBREG
20050b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
20060b57cec5SDimitry Andric                        sub_64));
20070b57cec5SDimitry Andric  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
20080b57cec5SDimitry Andric                                       sub_32);
20090b57cec5SDimitry Andric  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
20100b57cec5SDimitry Andric                                         sub_32);
20110b57cec5SDimitry Andric
20120b57cec5SDimitry Andric  /*  BE variable doubleword
20130b57cec5SDimitry Andric      Same as the LE doubleword except we shift in the VMX register for opposite
20140b57cec5SDimitry Andric      element indices.
20150b57cec5SDimitry Andric  */
20160b57cec5SDimitry Andric  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
2017*480093f4SDimitry Andric                                        (RLDICR (ANDI8_rec $Idx, 1), 3, 60)));
20180b57cec5SDimitry Andric  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
20190b57cec5SDimitry Andric  dag BE_VARIABLE_DWORD =
20200b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
20210b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
20220b57cec5SDimitry Andric                  sub_64));
20230b57cec5SDimitry Andric
20240b57cec5SDimitry Andric  /*  BE variable float
20250b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
20260b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
20270b57cec5SDimitry Andric  */
20280b57cec5SDimitry Andric  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
20290b57cec5SDimitry Andric  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
20300b57cec5SDimitry Andric  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
20310b57cec5SDimitry Andric
20320b57cec5SDimitry Andric  /* BE variable double
20330b57cec5SDimitry Andric      Same as the BE doubleword except there is no move.
20340b57cec5SDimitry Andric  */
20350b57cec5SDimitry Andric  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
20360b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
20370b57cec5SDimitry Andric                                         BE_VDWORD_PERM_VEC));
20380b57cec5SDimitry Andric  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
20390b57cec5SDimitry Andric}
20400b57cec5SDimitry Andric
20410b57cec5SDimitry Andricdef NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">;
20420b57cec5SDimitry Andriclet AddedComplexity = 400 in {
20430b57cec5SDimitry Andric// v4f32 scalar <-> vector conversions (BE)
20440b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasP8Vector] in {
20450b57cec5SDimitry Andric  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
20460b57cec5SDimitry Andric            (v4f32 (XSCVDPSPN $A))>;
20470b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
20480b57cec5SDimitry Andric            (f32 (XSCVSPDPN $S))>;
20490b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
20500b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
20510b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
20520b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
20530b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
20540b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
20550b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
20560b57cec5SDimitry Andric            (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
20570b57cec5SDimitry Andric} // IsBigEndian, HasP8Vector
20580b57cec5SDimitry Andric
20590b57cec5SDimitry Andric// Variable index vector_extract for v2f64 does not require P8Vector
20600b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasVSX] in
20610b57cec5SDimitry Andric  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
20620b57cec5SDimitry Andric            (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
20630b57cec5SDimitry Andric
20640b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasDirectMove] in {
20650b57cec5SDimitry Andric  // v16i8 scalar <-> vector conversions (BE)
20660b57cec5SDimitry Andric  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
20670b57cec5SDimitry Andric            (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
20680b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
20690b57cec5SDimitry Andric            (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
20700b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
20710b57cec5SDimitry Andric            (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
20720b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
20730b57cec5SDimitry Andric            (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
20740b57cec5SDimitry Andric
20750b57cec5SDimitry Andric  // v2i64 scalar <-> vector conversions (BE)
20760b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
20770b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
20780b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
20790b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
20800b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
20810b57cec5SDimitry Andric            (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
20820b57cec5SDimitry Andric} // IsBigEndian, HasDirectMove
20830b57cec5SDimitry Andric
20840b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in {
20850b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
20860b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_15)>;
20870b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
20880b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_14)>;
20890b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
20900b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_13)>;
20910b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
20920b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_12)>;
20930b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
20940b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_11)>;
20950b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
20960b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_10)>;
20970b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
20980b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_9)>;
20990b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
21000b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_8)>;
21010b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
21020b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_7)>;
21030b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
21040b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_6)>;
21050b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
21060b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_5)>;
21070b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
21080b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_4)>;
21090b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
21100b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_3)>;
21110b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
21120b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_2)>;
21130b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
21140b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_1)>;
21150b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
21160b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_0)>;
21170b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
21180b57cec5SDimitry Andric            (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
21190b57cec5SDimitry Andric
21200b57cec5SDimitry Andric  // v8i16 scalar <-> vector conversions (BE)
21210b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
21220b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_7)>;
21230b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
21240b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_6)>;
21250b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
21260b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_5)>;
21270b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
21280b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_4)>;
21290b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
21300b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_3)>;
21310b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
21320b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_2)>;
21330b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
21340b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_1)>;
21350b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
21360b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_0)>;
21370b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
21380b57cec5SDimitry Andric            (i32 VectorExtractions.BE_VARIABLE_HALF)>;
21390b57cec5SDimitry Andric
21400b57cec5SDimitry Andric  // v4i32 scalar <-> vector conversions (BE)
21410b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
21420b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_3)>;
21430b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
21440b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
21450b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
21460b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_1)>;
21470b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
21480b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_0)>;
21490b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
21500b57cec5SDimitry Andric            (i32 VectorExtractions.BE_VARIABLE_WORD)>;
21510b57cec5SDimitry Andric} // IsBigEndian, HasDirectMove, NoP9Altivec
21520b57cec5SDimitry Andric
21530b57cec5SDimitry Andric// v4f32 scalar <-> vector conversions (LE)
21540b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasP8Vector] in {
21550b57cec5SDimitry Andric  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
21560b57cec5SDimitry Andric            (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
21570b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
21580b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
21590b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
21600b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
21610b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
21620b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
21630b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
21640b57cec5SDimitry Andric            (f32 (XSCVSPDPN $S))>;
21650b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
21660b57cec5SDimitry Andric            (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
21670b57cec5SDimitry Andric} // IsLittleEndian, HasP8Vector
21680b57cec5SDimitry Andric
21690b57cec5SDimitry Andric// Variable index vector_extract for v2f64 does not require P8Vector
21700b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasVSX] in
21710b57cec5SDimitry Andric  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
21720b57cec5SDimitry Andric            (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
21730b57cec5SDimitry Andric
21740b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
21750b57cec5SDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
21760b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
21770b57cec5SDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
21780b57cec5SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
21790b57cec5SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
21800b57cec5SDimitry Andric
21810b57cec5SDimitry Andric// Variable index unsigned vector_extract on Power9
21820b57cec5SDimitry Andriclet Predicates = [HasP9Altivec, IsLittleEndian] in {
21830b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
21840b57cec5SDimitry Andric            (VEXTUBRX $Idx, $S)>;
21850b57cec5SDimitry Andric
21860b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
21870b57cec5SDimitry Andric            (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
21880b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
21890b57cec5SDimitry Andric            (VEXTUHRX (LI8 0), $S)>;
21900b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
21910b57cec5SDimitry Andric            (VEXTUHRX (LI8 2), $S)>;
21920b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
21930b57cec5SDimitry Andric            (VEXTUHRX (LI8 4), $S)>;
21940b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
21950b57cec5SDimitry Andric            (VEXTUHRX (LI8 6), $S)>;
21960b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
21970b57cec5SDimitry Andric            (VEXTUHRX (LI8 8), $S)>;
21980b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
21990b57cec5SDimitry Andric            (VEXTUHRX (LI8 10), $S)>;
22000b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
22010b57cec5SDimitry Andric            (VEXTUHRX (LI8 12), $S)>;
22020b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
22030b57cec5SDimitry Andric            (VEXTUHRX (LI8 14), $S)>;
22040b57cec5SDimitry Andric
22050b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
22060b57cec5SDimitry Andric            (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
22070b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
22080b57cec5SDimitry Andric            (VEXTUWRX (LI8 0), $S)>;
22090b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
22100b57cec5SDimitry Andric            (VEXTUWRX (LI8 4), $S)>;
22110b57cec5SDimitry Andric  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
22120b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
22130b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
22140b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
22150b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
22160b57cec5SDimitry Andric            (VEXTUWRX (LI8 12), $S)>;
22170b57cec5SDimitry Andric
22180b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
22190b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
22200b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
22210b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (LI8 0), $S))>;
22220b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
22230b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (LI8 4), $S))>;
22240b57cec5SDimitry Andric  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
22250b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
22260b57cec5SDimitry Andric            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
22270b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
22280b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
22290b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (LI8 12), $S))>;
22300b57cec5SDimitry Andric
22310b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
22320b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
22330b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
22340b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
22350b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
22360b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
22370b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
22380b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
22390b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
22400b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
22410b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
22420b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
22430b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
22440b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
22450b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
22460b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
22470b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
22480b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
22490b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
22500b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
22510b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
22520b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
22530b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
22540b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
22550b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
22560b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
22570b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
22580b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
22590b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
22600b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
22610b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
22620b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
22630b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
22640b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
22650b57cec5SDimitry Andric
22660b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
22670b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX
22680b57cec5SDimitry Andric	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
22690b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
22700b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
22710b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
22720b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
22730b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
22740b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
22750b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
22760b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
22770b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
22780b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
22790b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
22800b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
22810b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
22820b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
22830b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
22840b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
22850b57cec5SDimitry Andric
22860b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
22870b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX
22880b57cec5SDimitry Andric	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
22890b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
22900b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
22910b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
22920b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
22930b57cec5SDimitry Andric  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
22940b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
22950b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
22960b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
22970b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
22980b57cec5SDimitry Andric}
22990b57cec5SDimitry Andric
23000b57cec5SDimitry Andriclet Predicates = [HasP9Altivec, IsBigEndian] in {
23010b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
23020b57cec5SDimitry Andric            (VEXTUBLX $Idx, $S)>;
23030b57cec5SDimitry Andric
23040b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
23050b57cec5SDimitry Andric            (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
23060b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
23070b57cec5SDimitry Andric            (VEXTUHLX (LI8 0), $S)>;
23080b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
23090b57cec5SDimitry Andric            (VEXTUHLX (LI8 2), $S)>;
23100b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
23110b57cec5SDimitry Andric            (VEXTUHLX (LI8 4), $S)>;
23120b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
23130b57cec5SDimitry Andric            (VEXTUHLX (LI8 6), $S)>;
23140b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
23150b57cec5SDimitry Andric            (VEXTUHLX (LI8 8), $S)>;
23160b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
23170b57cec5SDimitry Andric            (VEXTUHLX (LI8 10), $S)>;
23180b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
23190b57cec5SDimitry Andric            (VEXTUHLX (LI8 12), $S)>;
23200b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
23210b57cec5SDimitry Andric            (VEXTUHLX (LI8 14), $S)>;
23220b57cec5SDimitry Andric
23230b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
23240b57cec5SDimitry Andric            (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
23250b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
23260b57cec5SDimitry Andric            (VEXTUWLX (LI8 0), $S)>;
23270b57cec5SDimitry Andric
23280b57cec5SDimitry Andric  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
23290b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
23300b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
23310b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
23320b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
23330b57cec5SDimitry Andric            (VEXTUWLX (LI8 8), $S)>;
23340b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
23350b57cec5SDimitry Andric            (VEXTUWLX (LI8 12), $S)>;
23360b57cec5SDimitry Andric
23370b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
23380b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
23390b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
23400b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (LI8 0), $S))>;
23410b57cec5SDimitry Andric  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
23420b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
23430b57cec5SDimitry Andric            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
23440b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
23450b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
23460b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (LI8 8), $S))>;
23470b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
23480b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (LI8 12), $S))>;
23490b57cec5SDimitry Andric
23500b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
23510b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
23520b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
23530b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
23540b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
23550b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
23560b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
23570b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
23580b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
23590b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
23600b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
23610b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
23620b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
23630b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
23640b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
23650b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
23660b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
23670b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
23680b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
23690b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
23700b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
23710b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
23720b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
23730b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
23740b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
23750b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
23760b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
23770b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
23780b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
23790b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
23800b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
23810b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
23820b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
23830b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
23840b57cec5SDimitry Andric
23850b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
23860b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX
23870b57cec5SDimitry Andric	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
23880b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
23890b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
23900b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
23910b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
23920b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
23930b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
23940b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
23950b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
23960b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
23970b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
23980b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
23990b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
24000b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
24010b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
24020b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
24030b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
24040b57cec5SDimitry Andric
24050b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
24060b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX
24070b57cec5SDimitry Andric	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
24080b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
24090b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
24100b57cec5SDimitry Andric  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
24110b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
24120b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
24130b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
24140b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
24150b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
24160b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
24170b57cec5SDimitry Andric}
24180b57cec5SDimitry Andric
24190b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasDirectMove] in {
24200b57cec5SDimitry Andric  // v16i8 scalar <-> vector conversions (LE)
24210b57cec5SDimitry Andric  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
24220b57cec5SDimitry Andric            (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
24230b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
24240b57cec5SDimitry Andric            (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
24250b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
24260b57cec5SDimitry Andric            (v4i32 MovesToVSR.LE_WORD_0)>;
24270b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
24280b57cec5SDimitry Andric            (v2i64 MovesToVSR.LE_DWORD_0)>;
24290b57cec5SDimitry Andric  // v2i64 scalar <-> vector conversions (LE)
24300b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
24310b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
24320b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
24330b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
24340b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
24350b57cec5SDimitry Andric            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
24360b57cec5SDimitry Andric} // IsLittleEndian, HasDirectMove
24370b57cec5SDimitry Andric
24380b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in {
24390b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
24400b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_0)>;
24410b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
24420b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_1)>;
24430b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
24440b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_2)>;
24450b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
24460b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_3)>;
24470b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
24480b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_4)>;
24490b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
24500b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_5)>;
24510b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
24520b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_6)>;
24530b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
24540b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_7)>;
24550b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
24560b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_8)>;
24570b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
24580b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_9)>;
24590b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
24600b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_10)>;
24610b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
24620b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_11)>;
24630b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
24640b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_12)>;
24650b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
24660b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_13)>;
24670b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
24680b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_14)>;
24690b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
24700b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_15)>;
24710b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
24720b57cec5SDimitry Andric            (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
24730b57cec5SDimitry Andric
24740b57cec5SDimitry Andric  // v8i16 scalar <-> vector conversions (LE)
24750b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
24760b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_0)>;
24770b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
24780b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_1)>;
24790b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
24800b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_2)>;
24810b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
24820b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_3)>;
24830b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
24840b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_4)>;
24850b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
24860b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_5)>;
24870b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
24880b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_6)>;
24890b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
24900b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_7)>;
24910b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
24920b57cec5SDimitry Andric            (i32 VectorExtractions.LE_VARIABLE_HALF)>;
24930b57cec5SDimitry Andric
24940b57cec5SDimitry Andric  // v4i32 scalar <-> vector conversions (LE)
24950b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
24960b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_0)>;
24970b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
24980b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_1)>;
24990b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
25000b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
25010b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
25020b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_3)>;
25030b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
25040b57cec5SDimitry Andric            (i32 VectorExtractions.LE_VARIABLE_WORD)>;
25050b57cec5SDimitry Andric} // IsLittleEndian, HasDirectMove, NoP9Altivec
25060b57cec5SDimitry Andric
25070b57cec5SDimitry Andriclet Predicates = [HasDirectMove, HasVSX] in {
25080b57cec5SDimitry Andric// bitconvert f32 -> i32
25090b57cec5SDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR)
25100b57cec5SDimitry Andricdef : Pat<(i32 (bitconvert f32:$S)),
25110b57cec5SDimitry Andric          (i32 (MFVSRWZ (EXTRACT_SUBREG
25120b57cec5SDimitry Andric                          (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
25130b57cec5SDimitry Andric                          sub_64)))>;
25140b57cec5SDimitry Andric// bitconvert i32 -> f32
25150b57cec5SDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single)
25160b57cec5SDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)),
25170b57cec5SDimitry Andric          (f32 (XSCVSPDPN
25180b57cec5SDimitry Andric                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
25190b57cec5SDimitry Andric
25200b57cec5SDimitry Andric// bitconvert f64 -> i64
25210b57cec5SDimitry Andric// (move to GPR, nothing else needed)
25220b57cec5SDimitry Andricdef : Pat<(i64 (bitconvert f64:$S)),
25230b57cec5SDimitry Andric          (i64 (MFVSRD $S))>;
25240b57cec5SDimitry Andric
25250b57cec5SDimitry Andric// bitconvert i64 -> f64
25260b57cec5SDimitry Andric// (move to FPR, nothing else needed)
25270b57cec5SDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)),
25280b57cec5SDimitry Andric          (f64 (MTVSRD $S))>;
2529*480093f4SDimitry Andric
2530*480093f4SDimitry Andric// Rounding to integer.
2531*480093f4SDimitry Andricdef : Pat<(i64 (lrint f64:$S)),
2532*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
2533*480093f4SDimitry Andricdef : Pat<(i64 (lrint f32:$S)),
2534*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
2535*480093f4SDimitry Andricdef : Pat<(i64 (llrint f64:$S)),
2536*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID $S)))>;
2537*480093f4SDimitry Andricdef : Pat<(i64 (llrint f32:$S)),
2538*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID (COPY_TO_REGCLASS $S, F8RC))))>;
2539*480093f4SDimitry Andricdef : Pat<(i64 (lround f64:$S)),
2540*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
2541*480093f4SDimitry Andricdef : Pat<(i64 (lround f32:$S)),
2542*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
2543*480093f4SDimitry Andricdef : Pat<(i64 (llround f64:$S)),
2544*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI $S))))>;
2545*480093f4SDimitry Andricdef : Pat<(i64 (llround f32:$S)),
2546*480093f4SDimitry Andric          (i64 (MFVSRD (FCTID (XSRDPI (COPY_TO_REGCLASS $S, VSFRC)))))>;
2547*480093f4SDimitry Andric}
2548*480093f4SDimitry Andric
2549*480093f4SDimitry Andriclet Predicates = [HasVSX] in {
2550*480093f4SDimitry Andric// Rounding for single precision.
2551*480093f4SDimitry Andricdef : Pat<(f32 (fround f32:$S)),
2552*480093f4SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPI
2553*480093f4SDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2554*480093f4SDimitry Andricdef : Pat<(f32 (fnearbyint f32:$S)),
2555*480093f4SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIC
2556*480093f4SDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2557*480093f4SDimitry Andricdef : Pat<(f32 (ffloor f32:$S)),
2558*480093f4SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIM
2559*480093f4SDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2560*480093f4SDimitry Andricdef : Pat<(f32 (fceil f32:$S)),
2561*480093f4SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIP
2562*480093f4SDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
2563*480093f4SDimitry Andricdef : Pat<(f32 (ftrunc f32:$S)),
2564*480093f4SDimitry Andric          (f32 (COPY_TO_REGCLASS (XSRDPIZ
2565*480093f4SDimitry Andric                                   (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>;
25660b57cec5SDimitry Andric}
25670b57cec5SDimitry Andric
25680b57cec5SDimitry Andric// Materialize a zero-vector of long long
25690b57cec5SDimitry Andricdef : Pat<(v2i64 immAllZerosV),
25700b57cec5SDimitry Andric          (v2i64 (XXLXORz))>;
25710b57cec5SDimitry Andric}
25720b57cec5SDimitry Andric
25730b57cec5SDimitry Andricdef AlignValues {
25740b57cec5SDimitry Andric  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
25750b57cec5SDimitry Andric  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
25760b57cec5SDimitry Andric}
25770b57cec5SDimitry Andric
25780b57cec5SDimitry Andric// The following VSX instructions were introduced in Power ISA 3.0
25790b57cec5SDimitry Andricdef HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
25800b57cec5SDimitry Andriclet AddedComplexity = 400, Predicates = [HasP9Vector] in {
25810b57cec5SDimitry Andric
25820b57cec5SDimitry Andric  // [PO VRT XO VRB XO /]
25830b57cec5SDimitry Andric  class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25840b57cec5SDimitry Andric                      list<dag> pattern>
25850b57cec5SDimitry Andric    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
25860b57cec5SDimitry Andric                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
25870b57cec5SDimitry Andric
25880b57cec5SDimitry Andric  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
25890b57cec5SDimitry Andric  class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25900b57cec5SDimitry Andric                         list<dag> pattern>
2591*480093f4SDimitry Andric    : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isRecordForm;
25920b57cec5SDimitry Andric
25930b57cec5SDimitry Andric  // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
25940b57cec5SDimitry Andric  // So we use different operand class for VRB
25950b57cec5SDimitry Andric  class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25960b57cec5SDimitry Andric                           RegisterOperand vbtype, list<dag> pattern>
25970b57cec5SDimitry Andric    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
25980b57cec5SDimitry Andric                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
25990b57cec5SDimitry Andric
26000b57cec5SDimitry Andric  // [PO VRT XO VRB XO /]
26010b57cec5SDimitry Andric  class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
26020b57cec5SDimitry Andric                      list<dag> pattern>
26030b57cec5SDimitry Andric    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
26040b57cec5SDimitry Andric                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
26050b57cec5SDimitry Andric
26060b57cec5SDimitry Andric  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
26070b57cec5SDimitry Andric  class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
26080b57cec5SDimitry Andric                         list<dag> pattern>
2609*480093f4SDimitry Andric    : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isRecordForm;
26100b57cec5SDimitry Andric
26110b57cec5SDimitry Andric  // [PO T XO B XO BX /]
26120b57cec5SDimitry Andric  class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
26130b57cec5SDimitry Andric                        list<dag> pattern>
26140b57cec5SDimitry Andric    : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
26150b57cec5SDimitry Andric                      !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
26160b57cec5SDimitry Andric
26170b57cec5SDimitry Andric  // [PO T XO B XO BX TX]
26180b57cec5SDimitry Andric  class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
26190b57cec5SDimitry Andric                        RegisterOperand vtype, list<dag> pattern>
26200b57cec5SDimitry Andric    : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
26210b57cec5SDimitry Andric                      !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
26220b57cec5SDimitry Andric
26230b57cec5SDimitry Andric  // [PO T A B XO AX BX TX], src and dest register use different operand class
26240b57cec5SDimitry Andric  class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
26250b57cec5SDimitry Andric                  RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
26260b57cec5SDimitry Andric                  InstrItinClass itin, list<dag> pattern>
26270b57cec5SDimitry Andric    : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
26280b57cec5SDimitry Andric              !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
26290b57cec5SDimitry Andric
26300b57cec5SDimitry Andric  // [PO VRT VRA VRB XO /]
26310b57cec5SDimitry Andric  class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
26320b57cec5SDimitry Andric                      list<dag> pattern>
26330b57cec5SDimitry Andric    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
26340b57cec5SDimitry Andric              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
26350b57cec5SDimitry Andric
26360b57cec5SDimitry Andric  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
26370b57cec5SDimitry Andric  class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
26380b57cec5SDimitry Andric                         list<dag> pattern>
2639*480093f4SDimitry Andric    : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isRecordForm;
26400b57cec5SDimitry Andric
26410b57cec5SDimitry Andric  // [PO VRT VRA VRB XO /]
26420b57cec5SDimitry Andric  class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
26430b57cec5SDimitry Andric                          list<dag> pattern>
26440b57cec5SDimitry Andric    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
26450b57cec5SDimitry Andric              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
26460b57cec5SDimitry Andric              RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
26470b57cec5SDimitry Andric
26480b57cec5SDimitry Andric  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
26490b57cec5SDimitry Andric  class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
26500b57cec5SDimitry Andric                          list<dag> pattern>
2651*480093f4SDimitry Andric    : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isRecordForm;
26520b57cec5SDimitry Andric
26530b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
26540b57cec5SDimitry Andric  // Quad-Precision Scalar Move Instructions:
26550b57cec5SDimitry Andric
26560b57cec5SDimitry Andric  // Copy Sign
26570b57cec5SDimitry Andric  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
26580b57cec5SDimitry Andric                                [(set f128:$vT,
26590b57cec5SDimitry Andric                                      (fcopysign f128:$vB, f128:$vA))]>;
26600b57cec5SDimitry Andric
26610b57cec5SDimitry Andric  // Absolute/Negative-Absolute/Negate
26620b57cec5SDimitry Andric  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
26630b57cec5SDimitry Andric                                [(set f128:$vT, (fabs f128:$vB))]>;
26640b57cec5SDimitry Andric  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
26650b57cec5SDimitry Andric                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
26660b57cec5SDimitry Andric  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
26670b57cec5SDimitry Andric                                [(set f128:$vT, (fneg f128:$vB))]>;
26680b57cec5SDimitry Andric
26690b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
26700b57cec5SDimitry Andric  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
26710b57cec5SDimitry Andric
26720b57cec5SDimitry Andric  // Add/Divide/Multiply/Subtract
26730b57cec5SDimitry Andric  let isCommutable = 1 in {
26740b57cec5SDimitry Andric  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
26750b57cec5SDimitry Andric                                   [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>;
26760b57cec5SDimitry Andric  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
26770b57cec5SDimitry Andric                                   [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>;
26780b57cec5SDimitry Andric  }
26790b57cec5SDimitry Andric  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
26800b57cec5SDimitry Andric                                   [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>;
26810b57cec5SDimitry Andric  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
26820b57cec5SDimitry Andric                                   [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>;
26830b57cec5SDimitry Andric  // Square-Root
26840b57cec5SDimitry Andric  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
26850b57cec5SDimitry Andric                                   [(set f128:$vT, (fsqrt f128:$vB))]>;
26860b57cec5SDimitry Andric  // (Negative) Multiply-{Add/Subtract}
26870b57cec5SDimitry Andric  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
26880b57cec5SDimitry Andric                                    [(set f128:$vT,
26890b57cec5SDimitry Andric                                          (fma f128:$vA, f128:$vB,
26900b57cec5SDimitry Andric                                               f128:$vTi))]>;
26910b57cec5SDimitry Andric  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
26920b57cec5SDimitry Andric                                       [(set f128:$vT,
26930b57cec5SDimitry Andric                                             (fma f128:$vA, f128:$vB,
26940b57cec5SDimitry Andric                                                  (fneg f128:$vTi)))]>;
26950b57cec5SDimitry Andric  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
26960b57cec5SDimitry Andric                                     [(set f128:$vT,
26970b57cec5SDimitry Andric                                           (fneg (fma f128:$vA, f128:$vB,
26980b57cec5SDimitry Andric                                                      f128:$vTi)))]>;
26990b57cec5SDimitry Andric  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
27000b57cec5SDimitry Andric                                     [(set f128:$vT,
27010b57cec5SDimitry Andric                                           (fneg (fma f128:$vA, f128:$vB,
27020b57cec5SDimitry Andric                                                      (fneg f128:$vTi))))]>;
27030b57cec5SDimitry Andric
27040b57cec5SDimitry Andric  let isCommutable = 1 in {
27050b57cec5SDimitry Andric  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
27060b57cec5SDimitry Andric                                  [(set f128:$vT,
27070b57cec5SDimitry Andric                                  (int_ppc_addf128_round_to_odd
27080b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
27090b57cec5SDimitry Andric  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
27100b57cec5SDimitry Andric                                  [(set f128:$vT,
27110b57cec5SDimitry Andric                                  (int_ppc_mulf128_round_to_odd
27120b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
27130b57cec5SDimitry Andric  }
27140b57cec5SDimitry Andric  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
27150b57cec5SDimitry Andric                                  [(set f128:$vT,
27160b57cec5SDimitry Andric                                  (int_ppc_subf128_round_to_odd
27170b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
27180b57cec5SDimitry Andric  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
27190b57cec5SDimitry Andric                                  [(set f128:$vT,
27200b57cec5SDimitry Andric                                  (int_ppc_divf128_round_to_odd
27210b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
27220b57cec5SDimitry Andric  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
27230b57cec5SDimitry Andric                                  [(set f128:$vT,
27240b57cec5SDimitry Andric                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
27250b57cec5SDimitry Andric
27260b57cec5SDimitry Andric
27270b57cec5SDimitry Andric  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
27280b57cec5SDimitry Andric                                      [(set f128:$vT,
27290b57cec5SDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
27300b57cec5SDimitry Andric                                      f128:$vA,f128:$vB,f128:$vTi))]>;
27310b57cec5SDimitry Andric
27320b57cec5SDimitry Andric  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
27330b57cec5SDimitry Andric                                      [(set f128:$vT,
27340b57cec5SDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
27350b57cec5SDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
27360b57cec5SDimitry Andric  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
27370b57cec5SDimitry Andric                                      [(set f128:$vT,
27380b57cec5SDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
27390b57cec5SDimitry Andric                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
27400b57cec5SDimitry Andric  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
27410b57cec5SDimitry Andric                                      [(set f128:$vT,
27420b57cec5SDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
27430b57cec5SDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
27440b57cec5SDimitry Andric
27458bcb0991SDimitry Andric  // Additional fnmsub patterns: -a*b + c == -(a*b - c)
27468bcb0991SDimitry Andric  def : Pat<(fma (fneg f128:$A), f128:$B, f128:$C), (XSNMSUBQP $C, $A, $B)>;
27478bcb0991SDimitry Andric  def : Pat<(fma f128:$A, (fneg f128:$B), f128:$C), (XSNMSUBQP $C, $A, $B)>;
27480b57cec5SDimitry Andric
27490b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
27500b57cec5SDimitry Andric  // Quad/Double-Precision Compare Instructions:
27510b57cec5SDimitry Andric
27520b57cec5SDimitry Andric  // [PO BF // VRA VRB XO /]
27530b57cec5SDimitry Andric  class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
27540b57cec5SDimitry Andric                      list<dag> pattern>
27550b57cec5SDimitry Andric    : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
27560b57cec5SDimitry Andric               !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
27570b57cec5SDimitry Andric    let Pattern = pattern;
27580b57cec5SDimitry Andric  }
27590b57cec5SDimitry Andric
27600b57cec5SDimitry Andric  // QP Compare Ordered/Unordered
27610b57cec5SDimitry Andric  def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
27620b57cec5SDimitry Andric  def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
27630b57cec5SDimitry Andric
27640b57cec5SDimitry Andric  // DP/QP Compare Exponents
27650b57cec5SDimitry Andric  def XSCMPEXPDP : XX3Form_1<60, 59,
27660b57cec5SDimitry Andric                             (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
27670b57cec5SDimitry Andric                             "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
27680b57cec5SDimitry Andric  def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
27690b57cec5SDimitry Andric
27700b57cec5SDimitry Andric  // DP Compare ==, >=, >, !=
27710b57cec5SDimitry Andric  // Use vsrc for XT, because the entire register of XT is set.
27720b57cec5SDimitry Andric  // XT.dword[1] = 0x0000_0000_0000_0000
27730b57cec5SDimitry Andric  def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
27740b57cec5SDimitry Andric                                  IIC_FPCompare, []>;
27750b57cec5SDimitry Andric  def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
27760b57cec5SDimitry Andric                                  IIC_FPCompare, []>;
27770b57cec5SDimitry Andric  def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
27780b57cec5SDimitry Andric                                  IIC_FPCompare, []>;
27790b57cec5SDimitry Andric
27800b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
27810b57cec5SDimitry Andric  // Quad-Precision Floating-Point Conversion Instructions:
27820b57cec5SDimitry Andric
27830b57cec5SDimitry Andric  // Convert DP -> QP
27840b57cec5SDimitry Andric  def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
27850b57cec5SDimitry Andric                                     [(set f128:$vT, (fpextend f64:$vB))]>;
27860b57cec5SDimitry Andric
27870b57cec5SDimitry Andric  // Round & Convert QP -> DP (dword[1] is set to zero)
27880b57cec5SDimitry Andric  def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
27890b57cec5SDimitry Andric  def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
27900b57cec5SDimitry Andric                                        [(set f64:$vT,
27910b57cec5SDimitry Andric                                        (int_ppc_truncf128_round_to_odd
27920b57cec5SDimitry Andric                                        f128:$vB))]>;
27930b57cec5SDimitry Andric
27940b57cec5SDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
27950b57cec5SDimitry Andric  def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
27960b57cec5SDimitry Andric  def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
27970b57cec5SDimitry Andric  def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
27980b57cec5SDimitry Andric  def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
27990b57cec5SDimitry Andric
28000b57cec5SDimitry Andric  // Convert (Un)Signed DWord -> QP.
28010b57cec5SDimitry Andric  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
28020b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp i64:$src)),
28030b57cec5SDimitry Andric            (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
28040b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))),
28050b57cec5SDimitry Andric            (f128 (XSCVSDQP $src))>;
28060b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))),
28070b57cec5SDimitry Andric            (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
28080b57cec5SDimitry Andric
28090b57cec5SDimitry Andric  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
28100b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp i64:$src)),
28110b57cec5SDimitry Andric            (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
28120b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))),
28130b57cec5SDimitry Andric            (f128 (XSCVUDQP $src))>;
28140b57cec5SDimitry Andric
28150b57cec5SDimitry Andric  // Convert (Un)Signed Word -> QP.
28160b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp i32:$src)),
28170b57cec5SDimitry Andric            (f128 (XSCVSDQP (MTVSRWA $src)))>;
28180b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
28190b57cec5SDimitry Andric            (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
28200b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp i32:$src)),
28210b57cec5SDimitry Andric            (f128 (XSCVUDQP (MTVSRWZ $src)))>;
28220b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))),
28230b57cec5SDimitry Andric            (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
28240b57cec5SDimitry Andric
28250b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
28260b57cec5SDimitry Andric  // Round to Floating-Point Integer Instructions
28270b57cec5SDimitry Andric
28280b57cec5SDimitry Andric  // (Round &) Convert DP <-> HP
28290b57cec5SDimitry Andric  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
28300b57cec5SDimitry Andric  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
28310b57cec5SDimitry Andric  // but we still use vsfrc for it.
28320b57cec5SDimitry Andric  def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
28330b57cec5SDimitry Andric  def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
28340b57cec5SDimitry Andric
28350b57cec5SDimitry Andric  // Vector HP -> SP
28360b57cec5SDimitry Andric  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
28370b57cec5SDimitry Andric  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
28380b57cec5SDimitry Andric                                 [(set v4f32:$XT,
28390b57cec5SDimitry Andric                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
28400b57cec5SDimitry Andric
28410b57cec5SDimitry Andric  // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
28420b57cec5SDimitry Andric  // separate pattern so that it can convert the input register class from
28430b57cec5SDimitry Andric  // VRRC(v8i16) to VSRC.
28440b57cec5SDimitry Andric  def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
28450b57cec5SDimitry Andric            (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
28460b57cec5SDimitry Andric
28470b57cec5SDimitry Andric  class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
28480b57cec5SDimitry Andric                                list<dag> pattern>
28490b57cec5SDimitry Andric    : Z23Form_8<opcode, xo,
28500b57cec5SDimitry Andric                (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
28510b57cec5SDimitry Andric                !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
28520b57cec5SDimitry Andric    let RC = ex;
28530b57cec5SDimitry Andric  }
28540b57cec5SDimitry Andric
28550b57cec5SDimitry Andric  // Round to Quad-Precision Integer [with Inexact]
28560b57cec5SDimitry Andric  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
28570b57cec5SDimitry Andric  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
28580b57cec5SDimitry Andric
28590b57cec5SDimitry Andric  // Use current rounding mode
28600b57cec5SDimitry Andric  def : Pat<(f128 (fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
28610b57cec5SDimitry Andric  // Round to nearest, ties away from zero
28620b57cec5SDimitry Andric  def : Pat<(f128 (fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
28630b57cec5SDimitry Andric  // Round towards Zero
28640b57cec5SDimitry Andric  def : Pat<(f128 (ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
28650b57cec5SDimitry Andric  // Round towards +Inf
28660b57cec5SDimitry Andric  def : Pat<(f128 (fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
28670b57cec5SDimitry Andric  // Round towards -Inf
28680b57cec5SDimitry Andric  def : Pat<(f128 (ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
28690b57cec5SDimitry Andric
28700b57cec5SDimitry Andric  // Use current rounding mode, [with Inexact]
28710b57cec5SDimitry Andric  def : Pat<(f128 (frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
28720b57cec5SDimitry Andric
28730b57cec5SDimitry Andric  // Round Quad-Precision to Double-Extended Precision (fp80)
28740b57cec5SDimitry Andric  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
28750b57cec5SDimitry Andric
28760b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
28770b57cec5SDimitry Andric  // Insert/Extract Instructions
28780b57cec5SDimitry Andric
28790b57cec5SDimitry Andric  // Insert Exponent DP/QP
28800b57cec5SDimitry Andric  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
28810b57cec5SDimitry Andric  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
28820b57cec5SDimitry Andric                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
28830b57cec5SDimitry Andric  // vB NOTE: only vB.dword[0] is used, that's why we don't use
28840b57cec5SDimitry Andric  //          X_VT5_VA5_VB5 form
28850b57cec5SDimitry Andric  def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
28860b57cec5SDimitry Andric                          "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
28870b57cec5SDimitry Andric
28880b57cec5SDimitry Andric  def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
28890b57cec5SDimitry Andric            (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
28900b57cec5SDimitry Andric
28910b57cec5SDimitry Andric  // Extract Exponent/Significand DP/QP
28920b57cec5SDimitry Andric  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
28930b57cec5SDimitry Andric  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
28940b57cec5SDimitry Andric
28950b57cec5SDimitry Andric  def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
28960b57cec5SDimitry Andric  def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
28970b57cec5SDimitry Andric
28980b57cec5SDimitry Andric  def : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
28990b57cec5SDimitry Andric            (i64 (MFVSRD (EXTRACT_SUBREG
29000b57cec5SDimitry Andric                           (v2i64 (XSXEXPQP $vA)), sub_64)))>;
29010b57cec5SDimitry Andric
29020b57cec5SDimitry Andric  // Vector Insert Word
29030b57cec5SDimitry Andric  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
29040b57cec5SDimitry Andric  def XXINSERTW   :
29050b57cec5SDimitry Andric    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
29060b57cec5SDimitry Andric                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
29070b57cec5SDimitry Andric                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
29080b57cec5SDimitry Andric                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
29090b57cec5SDimitry Andric                                                   imm32SExt16:$UIM))]>,
29100b57cec5SDimitry Andric                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
29110b57cec5SDimitry Andric
29120b57cec5SDimitry Andric  // Vector Extract Unsigned Word
29130b57cec5SDimitry Andric  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
29140b57cec5SDimitry Andric                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
29150b57cec5SDimitry Andric                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
29160b57cec5SDimitry Andric
29170b57cec5SDimitry Andric  // Vector Insert Exponent DP/SP
29180b57cec5SDimitry Andric  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
29190b57cec5SDimitry Andric    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
29200b57cec5SDimitry Andric  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
29210b57cec5SDimitry Andric    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
29220b57cec5SDimitry Andric
29230b57cec5SDimitry Andric  // Vector Extract Exponent/Significand DP/SP
29240b57cec5SDimitry Andric  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
29250b57cec5SDimitry Andric                                 [(set v2i64: $XT,
29260b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
29270b57cec5SDimitry Andric  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
29280b57cec5SDimitry Andric                                 [(set v4i32: $XT,
29290b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
29300b57cec5SDimitry Andric  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
29310b57cec5SDimitry Andric                                 [(set v2i64: $XT,
29320b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
29330b57cec5SDimitry Andric  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
29340b57cec5SDimitry Andric                                 [(set v4i32: $XT,
29350b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
29360b57cec5SDimitry Andric
29370b57cec5SDimitry Andric  let AddedComplexity = 400, Predicates = [HasP9Vector] in {
29380b57cec5SDimitry Andric  // Extra patterns expanding to vector Extract Word/Insert Word
29390b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
29400b57cec5SDimitry Andric            (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
29410b57cec5SDimitry Andric  def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
29420b57cec5SDimitry Andric            (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
29430b57cec5SDimitry Andric  } // AddedComplexity = 400, HasP9Vector
29440b57cec5SDimitry Andric
29450b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
29460b57cec5SDimitry Andric
29470b57cec5SDimitry Andric  // Test Data Class SP/DP/QP
29480b57cec5SDimitry Andric  def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
29490b57cec5SDimitry Andric                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
29500b57cec5SDimitry Andric                              "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
29510b57cec5SDimitry Andric  def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
29520b57cec5SDimitry Andric                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
29530b57cec5SDimitry Andric                              "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
29540b57cec5SDimitry Andric  def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
29550b57cec5SDimitry Andric                              (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
29560b57cec5SDimitry Andric                              "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
29570b57cec5SDimitry Andric
29580b57cec5SDimitry Andric  // Vector Test Data Class SP/DP
29590b57cec5SDimitry Andric  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
29600b57cec5SDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
29610b57cec5SDimitry Andric                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
29620b57cec5SDimitry Andric                              [(set v4i32: $XT,
29638bcb0991SDimitry Andric                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
29640b57cec5SDimitry Andric  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
29650b57cec5SDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
29660b57cec5SDimitry Andric                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
29670b57cec5SDimitry Andric                              [(set v2i64: $XT,
29688bcb0991SDimitry Andric                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
29690b57cec5SDimitry Andric
29700b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
29710b57cec5SDimitry Andric
29720b57cec5SDimitry Andric  // Maximum/Minimum Type-C/Type-J DP
2973*480093f4SDimitry Andric  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc,
2974*480093f4SDimitry Andric                                 IIC_VecFP,
2975*480093f4SDimitry Andric                                 [(set f64:$XT, (PPCxsmaxc f64:$XA, f64:$XB))]>;
29760b57cec5SDimitry Andric  def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
29770b57cec5SDimitry Andric                                 IIC_VecFP, []>;
2978*480093f4SDimitry Andric  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc,
2979*480093f4SDimitry Andric                                 IIC_VecFP,
2980*480093f4SDimitry Andric                                 [(set f64:$XT, (PPCxsminc f64:$XA, f64:$XB))]>;
29810b57cec5SDimitry Andric  def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
29820b57cec5SDimitry Andric                                 IIC_VecFP, []>;
29830b57cec5SDimitry Andric
29840b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
29850b57cec5SDimitry Andric
29860b57cec5SDimitry Andric  // Vector Byte-Reverse H/W/D/Q Word
29870b57cec5SDimitry Andric  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
2988*480093f4SDimitry Andric  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc,
2989*480093f4SDimitry Andric    [(set v4i32:$XT, (bswap v4i32:$XB))]>;
2990*480093f4SDimitry Andric  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc,
2991*480093f4SDimitry Andric    [(set v2i64:$XT, (bswap v2i64:$XB))]>;
29920b57cec5SDimitry Andric  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
29930b57cec5SDimitry Andric
29940b57cec5SDimitry Andric  // Vector Reverse
2995*480093f4SDimitry Andric  def : Pat<(v8i16 (bswap v8i16 :$A)),
29960b57cec5SDimitry Andric            (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
2997*480093f4SDimitry Andric  def : Pat<(v1i128 (bswap v1i128 :$A)),
29980b57cec5SDimitry Andric            (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
29990b57cec5SDimitry Andric
30000b57cec5SDimitry Andric  // Vector Permute
30010b57cec5SDimitry Andric  def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
30020b57cec5SDimitry Andric                                IIC_VecPerm, []>;
30030b57cec5SDimitry Andric  def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
30040b57cec5SDimitry Andric                                IIC_VecPerm, []>;
30050b57cec5SDimitry Andric
30060b57cec5SDimitry Andric  // Vector Splat Immediate Byte
30070b57cec5SDimitry Andric  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
30080b57cec5SDimitry Andric                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
30090b57cec5SDimitry Andric
30100b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
30110b57cec5SDimitry Andric  // Vector/Scalar Load/Store Instructions
30120b57cec5SDimitry Andric
30130b57cec5SDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
30140b57cec5SDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
3015*480093f4SDimitry Andric  let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in {
30160b57cec5SDimitry Andric  // Load Vector
30170b57cec5SDimitry Andric  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
30180b57cec5SDimitry Andric                            "lxv $XT, $src", IIC_LdStLFD, []>;
30190b57cec5SDimitry Andric  // Load DWord
30200b57cec5SDimitry Andric  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
30210b57cec5SDimitry Andric                       "lxsd $vD, $src", IIC_LdStLFD, []>;
30220b57cec5SDimitry Andric  // Load SP from src, convert it to DP, and place in dword[0]
30230b57cec5SDimitry Andric  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
30240b57cec5SDimitry Andric                       "lxssp $vD, $src", IIC_LdStLFD, []>;
30250b57cec5SDimitry Andric
30260b57cec5SDimitry Andric  // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
30270b57cec5SDimitry Andric  // "out" and "in" dag
30280b57cec5SDimitry Andric  class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
30290b57cec5SDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
30300b57cec5SDimitry Andric    : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
30310b57cec5SDimitry Andric              !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
30320b57cec5SDimitry Andric
30330b57cec5SDimitry Andric  // Load as Integer Byte/Halfword & Zero Indexed
30340b57cec5SDimitry Andric  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
30350b57cec5SDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
30360b57cec5SDimitry Andric  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
30370b57cec5SDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
30380b57cec5SDimitry Andric
30390b57cec5SDimitry Andric  // Load Vector Halfword*8/Byte*16 Indexed
30400b57cec5SDimitry Andric  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
30410b57cec5SDimitry Andric  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
30420b57cec5SDimitry Andric
30430b57cec5SDimitry Andric  // Load Vector Indexed
30440b57cec5SDimitry Andric  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
30450b57cec5SDimitry Andric                [(set v2f64:$XT, (load xaddrX16:$src))]>;
30460b57cec5SDimitry Andric  // Load Vector (Left-justified) with Length
30470b57cec5SDimitry Andric  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
30480b57cec5SDimitry Andric                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
30490b57cec5SDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
30500b57cec5SDimitry Andric  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
30510b57cec5SDimitry Andric                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
30520b57cec5SDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
30530b57cec5SDimitry Andric
30540b57cec5SDimitry Andric  // Load Vector Word & Splat Indexed
30550b57cec5SDimitry Andric  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
30560b57cec5SDimitry Andric  } // mayLoad
30570b57cec5SDimitry Andric
30580b57cec5SDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
30590b57cec5SDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
3060*480093f4SDimitry Andric  let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
30610b57cec5SDimitry Andric  // Store Vector
30620b57cec5SDimitry Andric  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
30630b57cec5SDimitry Andric                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
30640b57cec5SDimitry Andric  // Store DWord
30650b57cec5SDimitry Andric  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
30660b57cec5SDimitry Andric                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
30670b57cec5SDimitry Andric  // Convert DP of dword[0] to SP, and Store to dst
30680b57cec5SDimitry Andric  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
30690b57cec5SDimitry Andric                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
30700b57cec5SDimitry Andric
30710b57cec5SDimitry Andric  // [PO S RA RB XO SX]
30720b57cec5SDimitry Andric  class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
30730b57cec5SDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
30740b57cec5SDimitry Andric    : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
30750b57cec5SDimitry Andric              !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
30760b57cec5SDimitry Andric
30770b57cec5SDimitry Andric  // Store as Integer Byte/Halfword Indexed
30780b57cec5SDimitry Andric  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
30790b57cec5SDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
30800b57cec5SDimitry Andric  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
30810b57cec5SDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
30820b57cec5SDimitry Andric  let isCodeGenOnly = 1 in {
30830b57cec5SDimitry Andric    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
30840b57cec5SDimitry Andric    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
30850b57cec5SDimitry Andric  }
30860b57cec5SDimitry Andric
30870b57cec5SDimitry Andric  // Store Vector Halfword*8/Byte*16 Indexed
30880b57cec5SDimitry Andric  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
30890b57cec5SDimitry Andric  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
30900b57cec5SDimitry Andric
30910b57cec5SDimitry Andric  // Store Vector Indexed
30920b57cec5SDimitry Andric  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
30930b57cec5SDimitry Andric                 [(store v2f64:$XT, xaddrX16:$dst)]>;
30940b57cec5SDimitry Andric
30950b57cec5SDimitry Andric  // Store Vector (Left-justified) with Length
30960b57cec5SDimitry Andric  def STXVL : XX1Form_memOp<31, 397, (outs),
30970b57cec5SDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
30980b57cec5SDimitry Andric                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
30990b57cec5SDimitry Andric                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
31000b57cec5SDimitry Andric                              i64:$rB)]>;
31010b57cec5SDimitry Andric  def STXVLL : XX1Form_memOp<31, 429, (outs),
31020b57cec5SDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
31030b57cec5SDimitry Andric                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
31040b57cec5SDimitry Andric                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
31050b57cec5SDimitry Andric                              i64:$rB)]>;
31060b57cec5SDimitry Andric  } // mayStore
31070b57cec5SDimitry Andric
31080b57cec5SDimitry Andric  let Predicates = [IsLittleEndian] in {
31090b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
31100b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
31110b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
31120b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
31130b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
31140b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
31150b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
31160b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
31170b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
31180b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
31190b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
31200b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
31210b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
31220b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
31230b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
31240b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
31250b57cec5SDimitry Andric  }
31260b57cec5SDimitry Andric
31270b57cec5SDimitry Andric  let Predicates = [IsBigEndian] in {
31280b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
31290b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
31300b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
31310b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
31320b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
31330b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
31340b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
31350b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
31360b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
31370b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
31380b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
31390b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
31400b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
31410b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
31420b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
31430b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
31440b57cec5SDimitry Andric  }
31450b57cec5SDimitry Andric
31460b57cec5SDimitry Andric  // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
31470b57cec5SDimitry Andric  // of f64
31480b57cec5SDimitry Andric  def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
31490b57cec5SDimitry Andric            (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
31500b57cec5SDimitry Andric  def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
31510b57cec5SDimitry Andric            (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
31520b57cec5SDimitry Andric
31530b57cec5SDimitry Andric  // Patterns for which instructions from ISA 3.0 are a better match
31540b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP9Vector] in {
31550b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
31560b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
31570b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
31580b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
31590b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
31600b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
31610b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
31620b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
31630b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
31640b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
31650b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
31660b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
31670b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
31680b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
31690b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
31700b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
31710b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
31720b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
31730b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
31740b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
31750b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
31760b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
31770b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
31780b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
31790b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
31800b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
31810b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
31820b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
31830b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
31840b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
31850b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
31860b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
31878bcb0991SDimitry Andric
31888bcb0991SDimitry Andric  def : Pat<(v8i16 (PPCld_vec_be xoaddr:$src)),
31898bcb0991SDimitry Andric            (COPY_TO_REGCLASS (LXVH8X xoaddr:$src), VRRC)>;
31908bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v8i16:$rS, xoaddr:$dst),
31918bcb0991SDimitry Andric            (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
31928bcb0991SDimitry Andric
31938bcb0991SDimitry Andric  def : Pat<(v16i8 (PPCld_vec_be xoaddr:$src)),
31948bcb0991SDimitry Andric            (COPY_TO_REGCLASS (LXVB16X xoaddr:$src), VRRC)>;
31958bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v16i8:$rS, xoaddr:$dst),
31968bcb0991SDimitry Andric            (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
31970b57cec5SDimitry Andric  } // IsLittleEndian, HasP9Vector
31980b57cec5SDimitry Andric
31990b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP9Vector] in {
32000b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
32010b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
32020b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
32030b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
32040b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
32050b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
32060b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
32070b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
32080b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
32090b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
32100b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
32110b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
32120b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
32130b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
32140b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
32150b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
32160b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
32170b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
32180b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
32190b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
32200b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
32210b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
32220b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
32230b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
32240b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
32250b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
32260b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
32270b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
32280b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
32290b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
32300b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
32310b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
32328bcb0991SDimitry Andric  } // IsBigEndian, HasP9Vector
32330b57cec5SDimitry Andric
32340b57cec5SDimitry Andric  // D-Form Load/Store
32350b57cec5SDimitry Andric  def : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
32360b57cec5SDimitry Andric  def : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
32370b57cec5SDimitry Andric  def : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
32380b57cec5SDimitry Andric  def : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
32390b57cec5SDimitry Andric  def : Pat<(f128  (quadwOffsetLoad iaddrX16:$src)),
32400b57cec5SDimitry Andric            (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
32410b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>;
32420b57cec5SDimitry Andric  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>;
32430b57cec5SDimitry Andric
32440b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
32450b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
32460b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
32470b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore  f128:$rS, iaddrX16:$dst),
32480b57cec5SDimitry Andric            (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
32490b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
32500b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst),
32510b57cec5SDimitry Andric            (STXV $rS, memrix16:$dst)>;
32520b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst),
32530b57cec5SDimitry Andric            (STXV $rS, memrix16:$dst)>;
32540b57cec5SDimitry Andric
32550b57cec5SDimitry Andric
32560b57cec5SDimitry Andric  def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
32570b57cec5SDimitry Andric  def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
32580b57cec5SDimitry Andric  def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
32590b57cec5SDimitry Andric  def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
32600b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
32610b57cec5SDimitry Andric  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
32620b57cec5SDimitry Andric  def : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
32630b57cec5SDimitry Andric            (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
32640b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
32650b57cec5SDimitry Andric            (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
32660b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
32670b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
32680b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
32690b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
32700b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
32710b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
32720b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
32730b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
32740b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
32750b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
32760b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
32770b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
32780b57cec5SDimitry Andric
32790b57cec5SDimitry Andric  let AddedComplexity = 400 in {
32800b57cec5SDimitry Andric    // LIWAX - This instruction is used for sign extending i32 -> i64.
32810b57cec5SDimitry Andric    // LIWZX - This instruction will be emitted for i32, f32, and when
32820b57cec5SDimitry Andric    //         zero-extending i32 to i64 (zext i32 -> i64).
32830b57cec5SDimitry Andric    let Predicates = [IsLittleEndian] in {
32840b57cec5SDimitry Andric
32850b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
32860b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
32870b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC), 2))>;
32880b57cec5SDimitry Andric
32890b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
32900b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
32910b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
32920b57cec5SDimitry Andric
32930b57cec5SDimitry Andric      def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
32940b57cec5SDimitry Andric                (v4i32 (XXPERMDIs
32950b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
32960b57cec5SDimitry Andric
32970b57cec5SDimitry Andric      def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
32980b57cec5SDimitry Andric                (v4f32 (XXPERMDIs
32990b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
33000b57cec5SDimitry Andric    }
33010b57cec5SDimitry Andric
33020b57cec5SDimitry Andric    let Predicates = [IsBigEndian] in {
33030b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
33040b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
33050b57cec5SDimitry Andric
33060b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
33070b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
33080b57cec5SDimitry Andric
33090b57cec5SDimitry Andric      def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
33100b57cec5SDimitry Andric                (v4i32 (XXSLDWIs
33110b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
33120b57cec5SDimitry Andric
33130b57cec5SDimitry Andric      def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
33140b57cec5SDimitry Andric                (v4f32 (XXSLDWIs
33150b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
33160b57cec5SDimitry Andric    }
33170b57cec5SDimitry Andric
33180b57cec5SDimitry Andric  }
33190b57cec5SDimitry Andric
33200b57cec5SDimitry Andric  // Build vectors from i8 loads
33210b57cec5SDimitry Andric  def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
33220b57cec5SDimitry Andric            (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
33230b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
33240b57cec5SDimitry Andric            (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
33250b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
33260b57cec5SDimitry Andric           (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
33270b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
33280b57cec5SDimitry Andric            (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
33290b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
33300b57cec5SDimitry Andric            (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
33310b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
33320b57cec5SDimitry Andric            (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
33330b57cec5SDimitry Andric
33340b57cec5SDimitry Andric  // Build vectors from i16 loads
33350b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
33360b57cec5SDimitry Andric            (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
33370b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
33380b57cec5SDimitry Andric            (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
33390b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
33400b57cec5SDimitry Andric           (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
33410b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
33420b57cec5SDimitry Andric            (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
33430b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
33440b57cec5SDimitry Andric            (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
33450b57cec5SDimitry Andric
33460b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP9Vector] in {
33470b57cec5SDimitry Andric  // Scalar stores of i8
33480b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
33490b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
33500b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
33510b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
33520b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
33530b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
33540b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
33550b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
33560b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
33570b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
33580b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
33590b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
33600b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
33610b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
33620b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
33630b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
33640b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
33650b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
33660b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
33670b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
33680b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
33690b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
33700b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
33710b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
33720b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
33730b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
33740b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
33750b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
33760b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
33770b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
33780b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
33790b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
33800b57cec5SDimitry Andric
33810b57cec5SDimitry Andric  // Scalar stores of i16
33820b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
33830b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
33840b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
33850b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
33860b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
33870b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
33880b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
33890b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
33900b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
33910b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
33920b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
33930b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
33940b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
33950b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
33960b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
33970b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
33980b57cec5SDimitry Andric  } // IsBigEndian, HasP9Vector
33990b57cec5SDimitry Andric
34000b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP9Vector] in {
34010b57cec5SDimitry Andric  // Scalar stores of i8
34020b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
34030b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
34040b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
34050b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
34060b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
34070b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
34080b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
34090b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
34100b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
34110b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
34120b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
34130b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
34140b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
34150b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
34160b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
34170b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
34180b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
34190b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
34200b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
34210b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
34220b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
34230b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
34240b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
34250b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
34260b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
34270b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
34280b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
34290b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
34300b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
34310b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
34320b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
34330b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
34340b57cec5SDimitry Andric
34350b57cec5SDimitry Andric  // Scalar stores of i16
34360b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
34370b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
34380b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
34390b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
34400b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
34410b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
34420b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
34430b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
34440b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
34450b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
34460b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
34470b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
34480b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
34490b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
34500b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
34510b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
34520b57cec5SDimitry Andric  } // IsLittleEndian, HasP9Vector
34530b57cec5SDimitry Andric
34540b57cec5SDimitry Andric
34550b57cec5SDimitry Andric  // Vector sign extensions
34560b57cec5SDimitry Andric  def : Pat<(f64 (PPCVexts f64:$A, 1)),
34570b57cec5SDimitry Andric            (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
34580b57cec5SDimitry Andric  def : Pat<(f64 (PPCVexts f64:$A, 2)),
34590b57cec5SDimitry Andric            (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
34600b57cec5SDimitry Andric
34610b57cec5SDimitry Andric  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
34620b57cec5SDimitry Andric                          "#DFLOADf32",
34630b57cec5SDimitry Andric                          [(set f32:$XT, (load iaddrX4:$src))]>;
34640b57cec5SDimitry Andric  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
34650b57cec5SDimitry Andric                          "#DFLOADf64",
34660b57cec5SDimitry Andric                          [(set f64:$XT, (load iaddrX4:$src))]>;
34670b57cec5SDimitry Andric  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
34680b57cec5SDimitry Andric                          "#DFSTOREf32",
34690b57cec5SDimitry Andric                          [(store f32:$XT, iaddrX4:$dst)]>;
34700b57cec5SDimitry Andric  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
34710b57cec5SDimitry Andric                          "#DFSTOREf64",
34720b57cec5SDimitry Andric                          [(store f64:$XT, iaddrX4:$dst)]>;
34730b57cec5SDimitry Andric
34740b57cec5SDimitry Andric  def : Pat<(f64 (extloadf32 iaddrX4:$src)),
34750b57cec5SDimitry Andric            (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>;
34760b57cec5SDimitry Andric  def : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))),
34770b57cec5SDimitry Andric            (f32 (DFLOADf32 iaddrX4:$src))>;
34780b57cec5SDimitry Andric
34790b57cec5SDimitry Andric  def : Pat<(v4f32 (PPCldvsxlh xaddr:$src)),
34800b57cec5SDimitry Andric            (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>;
34810b57cec5SDimitry Andric  def : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)),
34820b57cec5SDimitry Andric            (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>;
34830b57cec5SDimitry Andric
34840b57cec5SDimitry Andric  let AddedComplexity = 400 in {
34850b57cec5SDimitry Andric  // The following pseudoinstructions are used to ensure the utilization
34860b57cec5SDimitry Andric  // of all 64 VSX registers.
34870b57cec5SDimitry Andric    let Predicates = [IsLittleEndian, HasP9Vector] in {
34880b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
34890b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
34900b57cec5SDimitry Andric                (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>;
34910b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
34920b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
34930b57cec5SDimitry Andric		(COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>;
34940b57cec5SDimitry Andric
34950b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
34960b57cec5SDimitry Andric                (v2f64 (XXPERMDIs
34970b57cec5SDimitry Andric                (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>;
34980b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
34990b57cec5SDimitry Andric                (v2f64 (XXPERMDIs
35000b57cec5SDimitry Andric                (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>;
35010b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
35020b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35030b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
35040b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
35050b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35060b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
35070b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
35080b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
35090b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
35100b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
35110b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
35120b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35130b57cec5SDimitry Andric                             sub_64), iaddrX4:$src)>;
35140b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
35150b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
35160b57cec5SDimitry Andric                            iaddrX4:$src)>;
35170b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
35180b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
35190b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
35200b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
35210b57cec5SDimitry Andric    } // IsLittleEndian, HasP9Vector
35220b57cec5SDimitry Andric
35230b57cec5SDimitry Andric    let Predicates = [IsBigEndian, HasP9Vector] in {
35240b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
35250b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
35260b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
35270b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
35280b57cec5SDimitry Andric
35290b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
35300b57cec5SDimitry Andric                (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
35310b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
35320b57cec5SDimitry Andric                (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
35330b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
35340b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35350b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
35360b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
35370b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35380b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
35390b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
35400b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
35410b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
35420b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
35430b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
35440b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35450b57cec5SDimitry Andric                             sub_64), iaddrX4:$src)>;
35460b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
35470b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
35480b57cec5SDimitry Andric                             sub_64), iaddrX4:$src)>;
35490b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
35500b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
35510b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
35520b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
35530b57cec5SDimitry Andric    } // IsBigEndian, HasP9Vector
35540b57cec5SDimitry Andric  }
35550b57cec5SDimitry Andric
35560b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP9Vector] in {
35570b57cec5SDimitry Andric
35580b57cec5SDimitry Andric    // (Un)Signed DWord vector extract -> QP
35590b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
35600b57cec5SDimitry Andric              (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
35610b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
35620b57cec5SDimitry Andric              (f128 (XSCVSDQP
35630b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
35640b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
35650b57cec5SDimitry Andric              (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
35660b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
35670b57cec5SDimitry Andric              (f128 (XSCVUDQP
35680b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
35690b57cec5SDimitry Andric
35700b57cec5SDimitry Andric    // (Un)Signed Word vector extract -> QP
35710b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
35720b57cec5SDimitry Andric              (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
35730b57cec5SDimitry Andric    foreach Idx = [0,2,3] in {
35740b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
35750b57cec5SDimitry Andric                (f128 (XSCVSDQP (EXTRACT_SUBREG
35760b57cec5SDimitry Andric                                (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
35770b57cec5SDimitry Andric    }
35780b57cec5SDimitry Andric    foreach Idx = 0-3 in {
35790b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
35800b57cec5SDimitry Andric                (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
35810b57cec5SDimitry Andric    }
35820b57cec5SDimitry Andric
35830b57cec5SDimitry Andric    // (Un)Signed HWord vector extract -> QP
35840b57cec5SDimitry Andric    foreach Idx = 0-7 in {
35850b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
35860b57cec5SDimitry Andric                        (i32 (sext_inreg
35870b57cec5SDimitry Andric                               (vector_extract v8i16:$src, Idx), i16)))),
35880b57cec5SDimitry Andric              (f128 (XSCVSDQP (EXTRACT_SUBREG
35890b57cec5SDimitry Andric                                (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
35900b57cec5SDimitry Andric                                sub_64)))>;
35910b57cec5SDimitry Andric      // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
35920b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
35930b57cec5SDimitry Andric                        (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
35940b57cec5SDimitry Andric                (f128 (XSCVUDQP (EXTRACT_SUBREG
35950b57cec5SDimitry Andric                                  (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
35960b57cec5SDimitry Andric    }
35970b57cec5SDimitry Andric
35980b57cec5SDimitry Andric    // (Un)Signed Byte vector extract -> QP
35990b57cec5SDimitry Andric    foreach Idx = 0-15 in {
36000b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
36010b57cec5SDimitry Andric                        (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
36020b57cec5SDimitry Andric                                         i8)))),
36030b57cec5SDimitry Andric                (f128 (XSCVSDQP (EXTRACT_SUBREG
36040b57cec5SDimitry Andric                                  (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
36050b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
36060b57cec5SDimitry Andric                        (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
36070b57cec5SDimitry Andric                (f128 (XSCVUDQP
36080b57cec5SDimitry Andric                        (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
36090b57cec5SDimitry Andric    }
36100b57cec5SDimitry Andric
36110b57cec5SDimitry Andric    // Unsiged int in vsx register -> QP
36120b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
36130b57cec5SDimitry Andric              (f128 (XSCVUDQP
36140b57cec5SDimitry Andric                      (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
36150b57cec5SDimitry Andric  } // IsBigEndian, HasP9Vector
36160b57cec5SDimitry Andric
36170b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP9Vector] in {
36180b57cec5SDimitry Andric
36190b57cec5SDimitry Andric    // (Un)Signed DWord vector extract -> QP
36200b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
36210b57cec5SDimitry Andric              (f128 (XSCVSDQP
36220b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
36230b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
36240b57cec5SDimitry Andric              (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
36250b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
36260b57cec5SDimitry Andric              (f128 (XSCVUDQP
36270b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
36280b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
36290b57cec5SDimitry Andric              (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
36300b57cec5SDimitry Andric
36310b57cec5SDimitry Andric    // (Un)Signed Word vector extract -> QP
36320b57cec5SDimitry Andric    foreach Idx = [[0,3],[1,2],[3,0]] in {
36330b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
36340b57cec5SDimitry Andric                (f128 (XSCVSDQP (EXTRACT_SUBREG
36350b57cec5SDimitry Andric                                  (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
36360b57cec5SDimitry Andric                                  sub_64)))>;
36370b57cec5SDimitry Andric    }
36380b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
36390b57cec5SDimitry Andric              (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
36400b57cec5SDimitry Andric
36410b57cec5SDimitry Andric    foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
36420b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
36430b57cec5SDimitry Andric                (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
36440b57cec5SDimitry Andric    }
36450b57cec5SDimitry Andric
36460b57cec5SDimitry Andric    // (Un)Signed HWord vector extract -> QP
36470b57cec5SDimitry Andric    // The Nested foreach lists identifies the vector element and corresponding
36480b57cec5SDimitry Andric    // register byte location.
36490b57cec5SDimitry Andric    foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
36500b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
36510b57cec5SDimitry Andric                        (i32 (sext_inreg
36520b57cec5SDimitry Andric                               (vector_extract v8i16:$src, !head(Idx)), i16)))),
36530b57cec5SDimitry Andric                (f128 (XSCVSDQP
36540b57cec5SDimitry Andric                        (EXTRACT_SUBREG (VEXTSH2D
36550b57cec5SDimitry Andric                                          (VEXTRACTUH !head(!tail(Idx)), $src)),
36560b57cec5SDimitry Andric                                        sub_64)))>;
36570b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
36580b57cec5SDimitry Andric                        (and (i32 (vector_extract v8i16:$src, !head(Idx))),
36590b57cec5SDimitry Andric                             65535))),
36600b57cec5SDimitry Andric                (f128 (XSCVUDQP (EXTRACT_SUBREG
36610b57cec5SDimitry Andric                                  (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
36620b57cec5SDimitry Andric    }
36630b57cec5SDimitry Andric
36640b57cec5SDimitry Andric    // (Un)Signed Byte vector extract -> QP
36650b57cec5SDimitry Andric    foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
36660b57cec5SDimitry Andric                   [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
36670b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
36680b57cec5SDimitry Andric                        (i32 (sext_inreg
36690b57cec5SDimitry Andric                               (vector_extract v16i8:$src, !head(Idx)), i8)))),
36700b57cec5SDimitry Andric                (f128 (XSCVSDQP
36710b57cec5SDimitry Andric                        (EXTRACT_SUBREG
36720b57cec5SDimitry Andric                          (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
36730b57cec5SDimitry Andric                          sub_64)))>;
36740b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
36750b57cec5SDimitry Andric                        (and (i32 (vector_extract v16i8:$src, !head(Idx))),
36760b57cec5SDimitry Andric                             255))),
36770b57cec5SDimitry Andric                (f128 (XSCVUDQP
36780b57cec5SDimitry Andric                        (EXTRACT_SUBREG
36790b57cec5SDimitry Andric                          (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
36800b57cec5SDimitry Andric    }
36810b57cec5SDimitry Andric
36820b57cec5SDimitry Andric    // Unsiged int in vsx register -> QP
36830b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
36840b57cec5SDimitry Andric              (f128 (XSCVUDQP
36850b57cec5SDimitry Andric                      (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
36860b57cec5SDimitry Andric  } // IsLittleEndian, HasP9Vector
36870b57cec5SDimitry Andric
36880b57cec5SDimitry Andric  // Convert (Un)Signed DWord in memory -> QP
36890b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))),
36900b57cec5SDimitry Andric            (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>;
36910b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))),
36920b57cec5SDimitry Andric            (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>;
36930b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))),
36940b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>;
36950b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))),
36960b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>;
36970b57cec5SDimitry Andric
36980b57cec5SDimitry Andric  // Convert Unsigned HWord in memory -> QP
36990b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
37000b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
37010b57cec5SDimitry Andric
37020b57cec5SDimitry Andric  // Convert Unsigned Byte in memory -> QP
37030b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
37040b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
37050b57cec5SDimitry Andric
37060b57cec5SDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word.
37070b57cec5SDimitry Andric  def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
37080b57cec5SDimitry Andric  def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
37090b57cec5SDimitry Andric  def : Pat<(i32 (fp_to_sint f128:$src)),
37100b57cec5SDimitry Andric            (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
37110b57cec5SDimitry Andric  def : Pat<(i32 (fp_to_uint f128:$src)),
37120b57cec5SDimitry Andric            (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
37130b57cec5SDimitry Andric
37140b57cec5SDimitry Andric  // Instructions for store(fptosi).
37150b57cec5SDimitry Andric  // The 8-byte version is repeated here due to availability of D-Form STXSD.
37160b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37170b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8),
37180b57cec5SDimitry Andric            (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
37190b57cec5SDimitry Andric                    xaddrX4:$dst)>;
37200b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37210b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8),
37220b57cec5SDimitry Andric            (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
37230b57cec5SDimitry Andric                   iaddrX4:$dst)>;
37240b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37250b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
37260b57cec5SDimitry Andric            (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
37270b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37280b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
37290b57cec5SDimitry Andric            (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
37300b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37310b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
37320b57cec5SDimitry Andric            (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
37330b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37340b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8),
37350b57cec5SDimitry Andric            (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>;
37360b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37370b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8),
37380b57cec5SDimitry Andric            (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>;
37390b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37400b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
37410b57cec5SDimitry Andric            (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
37420b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37430b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
37440b57cec5SDimitry Andric            (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
37450b57cec5SDimitry Andric
37460b57cec5SDimitry Andric  // Instructions for store(fptoui).
37470b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37480b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8),
37490b57cec5SDimitry Andric            (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
37500b57cec5SDimitry Andric                    xaddrX4:$dst)>;
37510b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37520b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8),
37530b57cec5SDimitry Andric            (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
37540b57cec5SDimitry Andric                   iaddrX4:$dst)>;
37550b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37560b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
37570b57cec5SDimitry Andric            (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
37580b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37590b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
37600b57cec5SDimitry Andric            (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
37610b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37620b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
37630b57cec5SDimitry Andric            (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
37640b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37650b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8),
37660b57cec5SDimitry Andric            (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>;
37670b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37680b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8),
37690b57cec5SDimitry Andric            (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>;
37700b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37710b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
37720b57cec5SDimitry Andric            (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
37730b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
37740b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
37750b57cec5SDimitry Andric            (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
37760b57cec5SDimitry Andric
37770b57cec5SDimitry Andric  // Round & Convert QP -> DP/SP
37780b57cec5SDimitry Andric  def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>;
37790b57cec5SDimitry Andric  def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
37800b57cec5SDimitry Andric
37810b57cec5SDimitry Andric  // Convert SP -> QP
37820b57cec5SDimitry Andric  def : Pat<(f128 (fpextend f32:$src)),
37830b57cec5SDimitry Andric            (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
37840b57cec5SDimitry Andric
3785*480093f4SDimitry Andric  def : Pat<(f32 (PPCxsmaxc f32:$XA, f32:$XB)),
3786*480093f4SDimitry Andric            (f32 (COPY_TO_REGCLASS (XSMAXCDP (COPY_TO_REGCLASS $XA, VSSRC),
3787*480093f4SDimitry Andric                                             (COPY_TO_REGCLASS $XB, VSSRC)),
3788*480093f4SDimitry Andric                                   VSSRC))>;
3789*480093f4SDimitry Andric  def : Pat<(f32 (PPCxsminc f32:$XA, f32:$XB)),
3790*480093f4SDimitry Andric            (f32 (COPY_TO_REGCLASS (XSMINCDP (COPY_TO_REGCLASS $XA, VSSRC),
3791*480093f4SDimitry Andric                                             (COPY_TO_REGCLASS $XB, VSSRC)),
3792*480093f4SDimitry Andric                                   VSSRC))>;
3793*480093f4SDimitry Andric
37940b57cec5SDimitry Andric} // end HasP9Vector, AddedComplexity
37950b57cec5SDimitry Andric
37960b57cec5SDimitry Andriclet AddedComplexity = 400 in {
37970b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in {
37980b57cec5SDimitry Andric    def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
37990b57cec5SDimitry Andric              (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
38000b57cec5SDimitry Andric  }
38010b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in {
38020b57cec5SDimitry Andric    def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
38030b57cec5SDimitry Andric              (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
38040b57cec5SDimitry Andric  }
38050b57cec5SDimitry Andric}
38060b57cec5SDimitry Andric
3807*480093f4SDimitry Andriclet Predicates = [HasP9Vector], hasSideEffects = 0 in {
38080b57cec5SDimitry Andric  let mayStore = 1 in {
38090b57cec5SDimitry Andric    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
38100b57cec5SDimitry Andric                                          (ins spilltovsrrc:$XT, memrr:$dst),
38110b57cec5SDimitry Andric                                          "#SPILLTOVSR_STX", []>;
38120b57cec5SDimitry Andric    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
38130b57cec5SDimitry Andric                              "#SPILLTOVSR_ST", []>;
38140b57cec5SDimitry Andric  }
38150b57cec5SDimitry Andric  let mayLoad = 1 in {
38160b57cec5SDimitry Andric    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
38170b57cec5SDimitry Andric                                          (ins memrr:$src),
38180b57cec5SDimitry Andric                                          "#SPILLTOVSR_LDX", []>;
38190b57cec5SDimitry Andric    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
38200b57cec5SDimitry Andric                              "#SPILLTOVSR_LD", []>;
38210b57cec5SDimitry Andric
38220b57cec5SDimitry Andric  }
38230b57cec5SDimitry Andric}
38240b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64
38250b57cec5SDimitry Andricdef AnyExts {
38260b57cec5SDimitry Andric  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
38270b57cec5SDimitry Andric  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
38280b57cec5SDimitry Andric  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
38290b57cec5SDimitry Andric  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
38300b57cec5SDimitry Andric}
38310b57cec5SDimitry Andric
38320b57cec5SDimitry Andricdef DblToFlt {
38330b57cec5SDimitry Andric  dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
38340b57cec5SDimitry Andric  dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
38350b57cec5SDimitry Andric  dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
38360b57cec5SDimitry Andric  dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
38370b57cec5SDimitry Andric}
38380b57cec5SDimitry Andric
38390b57cec5SDimitry Andricdef ExtDbl {
38400b57cec5SDimitry Andric  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
38410b57cec5SDimitry Andric  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
38420b57cec5SDimitry Andric  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
38430b57cec5SDimitry Andric  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
38440b57cec5SDimitry Andric  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
38450b57cec5SDimitry Andric  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
38460b57cec5SDimitry Andric  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
38470b57cec5SDimitry Andric  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
38480b57cec5SDimitry Andric}
38490b57cec5SDimitry Andric
38500b57cec5SDimitry Andricdef ByteToWord {
38510b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
38520b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
38530b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
38540b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
38550b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
38560b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
38570b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
38580b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
38590b57cec5SDimitry Andric}
38600b57cec5SDimitry Andric
38610b57cec5SDimitry Andricdef ByteToDWord {
38620b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
38630b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
38640b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
38650b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
38660b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
38670b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
38680b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
38690b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
38700b57cec5SDimitry Andric}
38710b57cec5SDimitry Andric
38720b57cec5SDimitry Andricdef HWordToWord {
38730b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
38740b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
38750b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
38760b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
38770b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
38780b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
38790b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
38800b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
38810b57cec5SDimitry Andric}
38820b57cec5SDimitry Andric
38830b57cec5SDimitry Andricdef HWordToDWord {
38840b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
38850b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
38860b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
38870b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
38880b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
38890b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
38900b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
38910b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
38920b57cec5SDimitry Andric}
38930b57cec5SDimitry Andric
38940b57cec5SDimitry Andricdef WordToDWord {
38950b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
38960b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
38970b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
38980b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
38990b57cec5SDimitry Andric}
39000b57cec5SDimitry Andric
39010b57cec5SDimitry Andricdef FltToIntLoad {
39020b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
39030b57cec5SDimitry Andric}
39040b57cec5SDimitry Andricdef FltToUIntLoad {
39050b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
39060b57cec5SDimitry Andric}
39070b57cec5SDimitry Andricdef FltToLongLoad {
39080b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
39090b57cec5SDimitry Andric}
39100b57cec5SDimitry Andricdef FltToLongLoadP9 {
39110b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A)))));
39120b57cec5SDimitry Andric}
39130b57cec5SDimitry Andricdef FltToULongLoad {
39140b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
39150b57cec5SDimitry Andric}
39160b57cec5SDimitry Andricdef FltToULongLoadP9 {
39170b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A)))));
39180b57cec5SDimitry Andric}
39190b57cec5SDimitry Andricdef FltToLong {
39200b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
39210b57cec5SDimitry Andric}
39220b57cec5SDimitry Andricdef FltToULong {
39230b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
39240b57cec5SDimitry Andric}
39250b57cec5SDimitry Andricdef DblToInt {
39260b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
39270b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
39280b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
39290b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
39300b57cec5SDimitry Andric}
39310b57cec5SDimitry Andricdef DblToUInt {
39320b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
39330b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
39340b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
39350b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
39360b57cec5SDimitry Andric}
39370b57cec5SDimitry Andricdef DblToLong {
39380b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
39390b57cec5SDimitry Andric}
39400b57cec5SDimitry Andricdef DblToULong {
39410b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
39420b57cec5SDimitry Andric}
39430b57cec5SDimitry Andricdef DblToIntLoad {
39440b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
39450b57cec5SDimitry Andric}
39460b57cec5SDimitry Andricdef DblToIntLoadP9 {
39470b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A)))));
39480b57cec5SDimitry Andric}
39490b57cec5SDimitry Andricdef DblToUIntLoad {
39500b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
39510b57cec5SDimitry Andric}
39520b57cec5SDimitry Andricdef DblToUIntLoadP9 {
39530b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A)))));
39540b57cec5SDimitry Andric}
39550b57cec5SDimitry Andricdef DblToLongLoad {
39560b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
39570b57cec5SDimitry Andric}
39580b57cec5SDimitry Andricdef DblToULongLoad {
39590b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
39600b57cec5SDimitry Andric}
39610b57cec5SDimitry Andric
3962*480093f4SDimitry Andric// FP load dags (for f32 -> v4f32)
3963*480093f4SDimitry Andricdef LoadFP {
3964*480093f4SDimitry Andric  dag A = (f32 (load xoaddr:$A));
3965*480093f4SDimitry Andric  dag B = (f32 (load xoaddr:$B));
3966*480093f4SDimitry Andric  dag C = (f32 (load xoaddr:$C));
3967*480093f4SDimitry Andric  dag D = (f32 (load xoaddr:$D));
3968*480093f4SDimitry Andric}
3969*480093f4SDimitry Andric
39700b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32)
39710b57cec5SDimitry Andricdef MrgFP {
3972*480093f4SDimitry Andric  dag LD32A = (COPY_TO_REGCLASS (LIWZX xoaddr:$A), VSRC);
3973*480093f4SDimitry Andric  dag LD32B = (COPY_TO_REGCLASS (LIWZX xoaddr:$B), VSRC);
3974*480093f4SDimitry Andric  dag LD32C = (COPY_TO_REGCLASS (LIWZX xoaddr:$C), VSRC);
3975*480093f4SDimitry Andric  dag LD32D = (COPY_TO_REGCLASS (LIWZX xoaddr:$D), VSRC);
39760b57cec5SDimitry Andric  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
39770b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $C, VSRC), 0));
39780b57cec5SDimitry Andric  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
39790b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $D, VSRC), 0));
39800b57cec5SDimitry Andric  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
39810b57cec5SDimitry Andric  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
39820b57cec5SDimitry Andric  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
39830b57cec5SDimitry Andric  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
39840b57cec5SDimitry Andric}
39850b57cec5SDimitry Andric
39860b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors.
39870b57cec5SDimitry Andricdef MrgWords {
39880b57cec5SDimitry Andric  // For big endian, we merge low and hi doublewords (A, B).
39890b57cec5SDimitry Andric  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
39900b57cec5SDimitry Andric  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
39910b57cec5SDimitry Andric  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
39920b57cec5SDimitry Andric  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
39930b57cec5SDimitry Andric  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
39940b57cec5SDimitry Andric  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
39950b57cec5SDimitry Andric
39960b57cec5SDimitry Andric  // For little endian, we merge low and hi doublewords (B, A).
39970b57cec5SDimitry Andric  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
39980b57cec5SDimitry Andric  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
39990b57cec5SDimitry Andric  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
40000b57cec5SDimitry Andric  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
40010b57cec5SDimitry Andric  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
40020b57cec5SDimitry Andric  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
40030b57cec5SDimitry Andric
40040b57cec5SDimitry Andric  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
40050b57cec5SDimitry Andric  // then merge.
40060b57cec5SDimitry Andric  dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
40070b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$C, VSRC), 0));
40080b57cec5SDimitry Andric  dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
40090b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$D, VSRC), 0));
40100b57cec5SDimitry Andric  dag CVACS = (v4i32 (XVCVDPSXWS AC));
40110b57cec5SDimitry Andric  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
40120b57cec5SDimitry Andric  dag CVACU = (v4i32 (XVCVDPUXWS AC));
40130b57cec5SDimitry Andric  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
40140b57cec5SDimitry Andric
40150b57cec5SDimitry Andric  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
40160b57cec5SDimitry Andric  // then merge.
40170b57cec5SDimitry Andric  dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
40180b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$B, VSRC), 0));
40190b57cec5SDimitry Andric  dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
40200b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$A, VSRC), 0));
40210b57cec5SDimitry Andric  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
40220b57cec5SDimitry Andric  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
40230b57cec5SDimitry Andric  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
40240b57cec5SDimitry Andric  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
40250b57cec5SDimitry Andric}
40260b57cec5SDimitry Andric
40270b57cec5SDimitry Andric// Patterns for BUILD_VECTOR nodes.
40280b57cec5SDimitry Andriclet AddedComplexity = 400 in {
40290b57cec5SDimitry Andric
40300b57cec5SDimitry Andric  let Predicates = [HasVSX] in {
40310b57cec5SDimitry Andric    // Build vectors of floating point converted to i32.
40320b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
40330b57cec5SDimitry Andric                                   DblToInt.A, DblToInt.A)),
40340b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
40350b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
40360b57cec5SDimitry Andric                                   DblToUInt.A, DblToUInt.A)),
40370b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
40380b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
40390b57cec5SDimitry Andric              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
40400b57cec5SDimitry Andric                               (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
40410b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
40420b57cec5SDimitry Andric              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
40430b57cec5SDimitry Andric                               (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
40440b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
40450b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
40460b57cec5SDimitry Andric                                (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
40470b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
40480b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
40490b57cec5SDimitry Andric                                (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
40500b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
40510b57cec5SDimitry Andric              (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
40528bcb0991SDimitry Andric    def : Pat<(v2f64 (PPCldsplat xoaddr:$A)),
40538bcb0991SDimitry Andric              (v2f64 (LXVDSX xoaddr:$A))>;
40548bcb0991SDimitry Andric    def : Pat<(v2i64 (PPCldsplat xoaddr:$A)),
40558bcb0991SDimitry Andric              (v2i64 (LXVDSX xoaddr:$A))>;
40560b57cec5SDimitry Andric
40570b57cec5SDimitry Andric    // Build vectors of floating point converted to i64.
40580b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
40590b57cec5SDimitry Andric              (v2i64 (XXPERMDIs
40600b57cec5SDimitry Andric                       (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
40610b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
40620b57cec5SDimitry Andric              (v2i64 (XXPERMDIs
40630b57cec5SDimitry Andric                       (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
40640b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
40650b57cec5SDimitry Andric              (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
40660b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
40670b57cec5SDimitry Andric              (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
40680b57cec5SDimitry Andric  }
40690b57cec5SDimitry Andric
40700b57cec5SDimitry Andric  let Predicates = [HasVSX, NoP9Vector] in {
40710b57cec5SDimitry Andric    // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
40720b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
40730b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
40740b57cec5SDimitry Andric                                (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
40750b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
40760b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
40770b57cec5SDimitry Andric                                (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
40780b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
40790b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
40800b57cec5SDimitry Andric                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
40810b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
40820b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
40830b57cec5SDimitry Andric                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
40840b57cec5SDimitry Andric  }
40850b57cec5SDimitry Andric
40860b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP8Vector] in {
40870b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVU,
40880b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
40890b57cec5SDimitry Andric                              (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
40900b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVS,
40910b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
40920b57cec5SDimitry Andric                              (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
40930b57cec5SDimitry Andric    def : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src),
40940b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40950b57cec5SDimitry Andric    def : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src),
40960b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40970b57cec5SDimitry Andric
40980b57cec5SDimitry Andric    // Elements in a register on a BE system are in order <0, 1, 2, 3>.
40990b57cec5SDimitry Andric    // The store instructions store the second word from the left.
41000b57cec5SDimitry Andric    // So to align element zero, we need to modulo-left-shift by 3 words.
41010b57cec5SDimitry Andric    // Similar logic applies for elements 2 and 3.
41020b57cec5SDimitry Andric    foreach Idx = [ [0,3], [2,1], [3,2] ] in {
41030b57cec5SDimitry Andric      def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
41040b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
41050b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
41060b57cec5SDimitry Andric      def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
41070b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
41080b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
41090b57cec5SDimitry Andric    }
41100b57cec5SDimitry Andric  }
41110b57cec5SDimitry Andric
41120b57cec5SDimitry Andric  let Predicates = [HasP8Vector, IsBigEndian, NoP9Vector] in {
41130b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
41140b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
41150b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
41160b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
41170b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
41180b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
41190b57cec5SDimitry Andric                          xoaddr:$src)>;
41200b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
41210b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
41220b57cec5SDimitry Andric                          xoaddr:$src)>;
41230b57cec5SDimitry Andric   }
41240b57cec5SDimitry Andric
41250b57cec5SDimitry Andric  // Big endian, available on all targets with VSX
41260b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasVSX] in {
41270b57cec5SDimitry Andric    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
41280b57cec5SDimitry Andric              (v2f64 (XXPERMDI
41290b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $A, VSRC),
41300b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $B, VSRC), 0))>;
4131*480093f4SDimitry Andric    // Using VMRGEW to assemble the final vector would be a lower latency
4132*480093f4SDimitry Andric    // solution. However, we choose to go with the slightly higher latency
4133*480093f4SDimitry Andric    // XXPERMDI for 2 reasons:
4134*480093f4SDimitry Andric    // 1. This is likely to occur in unrolled loops where regpressure is high,
4135*480093f4SDimitry Andric    //    so we want to use the latter as it has access to all 64 VSX registers.
4136*480093f4SDimitry Andric    // 2. Using Altivec instructions in this sequence would likely cause the
4137*480093f4SDimitry Andric    //    allocation of Altivec registers even for the loads which in turn would
4138*480093f4SDimitry Andric    //    force the use of LXSIWZX for the loads, adding a cycle of latency to
4139*480093f4SDimitry Andric    //    each of the loads which would otherwise be able to use LFIWZX.
4140*480093f4SDimitry Andric    def : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
4141*480093f4SDimitry Andric              (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32A, MrgFP.LD32B),
4142*480093f4SDimitry Andric                               (XXMRGHW MrgFP.LD32C, MrgFP.LD32D), 3))>;
41430b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
41440b57cec5SDimitry Andric              (VMRGEW MrgFP.AC, MrgFP.BD)>;
41450b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
41460b57cec5SDimitry Andric                                   DblToFlt.B0, DblToFlt.B1)),
41470b57cec5SDimitry Andric              (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
41480b57cec5SDimitry Andric
41490b57cec5SDimitry Andric    // Convert 4 doubles to a vector of ints.
41500b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
41510b57cec5SDimitry Andric                                   DblToInt.C, DblToInt.D)),
41520b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
41530b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
41540b57cec5SDimitry Andric                                   DblToUInt.C, DblToUInt.D)),
41550b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
41560b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
41570b57cec5SDimitry Andric                                   ExtDbl.B0S, ExtDbl.B1S)),
41580b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
41590b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
41600b57cec5SDimitry Andric                                   ExtDbl.B0U, ExtDbl.B1U)),
41610b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
41620b57cec5SDimitry Andric  }
41630b57cec5SDimitry Andric
41640b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP8Vector] in {
41650b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVU,
41660b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
41670b57cec5SDimitry Andric                              (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
41680b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVS,
41690b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
41700b57cec5SDimitry Andric                              (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
41710b57cec5SDimitry Andric    def : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src),
41720b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
41730b57cec5SDimitry Andric    def : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src),
41740b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
41750b57cec5SDimitry Andric
41760b57cec5SDimitry Andric    // Elements in a register on a LE system are in order <3, 2, 1, 0>.
41770b57cec5SDimitry Andric    // The store instructions store the second word from the left.
41780b57cec5SDimitry Andric    // So to align element 3, we need to modulo-left-shift by 3 words.
41790b57cec5SDimitry Andric    // Similar logic applies for elements 0 and 1.
41800b57cec5SDimitry Andric    foreach Idx = [ [0,2], [1,1], [3,3] ] in {
41810b57cec5SDimitry Andric      def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
41820b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
41830b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
41840b57cec5SDimitry Andric      def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
41850b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
41860b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
41870b57cec5SDimitry Andric    }
41880b57cec5SDimitry Andric  }
41890b57cec5SDimitry Andric
41900b57cec5SDimitry Andric  let Predicates = [HasP8Vector, IsLittleEndian, NoP9Vector] in {
41910b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
41920b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
41930b57cec5SDimitry Andric                          xoaddr:$src)>;
41940b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
41950b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
41960b57cec5SDimitry Andric                          xoaddr:$src)>;
41970b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
41980b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
41990b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
42000b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
42010b57cec5SDimitry Andric   }
42020b57cec5SDimitry Andric
42030b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasVSX] in {
42040b57cec5SDimitry Andric  // Little endian, available on all targets with VSX
42050b57cec5SDimitry Andric    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
42060b57cec5SDimitry Andric              (v2f64 (XXPERMDI
42070b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $B, VSRC),
42080b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $A, VSRC), 0))>;
4209*480093f4SDimitry Andric    // Using VMRGEW to assemble the final vector would be a lower latency
4210*480093f4SDimitry Andric    // solution. However, we choose to go with the slightly higher latency
4211*480093f4SDimitry Andric    // XXPERMDI for 2 reasons:
4212*480093f4SDimitry Andric    // 1. This is likely to occur in unrolled loops where regpressure is high,
4213*480093f4SDimitry Andric    //    so we want to use the latter as it has access to all 64 VSX registers.
4214*480093f4SDimitry Andric    // 2. Using Altivec instructions in this sequence would likely cause the
4215*480093f4SDimitry Andric    //    allocation of Altivec registers even for the loads which in turn would
4216*480093f4SDimitry Andric    //    force the use of LXSIWZX for the loads, adding a cycle of latency to
4217*480093f4SDimitry Andric    //    each of the loads which would otherwise be able to use LFIWZX.
4218*480093f4SDimitry Andric    def : Pat<(v4f32 (build_vector LoadFP.A, LoadFP.B, LoadFP.C, LoadFP.D)),
4219*480093f4SDimitry Andric              (v4f32 (XXPERMDI (XXMRGHW MrgFP.LD32D, MrgFP.LD32C),
4220*480093f4SDimitry Andric                               (XXMRGHW MrgFP.LD32B, MrgFP.LD32A), 3))>;
42210b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
42220b57cec5SDimitry Andric              (VMRGEW MrgFP.AC, MrgFP.BD)>;
42230b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
42240b57cec5SDimitry Andric                                   DblToFlt.B0, DblToFlt.B1)),
42250b57cec5SDimitry Andric              (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
42260b57cec5SDimitry Andric
42270b57cec5SDimitry Andric    // Convert 4 doubles to a vector of ints.
42280b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
42290b57cec5SDimitry Andric                                   DblToInt.C, DblToInt.D)),
42300b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
42310b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
42320b57cec5SDimitry Andric                                   DblToUInt.C, DblToUInt.D)),
42330b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
42340b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
42350b57cec5SDimitry Andric                                   ExtDbl.B0S, ExtDbl.B1S)),
42360b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
42370b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
42380b57cec5SDimitry Andric                                   ExtDbl.B0U, ExtDbl.B1U)),
42390b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
42400b57cec5SDimitry Andric  }
42410b57cec5SDimitry Andric
42420b57cec5SDimitry Andric  let Predicates = [HasDirectMove] in {
42430b57cec5SDimitry Andric    // Endianness-neutral constant splat on P8 and newer targets. The reason
42440b57cec5SDimitry Andric    // for this pattern is that on targets with direct moves, we don't expand
42450b57cec5SDimitry Andric    // BUILD_VECTOR nodes for v4i32.
42460b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
42470b57cec5SDimitry Andric                                   immSExt5NonZero:$A, immSExt5NonZero:$A)),
42480b57cec5SDimitry Andric              (v4i32 (VSPLTISW imm:$A))>;
42490b57cec5SDimitry Andric  }
42500b57cec5SDimitry Andric
42510b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
42520b57cec5SDimitry Andric    // Big endian integer vectors using direct moves.
42530b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
42540b57cec5SDimitry Andric              (v2i64 (XXPERMDI
42550b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
42560b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
42570b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
42580b57cec5SDimitry Andric              (XXPERMDI
42590b57cec5SDimitry Andric                (COPY_TO_REGCLASS
42600b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
42610b57cec5SDimitry Andric                (COPY_TO_REGCLASS
42620b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
42630b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
42640b57cec5SDimitry Andric              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
42650b57cec5SDimitry Andric  }
42660b57cec5SDimitry Andric
42670b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
42680b57cec5SDimitry Andric    // Little endian integer vectors using direct moves.
42690b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
42700b57cec5SDimitry Andric              (v2i64 (XXPERMDI
42710b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
42720b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
42730b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
42740b57cec5SDimitry Andric              (XXPERMDI
42750b57cec5SDimitry Andric                (COPY_TO_REGCLASS
42760b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
42770b57cec5SDimitry Andric                (COPY_TO_REGCLASS
42780b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
42790b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
42800b57cec5SDimitry Andric              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
42810b57cec5SDimitry Andric  }
42820b57cec5SDimitry Andric
42838bcb0991SDimitry Andric  let Predicates = [HasP8Vector] in {
42848bcb0991SDimitry Andric    def : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
42858bcb0991SDimitry Andric              (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
42868bcb0991SDimitry Andric    def : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
42878bcb0991SDimitry Andric              (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
42888bcb0991SDimitry Andric    def : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
42898bcb0991SDimitry Andric              (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
42908bcb0991SDimitry Andric    def : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
42918bcb0991SDimitry Andric              (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
42928bcb0991SDimitry Andric  }
42938bcb0991SDimitry Andric
42940b57cec5SDimitry Andric  let Predicates = [HasP9Vector] in {
42950b57cec5SDimitry Andric    // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
42960b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector i32:$A)),
42970b57cec5SDimitry Andric              (v4i32 (MTVSRWS $A))>;
42980b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
42990b57cec5SDimitry Andric              (v4i32 (MTVSRWS $A))>;
43008bcb0991SDimitry Andric    def : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43018bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43028bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43038bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43048bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43058bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43068bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
43078bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
43080b57cec5SDimitry Andric              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
43090b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
43100b57cec5SDimitry Andric              (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
43110b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
43120b57cec5SDimitry Andric              (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
43130b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
43140b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
43150b57cec5SDimitry Andric                                (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>;
43160b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
43170b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
43180b57cec5SDimitry Andric                                (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>;
43190b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
43200b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
43210b57cec5SDimitry Andric                                              (DFLOADf32 iaddrX4:$A),
43220b57cec5SDimitry Andric                                              VSFRC)), 0))>;
43230b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
43240b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
43250b57cec5SDimitry Andric                                              (DFLOADf32 iaddrX4:$A),
43260b57cec5SDimitry Andric                                              VSFRC)), 0))>;
43278bcb0991SDimitry Andric    def : Pat<(v4f32 (PPCldsplat xoaddr:$A)),
43288bcb0991SDimitry Andric              (v4f32 (LXVWSX xoaddr:$A))>;
43298bcb0991SDimitry Andric    def : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
43308bcb0991SDimitry Andric              (v4i32 (LXVWSX xoaddr:$A))>;
43310b57cec5SDimitry Andric  }
43320b57cec5SDimitry Andric
43330b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
43340b57cec5SDimitry Andric    def : Pat<(i64 (extractelt v2i64:$A, 1)),
43350b57cec5SDimitry Andric              (i64 (MFVSRLD $A))>;
43360b57cec5SDimitry Andric    // Better way to build integer vectors if we have MTVSRDD. Big endian.
43370b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
43380b57cec5SDimitry Andric              (v2i64 (MTVSRDD $rB, $rA))>;
43390b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
43400b57cec5SDimitry Andric              (MTVSRDD
43410b57cec5SDimitry Andric                (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
43420b57cec5SDimitry Andric                (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
43430b57cec5SDimitry Andric  }
43440b57cec5SDimitry Andric
43450b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
43460b57cec5SDimitry Andric    def : Pat<(i64 (extractelt v2i64:$A, 0)),
43470b57cec5SDimitry Andric              (i64 (MFVSRLD $A))>;
43480b57cec5SDimitry Andric    // Better way to build integer vectors if we have MTVSRDD. Little endian.
43490b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
43500b57cec5SDimitry Andric              (v2i64 (MTVSRDD $rB, $rA))>;
43510b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
43520b57cec5SDimitry Andric              (MTVSRDD
43530b57cec5SDimitry Andric                (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
43540b57cec5SDimitry Andric                (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
43550b57cec5SDimitry Andric  }
43560b57cec5SDimitry Andric  // P9 Altivec instructions that can be used to build vectors.
43570b57cec5SDimitry Andric  // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
43580b57cec5SDimitry Andric  // with complexities of existing build vector patterns in this file.
43590b57cec5SDimitry Andric  let Predicates = [HasP9Altivec, IsLittleEndian] in {
43600b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
43610b57cec5SDimitry Andric              (v2i64 (VEXTSW2D $A))>;
43620b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
43630b57cec5SDimitry Andric              (v2i64 (VEXTSH2D $A))>;
43640b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
43650b57cec5SDimitry Andric                      HWordToWord.LE_A2, HWordToWord.LE_A3)),
43660b57cec5SDimitry Andric              (v4i32 (VEXTSH2W $A))>;
43670b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
43680b57cec5SDimitry Andric                      ByteToWord.LE_A2, ByteToWord.LE_A3)),
43690b57cec5SDimitry Andric              (v4i32 (VEXTSB2W $A))>;
43700b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
43710b57cec5SDimitry Andric              (v2i64 (VEXTSB2D $A))>;
43720b57cec5SDimitry Andric  }
43730b57cec5SDimitry Andric
43740b57cec5SDimitry Andric  let Predicates = [HasP9Altivec, IsBigEndian] in {
43750b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
43760b57cec5SDimitry Andric              (v2i64 (VEXTSW2D $A))>;
43770b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
43780b57cec5SDimitry Andric              (v2i64 (VEXTSH2D $A))>;
43790b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
43800b57cec5SDimitry Andric                      HWordToWord.BE_A2, HWordToWord.BE_A3)),
43810b57cec5SDimitry Andric              (v4i32 (VEXTSH2W $A))>;
43820b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
43830b57cec5SDimitry Andric                      ByteToWord.BE_A2, ByteToWord.BE_A3)),
43840b57cec5SDimitry Andric              (v4i32 (VEXTSB2W $A))>;
43850b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
43860b57cec5SDimitry Andric              (v2i64 (VEXTSB2D $A))>;
43870b57cec5SDimitry Andric  }
43880b57cec5SDimitry Andric
43890b57cec5SDimitry Andric  let Predicates = [HasP9Altivec] in {
43900b57cec5SDimitry Andric    def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)),
43910b57cec5SDimitry Andric              (v2i64 (VEXTSB2D $A))>;
43920b57cec5SDimitry Andric    def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)),
43930b57cec5SDimitry Andric              (v2i64 (VEXTSH2D $A))>;
43940b57cec5SDimitry Andric    def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)),
43950b57cec5SDimitry Andric              (v2i64 (VEXTSW2D $A))>;
43960b57cec5SDimitry Andric    def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)),
43970b57cec5SDimitry Andric              (v4i32 (VEXTSB2W $A))>;
43980b57cec5SDimitry Andric    def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)),
43990b57cec5SDimitry Andric              (v4i32 (VEXTSH2W $A))>;
44000b57cec5SDimitry Andric  }
44010b57cec5SDimitry Andric}
44020b57cec5SDimitry Andric
44030b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be
44040b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef.
44050b57cec5SDimitry Andriclet Predicates = [HasP9Altivec] in {
44060b57cec5SDimitry Andric
44070b57cec5SDimitry Andric  def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
44080b57cec5SDimitry Andric            (v4i32 (VABSDUW $A, $B))>;
44090b57cec5SDimitry Andric
44100b57cec5SDimitry Andric  def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
44110b57cec5SDimitry Andric            (v8i16 (VABSDUH $A, $B))>;
44120b57cec5SDimitry Andric
44130b57cec5SDimitry Andric  def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
44140b57cec5SDimitry Andric            (v16i8 (VABSDUB $A, $B))>;
44150b57cec5SDimitry Andric
44160b57cec5SDimitry Andric  // As PPCVABSD description, the last operand indicates whether do the
44170b57cec5SDimitry Andric  // sign bit flip.
44180b57cec5SDimitry Andric  def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
44190b57cec5SDimitry Andric            (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
44200b57cec5SDimitry Andric}
4421