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
1230b57cec5SDimitry Andric    def o    : 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)))]>,
1270b57cec5SDimitry Andric                       isDOT;
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 Andriclet Uses = [RM] in {
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric  // Load indexed instructions
1580b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
1590b57cec5SDimitry Andric    let CodeSize = 3 in
1600b57cec5SDimitry Andric    def LXSDX : XX1Form_memOp<31, 588,
1610b57cec5SDimitry Andric                        (outs vsfrc:$XT), (ins memrr:$src),
1620b57cec5SDimitry Andric                        "lxsdx $XT, $src", IIC_LdStLFD,
1630b57cec5SDimitry Andric                        []>;
1640b57cec5SDimitry Andric
1650b57cec5SDimitry Andric    // Pseudo instruction XFLOADf64 will be expanded to LXSDX or LFDX later
1660b57cec5SDimitry Andric    let CodeSize = 3 in
1670b57cec5SDimitry Andric      def XFLOADf64  : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
1680b57cec5SDimitry Andric                              "#XFLOADf64",
1690b57cec5SDimitry Andric                              [(set f64:$XT, (load xoaddr:$src))]>;
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
1720b57cec5SDimitry Andric    def LXVD2X : XX1Form_memOp<31, 844,
1730b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
1740b57cec5SDimitry Andric                         "lxvd2x $XT, $src", IIC_LdStLFD,
1750b57cec5SDimitry Andric                         [(set v2f64:$XT, (int_ppc_vsx_lxvd2x xoaddr:$src))]>;
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric    def LXVDSX : XX1Form_memOp<31, 332,
1780b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
1790b57cec5SDimitry Andric                         "lxvdsx $XT, $src", IIC_LdStLFD, []>;
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in
1820b57cec5SDimitry Andric    def LXVW4X : XX1Form_memOp<31, 780,
1830b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins memrr:$src),
1840b57cec5SDimitry Andric                         "lxvw4x $XT, $src", IIC_LdStLFD,
1850b57cec5SDimitry Andric                         []>;
1860b57cec5SDimitry Andric  } // mayLoad
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric  // Store indexed instructions
1890b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
1900b57cec5SDimitry Andric    let CodeSize = 3 in
1910b57cec5SDimitry Andric    def STXSDX : XX1Form_memOp<31, 716,
1920b57cec5SDimitry Andric                        (outs), (ins vsfrc:$XT, memrr:$dst),
1930b57cec5SDimitry Andric                        "stxsdx $XT, $dst", IIC_LdStSTFD,
1940b57cec5SDimitry Andric                        []>;
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf64  will be expanded to STXSDX or STFDX later
1970b57cec5SDimitry Andric    let CodeSize = 3 in
1980b57cec5SDimitry Andric      def XFSTOREf64 : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
1990b57cec5SDimitry Andric                              "#XFSTOREf64",
2000b57cec5SDimitry Andric                              [(store f64:$XT, xoaddr:$dst)]>;
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric    let Predicates = [HasVSX, HasOnlySwappingMemOps] in {
2030b57cec5SDimitry Andric    // The behaviour of this instruction is endianness-specific so we provide no
2040b57cec5SDimitry Andric    // pattern to match it without considering endianness.
2050b57cec5SDimitry Andric    def STXVD2X : XX1Form_memOp<31, 972,
2060b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
2070b57cec5SDimitry Andric                         "stxvd2x $XT, $dst", IIC_LdStSTFD,
2080b57cec5SDimitry Andric                         []>;
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric    def STXVW4X : XX1Form_memOp<31, 908,
2110b57cec5SDimitry Andric                         (outs), (ins vsrc:$XT, memrr:$dst),
2120b57cec5SDimitry Andric                         "stxvw4x $XT, $dst", IIC_LdStSTFD,
2130b57cec5SDimitry Andric                         []>;
2140b57cec5SDimitry Andric    }
2150b57cec5SDimitry Andric  } // mayStore
2160b57cec5SDimitry Andric
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
12580b57cec5SDimitry Andricdef ScalarLoads {
12590b57cec5SDimitry Andric  dag Li8 =       (i32 (extloadi8 xoaddr:$src));
12600b57cec5SDimitry Andric  dag ZELi8 =     (i32 (zextloadi8 xoaddr:$src));
12610b57cec5SDimitry Andric  dag ZELi8i64 =  (i64 (zextloadi8 xoaddr:$src));
12620b57cec5SDimitry Andric  dag SELi8 =     (i32 (sext_inreg (extloadi8 xoaddr:$src), i8));
12630b57cec5SDimitry Andric  dag SELi8i64 =  (i64 (sext_inreg (extloadi8 xoaddr:$src), i8));
12640b57cec5SDimitry Andric
12650b57cec5SDimitry Andric  dag Li16 =      (i32 (extloadi16 xoaddr:$src));
12660b57cec5SDimitry Andric  dag ZELi16 =    (i32 (zextloadi16 xoaddr:$src));
12670b57cec5SDimitry Andric  dag ZELi16i64 = (i64 (zextloadi16 xoaddr:$src));
12680b57cec5SDimitry Andric  dag SELi16 =    (i32 (sextloadi16 xoaddr:$src));
12690b57cec5SDimitry Andric  dag SELi16i64 = (i64 (sextloadi16 xoaddr:$src));
12700b57cec5SDimitry Andric
12710b57cec5SDimitry Andric  dag Li32 = (i32 (load xoaddr:$src));
12720b57cec5SDimitry Andric}
12730b57cec5SDimitry Andric
12740b57cec5SDimitry Andricdef DWToSPExtractConv {
12750b57cec5SDimitry Andric  dag El0US1 = (f32 (PPCfcfidus
12760b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
12770b57cec5SDimitry Andric  dag El1US1 = (f32 (PPCfcfidus
12780b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
12790b57cec5SDimitry Andric  dag El0US2 = (f32 (PPCfcfidus
12800b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
12810b57cec5SDimitry Andric  dag El1US2 = (f32 (PPCfcfidus
12820b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
12830b57cec5SDimitry Andric  dag El0SS1 = (f32 (PPCfcfids
12840b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 0))))));
12850b57cec5SDimitry Andric  dag El1SS1 = (f32 (PPCfcfids
12860b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S1, 1))))));
12870b57cec5SDimitry Andric  dag El0SS2 = (f32 (PPCfcfids
12880b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 0))))));
12890b57cec5SDimitry Andric  dag El1SS2 = (f32 (PPCfcfids
12900b57cec5SDimitry Andric                    (f64 (PPCmtvsra (i64 (vector_extract v2i64:$S2, 1))))));
12910b57cec5SDimitry Andric  dag BVU = (v4f32 (build_vector El0US1, El1US1, El0US2, El1US2));
12920b57cec5SDimitry Andric  dag BVS = (v4f32 (build_vector El0SS1, El1SS1, El0SS2, El1SS2));
12930b57cec5SDimitry Andric}
12940b57cec5SDimitry Andric
12950b57cec5SDimitry Andric// The following VSX instructions were introduced in Power ISA 2.07
12960b57cec5SDimitry Andric/* FIXME: if the operands are v2i64, these patterns will not match.
12970b57cec5SDimitry Andric   we should define new patterns or otherwise match the same patterns
12980b57cec5SDimitry Andric   when the elements are larger than i32.
12990b57cec5SDimitry Andric*/
13000b57cec5SDimitry Andricdef HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
13010b57cec5SDimitry Andricdef HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
13020b57cec5SDimitry Andricdef NoP9Vector : Predicate<"!PPCSubTarget->hasP9Vector()">;
13030b57cec5SDimitry Andriclet Predicates = [HasP8Vector] in {
13040b57cec5SDimitry Andriclet AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX patterns.
13050b57cec5SDimitry Andric  let isCommutable = 1 in {
13060b57cec5SDimitry Andric    def XXLEQV : XX3Form<60, 186,
13070b57cec5SDimitry Andric                         (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
13080b57cec5SDimitry Andric                         "xxleqv $XT, $XA, $XB", IIC_VecGeneral,
13090b57cec5SDimitry Andric                         [(set v4i32:$XT, (vnot_ppc (xor v4i32:$XA, v4i32:$XB)))]>;
13100b57cec5SDimitry Andric    def XXLNAND : XX3Form<60, 178,
13110b57cec5SDimitry Andric                          (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
13120b57cec5SDimitry Andric                          "xxlnand $XT, $XA, $XB", IIC_VecGeneral,
13130b57cec5SDimitry Andric                          [(set v4i32:$XT, (vnot_ppc (and v4i32:$XA,
13140b57cec5SDimitry Andric                                                    v4i32:$XB)))]>;
13150b57cec5SDimitry Andric  } // isCommutable
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_xxleqv v4i32:$A, v4i32:$B),
13180b57cec5SDimitry Andric            (XXLEQV $A, $B)>;
13190b57cec5SDimitry Andric
13208bcb0991SDimitry Andric  let isCodeGenOnly = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
13218bcb0991SDimitry Andric      isReMaterializable = 1 in {
13228bcb0991SDimitry Andric    def XXLEQVOnes : XX3Form_SameOp<60, 186, (outs vsrc:$XT), (ins),
13238bcb0991SDimitry Andric                         "xxleqv $XT, $XT, $XT", IIC_VecGeneral,
13248bcb0991SDimitry Andric                         [(set v4i32:$XT, (bitconvert (v16i8 immAllOnesV)))]>;
13258bcb0991SDimitry Andric  }
13268bcb0991SDimitry Andric
13270b57cec5SDimitry Andric  def XXLORC : XX3Form<60, 170,
13280b57cec5SDimitry Andric                       (outs vsrc:$XT), (ins vsrc:$XA, vsrc:$XB),
13290b57cec5SDimitry Andric                       "xxlorc $XT, $XA, $XB", IIC_VecGeneral,
13300b57cec5SDimitry Andric                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc v4i32:$XB)))]>;
13310b57cec5SDimitry Andric
13320b57cec5SDimitry Andric  // VSX scalar loads introduced in ISA 2.07
13330b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
13340b57cec5SDimitry Andric    let CodeSize = 3 in
13350b57cec5SDimitry Andric    def LXSSPX : XX1Form_memOp<31, 524, (outs vssrc:$XT), (ins memrr:$src),
13360b57cec5SDimitry Andric                         "lxsspx $XT, $src", IIC_LdStLFD, []>;
13370b57cec5SDimitry Andric    def LXSIWAX : XX1Form_memOp<31, 76, (outs vsfrc:$XT), (ins memrr:$src),
13380b57cec5SDimitry Andric                          "lxsiwax $XT, $src", IIC_LdStLFD, []>;
13390b57cec5SDimitry Andric    def LXSIWZX : XX1Form_memOp<31, 12, (outs vsfrc:$XT), (ins memrr:$src),
13400b57cec5SDimitry Andric                          "lxsiwzx $XT, $src", IIC_LdStLFD, []>;
13410b57cec5SDimitry Andric
13420b57cec5SDimitry Andric    // Pseudo instruction XFLOADf32 will be expanded to LXSSPX or LFSX later
13430b57cec5SDimitry Andric    let CodeSize = 3 in
13440b57cec5SDimitry Andric    def XFLOADf32  : PseudoXFormMemOp<(outs vssrc:$XT), (ins memrr:$src),
13450b57cec5SDimitry Andric                            "#XFLOADf32",
13460b57cec5SDimitry Andric                            [(set f32:$XT, (load xoaddr:$src))]>;
13470b57cec5SDimitry Andric    // Pseudo instruction LIWAX will be expanded to LXSIWAX or LFIWAX later
13480b57cec5SDimitry Andric    def LIWAX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
13490b57cec5SDimitry Andric                       "#LIWAX",
13500b57cec5SDimitry Andric                       [(set f64:$XT, (PPClfiwax xoaddr:$src))]>;
13510b57cec5SDimitry Andric    // Pseudo instruction LIWZX will be expanded to LXSIWZX or LFIWZX later
13520b57cec5SDimitry Andric    def LIWZX : PseudoXFormMemOp<(outs vsfrc:$XT), (ins memrr:$src),
13530b57cec5SDimitry Andric                       "#LIWZX",
13540b57cec5SDimitry Andric                       [(set f64:$XT, (PPClfiwzx xoaddr:$src))]>;
13550b57cec5SDimitry Andric  } // mayLoad
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andric  // VSX scalar stores introduced in ISA 2.07
13580b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
13590b57cec5SDimitry Andric    let CodeSize = 3 in
13600b57cec5SDimitry Andric    def STXSSPX : XX1Form_memOp<31, 652, (outs), (ins vssrc:$XT, memrr:$dst),
13610b57cec5SDimitry Andric                          "stxsspx $XT, $dst", IIC_LdStSTFD, []>;
13620b57cec5SDimitry Andric    def STXSIWX : XX1Form_memOp<31, 140, (outs), (ins vsfrc:$XT, memrr:$dst),
13630b57cec5SDimitry Andric                          "stxsiwx $XT, $dst", IIC_LdStSTFD, []>;
13640b57cec5SDimitry Andric
13650b57cec5SDimitry Andric    // Pseudo instruction XFSTOREf32 will be expanded to STXSSPX or STFSX later
13660b57cec5SDimitry Andric    let CodeSize = 3 in
13670b57cec5SDimitry Andric    def XFSTOREf32 : PseudoXFormMemOp<(outs), (ins vssrc:$XT, memrr:$dst),
13680b57cec5SDimitry Andric                            "#XFSTOREf32",
13690b57cec5SDimitry Andric                            [(store f32:$XT, xoaddr:$dst)]>;
13700b57cec5SDimitry Andric    // Pseudo instruction STIWX will be expanded to STXSIWX or STFIWX later
13710b57cec5SDimitry Andric    def STIWX : PseudoXFormMemOp<(outs), (ins vsfrc:$XT, memrr:$dst),
13720b57cec5SDimitry Andric                       "#STIWX",
13730b57cec5SDimitry Andric                      [(PPCstfiwx f64:$XT, xoaddr:$dst)]>;
13740b57cec5SDimitry Andric  } // mayStore
13750b57cec5SDimitry Andric
13760b57cec5SDimitry Andric  def : Pat<(f64 (extloadf32 xoaddr:$src)),
13770b57cec5SDimitry Andric            (COPY_TO_REGCLASS (XFLOADf32 xoaddr:$src), VSFRC)>;
13780b57cec5SDimitry Andric  def : Pat<(f32 (fpround (f64 (extloadf32 xoaddr:$src)))),
13790b57cec5SDimitry Andric            (f32 (XFLOADf32 xoaddr:$src))>;
13800b57cec5SDimitry Andric  def : Pat<(f64 (fpextend f32:$src)),
13810b57cec5SDimitry Andric            (COPY_TO_REGCLASS $src, VSFRC)>;
13820b57cec5SDimitry Andric
13830b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
13840b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
13850b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
13860b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
13870b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
13880b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
13890b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
13900b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
13910b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
13920b57cec5SDimitry Andric            (SELECT_VSSRC (CREQV $lhs, $rhs), $tval, $fval)>;
13930b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
13940b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $rhs, $lhs), $tval, $fval)>;
13950b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
13960b57cec5SDimitry Andric            (SELECT_VSSRC (CRORC  $lhs, $rhs), $tval, $fval)>;
13970b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
13980b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $rhs, $lhs), $tval, $fval)>;
13990b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
14000b57cec5SDimitry Andric            (SELECT_VSSRC (CRANDC $lhs, $rhs), $tval, $fval)>;
14010b57cec5SDimitry Andric  def : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
14020b57cec5SDimitry Andric            (SELECT_VSSRC (CRXOR $lhs, $rhs), $tval, $fval)>;
14030b57cec5SDimitry Andric
14040b57cec5SDimitry Andric  // VSX Elementary Scalar FP arithmetic (SP)
14050b57cec5SDimitry Andric  let isCommutable = 1 in {
14060b57cec5SDimitry Andric    def XSADDSP : XX3Form<60, 0,
14070b57cec5SDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14080b57cec5SDimitry Andric                          "xsaddsp $XT, $XA, $XB", IIC_VecFP,
14090b57cec5SDimitry Andric                          [(set f32:$XT, (fadd f32:$XA, f32:$XB))]>;
14100b57cec5SDimitry Andric    def XSMULSP : XX3Form<60, 16,
14110b57cec5SDimitry Andric                          (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14120b57cec5SDimitry Andric                          "xsmulsp $XT, $XA, $XB", IIC_VecFP,
14130b57cec5SDimitry Andric                          [(set f32:$XT, (fmul f32:$XA, f32:$XB))]>;
14140b57cec5SDimitry Andric  } // isCommutable
14150b57cec5SDimitry Andric  def XSSUBSP : XX3Form<60, 8,
14160b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14170b57cec5SDimitry Andric                        "xssubsp $XT, $XA, $XB", IIC_VecFP,
14180b57cec5SDimitry Andric                        [(set f32:$XT, (fsub f32:$XA, f32:$XB))]>;
14190b57cec5SDimitry Andric  def XSDIVSP : XX3Form<60, 24,
14200b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XA, vssrc:$XB),
14210b57cec5SDimitry Andric                        "xsdivsp $XT, $XA, $XB", IIC_FPDivS,
14220b57cec5SDimitry Andric                        [(set f32:$XT, (fdiv f32:$XA, f32:$XB))]>;
14230b57cec5SDimitry Andric  def XSRESP : XX2Form<60, 26,
14240b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
14250b57cec5SDimitry Andric                        "xsresp $XT, $XB", IIC_VecFP,
14260b57cec5SDimitry Andric                        [(set f32:$XT, (PPCfre f32:$XB))]>;
14270b57cec5SDimitry Andric  def XSRSP : XX2Form<60, 281,
14280b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vsfrc:$XB),
14290b57cec5SDimitry Andric                        "xsrsp $XT, $XB", IIC_VecFP, []>;
14300b57cec5SDimitry Andric  def XSSQRTSP : XX2Form<60, 11,
14310b57cec5SDimitry Andric                        (outs vssrc:$XT), (ins vssrc:$XB),
14320b57cec5SDimitry Andric                        "xssqrtsp $XT, $XB", IIC_FPSqrtS,
14330b57cec5SDimitry Andric                        [(set f32:$XT, (fsqrt f32:$XB))]>;
14340b57cec5SDimitry Andric  def XSRSQRTESP : XX2Form<60, 10,
14350b57cec5SDimitry Andric                           (outs vssrc:$XT), (ins vssrc:$XB),
14360b57cec5SDimitry Andric                           "xsrsqrtesp $XT, $XB", IIC_VecFP,
14370b57cec5SDimitry Andric                           [(set f32:$XT, (PPCfrsqrte f32:$XB))]>;
14380b57cec5SDimitry Andric
14390b57cec5SDimitry Andric  // FMA Instructions
14400b57cec5SDimitry Andric  let BaseName = "XSMADDASP" in {
14410b57cec5SDimitry Andric  let isCommutable = 1 in
14420b57cec5SDimitry Andric  def XSMADDASP : XX3Form<60, 1,
14430b57cec5SDimitry Andric                          (outs vssrc:$XT),
14440b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14450b57cec5SDimitry Andric                          "xsmaddasp $XT, $XA, $XB", IIC_VecFP,
14460b57cec5SDimitry Andric                          [(set f32:$XT, (fma f32:$XA, f32:$XB, f32:$XTi))]>,
14470b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14480b57cec5SDimitry Andric                          AltVSXFMARel;
14490b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
14500b57cec5SDimitry Andric  def XSMADDMSP : XX3Form<60, 9,
14510b57cec5SDimitry Andric                          (outs vssrc:$XT),
14520b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14530b57cec5SDimitry Andric                          "xsmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
14540b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14550b57cec5SDimitry Andric                          AltVSXFMARel;
14560b57cec5SDimitry Andric  }
14570b57cec5SDimitry Andric
14580b57cec5SDimitry Andric  let BaseName = "XSMSUBASP" in {
14590b57cec5SDimitry Andric  let isCommutable = 1 in
14600b57cec5SDimitry Andric  def XSMSUBASP : XX3Form<60, 17,
14610b57cec5SDimitry Andric                          (outs vssrc:$XT),
14620b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14630b57cec5SDimitry Andric                          "xsmsubasp $XT, $XA, $XB", IIC_VecFP,
14640b57cec5SDimitry Andric                          [(set f32:$XT, (fma f32:$XA, f32:$XB,
14650b57cec5SDimitry Andric                                              (fneg f32:$XTi)))]>,
14660b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14670b57cec5SDimitry Andric                          AltVSXFMARel;
14680b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
14690b57cec5SDimitry Andric  def XSMSUBMSP : XX3Form<60, 25,
14700b57cec5SDimitry Andric                          (outs vssrc:$XT),
14710b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14720b57cec5SDimitry Andric                          "xsmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
14730b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14740b57cec5SDimitry Andric                          AltVSXFMARel;
14750b57cec5SDimitry Andric  }
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andric  let BaseName = "XSNMADDASP" in {
14780b57cec5SDimitry Andric  let isCommutable = 1 in
14790b57cec5SDimitry Andric  def XSNMADDASP : XX3Form<60, 129,
14800b57cec5SDimitry Andric                          (outs vssrc:$XT),
14810b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14820b57cec5SDimitry Andric                          "xsnmaddasp $XT, $XA, $XB", IIC_VecFP,
14830b57cec5SDimitry Andric                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
14840b57cec5SDimitry Andric                                                    f32:$XTi)))]>,
14850b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14860b57cec5SDimitry Andric                          AltVSXFMARel;
14870b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
14880b57cec5SDimitry Andric  def XSNMADDMSP : XX3Form<60, 137,
14890b57cec5SDimitry Andric                          (outs vssrc:$XT),
14900b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
14910b57cec5SDimitry Andric                          "xsnmaddmsp $XT, $XA, $XB", IIC_VecFP, []>,
14920b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
14930b57cec5SDimitry Andric                          AltVSXFMARel;
14940b57cec5SDimitry Andric  }
14950b57cec5SDimitry Andric
14960b57cec5SDimitry Andric  let BaseName = "XSNMSUBASP" in {
14970b57cec5SDimitry Andric  let isCommutable = 1 in
14980b57cec5SDimitry Andric  def XSNMSUBASP : XX3Form<60, 145,
14990b57cec5SDimitry Andric                          (outs vssrc:$XT),
15000b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15010b57cec5SDimitry Andric                          "xsnmsubasp $XT, $XA, $XB", IIC_VecFP,
15020b57cec5SDimitry Andric                          [(set f32:$XT, (fneg (fma f32:$XA, f32:$XB,
15030b57cec5SDimitry Andric                                                    (fneg f32:$XTi))))]>,
15040b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15050b57cec5SDimitry Andric                          AltVSXFMARel;
15060b57cec5SDimitry Andric  let IsVSXFMAAlt = 1 in
15070b57cec5SDimitry Andric  def XSNMSUBMSP : XX3Form<60, 153,
15080b57cec5SDimitry Andric                          (outs vssrc:$XT),
15090b57cec5SDimitry Andric                          (ins vssrc:$XTi, vssrc:$XA, vssrc:$XB),
15100b57cec5SDimitry Andric                          "xsnmsubmsp $XT, $XA, $XB", IIC_VecFP, []>,
15110b57cec5SDimitry Andric                          RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">,
15120b57cec5SDimitry Andric                          AltVSXFMARel;
15130b57cec5SDimitry Andric  }
15140b57cec5SDimitry Andric
15158bcb0991SDimitry Andric  // Additional xsnmsubasp patterns: -a*b + c == -(a*b - c)
15168bcb0991SDimitry Andric  def : Pat<(fma (fneg f32:$A), f32:$B, f32:$C),
15178bcb0991SDimitry Andric            (XSNMSUBASP $C, $A, $B)>;
15188bcb0991SDimitry Andric  def : Pat<(fma f32:$A, (fneg f32:$B), f32:$C),
15198bcb0991SDimitry Andric            (XSNMSUBASP $C, $A, $B)>;
15208bcb0991SDimitry Andric
15210b57cec5SDimitry Andric  // Single Precision Conversions (FP <-> INT)
15220b57cec5SDimitry Andric  def XSCVSXDSP : XX2Form<60, 312,
15230b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
15240b57cec5SDimitry Andric                      "xscvsxdsp $XT, $XB", IIC_VecFP,
15250b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfcfids f64:$XB))]>;
15260b57cec5SDimitry Andric  def XSCVUXDSP : XX2Form<60, 296,
15270b57cec5SDimitry Andric                      (outs vssrc:$XT), (ins vsfrc:$XB),
15280b57cec5SDimitry Andric                      "xscvuxdsp $XT, $XB", IIC_VecFP,
15290b57cec5SDimitry Andric                      [(set f32:$XT, (PPCfcfidus f64:$XB))]>;
15300b57cec5SDimitry Andric
15310b57cec5SDimitry Andric  // Conversions between vector and scalar single precision
15320b57cec5SDimitry Andric  def XSCVDPSPN : XX2Form<60, 267, (outs vsrc:$XT), (ins vssrc:$XB),
15330b57cec5SDimitry Andric                          "xscvdpspn $XT, $XB", IIC_VecFP, []>;
15340b57cec5SDimitry Andric  def XSCVSPDPN : XX2Form<60, 331, (outs vssrc:$XT), (ins vsrc:$XB),
15350b57cec5SDimitry Andric                          "xscvspdpn $XT, $XB", IIC_VecFP, []>;
15360b57cec5SDimitry Andric
15370b57cec5SDimitry Andric  let Predicates = [IsLittleEndian] in {
15380b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0SS1,
15390b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
15400b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1SS1,
15410b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS
15420b57cec5SDimitry Andric                              (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
15430b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0US1,
15440b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
15450b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1US1,
15460b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS
15470b57cec5SDimitry Andric                              (f64 (COPY_TO_REGCLASS $S1, VSRC)), VSFRC)))>;
15480b57cec5SDimitry Andric  }
15490b57cec5SDimitry Andric
15500b57cec5SDimitry Andric  let Predicates = [IsBigEndian] in {
15510b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0SS1,
15520b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
15530b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1SS1,
15540b57cec5SDimitry Andric            (f32 (XSCVSXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
15550b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El0US1,
15560b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS $S1, VSFRC)))>;
15570b57cec5SDimitry Andric  def : Pat<DWToSPExtractConv.El1US1,
15580b57cec5SDimitry Andric            (f32 (XSCVUXDSP (COPY_TO_REGCLASS (XXPERMDI $S1, $S1, 2), VSFRC)))>;
15590b57cec5SDimitry Andric  }
15600b57cec5SDimitry Andric
15610b57cec5SDimitry Andric  // Instructions for converting float to i64 feeding a store.
15620b57cec5SDimitry Andric  let Predicates = [NoP9Vector] in {
15630b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
15640b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 8),
15650b57cec5SDimitry Andric            (STXSDX (XSCVDPSXDS f64:$src), xoaddr:$dst)>;
15660b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
15670b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 8),
15680b57cec5SDimitry Andric            (STXSDX (XSCVDPUXDS f64:$src), xoaddr:$dst)>;
15690b57cec5SDimitry Andric  }
15700b57cec5SDimitry Andric
15710b57cec5SDimitry Andric  // Instructions for converting float to i32 feeding a store.
15720b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
15730b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 4),
15740b57cec5SDimitry Andric            (STIWX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
15750b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
15760b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 4),
15770b57cec5SDimitry Andric            (STIWX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
15780b57cec5SDimitry Andric
15790b57cec5SDimitry Andric  def : Pat<(v2i64 (smax v2i64:$src1, v2i64:$src2)),
15800b57cec5SDimitry Andric            (v2i64 (VMAXSD (COPY_TO_REGCLASS $src1, VRRC),
15810b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
15820b57cec5SDimitry Andric  def : Pat<(v2i64 (umax v2i64:$src1, v2i64:$src2)),
15830b57cec5SDimitry Andric            (v2i64 (VMAXUD (COPY_TO_REGCLASS $src1, VRRC),
15840b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
15850b57cec5SDimitry Andric  def : Pat<(v2i64 (smin v2i64:$src1, v2i64:$src2)),
15860b57cec5SDimitry Andric            (v2i64 (VMINSD (COPY_TO_REGCLASS $src1, VRRC),
15870b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
15880b57cec5SDimitry Andric  def : Pat<(v2i64 (umin v2i64:$src1, v2i64:$src2)),
15890b57cec5SDimitry Andric            (v2i64 (VMINUD (COPY_TO_REGCLASS $src1, VRRC),
15900b57cec5SDimitry Andric                           (COPY_TO_REGCLASS $src2, VRRC)))>;
15910b57cec5SDimitry Andric} // AddedComplexity = 400
15920b57cec5SDimitry Andric} // HasP8Vector
15930b57cec5SDimitry Andric
15940b57cec5SDimitry Andriclet AddedComplexity = 400 in {
15950b57cec5SDimitry Andriclet Predicates = [HasDirectMove] in {
15960b57cec5SDimitry Andric  // VSX direct move instructions
15970b57cec5SDimitry Andric  def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsfrc:$XT),
15980b57cec5SDimitry Andric                              "mfvsrd $rA, $XT", IIC_VecGeneral,
15990b57cec5SDimitry Andric                              [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
16000b57cec5SDimitry Andric      Requires<[In64BitMode]>;
16010b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
16020b57cec5SDimitry Andric  def MFVRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins vsrc:$XT),
16030b57cec5SDimitry Andric                             "mfvsrd $rA, $XT", IIC_VecGeneral,
16040b57cec5SDimitry Andric                             []>,
16050b57cec5SDimitry Andric      Requires<[In64BitMode]>;
16060b57cec5SDimitry Andric  def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsfrc:$XT),
16070b57cec5SDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
16080b57cec5SDimitry Andric                               [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
16098bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16108bcb0991SDimitry Andric  def MFVRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins vsrc:$XT),
16118bcb0991SDimitry Andric                               "mfvsrwz $rA, $XT", IIC_VecGeneral,
16128bcb0991SDimitry Andric                               []>;
16130b57cec5SDimitry Andric  def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins g8rc:$rA),
16140b57cec5SDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
16150b57cec5SDimitry Andric                              [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
16160b57cec5SDimitry Andric      Requires<[In64BitMode]>;
16178bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16188bcb0991SDimitry Andric  def MTVRD : XX1_RS6_RD5_XO<31, 179, (outs vsrc:$XT), (ins g8rc:$rA),
16198bcb0991SDimitry Andric                              "mtvsrd $XT, $rA", IIC_VecGeneral,
16208bcb0991SDimitry Andric                              []>,
16218bcb0991SDimitry Andric      Requires<[In64BitMode]>;
16220b57cec5SDimitry Andric  def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins gprc:$rA),
16230b57cec5SDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
16240b57cec5SDimitry Andric                               [(set f64:$XT, (PPCmtvsra i32:$rA))]>;
16258bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16268bcb0991SDimitry Andric  def MTVRWA : XX1_RS6_RD5_XO<31, 211, (outs vsrc:$XT), (ins gprc:$rA),
16278bcb0991SDimitry Andric                               "mtvsrwa $XT, $rA", IIC_VecGeneral,
16288bcb0991SDimitry Andric                               []>;
16290b57cec5SDimitry Andric  def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins gprc:$rA),
16300b57cec5SDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
16310b57cec5SDimitry Andric                               [(set f64:$XT, (PPCmtvsrz i32:$rA))]>;
16328bcb0991SDimitry Andric  let isCodeGenOnly = 1 in
16338bcb0991SDimitry Andric  def MTVRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsrc:$XT), (ins gprc:$rA),
16348bcb0991SDimitry Andric                               "mtvsrwz $XT, $rA", IIC_VecGeneral,
16358bcb0991SDimitry Andric                               []>;
16360b57cec5SDimitry Andric} // HasDirectMove
16370b57cec5SDimitry Andric
16380b57cec5SDimitry Andriclet Predicates = [IsISA3_0, HasDirectMove] in {
16390b57cec5SDimitry Andric  def MTVSRWS: XX1_RS6_RD5_XO<31, 403, (outs vsrc:$XT), (ins gprc:$rA),
16400b57cec5SDimitry Andric                              "mtvsrws $XT, $rA", IIC_VecGeneral, []>;
16410b57cec5SDimitry Andric
16420b57cec5SDimitry Andric  def MTVSRDD: XX1Form<31, 435, (outs vsrc:$XT), (ins g8rc_nox0:$rA, g8rc:$rB),
16430b57cec5SDimitry Andric                       "mtvsrdd $XT, $rA, $rB", IIC_VecGeneral,
16440b57cec5SDimitry Andric                       []>, Requires<[In64BitMode]>;
16450b57cec5SDimitry Andric
16460b57cec5SDimitry Andric  def MFVSRLD: XX1_RS6_RD5_XO<31, 307, (outs g8rc:$rA), (ins vsrc:$XT),
16470b57cec5SDimitry Andric                              "mfvsrld $rA, $XT", IIC_VecGeneral,
16480b57cec5SDimitry Andric                              []>, Requires<[In64BitMode]>;
16490b57cec5SDimitry Andric
16500b57cec5SDimitry Andric} // IsISA3_0, HasDirectMove
16510b57cec5SDimitry Andric} // AddedComplexity = 400
16520b57cec5SDimitry Andric
16530b57cec5SDimitry Andric// We want to parse this from asm, but we don't want to emit this as it would
16540b57cec5SDimitry Andric// be emitted with a VSX reg. So leave Emit = 0 here.
16550b57cec5SDimitry Andricdef : InstAlias<"mfvrd $rA, $XT",
16560b57cec5SDimitry Andric                (MFVRD g8rc:$rA, vrrc:$XT), 0>;
16570b57cec5SDimitry Andricdef : InstAlias<"mffprd $rA, $src",
16580b57cec5SDimitry Andric                (MFVSRD g8rc:$rA, f8rc:$src)>;
16598bcb0991SDimitry Andricdef : InstAlias<"mtvrd $XT, $rA",
16608bcb0991SDimitry Andric                (MTVRD vrrc:$XT, g8rc:$rA), 0>;
16618bcb0991SDimitry Andricdef : InstAlias<"mtfprd $dst, $rA",
16628bcb0991SDimitry Andric                (MTVSRD f8rc:$dst, g8rc:$rA)>;
16638bcb0991SDimitry Andricdef : InstAlias<"mfvrwz $rA, $XT",
16648bcb0991SDimitry Andric                (MFVRWZ gprc:$rA, vrrc:$XT), 0>;
16658bcb0991SDimitry Andricdef : InstAlias<"mffprwz $rA, $src",
16668bcb0991SDimitry Andric                (MFVSRWZ gprc:$rA, f8rc:$src)>;
16678bcb0991SDimitry Andricdef : InstAlias<"mtvrwa $XT, $rA",
16688bcb0991SDimitry Andric                (MTVRWA vrrc:$XT, gprc:$rA), 0>;
16698bcb0991SDimitry Andricdef : InstAlias<"mtfprwa $dst, $rA",
16708bcb0991SDimitry Andric                (MTVSRWA f8rc:$dst, gprc:$rA)>;
16718bcb0991SDimitry Andricdef : InstAlias<"mtvrwz $XT, $rA",
16728bcb0991SDimitry Andric                (MTVRWZ vrrc:$XT, gprc:$rA), 0>;
16738bcb0991SDimitry Andricdef : InstAlias<"mtfprwz $dst, $rA",
16748bcb0991SDimitry Andric                (MTVSRWZ f8rc:$dst, gprc:$rA)>;
16750b57cec5SDimitry Andric
16760b57cec5SDimitry Andric/*  Direct moves of various widths from GPR's into VSR's. Each move lines
16770b57cec5SDimitry Andric    the value up into element 0 (both BE and LE). Namely, entities smaller than
16780b57cec5SDimitry Andric    a doubleword are shifted left and moved for BE. For LE, they're moved, then
16790b57cec5SDimitry Andric    swapped to go into the least significant element of the VSR.
16800b57cec5SDimitry Andric*/
16810b57cec5SDimitry Andricdef MovesToVSR {
16820b57cec5SDimitry Andric  dag BE_BYTE_0 =
16830b57cec5SDimitry Andric    (MTVSRD
16840b57cec5SDimitry Andric      (RLDICR
16850b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 56, 7));
16860b57cec5SDimitry Andric  dag BE_HALF_0 =
16870b57cec5SDimitry Andric    (MTVSRD
16880b57cec5SDimitry Andric      (RLDICR
16890b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 48, 15));
16900b57cec5SDimitry Andric  dag BE_WORD_0 =
16910b57cec5SDimitry Andric    (MTVSRD
16920b57cec5SDimitry Andric      (RLDICR
16930b57cec5SDimitry Andric        (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32), 32, 31));
16940b57cec5SDimitry Andric  dag BE_DWORD_0 = (MTVSRD $A);
16950b57cec5SDimitry Andric
16960b57cec5SDimitry Andric  dag LE_MTVSRW = (MTVSRD (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32));
16970b57cec5SDimitry Andric  dag LE_WORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
16980b57cec5SDimitry Andric                                        LE_MTVSRW, sub_64));
16990b57cec5SDimitry Andric  dag LE_WORD_0 = (XXPERMDI LE_WORD_1, LE_WORD_1, 2);
17000b57cec5SDimitry Andric  dag LE_DWORD_1 = (v2i64 (INSERT_SUBREG (v2i64 (IMPLICIT_DEF)),
17010b57cec5SDimitry Andric                                         BE_DWORD_0, sub_64));
17020b57cec5SDimitry Andric  dag LE_DWORD_0 = (XXPERMDI LE_DWORD_1, LE_DWORD_1, 2);
17030b57cec5SDimitry Andric}
17040b57cec5SDimitry Andric
17050b57cec5SDimitry Andric/*  Patterns for extracting elements out of vectors. Integer elements are
17060b57cec5SDimitry Andric    extracted using direct move operations. Patterns for extracting elements
17070b57cec5SDimitry Andric    whose indices are not available at compile time are also provided with
17080b57cec5SDimitry Andric    various _VARIABLE_ patterns.
17090b57cec5SDimitry Andric    The numbering for the DAG's is for LE, but when used on BE, the correct
17100b57cec5SDimitry Andric    LE element can just be used (i.e. LE_BYTE_2 == BE_BYTE_13).
17110b57cec5SDimitry Andric*/
17120b57cec5SDimitry Andricdef VectorExtractions {
17130b57cec5SDimitry Andric  // Doubleword extraction
17140b57cec5SDimitry Andric  dag LE_DWORD_0 =
17150b57cec5SDimitry Andric    (MFVSRD
17160b57cec5SDimitry Andric      (EXTRACT_SUBREG
17170b57cec5SDimitry Andric        (XXPERMDI (COPY_TO_REGCLASS $S, VSRC),
17180b57cec5SDimitry Andric                  (COPY_TO_REGCLASS $S, VSRC), 2), sub_64));
17190b57cec5SDimitry Andric  dag LE_DWORD_1 = (MFVSRD
17200b57cec5SDimitry Andric                     (EXTRACT_SUBREG
17210b57cec5SDimitry Andric                       (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
17220b57cec5SDimitry Andric
17230b57cec5SDimitry Andric  // Word extraction
17240b57cec5SDimitry Andric  dag LE_WORD_0 = (MFVSRWZ (EXTRACT_SUBREG (XXPERMDI $S, $S, 2), sub_64));
17250b57cec5SDimitry Andric  dag LE_WORD_1 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 1), sub_64));
17260b57cec5SDimitry Andric  dag LE_WORD_2 = (MFVSRWZ (EXTRACT_SUBREG
17270b57cec5SDimitry Andric                             (v2i64 (COPY_TO_REGCLASS $S, VSRC)), sub_64));
17280b57cec5SDimitry Andric  dag LE_WORD_3 = (MFVSRWZ (EXTRACT_SUBREG (XXSLDWI $S, $S, 3), sub_64));
17290b57cec5SDimitry Andric
17300b57cec5SDimitry Andric  // Halfword extraction
17310b57cec5SDimitry Andric  dag LE_HALF_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 48), sub_32));
17320b57cec5SDimitry Andric  dag LE_HALF_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 48), sub_32));
17330b57cec5SDimitry Andric  dag LE_HALF_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 48), sub_32));
17340b57cec5SDimitry Andric  dag LE_HALF_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 48), sub_32));
17350b57cec5SDimitry Andric  dag LE_HALF_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 48), sub_32));
17360b57cec5SDimitry Andric  dag LE_HALF_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 48), sub_32));
17370b57cec5SDimitry Andric  dag LE_HALF_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 48), sub_32));
17380b57cec5SDimitry Andric  dag LE_HALF_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 48), sub_32));
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andric  // Byte extraction
17410b57cec5SDimitry Andric  dag LE_BYTE_0 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 0, 56), sub_32));
17420b57cec5SDimitry Andric  dag LE_BYTE_1 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 56, 56), sub_32));
17430b57cec5SDimitry Andric  dag LE_BYTE_2 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 48, 56), sub_32));
17440b57cec5SDimitry Andric  dag LE_BYTE_3 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 40, 56), sub_32));
17450b57cec5SDimitry Andric  dag LE_BYTE_4 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 32, 56), sub_32));
17460b57cec5SDimitry Andric  dag LE_BYTE_5 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 24, 56), sub_32));
17470b57cec5SDimitry Andric  dag LE_BYTE_6 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 16, 56), sub_32));
17480b57cec5SDimitry Andric  dag LE_BYTE_7 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_0, 8, 56), sub_32));
17490b57cec5SDimitry Andric  dag LE_BYTE_8 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 0, 56), sub_32));
17500b57cec5SDimitry Andric  dag LE_BYTE_9 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 56, 56), sub_32));
17510b57cec5SDimitry Andric  dag LE_BYTE_10 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 48, 56), sub_32));
17520b57cec5SDimitry Andric  dag LE_BYTE_11 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 40, 56), sub_32));
17530b57cec5SDimitry Andric  dag LE_BYTE_12 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 32, 56), sub_32));
17540b57cec5SDimitry Andric  dag LE_BYTE_13 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 24, 56), sub_32));
17550b57cec5SDimitry Andric  dag LE_BYTE_14 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 16, 56), sub_32));
17560b57cec5SDimitry Andric  dag LE_BYTE_15 = (i32 (EXTRACT_SUBREG (RLDICL LE_DWORD_1, 8, 56), sub_32));
17570b57cec5SDimitry Andric
17580b57cec5SDimitry Andric  /* Variable element number (BE and LE patterns must be specified separately)
17590b57cec5SDimitry Andric     This is a rather involved process.
17600b57cec5SDimitry Andric
17610b57cec5SDimitry Andric     Conceptually, this is how the move is accomplished:
17620b57cec5SDimitry Andric     1. Identify which doubleword contains the element
17630b57cec5SDimitry Andric     2. Shift in the VMX register so that the correct doubleword is correctly
17640b57cec5SDimitry Andric        lined up for the MFVSRD
17650b57cec5SDimitry Andric     3. Perform the move so that the element (along with some extra stuff)
17660b57cec5SDimitry Andric        is in the GPR
17670b57cec5SDimitry Andric     4. Right shift within the GPR so that the element is right-justified
17680b57cec5SDimitry Andric
17690b57cec5SDimitry Andric     Of course, the index is an element number which has a different meaning
17700b57cec5SDimitry Andric     on LE/BE so the patterns have to be specified separately.
17710b57cec5SDimitry Andric
17720b57cec5SDimitry Andric     Note: The final result will be the element right-justified with high
17730b57cec5SDimitry Andric           order bits being arbitrarily defined (namely, whatever was in the
17740b57cec5SDimitry Andric           vector register to the left of the value originally).
17750b57cec5SDimitry Andric  */
17760b57cec5SDimitry Andric
17770b57cec5SDimitry Andric  /*  LE variable byte
17780b57cec5SDimitry Andric      Number 1. above:
17790b57cec5SDimitry Andric      - For elements 0-7, we shift left by 8 bytes since they're on the right
17800b57cec5SDimitry Andric      - For elements 8-15, we need not shift (shift left by zero bytes)
17810b57cec5SDimitry Andric      This is accomplished by inverting the bits of the index and AND-ing
17820b57cec5SDimitry Andric      with 0x8 (i.e. clearing all bits of the index and inverting bit 60).
17830b57cec5SDimitry Andric  */
17840b57cec5SDimitry Andric  dag LE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDC8 (LI8 8), $Idx)));
17850b57cec5SDimitry Andric
17860b57cec5SDimitry Andric  //  Number 2. above:
17870b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
17880b57cec5SDimitry Andric  dag LE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, LE_VBYTE_PERM_VEC));
17890b57cec5SDimitry Andric
17900b57cec5SDimitry Andric  //  Number 3. above:
17910b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
17920b57cec5SDimitry Andric  dag LE_MV_VBYTE = (MFVSRD
17930b57cec5SDimitry Andric                      (EXTRACT_SUBREG
17940b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VBYTE_PERMUTE, VSRC)),
17950b57cec5SDimitry Andric                        sub_64));
17960b57cec5SDimitry Andric
17970b57cec5SDimitry Andric  /*  Number 4. above:
17980b57cec5SDimitry Andric      - Truncate the element number to the range 0-7 (8-15 are symmetrical
17990b57cec5SDimitry Andric        and out of range values are truncated accordingly)
18000b57cec5SDimitry Andric      - Multiply by 8 as we need to shift right by the number of bits, not bytes
18010b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
18020b57cec5SDimitry Andric  */
18030b57cec5SDimitry Andric  dag LE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 7), $Idx), 3, 60),
18040b57cec5SDimitry Andric                                       sub_32);
18050b57cec5SDimitry Andric  dag LE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD LE_MV_VBYTE, LE_VBYTE_SHIFT),
18060b57cec5SDimitry Andric                                         sub_32);
18070b57cec5SDimitry Andric
18080b57cec5SDimitry Andric  /*  LE variable halfword
18090b57cec5SDimitry Andric      Number 1. above:
18100b57cec5SDimitry Andric      - For elements 0-3, we shift left by 8 since they're on the right
18110b57cec5SDimitry Andric      - For elements 4-7, we need not shift (shift left by zero bytes)
18120b57cec5SDimitry Andric      Similarly to the byte pattern, we invert the bits of the index, but we
18130b57cec5SDimitry Andric      AND with 0x4 (i.e. clear all bits of the index and invert bit 61).
18140b57cec5SDimitry Andric      Of course, the shift is still by 8 bytes, so we must multiply by 2.
18150b57cec5SDimitry Andric  */
18160b57cec5SDimitry Andric  dag LE_VHALF_PERM_VEC =
18170b57cec5SDimitry Andric    (v16i8 (LVSL ZERO8, (RLDICR (ANDC8 (LI8 4), $Idx), 1, 62)));
18180b57cec5SDimitry Andric
18190b57cec5SDimitry Andric  //  Number 2. above:
18200b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
18210b57cec5SDimitry Andric  dag LE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, LE_VHALF_PERM_VEC));
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andric  //  Number 3. above:
18240b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
18250b57cec5SDimitry Andric  dag LE_MV_VHALF = (MFVSRD
18260b57cec5SDimitry Andric                      (EXTRACT_SUBREG
18270b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VHALF_PERMUTE, VSRC)),
18280b57cec5SDimitry Andric                        sub_64));
18290b57cec5SDimitry Andric
18300b57cec5SDimitry Andric  /*  Number 4. above:
18310b57cec5SDimitry Andric      - Truncate the element number to the range 0-3 (4-7 are symmetrical
18320b57cec5SDimitry Andric        and out of range values are truncated accordingly)
18330b57cec5SDimitry Andric      - Multiply by 16 as we need to shift right by the number of bits
18340b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
18350b57cec5SDimitry Andric  */
18360b57cec5SDimitry Andric  dag LE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 3), $Idx), 4, 59),
18370b57cec5SDimitry Andric                                       sub_32);
18380b57cec5SDimitry Andric  dag LE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD LE_MV_VHALF, LE_VHALF_SHIFT),
18390b57cec5SDimitry Andric                                         sub_32);
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andric  /*  LE variable word
18420b57cec5SDimitry Andric      Number 1. above:
18430b57cec5SDimitry Andric      - For elements 0-1, we shift left by 8 since they're on the right
18440b57cec5SDimitry Andric      - For elements 2-3, we need not shift
18450b57cec5SDimitry Andric  */
18460b57cec5SDimitry Andric  dag LE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
18470b57cec5SDimitry Andric                                       (RLDICR (ANDC8 (LI8 2), $Idx), 2, 61)));
18480b57cec5SDimitry Andric
18490b57cec5SDimitry Andric  //  Number 2. above:
18500b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
18510b57cec5SDimitry Andric  dag LE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VWORD_PERM_VEC));
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andric  //  Number 3. above:
18540b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
18550b57cec5SDimitry Andric  dag LE_MV_VWORD = (MFVSRD
18560b57cec5SDimitry Andric                      (EXTRACT_SUBREG
18570b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS LE_VWORD_PERMUTE, VSRC)),
18580b57cec5SDimitry Andric                        sub_64));
18590b57cec5SDimitry Andric
18600b57cec5SDimitry Andric  /*  Number 4. above:
18610b57cec5SDimitry Andric      - Truncate the element number to the range 0-1 (2-3 are symmetrical
18620b57cec5SDimitry Andric        and out of range values are truncated accordingly)
18630b57cec5SDimitry Andric      - Multiply by 32 as we need to shift right by the number of bits
18640b57cec5SDimitry Andric      - Shift right in the GPR by the calculated value
18650b57cec5SDimitry Andric  */
18660b57cec5SDimitry Andric  dag LE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (AND8 (LI8 1), $Idx), 5, 58),
18670b57cec5SDimitry Andric                                       sub_32);
18680b57cec5SDimitry Andric  dag LE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD LE_MV_VWORD, LE_VWORD_SHIFT),
18690b57cec5SDimitry Andric                                         sub_32);
18700b57cec5SDimitry Andric
18710b57cec5SDimitry Andric  /*  LE variable doubleword
18720b57cec5SDimitry Andric      Number 1. above:
18730b57cec5SDimitry Andric      - For element 0, we shift left by 8 since it's on the right
18740b57cec5SDimitry Andric      - For element 1, we need not shift
18750b57cec5SDimitry Andric  */
18760b57cec5SDimitry Andric  dag LE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
18770b57cec5SDimitry Andric                                        (RLDICR (ANDC8 (LI8 1), $Idx), 3, 60)));
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andric  //  Number 2. above:
18800b57cec5SDimitry Andric  //  - Now that we set up the shift amount, we shift in the VMX register
18810b57cec5SDimitry Andric  dag LE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, LE_VDWORD_PERM_VEC));
18820b57cec5SDimitry Andric
18830b57cec5SDimitry Andric  // Number 3. above:
18840b57cec5SDimitry Andric  //  - The doubleword containing our element is moved to a GPR
18850b57cec5SDimitry Andric  //  - Number 4. is not needed for the doubleword as the value is 64-bits
18860b57cec5SDimitry Andric  dag LE_VARIABLE_DWORD =
18870b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
18880b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS LE_VDWORD_PERMUTE, VSRC)),
18890b57cec5SDimitry Andric                  sub_64));
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andric  /*  LE variable float
18920b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
18930b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
18940b57cec5SDimitry Andric  */
18950b57cec5SDimitry Andric  dag LE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8,
18960b57cec5SDimitry Andric                                  (RLDICR (XOR8 (LI8 3), $Idx), 2, 61)));
18970b57cec5SDimitry Andric  dag LE_VFLOAT_PERMUTE = (VPERM $S, $S, LE_VFLOAT_PERM_VEC);
18980b57cec5SDimitry Andric  dag LE_VARIABLE_FLOAT = (XSCVSPDPN LE_VFLOAT_PERMUTE);
18990b57cec5SDimitry Andric
19000b57cec5SDimitry Andric  /*  LE variable double
19010b57cec5SDimitry Andric      Same as the LE doubleword except there is no move.
19020b57cec5SDimitry Andric  */
19030b57cec5SDimitry Andric  dag LE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
19040b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
19050b57cec5SDimitry Andric                                         LE_VDWORD_PERM_VEC));
19060b57cec5SDimitry Andric  dag LE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS LE_VDOUBLE_PERMUTE, VSRC);
19070b57cec5SDimitry Andric
19080b57cec5SDimitry Andric  /*  BE variable byte
19090b57cec5SDimitry Andric      The algorithm here is the same as the LE variable byte except:
19100b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
19110b57cec5SDimitry Andric        we simply AND the element number with 0x8
19120b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
19130b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-7
19140b57cec5SDimitry Andric  */
19150b57cec5SDimitry Andric  dag BE_VBYTE_PERM_VEC = (v16i8 (LVSL ZERO8, (ANDIo8 $Idx, 8)));
19160b57cec5SDimitry Andric  dag BE_VBYTE_PERMUTE = (v16i8 (VPERM $S, $S, BE_VBYTE_PERM_VEC));
19170b57cec5SDimitry Andric  dag BE_MV_VBYTE = (MFVSRD
19180b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19190b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VBYTE_PERMUTE, VSRC)),
19200b57cec5SDimitry Andric                        sub_64));
19210b57cec5SDimitry Andric  dag BE_VBYTE_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 7), $Idx), 3, 60),
19220b57cec5SDimitry Andric                                       sub_32);
19230b57cec5SDimitry Andric  dag BE_VARIABLE_BYTE = (EXTRACT_SUBREG (SRD BE_MV_VBYTE, BE_VBYTE_SHIFT),
19240b57cec5SDimitry Andric                                         sub_32);
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andric  /*  BE variable halfword
19270b57cec5SDimitry Andric      The algorithm here is the same as the LE variable halfword except:
19280b57cec5SDimitry Andric      - The shift in the VMX register is by 0/8 for opposite element numbers so
19290b57cec5SDimitry Andric        we simply AND the element number with 0x4 and multiply by 2
19300b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
19310b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-3
19320b57cec5SDimitry Andric  */
19330b57cec5SDimitry Andric  dag BE_VHALF_PERM_VEC = (v16i8 (LVSL ZERO8,
19340b57cec5SDimitry Andric                                       (RLDICR (ANDIo8 $Idx, 4), 1, 62)));
19350b57cec5SDimitry Andric  dag BE_VHALF_PERMUTE = (v16i8 (VPERM $S, $S, BE_VHALF_PERM_VEC));
19360b57cec5SDimitry Andric  dag BE_MV_VHALF = (MFVSRD
19370b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19380b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VHALF_PERMUTE, VSRC)),
19390b57cec5SDimitry Andric                        sub_64));
19400b57cec5SDimitry Andric  dag BE_VHALF_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 3), $Idx), 4, 59),
19410b57cec5SDimitry Andric                                       sub_32);
19420b57cec5SDimitry Andric  dag BE_VARIABLE_HALF = (EXTRACT_SUBREG (SRD BE_MV_VHALF, BE_VHALF_SHIFT),
19430b57cec5SDimitry Andric                                         sub_32);
19440b57cec5SDimitry Andric
19450b57cec5SDimitry Andric  /*  BE variable word
19460b57cec5SDimitry Andric      The algorithm is the same as the LE variable word except:
19470b57cec5SDimitry Andric      - The shift in the VMX register happens for opposite element numbers
19480b57cec5SDimitry Andric      - The order of elements after the move to GPR is reversed, so we invert
19490b57cec5SDimitry Andric        the bits of the index prior to truncating to the range 0-1
19500b57cec5SDimitry Andric  */
19510b57cec5SDimitry Andric  dag BE_VWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
19520b57cec5SDimitry Andric                                       (RLDICR (ANDIo8 $Idx, 2), 2, 61)));
19530b57cec5SDimitry Andric  dag BE_VWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VWORD_PERM_VEC));
19540b57cec5SDimitry Andric  dag BE_MV_VWORD = (MFVSRD
19550b57cec5SDimitry Andric                      (EXTRACT_SUBREG
19560b57cec5SDimitry Andric                        (v2i64 (COPY_TO_REGCLASS BE_VWORD_PERMUTE, VSRC)),
19570b57cec5SDimitry Andric                        sub_64));
19580b57cec5SDimitry Andric  dag BE_VWORD_SHIFT = (EXTRACT_SUBREG (RLDICR (ANDC8 (LI8 1), $Idx), 5, 58),
19590b57cec5SDimitry Andric                                       sub_32);
19600b57cec5SDimitry Andric  dag BE_VARIABLE_WORD = (EXTRACT_SUBREG (SRD BE_MV_VWORD, BE_VWORD_SHIFT),
19610b57cec5SDimitry Andric                                         sub_32);
19620b57cec5SDimitry Andric
19630b57cec5SDimitry Andric  /*  BE variable doubleword
19640b57cec5SDimitry Andric      Same as the LE doubleword except we shift in the VMX register for opposite
19650b57cec5SDimitry Andric      element indices.
19660b57cec5SDimitry Andric  */
19670b57cec5SDimitry Andric  dag BE_VDWORD_PERM_VEC = (v16i8 (LVSL ZERO8,
19680b57cec5SDimitry Andric                                        (RLDICR (ANDIo8 $Idx, 1), 3, 60)));
19690b57cec5SDimitry Andric  dag BE_VDWORD_PERMUTE = (v16i8 (VPERM $S, $S, BE_VDWORD_PERM_VEC));
19700b57cec5SDimitry Andric  dag BE_VARIABLE_DWORD =
19710b57cec5SDimitry Andric        (MFVSRD (EXTRACT_SUBREG
19720b57cec5SDimitry Andric                  (v2i64 (COPY_TO_REGCLASS BE_VDWORD_PERMUTE, VSRC)),
19730b57cec5SDimitry Andric                  sub_64));
19740b57cec5SDimitry Andric
19750b57cec5SDimitry Andric  /*  BE variable float
19760b57cec5SDimitry Andric      - Shift the vector to line up the desired element to BE Word 0
19770b57cec5SDimitry Andric      - Convert 32-bit float to a 64-bit single precision float
19780b57cec5SDimitry Andric  */
19790b57cec5SDimitry Andric  dag BE_VFLOAT_PERM_VEC = (v16i8 (LVSL ZERO8, (RLDICR $Idx, 2, 61)));
19800b57cec5SDimitry Andric  dag BE_VFLOAT_PERMUTE = (VPERM $S, $S, BE_VFLOAT_PERM_VEC);
19810b57cec5SDimitry Andric  dag BE_VARIABLE_FLOAT = (XSCVSPDPN BE_VFLOAT_PERMUTE);
19820b57cec5SDimitry Andric
19830b57cec5SDimitry Andric  /* BE variable double
19840b57cec5SDimitry Andric      Same as the BE doubleword except there is no move.
19850b57cec5SDimitry Andric  */
19860b57cec5SDimitry Andric  dag BE_VDOUBLE_PERMUTE = (v16i8 (VPERM (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
19870b57cec5SDimitry Andric                                         (v16i8 (COPY_TO_REGCLASS $S, VRRC)),
19880b57cec5SDimitry Andric                                         BE_VDWORD_PERM_VEC));
19890b57cec5SDimitry Andric  dag BE_VARIABLE_DOUBLE = (COPY_TO_REGCLASS BE_VDOUBLE_PERMUTE, VSRC);
19900b57cec5SDimitry Andric}
19910b57cec5SDimitry Andric
19920b57cec5SDimitry Andricdef NoP9Altivec : Predicate<"!PPCSubTarget->hasP9Altivec()">;
19930b57cec5SDimitry Andriclet AddedComplexity = 400 in {
19940b57cec5SDimitry Andric// v4f32 scalar <-> vector conversions (BE)
19950b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasP8Vector] in {
19960b57cec5SDimitry Andric  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
19970b57cec5SDimitry Andric            (v4f32 (XSCVDPSPN $A))>;
19980b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
19990b57cec5SDimitry Andric            (f32 (XSCVSPDPN $S))>;
20000b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
20010b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
20020b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
20030b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
20040b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
20050b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
20060b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
20070b57cec5SDimitry Andric            (f32 VectorExtractions.BE_VARIABLE_FLOAT)>;
20080b57cec5SDimitry Andric} // IsBigEndian, HasP8Vector
20090b57cec5SDimitry Andric
20100b57cec5SDimitry Andric// Variable index vector_extract for v2f64 does not require P8Vector
20110b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasVSX] in
20120b57cec5SDimitry Andric  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
20130b57cec5SDimitry Andric            (f64 VectorExtractions.BE_VARIABLE_DOUBLE)>;
20140b57cec5SDimitry Andric
20150b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasDirectMove] in {
20160b57cec5SDimitry Andric  // v16i8 scalar <-> vector conversions (BE)
20170b57cec5SDimitry Andric  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
20180b57cec5SDimitry Andric            (v16i8 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_BYTE_0, sub_64))>;
20190b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
20200b57cec5SDimitry Andric            (v8i16 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_HALF_0, sub_64))>;
20210b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
20220b57cec5SDimitry Andric            (v4i32 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_WORD_0, sub_64))>;
20230b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
20240b57cec5SDimitry Andric            (v2i64 (SUBREG_TO_REG (i64 1), MovesToVSR.BE_DWORD_0, sub_64))>;
20250b57cec5SDimitry Andric
20260b57cec5SDimitry Andric  // v2i64 scalar <-> vector conversions (BE)
20270b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
20280b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
20290b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
20300b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
20310b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
20320b57cec5SDimitry Andric            (i64 VectorExtractions.BE_VARIABLE_DWORD)>;
20330b57cec5SDimitry Andric} // IsBigEndian, HasDirectMove
20340b57cec5SDimitry Andric
20350b57cec5SDimitry Andriclet Predicates = [IsBigEndian, HasDirectMove, NoP9Altivec] in {
20360b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
20370b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_15)>;
20380b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
20390b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_14)>;
20400b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
20410b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_13)>;
20420b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
20430b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_12)>;
20440b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
20450b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_11)>;
20460b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
20470b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_10)>;
20480b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
20490b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_9)>;
20500b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
20510b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_8)>;
20520b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
20530b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_7)>;
20540b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
20550b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_6)>;
20560b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
20570b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_5)>;
20580b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
20590b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_4)>;
20600b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
20610b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_3)>;
20620b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
20630b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_2)>;
20640b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
20650b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_1)>;
20660b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
20670b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_0)>;
20680b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
20690b57cec5SDimitry Andric            (i32 VectorExtractions.BE_VARIABLE_BYTE)>;
20700b57cec5SDimitry Andric
20710b57cec5SDimitry Andric  // v8i16 scalar <-> vector conversions (BE)
20720b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
20730b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_7)>;
20740b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
20750b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_6)>;
20760b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
20770b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_5)>;
20780b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
20790b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_4)>;
20800b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
20810b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_3)>;
20820b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
20830b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_2)>;
20840b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
20850b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_1)>;
20860b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
20870b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_0)>;
20880b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
20890b57cec5SDimitry Andric            (i32 VectorExtractions.BE_VARIABLE_HALF)>;
20900b57cec5SDimitry Andric
20910b57cec5SDimitry Andric  // v4i32 scalar <-> vector conversions (BE)
20920b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
20930b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_3)>;
20940b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
20950b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
20960b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
20970b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_1)>;
20980b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
20990b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_0)>;
21000b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
21010b57cec5SDimitry Andric            (i32 VectorExtractions.BE_VARIABLE_WORD)>;
21020b57cec5SDimitry Andric} // IsBigEndian, HasDirectMove, NoP9Altivec
21030b57cec5SDimitry Andric
21040b57cec5SDimitry Andric// v4f32 scalar <-> vector conversions (LE)
21050b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasP8Vector] in {
21060b57cec5SDimitry Andric  def : Pat<(v4f32 (scalar_to_vector f32:$A)),
21070b57cec5SDimitry Andric            (v4f32 (XXSLDWI (XSCVDPSPN $A), (XSCVDPSPN $A), 1))>;
21080b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 0)),
21090b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 3)))>;
21100b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 1)),
21110b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXPERMDI $S, $S, 2)))>;
21120b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 2)),
21130b57cec5SDimitry Andric            (f32 (XSCVSPDPN (XXSLDWI $S, $S, 1)))>;
21140b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, 3)),
21150b57cec5SDimitry Andric            (f32 (XSCVSPDPN $S))>;
21160b57cec5SDimitry Andric  def : Pat<(f32 (vector_extract v4f32:$S, i64:$Idx)),
21170b57cec5SDimitry Andric            (f32 VectorExtractions.LE_VARIABLE_FLOAT)>;
21180b57cec5SDimitry Andric} // IsLittleEndian, HasP8Vector
21190b57cec5SDimitry Andric
21200b57cec5SDimitry Andric// Variable index vector_extract for v2f64 does not require P8Vector
21210b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasVSX] in
21220b57cec5SDimitry Andric  def : Pat<(f64 (vector_extract v2f64:$S, i64:$Idx)),
21230b57cec5SDimitry Andric            (f64 VectorExtractions.LE_VARIABLE_DOUBLE)>;
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_stxvd2x_be v2f64:$rS, xoaddr:$dst),
21260b57cec5SDimitry Andric            (STXVD2X $rS, xoaddr:$dst)>;
21270b57cec5SDimitry Andricdef : Pat<(int_ppc_vsx_stxvw4x_be v4i32:$rS, xoaddr:$dst),
21280b57cec5SDimitry Andric            (STXVW4X $rS, xoaddr:$dst)>;
21290b57cec5SDimitry Andricdef : Pat<(v4i32 (int_ppc_vsx_lxvw4x_be xoaddr:$src)), (LXVW4X xoaddr:$src)>;
21300b57cec5SDimitry Andricdef : Pat<(v2f64 (int_ppc_vsx_lxvd2x_be xoaddr:$src)), (LXVD2X xoaddr:$src)>;
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andric// Variable index unsigned vector_extract on Power9
21330b57cec5SDimitry Andriclet Predicates = [HasP9Altivec, IsLittleEndian] in {
21340b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
21350b57cec5SDimitry Andric            (VEXTUBRX $Idx, $S)>;
21360b57cec5SDimitry Andric
21370b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
21380b57cec5SDimitry Andric            (VEXTUHRX (RLWINM8 $Idx, 1, 28, 30), $S)>;
21390b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
21400b57cec5SDimitry Andric            (VEXTUHRX (LI8 0), $S)>;
21410b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
21420b57cec5SDimitry Andric            (VEXTUHRX (LI8 2), $S)>;
21430b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
21440b57cec5SDimitry Andric            (VEXTUHRX (LI8 4), $S)>;
21450b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
21460b57cec5SDimitry Andric            (VEXTUHRX (LI8 6), $S)>;
21470b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
21480b57cec5SDimitry Andric            (VEXTUHRX (LI8 8), $S)>;
21490b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
21500b57cec5SDimitry Andric            (VEXTUHRX (LI8 10), $S)>;
21510b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
21520b57cec5SDimitry Andric            (VEXTUHRX (LI8 12), $S)>;
21530b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
21540b57cec5SDimitry Andric            (VEXTUHRX (LI8 14), $S)>;
21550b57cec5SDimitry Andric
21560b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
21570b57cec5SDimitry Andric            (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S)>;
21580b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
21590b57cec5SDimitry Andric            (VEXTUWRX (LI8 0), $S)>;
21600b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
21610b57cec5SDimitry Andric            (VEXTUWRX (LI8 4), $S)>;
21620b57cec5SDimitry Andric  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
21630b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
21640b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
21650b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
21660b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
21670b57cec5SDimitry Andric            (VEXTUWRX (LI8 12), $S)>;
21680b57cec5SDimitry Andric
21690b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
21700b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (RLWINM8 $Idx, 2, 28, 29), $S))>;
21710b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
21720b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (LI8 0), $S))>;
21730b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
21740b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (LI8 4), $S))>;
21750b57cec5SDimitry Andric  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
21760b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
21770b57cec5SDimitry Andric            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
21780b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
21790b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
21800b57cec5SDimitry Andric            (EXTSW (VEXTUWRX (LI8 12), $S))>;
21810b57cec5SDimitry Andric
21820b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
21830b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX $Idx, $S), sub_32))>;
21840b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
21850b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 0), $S), sub_32))>;
21860b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
21870b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 1), $S), sub_32))>;
21880b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
21890b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 2), $S), sub_32))>;
21900b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
21910b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 3), $S), sub_32))>;
21920b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
21930b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 4), $S), sub_32))>;
21940b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
21950b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 5), $S), sub_32))>;
21960b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
21970b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 6), $S), sub_32))>;
21980b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
21990b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 7), $S), sub_32))>;
22000b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
22010b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 8), $S), sub_32))>;
22020b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
22030b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 9), $S), sub_32))>;
22040b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
22050b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 10), $S), sub_32))>;
22060b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
22070b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 11), $S), sub_32))>;
22080b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
22090b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 12), $S), sub_32))>;
22100b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
22110b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 13), $S), sub_32))>;
22120b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
22130b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 14), $S), sub_32))>;
22140b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
22150b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBRX (LI8 15), $S), sub_32))>;
22160b57cec5SDimitry Andric
22170b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
22180b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX
22190b57cec5SDimitry Andric	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
22200b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
22210b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 0), $S), sub_32))>;
22220b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
22230b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 2), $S), sub_32))>;
22240b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
22250b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 4), $S), sub_32))>;
22260b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
22270b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 6), $S), sub_32))>;
22280b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
22290b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 8), $S), sub_32))>;
22300b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
22310b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 10), $S), sub_32))>;
22320b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
22330b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 12), $S), sub_32))>;
22340b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
22350b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHRX (LI8 14), $S), sub_32))>;
22360b57cec5SDimitry Andric
22370b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
22380b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX
22390b57cec5SDimitry Andric	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
22400b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
22410b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 0), $S), sub_32))>;
22420b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
22430b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 4), $S), sub_32))>;
22440b57cec5SDimitry Andric  // For extracting LE word 2, MFVSRWZ is better than VEXTUWRX
22450b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
22460b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
22470b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
22480b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWRX (LI8 12), $S), sub_32))>;
22490b57cec5SDimitry Andric}
22500b57cec5SDimitry Andric
22510b57cec5SDimitry Andriclet Predicates = [HasP9Altivec, IsBigEndian] in {
22520b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v16i8:$S, i64:$Idx)))),
22530b57cec5SDimitry Andric            (VEXTUBLX $Idx, $S)>;
22540b57cec5SDimitry Andric
22550b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, i64:$Idx)))),
22560b57cec5SDimitry Andric            (VEXTUHLX (RLWINM8 $Idx, 1, 28, 30), $S)>;
22570b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 0)))),
22580b57cec5SDimitry Andric            (VEXTUHLX (LI8 0), $S)>;
22590b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 1)))),
22600b57cec5SDimitry Andric            (VEXTUHLX (LI8 2), $S)>;
22610b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 2)))),
22620b57cec5SDimitry Andric            (VEXTUHLX (LI8 4), $S)>;
22630b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 3)))),
22640b57cec5SDimitry Andric            (VEXTUHLX (LI8 6), $S)>;
22650b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 4)))),
22660b57cec5SDimitry Andric            (VEXTUHLX (LI8 8), $S)>;
22670b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 5)))),
22680b57cec5SDimitry Andric            (VEXTUHLX (LI8 10), $S)>;
22690b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 6)))),
22700b57cec5SDimitry Andric            (VEXTUHLX (LI8 12), $S)>;
22710b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i32 (vector_extract v8i16:$S, 7)))),
22720b57cec5SDimitry Andric            (VEXTUHLX (LI8 14), $S)>;
22730b57cec5SDimitry Andric
22740b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
22750b57cec5SDimitry Andric            (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S)>;
22760b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 0)))),
22770b57cec5SDimitry Andric            (VEXTUWLX (LI8 0), $S)>;
22780b57cec5SDimitry Andric
22790b57cec5SDimitry Andric  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
22800b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 1)))),
22810b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
22820b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32)>;
22830b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 2)))),
22840b57cec5SDimitry Andric            (VEXTUWLX (LI8 8), $S)>;
22850b57cec5SDimitry Andric  def : Pat<(i64 (zext (i32 (vector_extract v4i32:$S, 3)))),
22860b57cec5SDimitry Andric            (VEXTUWLX (LI8 12), $S)>;
22870b57cec5SDimitry Andric
22880b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, i64:$Idx)))),
22890b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (RLWINM8 $Idx, 2, 28, 29), $S))>;
22900b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 0)))),
22910b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (LI8 0), $S))>;
22920b57cec5SDimitry Andric  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
22930b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 1)))),
22940b57cec5SDimitry Andric            (EXTSW (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
22950b57cec5SDimitry Andric	    (i32 VectorExtractions.LE_WORD_2), sub_32))>;
22960b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 2)))),
22970b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (LI8 8), $S))>;
22980b57cec5SDimitry Andric  def : Pat<(i64 (sext (i32 (vector_extract v4i32:$S, 3)))),
22990b57cec5SDimitry Andric            (EXTSW (VEXTUWLX (LI8 12), $S))>;
23000b57cec5SDimitry Andric
23010b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
23020b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX $Idx, $S), sub_32))>;
23030b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
23040b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 0), $S), sub_32))>;
23050b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
23060b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 1), $S), sub_32))>;
23070b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
23080b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 2), $S), sub_32))>;
23090b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
23100b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 3), $S), sub_32))>;
23110b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
23120b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 4), $S), sub_32))>;
23130b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
23140b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 5), $S), sub_32))>;
23150b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
23160b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 6), $S), sub_32))>;
23170b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
23180b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 7), $S), sub_32))>;
23190b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
23200b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 8), $S), sub_32))>;
23210b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
23220b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 9), $S), sub_32))>;
23230b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
23240b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 10), $S), sub_32))>;
23250b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
23260b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 11), $S), sub_32))>;
23270b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
23280b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 12), $S), sub_32))>;
23290b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
23300b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 13), $S), sub_32))>;
23310b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
23320b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 14), $S), sub_32))>;
23330b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
23340b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUBLX (LI8 15), $S), sub_32))>;
23350b57cec5SDimitry Andric
23360b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
23370b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX
23380b57cec5SDimitry Andric	    (RLWINM8 $Idx, 1, 28, 30), $S), sub_32))>;
23390b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
23400b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 0), $S), sub_32))>;
23410b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
23420b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 2), $S), sub_32))>;
23430b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
23440b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 4), $S), sub_32))>;
23450b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
23460b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 6), $S), sub_32))>;
23470b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
23480b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 8), $S), sub_32))>;
23490b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
23500b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 10), $S), sub_32))>;
23510b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
23520b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 12), $S), sub_32))>;
23530b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
23540b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUHLX (LI8 14), $S), sub_32))>;
23550b57cec5SDimitry Andric
23560b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
23570b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX
23580b57cec5SDimitry Andric	    (RLWINM8 $Idx, 2, 28, 29), $S), sub_32))>;
23590b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
23600b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 0), $S), sub_32))>;
23610b57cec5SDimitry Andric  // For extracting BE word 1, MFVSRWZ is better than VEXTUWLX
23620b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
23630b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
23640b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
23650b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 8), $S), sub_32))>;
23660b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
23670b57cec5SDimitry Andric            (i32 (EXTRACT_SUBREG (VEXTUWLX (LI8 12), $S), sub_32))>;
23680b57cec5SDimitry Andric}
23690b57cec5SDimitry Andric
23700b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasDirectMove] in {
23710b57cec5SDimitry Andric  // v16i8 scalar <-> vector conversions (LE)
23720b57cec5SDimitry Andric  def : Pat<(v16i8 (scalar_to_vector i32:$A)),
23730b57cec5SDimitry Andric            (v16i8 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
23740b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector i32:$A)),
23750b57cec5SDimitry Andric            (v8i16 (COPY_TO_REGCLASS MovesToVSR.LE_WORD_0, VSRC))>;
23760b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector i32:$A)),
23770b57cec5SDimitry Andric            (v4i32 MovesToVSR.LE_WORD_0)>;
23780b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector i64:$A)),
23790b57cec5SDimitry Andric            (v2i64 MovesToVSR.LE_DWORD_0)>;
23800b57cec5SDimitry Andric  // v2i64 scalar <-> vector conversions (LE)
23810b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 0)),
23820b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_0)>;
23830b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, 1)),
23840b57cec5SDimitry Andric            (i64 VectorExtractions.LE_DWORD_1)>;
23850b57cec5SDimitry Andric  def : Pat<(i64 (vector_extract v2i64:$S, i64:$Idx)),
23860b57cec5SDimitry Andric            (i64 VectorExtractions.LE_VARIABLE_DWORD)>;
23870b57cec5SDimitry Andric} // IsLittleEndian, HasDirectMove
23880b57cec5SDimitry Andric
23890b57cec5SDimitry Andriclet Predicates = [IsLittleEndian, HasDirectMove, NoP9Altivec] in {
23900b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 0)),
23910b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_0)>;
23920b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 1)),
23930b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_1)>;
23940b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 2)),
23950b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_2)>;
23960b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 3)),
23970b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_3)>;
23980b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 4)),
23990b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_4)>;
24000b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 5)),
24010b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_5)>;
24020b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 6)),
24030b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_6)>;
24040b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 7)),
24050b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_7)>;
24060b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 8)),
24070b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_8)>;
24080b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 9)),
24090b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_9)>;
24100b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 10)),
24110b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_10)>;
24120b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 11)),
24130b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_11)>;
24140b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 12)),
24150b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_12)>;
24160b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 13)),
24170b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_13)>;
24180b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 14)),
24190b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_14)>;
24200b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, 15)),
24210b57cec5SDimitry Andric            (i32 VectorExtractions.LE_BYTE_15)>;
24220b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v16i8:$S, i64:$Idx)),
24230b57cec5SDimitry Andric            (i32 VectorExtractions.LE_VARIABLE_BYTE)>;
24240b57cec5SDimitry Andric
24250b57cec5SDimitry Andric  // v8i16 scalar <-> vector conversions (LE)
24260b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 0)),
24270b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_0)>;
24280b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 1)),
24290b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_1)>;
24300b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 2)),
24310b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_2)>;
24320b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 3)),
24330b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_3)>;
24340b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 4)),
24350b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_4)>;
24360b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 5)),
24370b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_5)>;
24380b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 6)),
24390b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_6)>;
24400b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, 7)),
24410b57cec5SDimitry Andric            (i32 VectorExtractions.LE_HALF_7)>;
24420b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v8i16:$S, i64:$Idx)),
24430b57cec5SDimitry Andric            (i32 VectorExtractions.LE_VARIABLE_HALF)>;
24440b57cec5SDimitry Andric
24450b57cec5SDimitry Andric  // v4i32 scalar <-> vector conversions (LE)
24460b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 0)),
24470b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_0)>;
24480b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 1)),
24490b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_1)>;
24500b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 2)),
24510b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_2)>;
24520b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, 3)),
24530b57cec5SDimitry Andric            (i32 VectorExtractions.LE_WORD_3)>;
24540b57cec5SDimitry Andric  def : Pat<(i32 (vector_extract v4i32:$S, i64:$Idx)),
24550b57cec5SDimitry Andric            (i32 VectorExtractions.LE_VARIABLE_WORD)>;
24560b57cec5SDimitry Andric} // IsLittleEndian, HasDirectMove, NoP9Altivec
24570b57cec5SDimitry Andric
24580b57cec5SDimitry Andriclet Predicates = [HasDirectMove, HasVSX] in {
24590b57cec5SDimitry Andric// bitconvert f32 -> i32
24600b57cec5SDimitry Andric// (convert to 32-bit fp single, shift right 1 word, move to GPR)
24610b57cec5SDimitry Andricdef : Pat<(i32 (bitconvert f32:$S)),
24620b57cec5SDimitry Andric          (i32 (MFVSRWZ (EXTRACT_SUBREG
24630b57cec5SDimitry Andric                          (XXSLDWI (XSCVDPSPN $S), (XSCVDPSPN $S), 3),
24640b57cec5SDimitry Andric                          sub_64)))>;
24650b57cec5SDimitry Andric// bitconvert i32 -> f32
24660b57cec5SDimitry Andric// (move to FPR, shift left 1 word, convert to 64-bit fp single)
24670b57cec5SDimitry Andricdef : Pat<(f32 (bitconvert i32:$A)),
24680b57cec5SDimitry Andric          (f32 (XSCVSPDPN
24690b57cec5SDimitry Andric                 (XXSLDWI MovesToVSR.LE_WORD_1, MovesToVSR.LE_WORD_1, 1)))>;
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric// bitconvert f64 -> i64
24720b57cec5SDimitry Andric// (move to GPR, nothing else needed)
24730b57cec5SDimitry Andricdef : Pat<(i64 (bitconvert f64:$S)),
24740b57cec5SDimitry Andric          (i64 (MFVSRD $S))>;
24750b57cec5SDimitry Andric
24760b57cec5SDimitry Andric// bitconvert i64 -> f64
24770b57cec5SDimitry Andric// (move to FPR, nothing else needed)
24780b57cec5SDimitry Andricdef : Pat<(f64 (bitconvert i64:$S)),
24790b57cec5SDimitry Andric          (f64 (MTVSRD $S))>;
24800b57cec5SDimitry Andric}
24810b57cec5SDimitry Andric
24820b57cec5SDimitry Andric// Materialize a zero-vector of long long
24830b57cec5SDimitry Andricdef : Pat<(v2i64 immAllZerosV),
24840b57cec5SDimitry Andric          (v2i64 (XXLXORz))>;
24850b57cec5SDimitry Andric}
24860b57cec5SDimitry Andric
24870b57cec5SDimitry Andricdef AlignValues {
24880b57cec5SDimitry Andric  dag F32_TO_BE_WORD1 = (v4f32 (XXSLDWI (XSCVDPSPN $B), (XSCVDPSPN $B), 3));
24890b57cec5SDimitry Andric  dag I32_TO_BE_WORD1 = (COPY_TO_REGCLASS (MTVSRWZ $B), VSRC);
24900b57cec5SDimitry Andric}
24910b57cec5SDimitry Andric
24920b57cec5SDimitry Andric// The following VSX instructions were introduced in Power ISA 3.0
24930b57cec5SDimitry Andricdef HasP9Vector : Predicate<"PPCSubTarget->hasP9Vector()">;
24940b57cec5SDimitry Andriclet AddedComplexity = 400, Predicates = [HasP9Vector] in {
24950b57cec5SDimitry Andric
24960b57cec5SDimitry Andric  // [PO VRT XO VRB XO /]
24970b57cec5SDimitry Andric  class X_VT5_XO5_VB5<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
24980b57cec5SDimitry Andric                      list<dag> pattern>
24990b57cec5SDimitry Andric    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vrrc:$vB),
25000b57cec5SDimitry Andric                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
25010b57cec5SDimitry Andric
25020b57cec5SDimitry Andric  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
25030b57cec5SDimitry Andric  class X_VT5_XO5_VB5_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25040b57cec5SDimitry Andric                         list<dag> pattern>
25050b57cec5SDimitry Andric    : X_VT5_XO5_VB5<opcode, xo2, xo, opc, pattern>, isDOT;
25060b57cec5SDimitry Andric
25070b57cec5SDimitry Andric  // [PO VRT XO VRB XO /], but the VRB is only used the left 64 bits (or less),
25080b57cec5SDimitry Andric  // So we use different operand class for VRB
25090b57cec5SDimitry Andric  class X_VT5_XO5_VB5_TyVB<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25100b57cec5SDimitry Andric                           RegisterOperand vbtype, list<dag> pattern>
25110b57cec5SDimitry Andric    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vrrc:$vT), (ins vbtype:$vB),
25120b57cec5SDimitry Andric                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
25130b57cec5SDimitry Andric
25140b57cec5SDimitry Andric  // [PO VRT XO VRB XO /]
25150b57cec5SDimitry Andric  class X_VT5_XO5_VB5_VSFR<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25160b57cec5SDimitry Andric                      list<dag> pattern>
25170b57cec5SDimitry Andric    : X_RD5_XO5_RS5<opcode, xo2, xo, (outs vfrc:$vT), (ins vrrc:$vB),
25180b57cec5SDimitry Andric                    !strconcat(opc, " $vT, $vB"), IIC_VecFP, pattern>;
25190b57cec5SDimitry Andric
25200b57cec5SDimitry Andric  // [PO VRT XO VRB XO RO], Round to Odd version of [PO VRT XO VRB XO /]
25210b57cec5SDimitry Andric  class X_VT5_XO5_VB5_VSFR_Ro<bits<6> opcode, bits<5> xo2, bits<10> xo, string opc,
25220b57cec5SDimitry Andric                         list<dag> pattern>
25230b57cec5SDimitry Andric    : X_VT5_XO5_VB5_VSFR<opcode, xo2, xo, opc, pattern>, isDOT;
25240b57cec5SDimitry Andric
25250b57cec5SDimitry Andric  // [PO T XO B XO BX /]
25260b57cec5SDimitry Andric  class XX2_RT5_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
25270b57cec5SDimitry Andric                        list<dag> pattern>
25280b57cec5SDimitry Andric    : XX2_RD5_XO5_RS6<opcode, xo2, xo, (outs g8rc:$rT), (ins vsfrc:$XB),
25290b57cec5SDimitry Andric                      !strconcat(opc, " $rT, $XB"), IIC_VecFP, pattern>;
25300b57cec5SDimitry Andric
25310b57cec5SDimitry Andric  // [PO T XO B XO BX TX]
25320b57cec5SDimitry Andric  class XX2_XT6_XO5_XB6<bits<6> opcode, bits<5> xo2, bits<9> xo, string opc,
25330b57cec5SDimitry Andric                        RegisterOperand vtype, list<dag> pattern>
25340b57cec5SDimitry Andric    : XX2_RD6_XO5_RS6<opcode, xo2, xo, (outs vtype:$XT), (ins vtype:$XB),
25350b57cec5SDimitry Andric                      !strconcat(opc, " $XT, $XB"), IIC_VecFP, pattern>;
25360b57cec5SDimitry Andric
25370b57cec5SDimitry Andric  // [PO T A B XO AX BX TX], src and dest register use different operand class
25380b57cec5SDimitry Andric  class XX3_XT5_XA5_XB5<bits<6> opcode, bits<8> xo, string opc,
25390b57cec5SDimitry Andric                  RegisterOperand xty, RegisterOperand aty, RegisterOperand bty,
25400b57cec5SDimitry Andric                  InstrItinClass itin, list<dag> pattern>
25410b57cec5SDimitry Andric    : XX3Form<opcode, xo, (outs xty:$XT), (ins aty:$XA, bty:$XB),
25420b57cec5SDimitry Andric              !strconcat(opc, " $XT, $XA, $XB"), itin, pattern>;
25430b57cec5SDimitry Andric
25440b57cec5SDimitry Andric  // [PO VRT VRA VRB XO /]
25450b57cec5SDimitry Andric  class X_VT5_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
25460b57cec5SDimitry Andric                      list<dag> pattern>
25470b57cec5SDimitry Andric    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vA, vrrc:$vB),
25480b57cec5SDimitry Andric              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>;
25490b57cec5SDimitry Andric
25500b57cec5SDimitry Andric  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
25510b57cec5SDimitry Andric  class X_VT5_VA5_VB5_Ro<bits<6> opcode, bits<10> xo, string opc,
25520b57cec5SDimitry Andric                         list<dag> pattern>
25530b57cec5SDimitry Andric    : X_VT5_VA5_VB5<opcode, xo, opc, pattern>, isDOT;
25540b57cec5SDimitry Andric
25550b57cec5SDimitry Andric  // [PO VRT VRA VRB XO /]
25560b57cec5SDimitry Andric  class X_VT5_VA5_VB5_FMA<bits<6> opcode, bits<10> xo, string opc,
25570b57cec5SDimitry Andric                          list<dag> pattern>
25580b57cec5SDimitry Andric    : XForm_1<opcode, xo, (outs vrrc:$vT), (ins vrrc:$vTi, vrrc:$vA, vrrc:$vB),
25590b57cec5SDimitry Andric              !strconcat(opc, " $vT, $vA, $vB"), IIC_VecFP, pattern>,
25600b57cec5SDimitry Andric              RegConstraint<"$vTi = $vT">, NoEncode<"$vTi">;
25610b57cec5SDimitry Andric
25620b57cec5SDimitry Andric  // [PO VRT VRA VRB XO RO], Round to Odd version of [PO VRT VRA VRB XO /]
25630b57cec5SDimitry Andric  class X_VT5_VA5_VB5_FMA_Ro<bits<6> opcode, bits<10> xo, string opc,
25640b57cec5SDimitry Andric                          list<dag> pattern>
25650b57cec5SDimitry Andric    : X_VT5_VA5_VB5_FMA<opcode, xo, opc, pattern>, isDOT;
25660b57cec5SDimitry Andric
25670b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
25680b57cec5SDimitry Andric  // Quad-Precision Scalar Move Instructions:
25690b57cec5SDimitry Andric
25700b57cec5SDimitry Andric  // Copy Sign
25710b57cec5SDimitry Andric  def XSCPSGNQP : X_VT5_VA5_VB5<63, 100, "xscpsgnqp",
25720b57cec5SDimitry Andric                                [(set f128:$vT,
25730b57cec5SDimitry Andric                                      (fcopysign f128:$vB, f128:$vA))]>;
25740b57cec5SDimitry Andric
25750b57cec5SDimitry Andric  // Absolute/Negative-Absolute/Negate
25760b57cec5SDimitry Andric  def XSABSQP   : X_VT5_XO5_VB5<63,  0, 804, "xsabsqp",
25770b57cec5SDimitry Andric                                [(set f128:$vT, (fabs f128:$vB))]>;
25780b57cec5SDimitry Andric  def XSNABSQP  : X_VT5_XO5_VB5<63,  8, 804, "xsnabsqp",
25790b57cec5SDimitry Andric                                [(set f128:$vT, (fneg (fabs f128:$vB)))]>;
25800b57cec5SDimitry Andric  def XSNEGQP   : X_VT5_XO5_VB5<63, 16, 804, "xsnegqp",
25810b57cec5SDimitry Andric                                [(set f128:$vT, (fneg f128:$vB))]>;
25820b57cec5SDimitry Andric
25830b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
25840b57cec5SDimitry Andric  // Quad-Precision Scalar Floating-Point Arithmetic Instructions:
25850b57cec5SDimitry Andric
25860b57cec5SDimitry Andric  // Add/Divide/Multiply/Subtract
25870b57cec5SDimitry Andric  let isCommutable = 1 in {
25880b57cec5SDimitry Andric  def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",
25890b57cec5SDimitry Andric                                   [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>;
25900b57cec5SDimitry Andric  def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",
25910b57cec5SDimitry Andric                                   [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>;
25920b57cec5SDimitry Andric  }
25930b57cec5SDimitry Andric  def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,
25940b57cec5SDimitry Andric                                   [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>;
25950b57cec5SDimitry Andric  def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",
25960b57cec5SDimitry Andric                                   [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>;
25970b57cec5SDimitry Andric  // Square-Root
25980b57cec5SDimitry Andric  def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",
25990b57cec5SDimitry Andric                                   [(set f128:$vT, (fsqrt f128:$vB))]>;
26000b57cec5SDimitry Andric  // (Negative) Multiply-{Add/Subtract}
26010b57cec5SDimitry Andric  def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",
26020b57cec5SDimitry Andric                                    [(set f128:$vT,
26030b57cec5SDimitry Andric                                          (fma f128:$vA, f128:$vB,
26040b57cec5SDimitry Andric                                               f128:$vTi))]>;
26050b57cec5SDimitry Andric  def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,
26060b57cec5SDimitry Andric                                       [(set f128:$vT,
26070b57cec5SDimitry Andric                                             (fma f128:$vA, f128:$vB,
26080b57cec5SDimitry Andric                                                  (fneg f128:$vTi)))]>;
26090b57cec5SDimitry Andric  def XSNMADDQP : X_VT5_VA5_VB5_FMA <63, 452, "xsnmaddqp",
26100b57cec5SDimitry Andric                                     [(set f128:$vT,
26110b57cec5SDimitry Andric                                           (fneg (fma f128:$vA, f128:$vB,
26120b57cec5SDimitry Andric                                                      f128:$vTi)))]>;
26130b57cec5SDimitry Andric  def XSNMSUBQP : X_VT5_VA5_VB5_FMA <63, 484, "xsnmsubqp",
26140b57cec5SDimitry Andric                                     [(set f128:$vT,
26150b57cec5SDimitry Andric                                           (fneg (fma f128:$vA, f128:$vB,
26160b57cec5SDimitry Andric                                                      (fneg f128:$vTi))))]>;
26170b57cec5SDimitry Andric
26180b57cec5SDimitry Andric  let isCommutable = 1 in {
26190b57cec5SDimitry Andric  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo",
26200b57cec5SDimitry Andric                                  [(set f128:$vT,
26210b57cec5SDimitry Andric                                  (int_ppc_addf128_round_to_odd
26220b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
26230b57cec5SDimitry Andric  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo",
26240b57cec5SDimitry Andric                                  [(set f128:$vT,
26250b57cec5SDimitry Andric                                  (int_ppc_mulf128_round_to_odd
26260b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
26270b57cec5SDimitry Andric  }
26280b57cec5SDimitry Andric  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo",
26290b57cec5SDimitry Andric                                  [(set f128:$vT,
26300b57cec5SDimitry Andric                                  (int_ppc_subf128_round_to_odd
26310b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
26320b57cec5SDimitry Andric  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo",
26330b57cec5SDimitry Andric                                  [(set f128:$vT,
26340b57cec5SDimitry Andric                                  (int_ppc_divf128_round_to_odd
26350b57cec5SDimitry Andric                                  f128:$vA, f128:$vB))]>;
26360b57cec5SDimitry Andric  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo",
26370b57cec5SDimitry Andric                                  [(set f128:$vT,
26380b57cec5SDimitry Andric                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;
26390b57cec5SDimitry Andric
26400b57cec5SDimitry Andric
26410b57cec5SDimitry Andric  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo",
26420b57cec5SDimitry Andric                                      [(set f128:$vT,
26430b57cec5SDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
26440b57cec5SDimitry Andric                                      f128:$vA,f128:$vB,f128:$vTi))]>;
26450b57cec5SDimitry Andric
26460b57cec5SDimitry Andric  def XSMSUBQPO : X_VT5_VA5_VB5_FMA_Ro<63, 420, "xsmsubqpo" ,
26470b57cec5SDimitry Andric                                      [(set f128:$vT,
26480b57cec5SDimitry Andric                                      (int_ppc_fmaf128_round_to_odd
26490b57cec5SDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi)))]>;
26500b57cec5SDimitry Andric  def XSNMADDQPO: X_VT5_VA5_VB5_FMA_Ro<63, 452, "xsnmaddqpo",
26510b57cec5SDimitry Andric                                      [(set f128:$vT,
26520b57cec5SDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
26530b57cec5SDimitry Andric                                      f128:$vA, f128:$vB, f128:$vTi)))]>;
26540b57cec5SDimitry Andric  def XSNMSUBQPO: X_VT5_VA5_VB5_FMA_Ro<63, 484, "xsnmsubqpo",
26550b57cec5SDimitry Andric                                      [(set f128:$vT,
26560b57cec5SDimitry Andric                                      (fneg (int_ppc_fmaf128_round_to_odd
26570b57cec5SDimitry Andric                                      f128:$vA, f128:$vB, (fneg f128:$vTi))))]>;
26580b57cec5SDimitry Andric
26598bcb0991SDimitry Andric  // Additional fnmsub patterns: -a*b + c == -(a*b - c)
26608bcb0991SDimitry Andric  def : Pat<(fma (fneg f128:$A), f128:$B, f128:$C), (XSNMSUBQP $C, $A, $B)>;
26618bcb0991SDimitry Andric  def : Pat<(fma f128:$A, (fneg f128:$B), f128:$C), (XSNMSUBQP $C, $A, $B)>;
26620b57cec5SDimitry Andric
26630b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
26640b57cec5SDimitry Andric  // Quad/Double-Precision Compare Instructions:
26650b57cec5SDimitry Andric
26660b57cec5SDimitry Andric  // [PO BF // VRA VRB XO /]
26670b57cec5SDimitry Andric  class X_BF3_VA5_VB5<bits<6> opcode, bits<10> xo, string opc,
26680b57cec5SDimitry Andric                      list<dag> pattern>
26690b57cec5SDimitry Andric    : XForm_17<opcode, xo, (outs crrc:$crD), (ins vrrc:$VA, vrrc:$VB),
26700b57cec5SDimitry Andric               !strconcat(opc, " $crD, $VA, $VB"), IIC_FPCompare> {
26710b57cec5SDimitry Andric    let Pattern = pattern;
26720b57cec5SDimitry Andric  }
26730b57cec5SDimitry Andric
26740b57cec5SDimitry Andric  // QP Compare Ordered/Unordered
26750b57cec5SDimitry Andric  def XSCMPOQP : X_BF3_VA5_VB5<63, 132, "xscmpoqp", []>;
26760b57cec5SDimitry Andric  def XSCMPUQP : X_BF3_VA5_VB5<63, 644, "xscmpuqp", []>;
26770b57cec5SDimitry Andric
26780b57cec5SDimitry Andric  // DP/QP Compare Exponents
26790b57cec5SDimitry Andric  def XSCMPEXPDP : XX3Form_1<60, 59,
26800b57cec5SDimitry Andric                             (outs crrc:$crD), (ins vsfrc:$XA, vsfrc:$XB),
26810b57cec5SDimitry Andric                             "xscmpexpdp $crD, $XA, $XB", IIC_FPCompare, []>;
26820b57cec5SDimitry Andric  def XSCMPEXPQP : X_BF3_VA5_VB5<63, 164, "xscmpexpqp", []>;
26830b57cec5SDimitry Andric
26840b57cec5SDimitry Andric  // DP Compare ==, >=, >, !=
26850b57cec5SDimitry Andric  // Use vsrc for XT, because the entire register of XT is set.
26860b57cec5SDimitry Andric  // XT.dword[1] = 0x0000_0000_0000_0000
26870b57cec5SDimitry Andric  def XSCMPEQDP : XX3_XT5_XA5_XB5<60,  3, "xscmpeqdp", vsrc, vsfrc, vsfrc,
26880b57cec5SDimitry Andric                                  IIC_FPCompare, []>;
26890b57cec5SDimitry Andric  def XSCMPGEDP : XX3_XT5_XA5_XB5<60, 19, "xscmpgedp", vsrc, vsfrc, vsfrc,
26900b57cec5SDimitry Andric                                  IIC_FPCompare, []>;
26910b57cec5SDimitry Andric  def XSCMPGTDP : XX3_XT5_XA5_XB5<60, 11, "xscmpgtdp", vsrc, vsfrc, vsfrc,
26920b57cec5SDimitry Andric                                  IIC_FPCompare, []>;
26930b57cec5SDimitry Andric
26940b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
26950b57cec5SDimitry Andric  // Quad-Precision Floating-Point Conversion Instructions:
26960b57cec5SDimitry Andric
26970b57cec5SDimitry Andric  // Convert DP -> QP
26980b57cec5SDimitry Andric  def XSCVDPQP  : X_VT5_XO5_VB5_TyVB<63, 22, 836, "xscvdpqp", vfrc,
26990b57cec5SDimitry Andric                                     [(set f128:$vT, (fpextend f64:$vB))]>;
27000b57cec5SDimitry Andric
27010b57cec5SDimitry Andric  // Round & Convert QP -> DP (dword[1] is set to zero)
27020b57cec5SDimitry Andric  def XSCVQPDP  : X_VT5_XO5_VB5_VSFR<63, 20, 836, "xscvqpdp" , []>;
27030b57cec5SDimitry Andric  def XSCVQPDPO : X_VT5_XO5_VB5_VSFR_Ro<63, 20, 836, "xscvqpdpo",
27040b57cec5SDimitry Andric                                        [(set f64:$vT,
27050b57cec5SDimitry Andric                                        (int_ppc_truncf128_round_to_odd
27060b57cec5SDimitry Andric                                        f128:$vB))]>;
27070b57cec5SDimitry Andric
27080b57cec5SDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word (dword[1] is set to zero)
27090b57cec5SDimitry Andric  def XSCVQPSDZ : X_VT5_XO5_VB5<63, 25, 836, "xscvqpsdz", []>;
27100b57cec5SDimitry Andric  def XSCVQPSWZ : X_VT5_XO5_VB5<63,  9, 836, "xscvqpswz", []>;
27110b57cec5SDimitry Andric  def XSCVQPUDZ : X_VT5_XO5_VB5<63, 17, 836, "xscvqpudz", []>;
27120b57cec5SDimitry Andric  def XSCVQPUWZ : X_VT5_XO5_VB5<63,  1, 836, "xscvqpuwz", []>;
27130b57cec5SDimitry Andric
27140b57cec5SDimitry Andric  // Convert (Un)Signed DWord -> QP.
27150b57cec5SDimitry Andric  def XSCVSDQP  : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>;
27160b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp i64:$src)),
27170b57cec5SDimitry Andric            (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
27180b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))),
27190b57cec5SDimitry Andric            (f128 (XSCVSDQP $src))>;
27200b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))),
27210b57cec5SDimitry Andric            (f128 (XSCVSDQP (VEXTSW2Ds $src)))>;
27220b57cec5SDimitry Andric
27230b57cec5SDimitry Andric  def XSCVUDQP  : X_VT5_XO5_VB5_TyVB<63,  2, 836, "xscvudqp", vfrc, []>;
27240b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp i64:$src)),
27250b57cec5SDimitry Andric            (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
27260b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))),
27270b57cec5SDimitry Andric            (f128 (XSCVUDQP $src))>;
27280b57cec5SDimitry Andric
27290b57cec5SDimitry Andric  // Convert (Un)Signed Word -> QP.
27300b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp i32:$src)),
27310b57cec5SDimitry Andric            (f128 (XSCVSDQP (MTVSRWA $src)))>;
27320b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))),
27330b57cec5SDimitry Andric            (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>;
27340b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp i32:$src)),
27350b57cec5SDimitry Andric            (f128 (XSCVUDQP (MTVSRWZ $src)))>;
27360b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))),
27370b57cec5SDimitry Andric            (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>;
27380b57cec5SDimitry Andric
27390b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
27400b57cec5SDimitry Andric  // Round to Floating-Point Integer Instructions
27410b57cec5SDimitry Andric
27420b57cec5SDimitry Andric  // (Round &) Convert DP <-> HP
27430b57cec5SDimitry Andric  // Note! xscvdphp's src and dest register both use the left 64 bits, so we use
27440b57cec5SDimitry Andric  // vsfrc for src and dest register. xscvhpdp's src only use the left 16 bits,
27450b57cec5SDimitry Andric  // but we still use vsfrc for it.
27460b57cec5SDimitry Andric  def XSCVDPHP : XX2_XT6_XO5_XB6<60, 17, 347, "xscvdphp", vsfrc, []>;
27470b57cec5SDimitry Andric  def XSCVHPDP : XX2_XT6_XO5_XB6<60, 16, 347, "xscvhpdp", vsfrc, []>;
27480b57cec5SDimitry Andric
27490b57cec5SDimitry Andric  // Vector HP -> SP
27500b57cec5SDimitry Andric  def XVCVHPSP : XX2_XT6_XO5_XB6<60, 24, 475, "xvcvhpsp", vsrc, []>;
27510b57cec5SDimitry Andric  def XVCVSPHP : XX2_XT6_XO5_XB6<60, 25, 475, "xvcvsphp", vsrc,
27520b57cec5SDimitry Andric                                 [(set v4f32:$XT,
27530b57cec5SDimitry Andric                                     (int_ppc_vsx_xvcvsphp v4f32:$XB))]>;
27540b57cec5SDimitry Andric
27550b57cec5SDimitry Andric  // Pattern for matching Vector HP -> Vector SP intrinsic. Defined as a
27560b57cec5SDimitry Andric  // separate pattern so that it can convert the input register class from
27570b57cec5SDimitry Andric  // VRRC(v8i16) to VSRC.
27580b57cec5SDimitry Andric  def : Pat<(v4f32 (int_ppc_vsx_xvcvhpsp v8i16:$A)),
27590b57cec5SDimitry Andric            (v4f32 (XVCVHPSP (COPY_TO_REGCLASS $A, VSRC)))>;
27600b57cec5SDimitry Andric
27610b57cec5SDimitry Andric  class Z23_VT5_R1_VB5_RMC2_EX1<bits<6> opcode, bits<8> xo, bit ex, string opc,
27620b57cec5SDimitry Andric                                list<dag> pattern>
27630b57cec5SDimitry Andric    : Z23Form_8<opcode, xo,
27640b57cec5SDimitry Andric                (outs vrrc:$vT), (ins u1imm:$r, vrrc:$vB, u2imm:$rmc),
27650b57cec5SDimitry Andric                !strconcat(opc, " $r, $vT, $vB, $rmc"), IIC_VecFP, pattern> {
27660b57cec5SDimitry Andric    let RC = ex;
27670b57cec5SDimitry Andric  }
27680b57cec5SDimitry Andric
27690b57cec5SDimitry Andric  // Round to Quad-Precision Integer [with Inexact]
27700b57cec5SDimitry Andric  def XSRQPI   : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 0, "xsrqpi" , []>;
27710b57cec5SDimitry Andric  def XSRQPIX  : Z23_VT5_R1_VB5_RMC2_EX1<63,  5, 1, "xsrqpix", []>;
27720b57cec5SDimitry Andric
27730b57cec5SDimitry Andric  // Use current rounding mode
27740b57cec5SDimitry Andric  def : Pat<(f128 (fnearbyint f128:$vB)), (f128 (XSRQPI 0, $vB, 3))>;
27750b57cec5SDimitry Andric  // Round to nearest, ties away from zero
27760b57cec5SDimitry Andric  def : Pat<(f128 (fround f128:$vB)), (f128 (XSRQPI 0, $vB, 0))>;
27770b57cec5SDimitry Andric  // Round towards Zero
27780b57cec5SDimitry Andric  def : Pat<(f128 (ftrunc f128:$vB)), (f128 (XSRQPI 1, $vB, 1))>;
27790b57cec5SDimitry Andric  // Round towards +Inf
27800b57cec5SDimitry Andric  def : Pat<(f128 (fceil f128:$vB)), (f128 (XSRQPI 1, $vB, 2))>;
27810b57cec5SDimitry Andric  // Round towards -Inf
27820b57cec5SDimitry Andric  def : Pat<(f128 (ffloor f128:$vB)), (f128 (XSRQPI 1, $vB, 3))>;
27830b57cec5SDimitry Andric
27840b57cec5SDimitry Andric  // Use current rounding mode, [with Inexact]
27850b57cec5SDimitry Andric  def : Pat<(f128 (frint f128:$vB)), (f128 (XSRQPIX 0, $vB, 3))>;
27860b57cec5SDimitry Andric
27870b57cec5SDimitry Andric  // Round Quad-Precision to Double-Extended Precision (fp80)
27880b57cec5SDimitry Andric  def XSRQPXP  : Z23_VT5_R1_VB5_RMC2_EX1<63, 37, 0, "xsrqpxp", []>;
27890b57cec5SDimitry Andric
27900b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
27910b57cec5SDimitry Andric  // Insert/Extract Instructions
27920b57cec5SDimitry Andric
27930b57cec5SDimitry Andric  // Insert Exponent DP/QP
27940b57cec5SDimitry Andric  // XT NOTE: XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU
27950b57cec5SDimitry Andric  def XSIEXPDP : XX1Form <60, 918, (outs vsrc:$XT), (ins g8rc:$rA, g8rc:$rB),
27960b57cec5SDimitry Andric                          "xsiexpdp $XT, $rA, $rB", IIC_VecFP, []>;
27970b57cec5SDimitry Andric  // vB NOTE: only vB.dword[0] is used, that's why we don't use
27980b57cec5SDimitry Andric  //          X_VT5_VA5_VB5 form
27990b57cec5SDimitry Andric  def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB),
28000b57cec5SDimitry Andric                          "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>;
28010b57cec5SDimitry Andric
28020b57cec5SDimitry Andric  def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)),
28030b57cec5SDimitry Andric            (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>;
28040b57cec5SDimitry Andric
28050b57cec5SDimitry Andric  // Extract Exponent/Significand DP/QP
28060b57cec5SDimitry Andric  def XSXEXPDP : XX2_RT5_XO5_XB6<60,  0, 347, "xsxexpdp", []>;
28070b57cec5SDimitry Andric  def XSXSIGDP : XX2_RT5_XO5_XB6<60,  1, 347, "xsxsigdp", []>;
28080b57cec5SDimitry Andric
28090b57cec5SDimitry Andric  def XSXEXPQP : X_VT5_XO5_VB5  <63,  2, 804, "xsxexpqp", []>;
28100b57cec5SDimitry Andric  def XSXSIGQP : X_VT5_XO5_VB5  <63, 18, 804, "xsxsigqp", []>;
28110b57cec5SDimitry Andric
28120b57cec5SDimitry Andric  def : Pat<(i64 (int_ppc_scalar_extract_expq  f128:$vA)),
28130b57cec5SDimitry Andric            (i64 (MFVSRD (EXTRACT_SUBREG
28140b57cec5SDimitry Andric                           (v2i64 (XSXEXPQP $vA)), sub_64)))>;
28150b57cec5SDimitry Andric
28160b57cec5SDimitry Andric  // Vector Insert Word
28170b57cec5SDimitry Andric  // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB.
28180b57cec5SDimitry Andric  def XXINSERTW   :
28190b57cec5SDimitry Andric    XX2_RD6_UIM5_RS6<60, 181, (outs vsrc:$XT),
28200b57cec5SDimitry Andric                     (ins vsrc:$XTi, vsrc:$XB, u4imm:$UIM),
28210b57cec5SDimitry Andric                     "xxinsertw $XT, $XB, $UIM", IIC_VecFP,
28220b57cec5SDimitry Andric                     [(set v4i32:$XT, (PPCvecinsert v4i32:$XTi, v4i32:$XB,
28230b57cec5SDimitry Andric                                                   imm32SExt16:$UIM))]>,
28240b57cec5SDimitry Andric                     RegConstraint<"$XTi = $XT">, NoEncode<"$XTi">;
28250b57cec5SDimitry Andric
28260b57cec5SDimitry Andric  // Vector Extract Unsigned Word
28270b57cec5SDimitry Andric  def XXEXTRACTUW : XX2_RD6_UIM5_RS6<60, 165,
28280b57cec5SDimitry Andric                                  (outs vsfrc:$XT), (ins vsrc:$XB, u4imm:$UIMM),
28290b57cec5SDimitry Andric                                  "xxextractuw $XT, $XB, $UIMM", IIC_VecFP, []>;
28300b57cec5SDimitry Andric
28310b57cec5SDimitry Andric  // Vector Insert Exponent DP/SP
28320b57cec5SDimitry Andric  def XVIEXPDP : XX3_XT5_XA5_XB5<60, 248, "xviexpdp", vsrc, vsrc, vsrc,
28330b57cec5SDimitry Andric    IIC_VecFP, [(set v2f64: $XT,(int_ppc_vsx_xviexpdp v2i64:$XA, v2i64:$XB))]>;
28340b57cec5SDimitry Andric  def XVIEXPSP : XX3_XT5_XA5_XB5<60, 216, "xviexpsp", vsrc, vsrc, vsrc,
28350b57cec5SDimitry Andric    IIC_VecFP, [(set v4f32: $XT,(int_ppc_vsx_xviexpsp v4i32:$XA, v4i32:$XB))]>;
28360b57cec5SDimitry Andric
28370b57cec5SDimitry Andric  // Vector Extract Exponent/Significand DP/SP
28380b57cec5SDimitry Andric  def XVXEXPDP : XX2_XT6_XO5_XB6<60,  0, 475, "xvxexpdp", vsrc,
28390b57cec5SDimitry Andric                                 [(set v2i64: $XT,
28400b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxexpdp v2f64:$XB))]>;
28410b57cec5SDimitry Andric  def XVXEXPSP : XX2_XT6_XO5_XB6<60,  8, 475, "xvxexpsp", vsrc,
28420b57cec5SDimitry Andric                                 [(set v4i32: $XT,
28430b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxexpsp v4f32:$XB))]>;
28440b57cec5SDimitry Andric  def XVXSIGDP : XX2_XT6_XO5_XB6<60,  1, 475, "xvxsigdp", vsrc,
28450b57cec5SDimitry Andric                                 [(set v2i64: $XT,
28460b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxsigdp v2f64:$XB))]>;
28470b57cec5SDimitry Andric  def XVXSIGSP : XX2_XT6_XO5_XB6<60,  9, 475, "xvxsigsp", vsrc,
28480b57cec5SDimitry Andric                                 [(set v4i32: $XT,
28490b57cec5SDimitry Andric                                  (int_ppc_vsx_xvxsigsp v4f32:$XB))]>;
28500b57cec5SDimitry Andric
28510b57cec5SDimitry Andric  let AddedComplexity = 400, Predicates = [HasP9Vector] in {
28520b57cec5SDimitry Andric  // Extra patterns expanding to vector Extract Word/Insert Word
28530b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_xxinsertw v4i32:$A, v2i64:$B, imm:$IMM)),
28540b57cec5SDimitry Andric            (v4i32 (XXINSERTW $A, $B, imm:$IMM))>;
28550b57cec5SDimitry Andric  def : Pat<(v2i64 (int_ppc_vsx_xxextractuw v2i64:$A, imm:$IMM)),
28560b57cec5SDimitry Andric            (v2i64 (COPY_TO_REGCLASS (XXEXTRACTUW $A, imm:$IMM), VSRC))>;
28570b57cec5SDimitry Andric  } // AddedComplexity = 400, HasP9Vector
28580b57cec5SDimitry Andric
28590b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
28600b57cec5SDimitry Andric
28610b57cec5SDimitry Andric  // Test Data Class SP/DP/QP
28620b57cec5SDimitry Andric  def XSTSTDCSP : XX2_BF3_DCMX7_RS6<60, 298,
28630b57cec5SDimitry Andric                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
28640b57cec5SDimitry Andric                              "xststdcsp $BF, $XB, $DCMX", IIC_VecFP, []>;
28650b57cec5SDimitry Andric  def XSTSTDCDP : XX2_BF3_DCMX7_RS6<60, 362,
28660b57cec5SDimitry Andric                              (outs crrc:$BF), (ins u7imm:$DCMX, vsfrc:$XB),
28670b57cec5SDimitry Andric                              "xststdcdp $BF, $XB, $DCMX", IIC_VecFP, []>;
28680b57cec5SDimitry Andric  def XSTSTDCQP : X_BF3_DCMX7_RS5  <63, 708,
28690b57cec5SDimitry Andric                              (outs crrc:$BF), (ins u7imm:$DCMX, vrrc:$vB),
28700b57cec5SDimitry Andric                              "xststdcqp $BF, $vB, $DCMX", IIC_VecFP, []>;
28710b57cec5SDimitry Andric
28720b57cec5SDimitry Andric  // Vector Test Data Class SP/DP
28730b57cec5SDimitry Andric  def XVTSTDCSP : XX2_RD6_DCMX7_RS6<60, 13, 5,
28740b57cec5SDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
28750b57cec5SDimitry Andric                              "xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
28760b57cec5SDimitry Andric                              [(set v4i32: $XT,
28778bcb0991SDimitry Andric                               (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
28780b57cec5SDimitry Andric  def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
28790b57cec5SDimitry Andric                              (outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
28800b57cec5SDimitry Andric                              "xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
28810b57cec5SDimitry Andric                              [(set v2i64: $XT,
28828bcb0991SDimitry Andric                               (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
28830b57cec5SDimitry Andric
28840b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
28850b57cec5SDimitry Andric
28860b57cec5SDimitry Andric  // Maximum/Minimum Type-C/Type-J DP
28870b57cec5SDimitry Andric  // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT
28880b57cec5SDimitry Andric  def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc,
28890b57cec5SDimitry Andric                                 IIC_VecFP, []>;
28900b57cec5SDimitry Andric  def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc,
28910b57cec5SDimitry Andric                                 IIC_VecFP, []>;
28920b57cec5SDimitry Andric  def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc,
28930b57cec5SDimitry Andric                                 IIC_VecFP, []>;
28940b57cec5SDimitry Andric  def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc,
28950b57cec5SDimitry Andric                                 IIC_VecFP, []>;
28960b57cec5SDimitry Andric
28970b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
28980b57cec5SDimitry Andric
28990b57cec5SDimitry Andric  // Vector Byte-Reverse H/W/D/Q Word
29000b57cec5SDimitry Andric  def XXBRH : XX2_XT6_XO5_XB6<60,  7, 475, "xxbrh", vsrc, []>;
29010b57cec5SDimitry Andric  def XXBRW : XX2_XT6_XO5_XB6<60, 15, 475, "xxbrw", vsrc, []>;
29020b57cec5SDimitry Andric  def XXBRD : XX2_XT6_XO5_XB6<60, 23, 475, "xxbrd", vsrc, []>;
29030b57cec5SDimitry Andric  def XXBRQ : XX2_XT6_XO5_XB6<60, 31, 475, "xxbrq", vsrc, []>;
29040b57cec5SDimitry Andric
29050b57cec5SDimitry Andric  // Vector Reverse
29060b57cec5SDimitry Andric  def : Pat<(v8i16 (PPCxxreverse v8i16 :$A)),
29070b57cec5SDimitry Andric            (v8i16 (COPY_TO_REGCLASS (XXBRH (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
29080b57cec5SDimitry Andric  def : Pat<(v4i32 (PPCxxreverse v4i32 :$A)),
29090b57cec5SDimitry Andric            (v4i32 (XXBRW $A))>;
29100b57cec5SDimitry Andric  def : Pat<(v2i64 (PPCxxreverse v2i64 :$A)),
29110b57cec5SDimitry Andric            (v2i64 (XXBRD $A))>;
29120b57cec5SDimitry Andric  def : Pat<(v1i128 (PPCxxreverse v1i128 :$A)),
29130b57cec5SDimitry Andric            (v1i128 (COPY_TO_REGCLASS (XXBRQ (COPY_TO_REGCLASS $A, VSRC)), VRRC))>;
29140b57cec5SDimitry Andric
29150b57cec5SDimitry Andric  // Vector Permute
29160b57cec5SDimitry Andric  def XXPERM  : XX3_XT5_XA5_XB5<60, 26, "xxperm" , vsrc, vsrc, vsrc,
29170b57cec5SDimitry Andric                                IIC_VecPerm, []>;
29180b57cec5SDimitry Andric  def XXPERMR : XX3_XT5_XA5_XB5<60, 58, "xxpermr", vsrc, vsrc, vsrc,
29190b57cec5SDimitry Andric                                IIC_VecPerm, []>;
29200b57cec5SDimitry Andric
29210b57cec5SDimitry Andric  // Vector Splat Immediate Byte
29220b57cec5SDimitry Andric  def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
29230b57cec5SDimitry Andric                            "xxspltib $XT, $IMM8", IIC_VecPerm, []>;
29240b57cec5SDimitry Andric
29250b57cec5SDimitry Andric  //===--------------------------------------------------------------------===//
29260b57cec5SDimitry Andric  // Vector/Scalar Load/Store Instructions
29270b57cec5SDimitry Andric
29280b57cec5SDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
29290b57cec5SDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
29300b57cec5SDimitry Andric  let mayLoad = 1, mayStore = 0 in {
29310b57cec5SDimitry Andric  // Load Vector
29320b57cec5SDimitry Andric  def LXV : DQ_RD6_RS5_DQ12<61, 1, (outs vsrc:$XT), (ins memrix16:$src),
29330b57cec5SDimitry Andric                            "lxv $XT, $src", IIC_LdStLFD, []>;
29340b57cec5SDimitry Andric  // Load DWord
29350b57cec5SDimitry Andric  def LXSD  : DSForm_1<57, 2, (outs vfrc:$vD), (ins memrix:$src),
29360b57cec5SDimitry Andric                       "lxsd $vD, $src", IIC_LdStLFD, []>;
29370b57cec5SDimitry Andric  // Load SP from src, convert it to DP, and place in dword[0]
29380b57cec5SDimitry Andric  def LXSSP : DSForm_1<57, 3, (outs vfrc:$vD), (ins memrix:$src),
29390b57cec5SDimitry Andric                       "lxssp $vD, $src", IIC_LdStLFD, []>;
29400b57cec5SDimitry Andric
29410b57cec5SDimitry Andric  // [PO T RA RB XO TX] almost equal to [PO S RA RB XO SX], but has different
29420b57cec5SDimitry Andric  // "out" and "in" dag
29430b57cec5SDimitry Andric  class X_XT6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
29440b57cec5SDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
29450b57cec5SDimitry Andric    : XX1Form_memOp<opcode, xo, (outs vtype:$XT), (ins memrr:$src),
29460b57cec5SDimitry Andric              !strconcat(opc, " $XT, $src"), IIC_LdStLFD, pattern>;
29470b57cec5SDimitry Andric
29480b57cec5SDimitry Andric  // Load as Integer Byte/Halfword & Zero Indexed
29490b57cec5SDimitry Andric  def LXSIBZX : X_XT6_RA5_RB5<31, 781, "lxsibzx", vsfrc,
29500b57cec5SDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 1))]>;
29510b57cec5SDimitry Andric  def LXSIHZX : X_XT6_RA5_RB5<31, 813, "lxsihzx", vsfrc,
29520b57cec5SDimitry Andric                              [(set f64:$XT, (PPClxsizx xoaddr:$src, 2))]>;
29530b57cec5SDimitry Andric
29540b57cec5SDimitry Andric  // Load Vector Halfword*8/Byte*16 Indexed
29550b57cec5SDimitry Andric  def LXVH8X  : X_XT6_RA5_RB5<31, 812, "lxvh8x" , vsrc, []>;
29560b57cec5SDimitry Andric  def LXVB16X : X_XT6_RA5_RB5<31, 876, "lxvb16x", vsrc, []>;
29570b57cec5SDimitry Andric
29580b57cec5SDimitry Andric  // Load Vector Indexed
29590b57cec5SDimitry Andric  def LXVX    : X_XT6_RA5_RB5<31, 268, "lxvx"   , vsrc,
29600b57cec5SDimitry Andric                [(set v2f64:$XT, (load xaddrX16:$src))]>;
29610b57cec5SDimitry Andric  // Load Vector (Left-justified) with Length
29620b57cec5SDimitry Andric  def LXVL : XX1Form_memOp<31, 269, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
29630b57cec5SDimitry Andric                   "lxvl $XT, $src, $rB", IIC_LdStLoad,
29640b57cec5SDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvl addr:$src, i64:$rB))]>;
29650b57cec5SDimitry Andric  def LXVLL : XX1Form_memOp<31,301, (outs vsrc:$XT), (ins memr:$src, g8rc:$rB),
29660b57cec5SDimitry Andric                   "lxvll $XT, $src, $rB", IIC_LdStLoad,
29670b57cec5SDimitry Andric                   [(set v4i32:$XT, (int_ppc_vsx_lxvll addr:$src, i64:$rB))]>;
29680b57cec5SDimitry Andric
29690b57cec5SDimitry Andric  // Load Vector Word & Splat Indexed
29700b57cec5SDimitry Andric  def LXVWSX  : X_XT6_RA5_RB5<31, 364, "lxvwsx" , vsrc, []>;
29710b57cec5SDimitry Andric  } // mayLoad
29720b57cec5SDimitry Andric
29730b57cec5SDimitry Andric  // When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
29740b57cec5SDimitry Andric  // PPCRegisterInfo::PPCRegisterInfo and maybe save yourself some debugging.
29750b57cec5SDimitry Andric  let mayStore = 1, mayLoad = 0 in {
29760b57cec5SDimitry Andric  // Store Vector
29770b57cec5SDimitry Andric  def STXV : DQ_RD6_RS5_DQ12<61, 5, (outs), (ins vsrc:$XT, memrix16:$dst),
29780b57cec5SDimitry Andric                             "stxv $XT, $dst", IIC_LdStSTFD, []>;
29790b57cec5SDimitry Andric  // Store DWord
29800b57cec5SDimitry Andric  def STXSD  : DSForm_1<61, 2, (outs), (ins vfrc:$vS, memrix:$dst),
29810b57cec5SDimitry Andric                        "stxsd $vS, $dst", IIC_LdStSTFD, []>;
29820b57cec5SDimitry Andric  // Convert DP of dword[0] to SP, and Store to dst
29830b57cec5SDimitry Andric  def STXSSP : DSForm_1<61, 3, (outs), (ins vfrc:$vS, memrix:$dst),
29840b57cec5SDimitry Andric                        "stxssp $vS, $dst", IIC_LdStSTFD, []>;
29850b57cec5SDimitry Andric
29860b57cec5SDimitry Andric  // [PO S RA RB XO SX]
29870b57cec5SDimitry Andric  class X_XS6_RA5_RB5<bits<6> opcode, bits<10> xo, string opc,
29880b57cec5SDimitry Andric                      RegisterOperand vtype, list<dag> pattern>
29890b57cec5SDimitry Andric    : XX1Form_memOp<opcode, xo, (outs), (ins vtype:$XT, memrr:$dst),
29900b57cec5SDimitry Andric              !strconcat(opc, " $XT, $dst"), IIC_LdStSTFD, pattern>;
29910b57cec5SDimitry Andric
29920b57cec5SDimitry Andric  // Store as Integer Byte/Halfword Indexed
29930b57cec5SDimitry Andric  def STXSIBX  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsfrc,
29940b57cec5SDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 1)]>;
29950b57cec5SDimitry Andric  def STXSIHX  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsfrc,
29960b57cec5SDimitry Andric                               [(PPCstxsix f64:$XT, xoaddr:$dst, 2)]>;
29970b57cec5SDimitry Andric  let isCodeGenOnly = 1 in {
29980b57cec5SDimitry Andric    def STXSIBXv  : X_XS6_RA5_RB5<31,  909, "stxsibx" , vsrc, []>;
29990b57cec5SDimitry Andric    def STXSIHXv  : X_XS6_RA5_RB5<31,  941, "stxsihx" , vsrc, []>;
30000b57cec5SDimitry Andric  }
30010b57cec5SDimitry Andric
30020b57cec5SDimitry Andric  // Store Vector Halfword*8/Byte*16 Indexed
30030b57cec5SDimitry Andric  def STXVH8X  : X_XS6_RA5_RB5<31,  940, "stxvh8x" , vsrc, []>;
30040b57cec5SDimitry Andric  def STXVB16X : X_XS6_RA5_RB5<31, 1004, "stxvb16x", vsrc, []>;
30050b57cec5SDimitry Andric
30060b57cec5SDimitry Andric  // Store Vector Indexed
30070b57cec5SDimitry Andric  def STXVX    : X_XS6_RA5_RB5<31,  396, "stxvx"   , vsrc,
30080b57cec5SDimitry Andric                 [(store v2f64:$XT, xaddrX16:$dst)]>;
30090b57cec5SDimitry Andric
30100b57cec5SDimitry Andric  // Store Vector (Left-justified) with Length
30110b57cec5SDimitry Andric  def STXVL : XX1Form_memOp<31, 397, (outs),
30120b57cec5SDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
30130b57cec5SDimitry Andric                            "stxvl $XT, $dst, $rB", IIC_LdStLoad,
30140b57cec5SDimitry Andric                            [(int_ppc_vsx_stxvl v4i32:$XT, addr:$dst,
30150b57cec5SDimitry Andric                              i64:$rB)]>;
30160b57cec5SDimitry Andric  def STXVLL : XX1Form_memOp<31, 429, (outs),
30170b57cec5SDimitry Andric                            (ins vsrc:$XT, memr:$dst, g8rc:$rB),
30180b57cec5SDimitry Andric                            "stxvll $XT, $dst, $rB", IIC_LdStLoad,
30190b57cec5SDimitry Andric                            [(int_ppc_vsx_stxvll v4i32:$XT, addr:$dst,
30200b57cec5SDimitry Andric                              i64:$rB)]>;
30210b57cec5SDimitry Andric  } // mayStore
30220b57cec5SDimitry Andric
30230b57cec5SDimitry Andric  let Predicates = [IsLittleEndian] in {
30240b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
30250b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
30260b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
30270b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
30280b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
30290b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
30300b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
30310b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
30320b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
30330b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
30340b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
30350b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
30360b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
30370b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
30380b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
30390b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
30400b57cec5SDimitry Andric  }
30410b57cec5SDimitry Andric
30420b57cec5SDimitry Andric  let Predicates = [IsBigEndian] in {
30430b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
30440b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 0))))>;
30450b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
30460b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 1))))>;
30470b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
30480b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 2))))>;
30490b57cec5SDimitry Andric  def: Pat<(f32 (PPCfcfids (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
30500b57cec5SDimitry Andric           (f32 (XSCVSPDPN (XVCVSXWSP (XXSPLTW $A, 3))))>;
30510b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 0)))))),
30520b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 0)), VSFRC))>;
30530b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 1)))))),
30540b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 1)), VSFRC))>;
30550b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 2)))))),
30560b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 2)), VSFRC))>;
30570b57cec5SDimitry Andric  def: Pat<(f64 (PPCfcfid (f64 (PPCmtvsra (i32 (extractelt v4i32:$A, 3)))))),
30580b57cec5SDimitry Andric           (f64 (COPY_TO_REGCLASS (XVCVSXWDP (XXSPLTW $A, 3)), VSFRC))>;
30590b57cec5SDimitry Andric  }
30600b57cec5SDimitry Andric
30610b57cec5SDimitry Andric  // Alternate patterns for PPCmtvsrz where the output is v8i16 or v16i8 instead
30620b57cec5SDimitry Andric  // of f64
30630b57cec5SDimitry Andric  def : Pat<(v8i16 (PPCmtvsrz i32:$A)),
30640b57cec5SDimitry Andric            (v8i16 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
30650b57cec5SDimitry Andric  def : Pat<(v16i8 (PPCmtvsrz i32:$A)),
30660b57cec5SDimitry Andric            (v16i8 (SUBREG_TO_REG (i64 1), (MTVSRWZ $A), sub_64))>;
30670b57cec5SDimitry Andric
30680b57cec5SDimitry Andric  // Patterns for which instructions from ISA 3.0 are a better match
30690b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP9Vector] in {
30700b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
30710b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
30720b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
30730b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
30740b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
30750b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
30760b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
30770b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
30780b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
30790b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
30800b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
30810b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
30820b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
30830b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
30840b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
30850b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
30860b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
30870b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
30880b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
30890b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
30900b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
30910b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
30920b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
30930b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
30940b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
30950b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
30960b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
30970b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
30980b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
30990b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
31000b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
31010b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
31028bcb0991SDimitry Andric
31038bcb0991SDimitry Andric  def : Pat<(v8i16 (PPCld_vec_be xoaddr:$src)),
31048bcb0991SDimitry Andric            (COPY_TO_REGCLASS (LXVH8X xoaddr:$src), VRRC)>;
31058bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v8i16:$rS, xoaddr:$dst),
31068bcb0991SDimitry Andric            (STXVH8X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
31078bcb0991SDimitry Andric
31088bcb0991SDimitry Andric  def : Pat<(v16i8 (PPCld_vec_be xoaddr:$src)),
31098bcb0991SDimitry Andric            (COPY_TO_REGCLASS (LXVB16X xoaddr:$src), VRRC)>;
31108bcb0991SDimitry Andric  def : Pat<(PPCst_vec_be v16i8:$rS, xoaddr:$dst),
31118bcb0991SDimitry Andric            (STXVB16X (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
31120b57cec5SDimitry Andric  } // IsLittleEndian, HasP9Vector
31130b57cec5SDimitry Andric
31140b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP9Vector] in {
31150b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
31160b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 0)))>;
31170b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
31180b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 4)))>;
31190b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
31200b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 8)))>;
31210b57cec5SDimitry Andric  def : Pat<(f32 (PPCfcfidus (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
31220b57cec5SDimitry Andric            (f32 (XSCVUXDSP (XXEXTRACTUW $A, 12)))>;
31230b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 0)))))),
31240b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 0)))>;
31250b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 1)))))),
31260b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 4)))>;
31270b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 2)))))),
31280b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 8)))>;
31290b57cec5SDimitry Andric  def : Pat<(f64 (PPCfcfidu (f64 (PPCmtvsrz (i32 (extractelt v4i32:$A, 3)))))),
31300b57cec5SDimitry Andric            (f64 (XSCVUXDDP (XXEXTRACTUW $A, 12)))>;
31310b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 0)),
31320b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 0))>;
31330b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 1)),
31340b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 4))>;
31350b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 2)),
31360b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 8))>;
31370b57cec5SDimitry Andric  def : Pat<(v4i32 (insertelt v4i32:$A, i32:$B, 3)),
31380b57cec5SDimitry Andric            (v4i32 (XXINSERTW v4i32:$A, AlignValues.I32_TO_BE_WORD1, 12))>;
31390b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 0)),
31400b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 0))>;
31410b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 1)),
31420b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 4))>;
31430b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 2)),
31440b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 8))>;
31450b57cec5SDimitry Andric  def : Pat<(v4f32 (insertelt v4f32:$A, f32:$B, 3)),
31460b57cec5SDimitry Andric            (v4f32 (XXINSERTW v4f32:$A, AlignValues.F32_TO_BE_WORD1, 12))>;
31478bcb0991SDimitry Andric  } // IsBigEndian, HasP9Vector
31480b57cec5SDimitry Andric
31490b57cec5SDimitry Andric  // D-Form Load/Store
31500b57cec5SDimitry Andric  def : Pat<(v4i32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
31510b57cec5SDimitry Andric  def : Pat<(v4f32 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
31520b57cec5SDimitry Andric  def : Pat<(v2i64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
31530b57cec5SDimitry Andric  def : Pat<(v2f64 (quadwOffsetLoad iaddrX16:$src)), (LXV memrix16:$src)>;
31540b57cec5SDimitry Andric  def : Pat<(f128  (quadwOffsetLoad iaddrX16:$src)),
31550b57cec5SDimitry Andric            (COPY_TO_REGCLASS (LXV memrix16:$src), VRRC)>;
31560b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x iaddrX16:$src)), (LXV memrix16:$src)>;
31570b57cec5SDimitry Andric  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x iaddrX16:$src)), (LXV memrix16:$src)>;
31580b57cec5SDimitry Andric
31590b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v4f32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
31600b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v4i32:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
31610b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v2f64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
31620b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore  f128:$rS, iaddrX16:$dst),
31630b57cec5SDimitry Andric            (STXV (COPY_TO_REGCLASS $rS, VSRC), memrix16:$dst)>;
31640b57cec5SDimitry Andric  def : Pat<(quadwOffsetStore v2i64:$rS, iaddrX16:$dst), (STXV $rS, memrix16:$dst)>;
31650b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, iaddrX16:$dst),
31660b57cec5SDimitry Andric            (STXV $rS, memrix16:$dst)>;
31670b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, iaddrX16:$dst),
31680b57cec5SDimitry Andric            (STXV $rS, memrix16:$dst)>;
31690b57cec5SDimitry Andric
31700b57cec5SDimitry Andric
31710b57cec5SDimitry Andric  def : Pat<(v2f64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
31720b57cec5SDimitry Andric  def : Pat<(v2i64 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
31730b57cec5SDimitry Andric  def : Pat<(v4f32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
31740b57cec5SDimitry Andric  def : Pat<(v4i32 (nonQuadwOffsetLoad xoaddr:$src)), (LXVX xoaddr:$src)>;
31750b57cec5SDimitry Andric  def : Pat<(v4i32 (int_ppc_vsx_lxvw4x xoaddr:$src)), (LXVX xoaddr:$src)>;
31760b57cec5SDimitry Andric  def : Pat<(v2f64 (int_ppc_vsx_lxvd2x xoaddr:$src)), (LXVX xoaddr:$src)>;
31770b57cec5SDimitry Andric  def : Pat<(f128  (nonQuadwOffsetLoad xoaddr:$src)),
31780b57cec5SDimitry Andric            (COPY_TO_REGCLASS (LXVX xoaddr:$src), VRRC)>;
31790b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore f128:$rS, xoaddr:$dst),
31800b57cec5SDimitry Andric            (STXVX (COPY_TO_REGCLASS $rS, VSRC), xoaddr:$dst)>;
31810b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v2f64:$rS, xoaddr:$dst),
31820b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
31830b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v2i64:$rS, xoaddr:$dst),
31840b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
31850b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v4f32:$rS, xoaddr:$dst),
31860b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
31870b57cec5SDimitry Andric  def : Pat<(nonQuadwOffsetStore v4i32:$rS, xoaddr:$dst),
31880b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
31890b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvw4x v4i32:$rS, xoaddr:$dst),
31900b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
31910b57cec5SDimitry Andric  def : Pat<(int_ppc_vsx_stxvd2x v2f64:$rS, xoaddr:$dst),
31920b57cec5SDimitry Andric            (STXVX $rS, xoaddr:$dst)>;
31930b57cec5SDimitry Andric
31940b57cec5SDimitry Andric  let AddedComplexity = 400 in {
31950b57cec5SDimitry Andric    // LIWAX - This instruction is used for sign extending i32 -> i64.
31960b57cec5SDimitry Andric    // LIWZX - This instruction will be emitted for i32, f32, and when
31970b57cec5SDimitry Andric    //         zero-extending i32 to i64 (zext i32 -> i64).
31980b57cec5SDimitry Andric    let Predicates = [IsLittleEndian] in {
31990b57cec5SDimitry Andric
32000b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
32010b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
32020b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC), 2))>;
32030b57cec5SDimitry Andric
32040b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
32050b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
32060b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
32070b57cec5SDimitry Andric
32080b57cec5SDimitry Andric      def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
32090b57cec5SDimitry Andric                (v4i32 (XXPERMDIs
32100b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
32110b57cec5SDimitry Andric
32120b57cec5SDimitry Andric      def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
32130b57cec5SDimitry Andric                (v4f32 (XXPERMDIs
32140b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 2))>;
32150b57cec5SDimitry Andric    }
32160b57cec5SDimitry Andric
32170b57cec5SDimitry Andric    let Predicates = [IsBigEndian] in {
32180b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (sextloadi32 xoaddr:$src)))),
32190b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (LIWAX xoaddr:$src), VSRC))>;
32200b57cec5SDimitry Andric
32210b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (zextloadi32 xoaddr:$src)))),
32220b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC))>;
32230b57cec5SDimitry Andric
32240b57cec5SDimitry Andric      def : Pat<(v4i32 (scalar_to_vector (i32 (load xoaddr:$src)))),
32250b57cec5SDimitry Andric                (v4i32 (XXSLDWIs
32260b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
32270b57cec5SDimitry Andric
32280b57cec5SDimitry Andric      def : Pat<(v4f32 (scalar_to_vector (f32 (load xoaddr:$src)))),
32290b57cec5SDimitry Andric                (v4f32 (XXSLDWIs
32300b57cec5SDimitry Andric                (COPY_TO_REGCLASS (LIWZX xoaddr:$src), VSRC), 1))>;
32310b57cec5SDimitry Andric    }
32320b57cec5SDimitry Andric
32330b57cec5SDimitry Andric  }
32340b57cec5SDimitry Andric
32350b57cec5SDimitry Andric  // Build vectors from i8 loads
32360b57cec5SDimitry Andric  def : Pat<(v16i8 (scalar_to_vector ScalarLoads.Li8)),
32370b57cec5SDimitry Andric            (v16i8 (VSPLTBs 7, (LXSIBZX xoaddr:$src)))>;
32380b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.ZELi8)),
32390b57cec5SDimitry Andric            (v8i16 (VSPLTHs 3, (LXSIBZX xoaddr:$src)))>;
32400b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi8)),
32410b57cec5SDimitry Andric           (v4i32 (XXSPLTWs (LXSIBZX xoaddr:$src), 1))>;
32420b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi8i64)),
32430b57cec5SDimitry Andric            (v2i64 (XXPERMDIs (LXSIBZX xoaddr:$src), 0))>;
32440b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi8)),
32450b57cec5SDimitry Andric            (v4i32 (XXSPLTWs (VEXTSB2Ws (LXSIBZX xoaddr:$src)), 1))>;
32460b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi8i64)),
32470b57cec5SDimitry Andric            (v2i64 (XXPERMDIs (VEXTSB2Ds (LXSIBZX xoaddr:$src)), 0))>;
32480b57cec5SDimitry Andric
32490b57cec5SDimitry Andric  // Build vectors from i16 loads
32500b57cec5SDimitry Andric  def : Pat<(v8i16 (scalar_to_vector ScalarLoads.Li16)),
32510b57cec5SDimitry Andric            (v8i16 (VSPLTHs 3, (LXSIHZX xoaddr:$src)))>;
32520b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.ZELi16)),
32530b57cec5SDimitry Andric            (v4i32 (XXSPLTWs (LXSIHZX xoaddr:$src), 1))>;
32540b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.ZELi16i64)),
32550b57cec5SDimitry Andric           (v2i64 (XXPERMDIs (LXSIHZX xoaddr:$src), 0))>;
32560b57cec5SDimitry Andric  def : Pat<(v4i32 (scalar_to_vector ScalarLoads.SELi16)),
32570b57cec5SDimitry Andric            (v4i32 (XXSPLTWs (VEXTSH2Ws (LXSIHZX xoaddr:$src)), 1))>;
32580b57cec5SDimitry Andric  def : Pat<(v2i64 (scalar_to_vector ScalarLoads.SELi16i64)),
32590b57cec5SDimitry Andric            (v2i64 (XXPERMDIs (VEXTSH2Ds (LXSIHZX xoaddr:$src)), 0))>;
32600b57cec5SDimitry Andric
32610b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP9Vector] in {
32620b57cec5SDimitry Andric  // Scalar stores of i8
32630b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
32640b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
32650b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
32660b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
32670b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
32680b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
32690b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
32700b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
32710b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
32720b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
32730b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
32740b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
32750b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
32760b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
32770b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
32780b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
32790b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
32800b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
32810b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
32820b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
32830b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
32840b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
32850b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
32860b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
32870b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
32880b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
32890b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
32900b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
32910b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
32920b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
32930b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
32940b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
32950b57cec5SDimitry Andric
32960b57cec5SDimitry Andric  // Scalar stores of i16
32970b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
32980b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
32990b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
33000b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
33010b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
33020b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
33030b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
33040b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
33050b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
33060b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
33070b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
33080b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
33090b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
33100b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
33110b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
33120b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
33130b57cec5SDimitry Andric  } // IsBigEndian, HasP9Vector
33140b57cec5SDimitry Andric
33150b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP9Vector] in {
33160b57cec5SDimitry Andric  // Scalar stores of i8
33170b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 0)), xoaddr:$dst),
33180b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
33190b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 1)), xoaddr:$dst),
33200b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 7)), VSRC), xoaddr:$dst)>;
33210b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 2)), xoaddr:$dst),
33220b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
33230b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 3)), xoaddr:$dst),
33240b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 5)), VSRC), xoaddr:$dst)>;
33250b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 4)), xoaddr:$dst),
33260b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
33270b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 5)), xoaddr:$dst),
33280b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 3)), VSRC), xoaddr:$dst)>;
33290b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 6)), xoaddr:$dst),
33300b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
33310b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 7)), xoaddr:$dst),
33320b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 1)), VSRC), xoaddr:$dst)>;
33330b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 8)), xoaddr:$dst),
33340b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
33350b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 9)), xoaddr:$dst),
33360b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 15)), VSRC), xoaddr:$dst)>;
33370b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 10)), xoaddr:$dst),
33380b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
33390b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 11)), xoaddr:$dst),
33400b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 13)), VSRC), xoaddr:$dst)>;
33410b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 12)), xoaddr:$dst),
33420b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
33430b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 13)), xoaddr:$dst),
33440b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 11)), VSRC), xoaddr:$dst)>;
33450b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 14)), xoaddr:$dst),
33460b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
33470b57cec5SDimitry Andric  def : Pat<(truncstorei8 (i32 (vector_extract v16i8:$S, 15)), xoaddr:$dst),
33480b57cec5SDimitry Andric            (STXSIBXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 9)), VSRC), xoaddr:$dst)>;
33490b57cec5SDimitry Andric
33500b57cec5SDimitry Andric  // Scalar stores of i16
33510b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 0)), xoaddr:$dst),
33520b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 8)), VSRC), xoaddr:$dst)>;
33530b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 1)), xoaddr:$dst),
33540b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 6)), VSRC), xoaddr:$dst)>;
33550b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 2)), xoaddr:$dst),
33560b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 4)), VSRC), xoaddr:$dst)>;
33570b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 3)), xoaddr:$dst),
33580b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 2)), VSRC), xoaddr:$dst)>;
33590b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 4)), xoaddr:$dst),
33600b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS $S, VSRC), xoaddr:$dst)>;
33610b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 5)), xoaddr:$dst),
33620b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 14)), VSRC), xoaddr:$dst)>;
33630b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 6)), xoaddr:$dst),
33640b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 12)), VSRC), xoaddr:$dst)>;
33650b57cec5SDimitry Andric  def : Pat<(truncstorei16 (i32 (vector_extract v8i16:$S, 7)), xoaddr:$dst),
33660b57cec5SDimitry Andric            (STXSIHXv (COPY_TO_REGCLASS (v16i8 (VSLDOI $S, $S, 10)), VSRC), xoaddr:$dst)>;
33670b57cec5SDimitry Andric  } // IsLittleEndian, HasP9Vector
33680b57cec5SDimitry Andric
33690b57cec5SDimitry Andric
33700b57cec5SDimitry Andric  // Vector sign extensions
33710b57cec5SDimitry Andric  def : Pat<(f64 (PPCVexts f64:$A, 1)),
33720b57cec5SDimitry Andric            (f64 (COPY_TO_REGCLASS (VEXTSB2Ds $A), VSFRC))>;
33730b57cec5SDimitry Andric  def : Pat<(f64 (PPCVexts f64:$A, 2)),
33740b57cec5SDimitry Andric            (f64 (COPY_TO_REGCLASS (VEXTSH2Ds $A), VSFRC))>;
33750b57cec5SDimitry Andric
33760b57cec5SDimitry Andric  def DFLOADf32  : PPCPostRAExpPseudo<(outs vssrc:$XT), (ins memrix:$src),
33770b57cec5SDimitry Andric                          "#DFLOADf32",
33780b57cec5SDimitry Andric                          [(set f32:$XT, (load iaddrX4:$src))]>;
33790b57cec5SDimitry Andric  def DFLOADf64  : PPCPostRAExpPseudo<(outs vsfrc:$XT), (ins memrix:$src),
33800b57cec5SDimitry Andric                          "#DFLOADf64",
33810b57cec5SDimitry Andric                          [(set f64:$XT, (load iaddrX4:$src))]>;
33820b57cec5SDimitry Andric  def DFSTOREf32 : PPCPostRAExpPseudo<(outs), (ins vssrc:$XT, memrix:$dst),
33830b57cec5SDimitry Andric                          "#DFSTOREf32",
33840b57cec5SDimitry Andric                          [(store f32:$XT, iaddrX4:$dst)]>;
33850b57cec5SDimitry Andric  def DFSTOREf64 : PPCPostRAExpPseudo<(outs), (ins vsfrc:$XT, memrix:$dst),
33860b57cec5SDimitry Andric                          "#DFSTOREf64",
33870b57cec5SDimitry Andric                          [(store f64:$XT, iaddrX4:$dst)]>;
33880b57cec5SDimitry Andric
33890b57cec5SDimitry Andric  def : Pat<(f64 (extloadf32 iaddrX4:$src)),
33900b57cec5SDimitry Andric            (COPY_TO_REGCLASS (DFLOADf32 iaddrX4:$src), VSFRC)>;
33910b57cec5SDimitry Andric  def : Pat<(f32 (fpround (f64 (extloadf32 iaddrX4:$src)))),
33920b57cec5SDimitry Andric            (f32 (DFLOADf32 iaddrX4:$src))>;
33930b57cec5SDimitry Andric
33940b57cec5SDimitry Andric  def : Pat<(v4f32 (PPCldvsxlh xaddr:$src)),
33950b57cec5SDimitry Andric            (COPY_TO_REGCLASS (XFLOADf64 xaddr:$src), VSRC)>;
33960b57cec5SDimitry Andric  def : Pat<(v4f32 (PPCldvsxlh iaddrX4:$src)),
33970b57cec5SDimitry Andric            (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC)>;
33980b57cec5SDimitry Andric
33990b57cec5SDimitry Andric  let AddedComplexity = 400 in {
34000b57cec5SDimitry Andric  // The following pseudoinstructions are used to ensure the utilization
34010b57cec5SDimitry Andric  // of all 64 VSX registers.
34020b57cec5SDimitry Andric    let Predicates = [IsLittleEndian, HasP9Vector] in {
34030b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
34040b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
34050b57cec5SDimitry Andric                (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>;
34060b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
34070b57cec5SDimitry Andric                (v2i64 (XXPERMDIs
34080b57cec5SDimitry Andric		(COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>;
34090b57cec5SDimitry Andric
34100b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
34110b57cec5SDimitry Andric                (v2f64 (XXPERMDIs
34120b57cec5SDimitry Andric                (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC), 2))>;
34130b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
34140b57cec5SDimitry Andric                (v2f64 (XXPERMDIs
34150b57cec5SDimitry Andric                (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC), 2))>;
34160b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
34170b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34180b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
34190b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
34200b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34210b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
34220b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
34230b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
34240b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
34250b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
34260b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
34270b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34280b57cec5SDimitry Andric                             sub_64), iaddrX4:$src)>;
34290b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
34300b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
34310b57cec5SDimitry Andric                            iaddrX4:$src)>;
34320b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
34330b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
34340b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
34350b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
34360b57cec5SDimitry Andric    } // IsLittleEndian, HasP9Vector
34370b57cec5SDimitry Andric
34380b57cec5SDimitry Andric    let Predicates = [IsBigEndian, HasP9Vector] in {
34390b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load iaddrX4:$src)))),
34400b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
34410b57cec5SDimitry Andric      def : Pat<(v2i64 (scalar_to_vector (i64 (load xaddrX4:$src)))),
34420b57cec5SDimitry Andric                (v2i64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
34430b57cec5SDimitry Andric
34440b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load iaddrX4:$src)))),
34450b57cec5SDimitry Andric                (v2f64 (COPY_TO_REGCLASS (DFLOADf64 iaddrX4:$src), VSRC))>;
34460b57cec5SDimitry Andric      def : Pat<(v2f64 (scalar_to_vector (f64 (load xaddrX4:$src)))),
34470b57cec5SDimitry Andric                (v2f64 (COPY_TO_REGCLASS (XFLOADf64 xaddrX4:$src), VSRC))>;
34480b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xaddrX4:$src),
34490b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34500b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
34510b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xaddrX4:$src),
34520b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34530b57cec5SDimitry Andric                             sub_64), xaddrX4:$src)>;
34540b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xaddrX4:$src),
34550b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
34560b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xaddrX4:$src),
34570b57cec5SDimitry Andric                (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xaddrX4:$src)>;
34580b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 1)), iaddrX4:$src),
34590b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34600b57cec5SDimitry Andric                             sub_64), iaddrX4:$src)>;
34610b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 1)), iaddrX4:$src),
34620b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2),
34630b57cec5SDimitry Andric                             sub_64), iaddrX4:$src)>;
34640b57cec5SDimitry Andric      def : Pat<(store (i64 (extractelt v2i64:$A, 0)), iaddrX4:$src),
34650b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
34660b57cec5SDimitry Andric      def : Pat<(store (f64 (extractelt v2f64:$A, 0)), iaddrX4:$src),
34670b57cec5SDimitry Andric                (DFSTOREf64 (EXTRACT_SUBREG $A, sub_64), iaddrX4:$src)>;
34680b57cec5SDimitry Andric    } // IsBigEndian, HasP9Vector
34690b57cec5SDimitry Andric  }
34700b57cec5SDimitry Andric
34710b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP9Vector] in {
34720b57cec5SDimitry Andric
34730b57cec5SDimitry Andric    // (Un)Signed DWord vector extract -> QP
34740b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
34750b57cec5SDimitry Andric              (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
34760b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
34770b57cec5SDimitry Andric              (f128 (XSCVSDQP
34780b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
34790b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
34800b57cec5SDimitry Andric              (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
34810b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
34820b57cec5SDimitry Andric              (f128 (XSCVUDQP
34830b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
34840b57cec5SDimitry Andric
34850b57cec5SDimitry Andric    // (Un)Signed Word vector extract -> QP
34860b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 1)))),
34870b57cec5SDimitry Andric              (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
34880b57cec5SDimitry Andric    foreach Idx = [0,2,3] in {
34890b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
34900b57cec5SDimitry Andric                (f128 (XSCVSDQP (EXTRACT_SUBREG
34910b57cec5SDimitry Andric                                (VEXTSW2D (VSPLTW Idx, $src)), sub_64)))>;
34920b57cec5SDimitry Andric    }
34930b57cec5SDimitry Andric    foreach Idx = 0-3 in {
34940b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, Idx)))),
34950b57cec5SDimitry Andric                (f128 (XSCVUDQP (XXEXTRACTUW $src, !shl(Idx, 2))))>;
34960b57cec5SDimitry Andric    }
34970b57cec5SDimitry Andric
34980b57cec5SDimitry Andric    // (Un)Signed HWord vector extract -> QP
34990b57cec5SDimitry Andric    foreach Idx = 0-7 in {
35000b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
35010b57cec5SDimitry Andric                        (i32 (sext_inreg
35020b57cec5SDimitry Andric                               (vector_extract v8i16:$src, Idx), i16)))),
35030b57cec5SDimitry Andric              (f128 (XSCVSDQP (EXTRACT_SUBREG
35040b57cec5SDimitry Andric                                (VEXTSH2D (VEXTRACTUH !add(Idx, Idx), $src)),
35050b57cec5SDimitry Andric                                sub_64)))>;
35060b57cec5SDimitry Andric      // The SDAG adds the `and` since an `i16` is being extracted as an `i32`.
35070b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
35080b57cec5SDimitry Andric                        (and (i32 (vector_extract v8i16:$src, Idx)), 65535))),
35090b57cec5SDimitry Andric                (f128 (XSCVUDQP (EXTRACT_SUBREG
35100b57cec5SDimitry Andric                                  (VEXTRACTUH !add(Idx, Idx), $src), sub_64)))>;
35110b57cec5SDimitry Andric    }
35120b57cec5SDimitry Andric
35130b57cec5SDimitry Andric    // (Un)Signed Byte vector extract -> QP
35140b57cec5SDimitry Andric    foreach Idx = 0-15 in {
35150b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
35160b57cec5SDimitry Andric                        (i32 (sext_inreg (vector_extract v16i8:$src, Idx),
35170b57cec5SDimitry Andric                                         i8)))),
35180b57cec5SDimitry Andric                (f128 (XSCVSDQP (EXTRACT_SUBREG
35190b57cec5SDimitry Andric                                  (VEXTSB2D (VEXTRACTUB Idx, $src)), sub_64)))>;
35200b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
35210b57cec5SDimitry Andric                        (and (i32 (vector_extract v16i8:$src, Idx)), 255))),
35220b57cec5SDimitry Andric                (f128 (XSCVUDQP
35230b57cec5SDimitry Andric                        (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>;
35240b57cec5SDimitry Andric    }
35250b57cec5SDimitry Andric
35260b57cec5SDimitry Andric    // Unsiged int in vsx register -> QP
35270b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
35280b57cec5SDimitry Andric              (f128 (XSCVUDQP
35290b57cec5SDimitry Andric                      (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>;
35300b57cec5SDimitry Andric  } // IsBigEndian, HasP9Vector
35310b57cec5SDimitry Andric
35320b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP9Vector] in {
35330b57cec5SDimitry Andric
35340b57cec5SDimitry Andric    // (Un)Signed DWord vector extract -> QP
35350b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 0)))),
35360b57cec5SDimitry Andric              (f128 (XSCVSDQP
35370b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
35380b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i64 (extractelt v2i64:$src, 1)))),
35390b57cec5SDimitry Andric              (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>;
35400b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 0)))),
35410b57cec5SDimitry Andric              (f128 (XSCVUDQP
35420b57cec5SDimitry Andric                      (EXTRACT_SUBREG (XXPERMDI $src, $src, 3), sub_64)))>;
35430b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i64 (extractelt v2i64:$src, 1)))),
35440b57cec5SDimitry Andric              (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>;
35450b57cec5SDimitry Andric
35460b57cec5SDimitry Andric    // (Un)Signed Word vector extract -> QP
35470b57cec5SDimitry Andric    foreach Idx = [[0,3],[1,2],[3,0]] in {
35480b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
35490b57cec5SDimitry Andric                (f128 (XSCVSDQP (EXTRACT_SUBREG
35500b57cec5SDimitry Andric                                  (VEXTSW2D (VSPLTW !head(!tail(Idx)), $src)),
35510b57cec5SDimitry Andric                                  sub_64)))>;
35520b57cec5SDimitry Andric    }
35530b57cec5SDimitry Andric    def : Pat<(f128 (sint_to_fp (i32 (extractelt v4i32:$src, 2)))),
35540b57cec5SDimitry Andric              (f128 (XSCVSDQP (EXTRACT_SUBREG (VEXTSW2D $src), sub_64)))>;
35550b57cec5SDimitry Andric
35560b57cec5SDimitry Andric    foreach Idx = [[0,12],[1,8],[2,4],[3,0]] in {
35570b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp (i32 (extractelt v4i32:$src, !head(Idx))))),
35580b57cec5SDimitry Andric                (f128 (XSCVUDQP (XXEXTRACTUW $src, !head(!tail(Idx)))))>;
35590b57cec5SDimitry Andric    }
35600b57cec5SDimitry Andric
35610b57cec5SDimitry Andric    // (Un)Signed HWord vector extract -> QP
35620b57cec5SDimitry Andric    // The Nested foreach lists identifies the vector element and corresponding
35630b57cec5SDimitry Andric    // register byte location.
35640b57cec5SDimitry Andric    foreach Idx = [[0,14],[1,12],[2,10],[3,8],[4,6],[5,4],[6,2],[7,0]] in {
35650b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
35660b57cec5SDimitry Andric                        (i32 (sext_inreg
35670b57cec5SDimitry Andric                               (vector_extract v8i16:$src, !head(Idx)), i16)))),
35680b57cec5SDimitry Andric                (f128 (XSCVSDQP
35690b57cec5SDimitry Andric                        (EXTRACT_SUBREG (VEXTSH2D
35700b57cec5SDimitry Andric                                          (VEXTRACTUH !head(!tail(Idx)), $src)),
35710b57cec5SDimitry Andric                                        sub_64)))>;
35720b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
35730b57cec5SDimitry Andric                        (and (i32 (vector_extract v8i16:$src, !head(Idx))),
35740b57cec5SDimitry Andric                             65535))),
35750b57cec5SDimitry Andric                (f128 (XSCVUDQP (EXTRACT_SUBREG
35760b57cec5SDimitry Andric                                  (VEXTRACTUH !head(!tail(Idx)), $src), sub_64)))>;
35770b57cec5SDimitry Andric    }
35780b57cec5SDimitry Andric
35790b57cec5SDimitry Andric    // (Un)Signed Byte vector extract -> QP
35800b57cec5SDimitry Andric    foreach Idx = [[0,15],[1,14],[2,13],[3,12],[4,11],[5,10],[6,9],[7,8],[8,7],
35810b57cec5SDimitry Andric                   [9,6],[10,5],[11,4],[12,3],[13,2],[14,1],[15,0]] in {
35820b57cec5SDimitry Andric      def : Pat<(f128 (sint_to_fp
35830b57cec5SDimitry Andric                        (i32 (sext_inreg
35840b57cec5SDimitry Andric                               (vector_extract v16i8:$src, !head(Idx)), i8)))),
35850b57cec5SDimitry Andric                (f128 (XSCVSDQP
35860b57cec5SDimitry Andric                        (EXTRACT_SUBREG
35870b57cec5SDimitry Andric                          (VEXTSB2D (VEXTRACTUB !head(!tail(Idx)), $src)),
35880b57cec5SDimitry Andric                          sub_64)))>;
35890b57cec5SDimitry Andric      def : Pat<(f128 (uint_to_fp
35900b57cec5SDimitry Andric                        (and (i32 (vector_extract v16i8:$src, !head(Idx))),
35910b57cec5SDimitry Andric                             255))),
35920b57cec5SDimitry Andric                (f128 (XSCVUDQP
35930b57cec5SDimitry Andric                        (EXTRACT_SUBREG
35940b57cec5SDimitry Andric                          (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>;
35950b57cec5SDimitry Andric    }
35960b57cec5SDimitry Andric
35970b57cec5SDimitry Andric    // Unsiged int in vsx register -> QP
35980b57cec5SDimitry Andric    def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))),
35990b57cec5SDimitry Andric              (f128 (XSCVUDQP
36000b57cec5SDimitry Andric                      (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>;
36010b57cec5SDimitry Andric  } // IsLittleEndian, HasP9Vector
36020b57cec5SDimitry Andric
36030b57cec5SDimitry Andric  // Convert (Un)Signed DWord in memory -> QP
36040b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i64 (load xaddrX4:$src)))),
36050b57cec5SDimitry Andric            (f128 (XSCVSDQP (LXSDX xaddrX4:$src)))>;
36060b57cec5SDimitry Andric  def : Pat<(f128 (sint_to_fp (i64 (load iaddrX4:$src)))),
36070b57cec5SDimitry Andric            (f128 (XSCVSDQP (LXSD iaddrX4:$src)))>;
36080b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i64 (load xaddrX4:$src)))),
36090b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSDX xaddrX4:$src)))>;
36100b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp (i64 (load iaddrX4:$src)))),
36110b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSD iaddrX4:$src)))>;
36120b57cec5SDimitry Andric
36130b57cec5SDimitry Andric  // Convert Unsigned HWord in memory -> QP
36140b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi16)),
36150b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSIHZX xaddr:$src)))>;
36160b57cec5SDimitry Andric
36170b57cec5SDimitry Andric  // Convert Unsigned Byte in memory -> QP
36180b57cec5SDimitry Andric  def : Pat<(f128 (uint_to_fp ScalarLoads.ZELi8)),
36190b57cec5SDimitry Andric            (f128 (XSCVUDQP (LXSIBZX xoaddr:$src)))>;
36200b57cec5SDimitry Andric
36210b57cec5SDimitry Andric  // Truncate & Convert QP -> (Un)Signed (D)Word.
36220b57cec5SDimitry Andric  def : Pat<(i64 (fp_to_sint f128:$src)), (i64 (MFVRD (XSCVQPSDZ $src)))>;
36230b57cec5SDimitry Andric  def : Pat<(i64 (fp_to_uint f128:$src)), (i64 (MFVRD (XSCVQPUDZ $src)))>;
36240b57cec5SDimitry Andric  def : Pat<(i32 (fp_to_sint f128:$src)),
36250b57cec5SDimitry Andric            (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC)))>;
36260b57cec5SDimitry Andric  def : Pat<(i32 (fp_to_uint f128:$src)),
36270b57cec5SDimitry Andric            (i32 (MFVSRWZ (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC)))>;
36280b57cec5SDimitry Andric
36290b57cec5SDimitry Andric  // Instructions for store(fptosi).
36300b57cec5SDimitry Andric  // The 8-byte version is repeated here due to availability of D-Form STXSD.
36310b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36320b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xaddrX4:$dst, 8),
36330b57cec5SDimitry Andric            (STXSDX (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
36340b57cec5SDimitry Andric                    xaddrX4:$dst)>;
36350b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36360b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), iaddrX4:$dst, 8),
36370b57cec5SDimitry Andric            (STXSD (COPY_TO_REGCLASS (XSCVQPSDZ f128:$src), VFRC),
36380b57cec5SDimitry Andric                   iaddrX4:$dst)>;
36390b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36400b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 4),
36410b57cec5SDimitry Andric            (STXSIWX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
36420b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36430b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 2),
36440b57cec5SDimitry Andric            (STXSIHX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
36450b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36460b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f128:$src)), xoaddr:$dst, 1),
36470b57cec5SDimitry Andric            (STXSIBX (COPY_TO_REGCLASS (XSCVQPSWZ $src), VFRC), xoaddr:$dst)>;
36480b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36490b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xaddrX4:$dst, 8),
36500b57cec5SDimitry Andric            (STXSDX (XSCVDPSXDS f64:$src), xaddrX4:$dst)>;
36510b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36520b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), iaddrX4:$dst, 8),
36530b57cec5SDimitry Andric            (STXSD (XSCVDPSXDS f64:$src), iaddrX4:$dst)>;
36540b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36550b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 2),
36560b57cec5SDimitry Andric            (STXSIHX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
36570b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36580b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_sint_in_vsr f64:$src)), xoaddr:$dst, 1),
36590b57cec5SDimitry Andric            (STXSIBX (XSCVDPSXWS f64:$src), xoaddr:$dst)>;
36600b57cec5SDimitry Andric
36610b57cec5SDimitry Andric  // Instructions for store(fptoui).
36620b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36630b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xaddrX4:$dst, 8),
36640b57cec5SDimitry Andric            (STXSDX (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
36650b57cec5SDimitry Andric                    xaddrX4:$dst)>;
36660b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36670b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), iaddrX4:$dst, 8),
36680b57cec5SDimitry Andric            (STXSD (COPY_TO_REGCLASS (XSCVQPUDZ f128:$src), VFRC),
36690b57cec5SDimitry Andric                   iaddrX4:$dst)>;
36700b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36710b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 4),
36720b57cec5SDimitry Andric            (STXSIWX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
36730b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36740b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 2),
36750b57cec5SDimitry Andric            (STXSIHX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
36760b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36770b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f128:$src)), xoaddr:$dst, 1),
36780b57cec5SDimitry Andric            (STXSIBX (COPY_TO_REGCLASS (XSCVQPUWZ $src), VFRC), xoaddr:$dst)>;
36790b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36800b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xaddrX4:$dst, 8),
36810b57cec5SDimitry Andric            (STXSDX (XSCVDPUXDS f64:$src), xaddrX4:$dst)>;
36820b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36830b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), iaddrX4:$dst, 8),
36840b57cec5SDimitry Andric            (STXSD (XSCVDPUXDS f64:$src), iaddrX4:$dst)>;
36850b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36860b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 2),
36870b57cec5SDimitry Andric            (STXSIHX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
36880b57cec5SDimitry Andric  def : Pat<(PPCstore_scal_int_from_vsr
36890b57cec5SDimitry Andric              (f64 (PPCcv_fp_to_uint_in_vsr f64:$src)), xoaddr:$dst, 1),
36900b57cec5SDimitry Andric            (STXSIBX (XSCVDPUXWS f64:$src), xoaddr:$dst)>;
36910b57cec5SDimitry Andric
36920b57cec5SDimitry Andric  // Round & Convert QP -> DP/SP
36930b57cec5SDimitry Andric  def : Pat<(f64 (fpround f128:$src)), (f64 (XSCVQPDP $src))>;
36940b57cec5SDimitry Andric  def : Pat<(f32 (fpround f128:$src)), (f32 (XSRSP (XSCVQPDPO $src)))>;
36950b57cec5SDimitry Andric
36960b57cec5SDimitry Andric  // Convert SP -> QP
36970b57cec5SDimitry Andric  def : Pat<(f128 (fpextend f32:$src)),
36980b57cec5SDimitry Andric            (f128 (XSCVDPQP (COPY_TO_REGCLASS $src, VFRC)))>;
36990b57cec5SDimitry Andric
37000b57cec5SDimitry Andric} // end HasP9Vector, AddedComplexity
37010b57cec5SDimitry Andric
37020b57cec5SDimitry Andriclet AddedComplexity = 400 in {
37030b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsBigEndian] in {
37040b57cec5SDimitry Andric    def : Pat<(f128 (PPCbuild_fp128 i64:$rB, i64:$rA)),
37050b57cec5SDimitry Andric              (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
37060b57cec5SDimitry Andric  }
37070b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasP9Vector, HasDirectMove, IsLittleEndian] in {
37080b57cec5SDimitry Andric    def : Pat<(f128 (PPCbuild_fp128 i64:$rA, i64:$rB)),
37090b57cec5SDimitry Andric              (f128 (COPY_TO_REGCLASS (MTVSRDD $rB, $rA), VRRC))>;
37100b57cec5SDimitry Andric  }
37110b57cec5SDimitry Andric}
37120b57cec5SDimitry Andric
37130b57cec5SDimitry Andriclet Predicates = [HasP9Vector] in {
37140b57cec5SDimitry Andric  let mayStore = 1 in {
37150b57cec5SDimitry Andric    def SPILLTOVSR_STX : PseudoXFormMemOp<(outs),
37160b57cec5SDimitry Andric                                          (ins spilltovsrrc:$XT, memrr:$dst),
37170b57cec5SDimitry Andric                                          "#SPILLTOVSR_STX", []>;
37180b57cec5SDimitry Andric    def SPILLTOVSR_ST : PPCPostRAExpPseudo<(outs), (ins spilltovsrrc:$XT, memrix:$dst),
37190b57cec5SDimitry Andric                              "#SPILLTOVSR_ST", []>;
37200b57cec5SDimitry Andric  }
37210b57cec5SDimitry Andric  let mayLoad = 1 in {
37220b57cec5SDimitry Andric    def SPILLTOVSR_LDX : PseudoXFormMemOp<(outs spilltovsrrc:$XT),
37230b57cec5SDimitry Andric                                          (ins memrr:$src),
37240b57cec5SDimitry Andric                                          "#SPILLTOVSR_LDX", []>;
37250b57cec5SDimitry Andric    def SPILLTOVSR_LD : PPCPostRAExpPseudo<(outs spilltovsrrc:$XT), (ins memrix:$src),
37260b57cec5SDimitry Andric                              "#SPILLTOVSR_LD", []>;
37270b57cec5SDimitry Andric
37280b57cec5SDimitry Andric  }
37290b57cec5SDimitry Andric}
37300b57cec5SDimitry Andric// Integer extend helper dags 32 -> 64
37310b57cec5SDimitry Andricdef AnyExts {
37320b57cec5SDimitry Andric  dag A = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $A, sub_32);
37330b57cec5SDimitry Andric  dag B = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $B, sub_32);
37340b57cec5SDimitry Andric  dag C = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $C, sub_32);
37350b57cec5SDimitry Andric  dag D = (INSERT_SUBREG (i64 (IMPLICIT_DEF)), $D, sub_32);
37360b57cec5SDimitry Andric}
37370b57cec5SDimitry Andric
37380b57cec5SDimitry Andricdef DblToFlt {
37390b57cec5SDimitry Andric  dag A0 = (f32 (fpround (f64 (extractelt v2f64:$A, 0))));
37400b57cec5SDimitry Andric  dag A1 = (f32 (fpround (f64 (extractelt v2f64:$A, 1))));
37410b57cec5SDimitry Andric  dag B0 = (f32 (fpround (f64 (extractelt v2f64:$B, 0))));
37420b57cec5SDimitry Andric  dag B1 = (f32 (fpround (f64 (extractelt v2f64:$B, 1))));
37430b57cec5SDimitry Andric}
37440b57cec5SDimitry Andric
37450b57cec5SDimitry Andricdef ExtDbl {
37460b57cec5SDimitry Andric  dag A0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 0))))));
37470b57cec5SDimitry Andric  dag A1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$A, 1))))));
37480b57cec5SDimitry Andric  dag B0S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 0))))));
37490b57cec5SDimitry Andric  dag B1S = (i32 (PPCmfvsr (f64 (PPCfctiwz (f64 (extractelt v2f64:$B, 1))))));
37500b57cec5SDimitry Andric  dag A0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 0))))));
37510b57cec5SDimitry Andric  dag A1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$A, 1))))));
37520b57cec5SDimitry Andric  dag B0U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 0))))));
37530b57cec5SDimitry Andric  dag B1U = (i32 (PPCmfvsr (f64 (PPCfctiwuz (f64 (extractelt v2f64:$B, 1))))));
37540b57cec5SDimitry Andric}
37550b57cec5SDimitry Andric
37560b57cec5SDimitry Andricdef ByteToWord {
37570b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 0)), i8));
37580b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 4)), i8));
37590b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 8)), i8));
37600b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 12)), i8));
37610b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 3)), i8));
37620b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 7)), i8));
37630b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 11)), i8));
37640b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v16i8:$A, 15)), i8));
37650b57cec5SDimitry Andric}
37660b57cec5SDimitry Andric
37670b57cec5SDimitry Andricdef ByteToDWord {
37680b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
37690b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 0)))), i8));
37700b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
37710b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 8)))), i8));
37720b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
37730b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 7)))), i8));
37740b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
37750b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v16i8:$A, 15)))), i8));
37760b57cec5SDimitry Andric}
37770b57cec5SDimitry Andric
37780b57cec5SDimitry Andricdef HWordToWord {
37790b57cec5SDimitry Andric  dag LE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 0)), i16));
37800b57cec5SDimitry Andric  dag LE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 2)), i16));
37810b57cec5SDimitry Andric  dag LE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 4)), i16));
37820b57cec5SDimitry Andric  dag LE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 6)), i16));
37830b57cec5SDimitry Andric  dag BE_A0 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 1)), i16));
37840b57cec5SDimitry Andric  dag BE_A1 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 3)), i16));
37850b57cec5SDimitry Andric  dag BE_A2 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 5)), i16));
37860b57cec5SDimitry Andric  dag BE_A3 = (i32 (sext_inreg (i32 (vector_extract v8i16:$A, 7)), i16));
37870b57cec5SDimitry Andric}
37880b57cec5SDimitry Andric
37890b57cec5SDimitry Andricdef HWordToDWord {
37900b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext_inreg
37910b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 0)))), i16));
37920b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext_inreg
37930b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 4)))), i16));
37940b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext_inreg
37950b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 3)))), i16));
37960b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext_inreg
37970b57cec5SDimitry Andric              (i64 (anyext (i32 (vector_extract v8i16:$A, 7)))), i16));
37980b57cec5SDimitry Andric}
37990b57cec5SDimitry Andric
38000b57cec5SDimitry Andricdef WordToDWord {
38010b57cec5SDimitry Andric  dag LE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 0))));
38020b57cec5SDimitry Andric  dag LE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 2))));
38030b57cec5SDimitry Andric  dag BE_A0 = (i64 (sext (i32 (vector_extract v4i32:$A, 1))));
38040b57cec5SDimitry Andric  dag BE_A1 = (i64 (sext (i32 (vector_extract v4i32:$A, 3))));
38050b57cec5SDimitry Andric}
38060b57cec5SDimitry Andric
38070b57cec5SDimitry Andricdef FltToIntLoad {
38080b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (extloadf32 xoaddr:$A)))));
38090b57cec5SDimitry Andric}
38100b57cec5SDimitry Andricdef FltToUIntLoad {
38110b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (extloadf32 xoaddr:$A)))));
38120b57cec5SDimitry Andric}
38130b57cec5SDimitry Andricdef FltToLongLoad {
38140b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 xoaddr:$A)))));
38150b57cec5SDimitry Andric}
38160b57cec5SDimitry Andricdef FltToLongLoadP9 {
38170b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (extloadf32 iaddrX4:$A)))));
38180b57cec5SDimitry Andric}
38190b57cec5SDimitry Andricdef FltToULongLoad {
38200b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 xoaddr:$A)))));
38210b57cec5SDimitry Andric}
38220b57cec5SDimitry Andricdef FltToULongLoadP9 {
38230b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (extloadf32 iaddrX4:$A)))));
38240b57cec5SDimitry Andric}
38250b57cec5SDimitry Andricdef FltToLong {
38260b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz (fpextend f32:$A)))));
38270b57cec5SDimitry Andric}
38280b57cec5SDimitry Andricdef FltToULong {
38290b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz (fpextend f32:$A)))));
38300b57cec5SDimitry Andric}
38310b57cec5SDimitry Andricdef DblToInt {
38320b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$A))));
38330b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$B))));
38340b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$C))));
38350b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwz f64:$D))));
38360b57cec5SDimitry Andric}
38370b57cec5SDimitry Andricdef DblToUInt {
38380b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$A))));
38390b57cec5SDimitry Andric  dag B = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$B))));
38400b57cec5SDimitry Andric  dag C = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$C))));
38410b57cec5SDimitry Andric  dag D = (i32 (PPCmfvsr (f64 (PPCfctiwuz f64:$D))));
38420b57cec5SDimitry Andric}
38430b57cec5SDimitry Andricdef DblToLong {
38440b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctidz f64:$A))));
38450b57cec5SDimitry Andric}
38460b57cec5SDimitry Andricdef DblToULong {
38470b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (f64 (PPCfctiduz f64:$A))));
38480b57cec5SDimitry Andric}
38490b57cec5SDimitry Andricdef DblToIntLoad {
38500b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load xoaddr:$A)))));
38510b57cec5SDimitry Andric}
38520b57cec5SDimitry Andricdef DblToIntLoadP9 {
38530b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwz (f64 (load iaddrX4:$A)))));
38540b57cec5SDimitry Andric}
38550b57cec5SDimitry Andricdef DblToUIntLoad {
38560b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load xoaddr:$A)))));
38570b57cec5SDimitry Andric}
38580b57cec5SDimitry Andricdef DblToUIntLoadP9 {
38590b57cec5SDimitry Andric  dag A = (i32 (PPCmfvsr (PPCfctiwuz (f64 (load iaddrX4:$A)))));
38600b57cec5SDimitry Andric}
38610b57cec5SDimitry Andricdef DblToLongLoad {
38620b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctidz (f64 (load xoaddr:$A)))));
38630b57cec5SDimitry Andric}
38640b57cec5SDimitry Andricdef DblToULongLoad {
38650b57cec5SDimitry Andric  dag A = (i64 (PPCmfvsr (PPCfctiduz (f64 (load xoaddr:$A)))));
38660b57cec5SDimitry Andric}
38670b57cec5SDimitry Andric
38680b57cec5SDimitry Andric// FP merge dags (for f32 -> v4f32)
38690b57cec5SDimitry Andricdef MrgFP {
38700b57cec5SDimitry Andric  dag AC = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $A, VSRC),
38710b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $C, VSRC), 0));
38720b57cec5SDimitry Andric  dag BD = (XVCVDPSP (XXPERMDI (COPY_TO_REGCLASS $B, VSRC),
38730b57cec5SDimitry Andric                               (COPY_TO_REGCLASS $D, VSRC), 0));
38740b57cec5SDimitry Andric  dag ABhToFlt = (XVCVDPSP (XXPERMDI $A, $B, 0));
38750b57cec5SDimitry Andric  dag ABlToFlt = (XVCVDPSP (XXPERMDI $A, $B, 3));
38760b57cec5SDimitry Andric  dag BAhToFlt = (XVCVDPSP (XXPERMDI $B, $A, 0));
38770b57cec5SDimitry Andric  dag BAlToFlt = (XVCVDPSP (XXPERMDI $B, $A, 3));
38780b57cec5SDimitry Andric}
38790b57cec5SDimitry Andric
38800b57cec5SDimitry Andric// Word-element merge dags - conversions from f64 to i32 merged into vectors.
38810b57cec5SDimitry Andricdef MrgWords {
38820b57cec5SDimitry Andric  // For big endian, we merge low and hi doublewords (A, B).
38830b57cec5SDimitry Andric  dag A0B0 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 0));
38840b57cec5SDimitry Andric  dag A1B1 = (v2f64 (XXPERMDI v2f64:$A, v2f64:$B, 3));
38850b57cec5SDimitry Andric  dag CVA1B1S = (v4i32 (XVCVDPSXWS A1B1));
38860b57cec5SDimitry Andric  dag CVA0B0S = (v4i32 (XVCVDPSXWS A0B0));
38870b57cec5SDimitry Andric  dag CVA1B1U = (v4i32 (XVCVDPUXWS A1B1));
38880b57cec5SDimitry Andric  dag CVA0B0U = (v4i32 (XVCVDPUXWS A0B0));
38890b57cec5SDimitry Andric
38900b57cec5SDimitry Andric  // For little endian, we merge low and hi doublewords (B, A).
38910b57cec5SDimitry Andric  dag B1A1 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 0));
38920b57cec5SDimitry Andric  dag B0A0 = (v2f64 (XXPERMDI v2f64:$B, v2f64:$A, 3));
38930b57cec5SDimitry Andric  dag CVB1A1S = (v4i32 (XVCVDPSXWS B1A1));
38940b57cec5SDimitry Andric  dag CVB0A0S = (v4i32 (XVCVDPSXWS B0A0));
38950b57cec5SDimitry Andric  dag CVB1A1U = (v4i32 (XVCVDPUXWS B1A1));
38960b57cec5SDimitry Andric  dag CVB0A0U = (v4i32 (XVCVDPUXWS B0A0));
38970b57cec5SDimitry Andric
38980b57cec5SDimitry Andric  // For big endian, we merge hi doublewords of (A, C) and (B, D), convert
38990b57cec5SDimitry Andric  // then merge.
39000b57cec5SDimitry Andric  dag AC = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$A, VSRC),
39010b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$C, VSRC), 0));
39020b57cec5SDimitry Andric  dag BD = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$B, VSRC),
39030b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$D, VSRC), 0));
39040b57cec5SDimitry Andric  dag CVACS = (v4i32 (XVCVDPSXWS AC));
39050b57cec5SDimitry Andric  dag CVBDS = (v4i32 (XVCVDPSXWS BD));
39060b57cec5SDimitry Andric  dag CVACU = (v4i32 (XVCVDPUXWS AC));
39070b57cec5SDimitry Andric  dag CVBDU = (v4i32 (XVCVDPUXWS BD));
39080b57cec5SDimitry Andric
39090b57cec5SDimitry Andric  // For little endian, we merge hi doublewords of (D, B) and (C, A), convert
39100b57cec5SDimitry Andric  // then merge.
39110b57cec5SDimitry Andric  dag DB = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$D, VSRC),
39120b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$B, VSRC), 0));
39130b57cec5SDimitry Andric  dag CA = (v2f64 (XXPERMDI (COPY_TO_REGCLASS f64:$C, VSRC),
39140b57cec5SDimitry Andric                            (COPY_TO_REGCLASS f64:$A, VSRC), 0));
39150b57cec5SDimitry Andric  dag CVDBS = (v4i32 (XVCVDPSXWS DB));
39160b57cec5SDimitry Andric  dag CVCAS = (v4i32 (XVCVDPSXWS CA));
39170b57cec5SDimitry Andric  dag CVDBU = (v4i32 (XVCVDPUXWS DB));
39180b57cec5SDimitry Andric  dag CVCAU = (v4i32 (XVCVDPUXWS CA));
39190b57cec5SDimitry Andric}
39200b57cec5SDimitry Andric
39210b57cec5SDimitry Andric// Patterns for BUILD_VECTOR nodes.
39220b57cec5SDimitry Andriclet AddedComplexity = 400 in {
39230b57cec5SDimitry Andric
39240b57cec5SDimitry Andric  let Predicates = [HasVSX] in {
39250b57cec5SDimitry Andric    // Build vectors of floating point converted to i32.
39260b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.A,
39270b57cec5SDimitry Andric                                   DblToInt.A, DblToInt.A)),
39280b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPSXWS $A), VSRC), 1))>;
39290b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.A,
39300b57cec5SDimitry Andric                                   DblToUInt.A, DblToUInt.A)),
39310b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS (XSCVDPUXWS $A), VSRC), 1))>;
39320b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector DblToLong.A, DblToLong.A)),
39330b57cec5SDimitry Andric              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC),
39340b57cec5SDimitry Andric                               (COPY_TO_REGCLASS (XSCVDPSXDS $A), VSRC), 0))>;
39350b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector DblToULong.A, DblToULong.A)),
39360b57cec5SDimitry Andric              (v2i64 (XXPERMDI (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC),
39370b57cec5SDimitry Andric                               (COPY_TO_REGCLASS (XSCVDPUXDS $A), VSRC), 0))>;
39380b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
39390b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
39400b57cec5SDimitry Andric                                (XSCVDPSXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
39410b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
39420b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
39430b57cec5SDimitry Andric                                (XSCVDPUXWSs (XFLOADf32 xoaddr:$A)), VSRC), 1))>;
39440b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector f32:$A, f32:$A, f32:$A, f32:$A)),
39450b57cec5SDimitry Andric              (v4f32 (XXSPLTW (v4f32 (XSCVDPSPN $A)), 0))>;
39468bcb0991SDimitry Andric    def : Pat<(v2f64 (PPCldsplat xoaddr:$A)),
39478bcb0991SDimitry Andric              (v2f64 (LXVDSX xoaddr:$A))>;
39488bcb0991SDimitry Andric    def : Pat<(v2i64 (PPCldsplat xoaddr:$A)),
39498bcb0991SDimitry Andric              (v2i64 (LXVDSX xoaddr:$A))>;
39500b57cec5SDimitry Andric
39510b57cec5SDimitry Andric    // Build vectors of floating point converted to i64.
39520b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector FltToLong.A, FltToLong.A)),
39530b57cec5SDimitry Andric              (v2i64 (XXPERMDIs
39540b57cec5SDimitry Andric                       (COPY_TO_REGCLASS (XSCVDPSXDSs $A), VSFRC), 0))>;
39550b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector FltToULong.A, FltToULong.A)),
39560b57cec5SDimitry Andric              (v2i64 (XXPERMDIs
39570b57cec5SDimitry Andric                       (COPY_TO_REGCLASS (XSCVDPUXDSs $A), VSFRC), 0))>;
39580b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector DblToLongLoad.A)),
39590b57cec5SDimitry Andric              (v2i64 (XVCVDPSXDS (LXVDSX xoaddr:$A)))>;
39600b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector DblToULongLoad.A)),
39610b57cec5SDimitry Andric              (v2i64 (XVCVDPUXDS (LXVDSX xoaddr:$A)))>;
39620b57cec5SDimitry Andric  }
39630b57cec5SDimitry Andric
39640b57cec5SDimitry Andric  let Predicates = [HasVSX, NoP9Vector] in {
39650b57cec5SDimitry Andric    // Load-and-splat with fp-to-int conversion (using X-Form VSX/FP loads).
39660b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToIntLoad.A)),
39670b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
39680b57cec5SDimitry Andric                                (XSCVDPSXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
39690b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoad.A)),
39700b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
39710b57cec5SDimitry Andric                                (XSCVDPUXWS (XFLOADf64 xoaddr:$A)), VSRC), 1))>;
39720b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToLongLoad.A)),
39730b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
39740b57cec5SDimitry Andric                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
39750b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToULongLoad.A)),
39760b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
39770b57cec5SDimitry Andric                                              (XFLOADf32 xoaddr:$A), VSFRC)), 0))>;
39780b57cec5SDimitry Andric  }
39790b57cec5SDimitry Andric
39800b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasP8Vector] in {
39810b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVU,
39820b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3),
39830b57cec5SDimitry Andric                              (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3)))>;
39840b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVS,
39850b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3),
39860b57cec5SDimitry Andric                              (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3)))>;
39870b57cec5SDimitry Andric    def : Pat<(store (i32 (extractelt v4i32:$A, 1)), xoaddr:$src),
39880b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
39890b57cec5SDimitry Andric    def : Pat<(store (f32 (extractelt v4f32:$A, 1)), xoaddr:$src),
39900b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
39910b57cec5SDimitry Andric
39920b57cec5SDimitry Andric    // Elements in a register on a BE system are in order <0, 1, 2, 3>.
39930b57cec5SDimitry Andric    // The store instructions store the second word from the left.
39940b57cec5SDimitry Andric    // So to align element zero, we need to modulo-left-shift by 3 words.
39950b57cec5SDimitry Andric    // Similar logic applies for elements 2 and 3.
39960b57cec5SDimitry Andric    foreach Idx = [ [0,3], [2,1], [3,2] ] in {
39970b57cec5SDimitry Andric      def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
39980b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
39990b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
40000b57cec5SDimitry Andric      def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
40010b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
40020b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
40030b57cec5SDimitry Andric    }
40040b57cec5SDimitry Andric  }
40050b57cec5SDimitry Andric
40060b57cec5SDimitry Andric  let Predicates = [HasP8Vector, IsBigEndian, NoP9Vector] in {
40070b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
40080b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40090b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
40100b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40110b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
40120b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
40130b57cec5SDimitry Andric                          xoaddr:$src)>;
40140b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
40150b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
40160b57cec5SDimitry Andric                          xoaddr:$src)>;
40170b57cec5SDimitry Andric   }
40180b57cec5SDimitry Andric
40190b57cec5SDimitry Andric  // Big endian, available on all targets with VSX
40200b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasVSX] in {
40210b57cec5SDimitry Andric    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
40220b57cec5SDimitry Andric              (v2f64 (XXPERMDI
40230b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $A, VSRC),
40240b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $B, VSRC), 0))>;
40250b57cec5SDimitry Andric
40260b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector f32:$A, f32:$B, f32:$C, f32:$D)),
40270b57cec5SDimitry Andric              (VMRGEW MrgFP.AC, MrgFP.BD)>;
40280b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
40290b57cec5SDimitry Andric                                   DblToFlt.B0, DblToFlt.B1)),
40300b57cec5SDimitry Andric              (v4f32 (VMRGEW MrgFP.ABhToFlt, MrgFP.ABlToFlt))>;
40310b57cec5SDimitry Andric
40320b57cec5SDimitry Andric    // Convert 4 doubles to a vector of ints.
40330b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
40340b57cec5SDimitry Andric                                   DblToInt.C, DblToInt.D)),
40350b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVACS, MrgWords.CVBDS))>;
40360b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
40370b57cec5SDimitry Andric                                   DblToUInt.C, DblToUInt.D)),
40380b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVACU, MrgWords.CVBDU))>;
40390b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
40400b57cec5SDimitry Andric                                   ExtDbl.B0S, ExtDbl.B1S)),
40410b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVA0B0S, MrgWords.CVA1B1S))>;
40420b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
40430b57cec5SDimitry Andric                                   ExtDbl.B0U, ExtDbl.B1U)),
40440b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVA0B0U, MrgWords.CVA1B1U))>;
40450b57cec5SDimitry Andric  }
40460b57cec5SDimitry Andric
40470b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasP8Vector] in {
40480b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVU,
40490b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVUXDSP $S2), (XVCVUXDSP $S2), 3),
40500b57cec5SDimitry Andric                              (XXSLDWI (XVCVUXDSP $S1), (XVCVUXDSP $S1), 3)))>;
40510b57cec5SDimitry Andric    def : Pat<DWToSPExtractConv.BVS,
40520b57cec5SDimitry Andric              (v4f32 (VPKUDUM (XXSLDWI (XVCVSXDSP $S2), (XVCVSXDSP $S2), 3),
40530b57cec5SDimitry Andric                              (XXSLDWI (XVCVSXDSP $S1), (XVCVSXDSP $S1), 3)))>;
40540b57cec5SDimitry Andric    def : Pat<(store (i32 (extractelt v4i32:$A, 2)), xoaddr:$src),
40550b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40560b57cec5SDimitry Andric    def : Pat<(store (f32 (extractelt v4f32:$A, 2)), xoaddr:$src),
40570b57cec5SDimitry Andric              (STIWX (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40580b57cec5SDimitry Andric
40590b57cec5SDimitry Andric    // Elements in a register on a LE system are in order <3, 2, 1, 0>.
40600b57cec5SDimitry Andric    // The store instructions store the second word from the left.
40610b57cec5SDimitry Andric    // So to align element 3, we need to modulo-left-shift by 3 words.
40620b57cec5SDimitry Andric    // Similar logic applies for elements 0 and 1.
40630b57cec5SDimitry Andric    foreach Idx = [ [0,2], [1,1], [3,3] ] in {
40640b57cec5SDimitry Andric      def : Pat<(store (i32 (extractelt v4i32:$A, !head(Idx))), xoaddr:$src),
40650b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
40660b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
40670b57cec5SDimitry Andric      def : Pat<(store (f32 (extractelt v4f32:$A, !head(Idx))), xoaddr:$src),
40680b57cec5SDimitry Andric                (STIWX (EXTRACT_SUBREG (XXSLDWI $A, $A, !head(!tail(Idx))),
40690b57cec5SDimitry Andric                                       sub_64), xoaddr:$src)>;
40700b57cec5SDimitry Andric    }
40710b57cec5SDimitry Andric  }
40720b57cec5SDimitry Andric
40730b57cec5SDimitry Andric  let Predicates = [HasP8Vector, IsLittleEndian, NoP9Vector] in {
40740b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 0)), xoaddr:$src),
40750b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
40760b57cec5SDimitry Andric                          xoaddr:$src)>;
40770b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 0)), xoaddr:$src),
40780b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG (XXPERMDI $A, $A, 2), sub_64),
40790b57cec5SDimitry Andric                          xoaddr:$src)>;
40800b57cec5SDimitry Andric    def : Pat<(store (i64 (extractelt v2i64:$A, 1)), xoaddr:$src),
40810b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40820b57cec5SDimitry Andric    def : Pat<(store (f64 (extractelt v2f64:$A, 1)), xoaddr:$src),
40830b57cec5SDimitry Andric              (XFSTOREf64 (EXTRACT_SUBREG $A, sub_64), xoaddr:$src)>;
40840b57cec5SDimitry Andric   }
40850b57cec5SDimitry Andric
40860b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasVSX] in {
40870b57cec5SDimitry Andric  // Little endian, available on all targets with VSX
40880b57cec5SDimitry Andric    def : Pat<(v2f64 (build_vector f64:$A, f64:$B)),
40890b57cec5SDimitry Andric              (v2f64 (XXPERMDI
40900b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $B, VSRC),
40910b57cec5SDimitry Andric                        (COPY_TO_REGCLASS $A, VSRC), 0))>;
40920b57cec5SDimitry Andric
40930b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector f32:$D, f32:$C, f32:$B, f32:$A)),
40940b57cec5SDimitry Andric              (VMRGEW MrgFP.AC, MrgFP.BD)>;
40950b57cec5SDimitry Andric    def : Pat<(v4f32 (build_vector DblToFlt.A0, DblToFlt.A1,
40960b57cec5SDimitry Andric                                   DblToFlt.B0, DblToFlt.B1)),
40970b57cec5SDimitry Andric              (v4f32 (VMRGEW MrgFP.BAhToFlt, MrgFP.BAlToFlt))>;
40980b57cec5SDimitry Andric
40990b57cec5SDimitry Andric    // Convert 4 doubles to a vector of ints.
41000b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToInt.A, DblToInt.B,
41010b57cec5SDimitry Andric                                   DblToInt.C, DblToInt.D)),
41020b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVDBS, MrgWords.CVCAS))>;
41030b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector DblToUInt.A, DblToUInt.B,
41040b57cec5SDimitry Andric                                   DblToUInt.C, DblToUInt.D)),
41050b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVDBU, MrgWords.CVCAU))>;
41060b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0S, ExtDbl.A1S,
41070b57cec5SDimitry Andric                                   ExtDbl.B0S, ExtDbl.B1S)),
41080b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVB1A1S, MrgWords.CVB0A0S))>;
41090b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ExtDbl.A0U, ExtDbl.A1U,
41100b57cec5SDimitry Andric                                   ExtDbl.B0U, ExtDbl.B1U)),
41110b57cec5SDimitry Andric              (v4i32 (VMRGEW MrgWords.CVB1A1U, MrgWords.CVB0A0U))>;
41120b57cec5SDimitry Andric  }
41130b57cec5SDimitry Andric
41140b57cec5SDimitry Andric  let Predicates = [HasDirectMove] in {
41150b57cec5SDimitry Andric    // Endianness-neutral constant splat on P8 and newer targets. The reason
41160b57cec5SDimitry Andric    // for this pattern is that on targets with direct moves, we don't expand
41170b57cec5SDimitry Andric    // BUILD_VECTOR nodes for v4i32.
41180b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector immSExt5NonZero:$A, immSExt5NonZero:$A,
41190b57cec5SDimitry Andric                                   immSExt5NonZero:$A, immSExt5NonZero:$A)),
41200b57cec5SDimitry Andric              (v4i32 (VSPLTISW imm:$A))>;
41210b57cec5SDimitry Andric  }
41220b57cec5SDimitry Andric
41230b57cec5SDimitry Andric  let Predicates = [IsBigEndian, HasDirectMove, NoP9Vector] in {
41240b57cec5SDimitry Andric    // Big endian integer vectors using direct moves.
41250b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
41260b57cec5SDimitry Andric              (v2i64 (XXPERMDI
41270b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC),
41280b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC), 0))>;
41290b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
41300b57cec5SDimitry Andric              (XXPERMDI
41310b57cec5SDimitry Andric                (COPY_TO_REGCLASS
41320b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.B, AnyExts.A, 32, 0)), VSRC),
41330b57cec5SDimitry Andric                (COPY_TO_REGCLASS
41340b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.D, AnyExts.C, 32, 0)), VSRC), 0)>;
41350b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
41360b57cec5SDimitry Andric              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
41370b57cec5SDimitry Andric  }
41380b57cec5SDimitry Andric
41390b57cec5SDimitry Andric  let Predicates = [IsLittleEndian, HasDirectMove, NoP9Vector] in {
41400b57cec5SDimitry Andric    // Little endian integer vectors using direct moves.
41410b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$A, i64:$B)),
41420b57cec5SDimitry Andric              (v2i64 (XXPERMDI
41430b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $B), VSRC),
41440b57cec5SDimitry Andric                        (COPY_TO_REGCLASS (MTVSRD $A), VSRC), 0))>;
41450b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
41460b57cec5SDimitry Andric              (XXPERMDI
41470b57cec5SDimitry Andric                (COPY_TO_REGCLASS
41480b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.C, AnyExts.D, 32, 0)), VSRC),
41490b57cec5SDimitry Andric                (COPY_TO_REGCLASS
41500b57cec5SDimitry Andric                  (MTVSRD (RLDIMI AnyExts.A, AnyExts.B, 32, 0)), VSRC), 0)>;
41510b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
41520b57cec5SDimitry Andric              (XXSPLTW (COPY_TO_REGCLASS (MTVSRWZ $A), VSRC), 1)>;
41530b57cec5SDimitry Andric  }
41540b57cec5SDimitry Andric
41558bcb0991SDimitry Andric  let Predicates = [HasP8Vector] in {
41568bcb0991SDimitry Andric    def : Pat<(v1i128 (bitconvert (v16i8 immAllOnesV))),
41578bcb0991SDimitry Andric              (v1i128 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
41588bcb0991SDimitry Andric    def : Pat<(v2i64 (bitconvert (v16i8 immAllOnesV))),
41598bcb0991SDimitry Andric              (v2i64 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
41608bcb0991SDimitry Andric    def : Pat<(v8i16 (bitconvert (v16i8 immAllOnesV))),
41618bcb0991SDimitry Andric              (v8i16 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
41628bcb0991SDimitry Andric    def : Pat<(v16i8 (bitconvert (v16i8 immAllOnesV))),
41638bcb0991SDimitry Andric              (v16i8 (COPY_TO_REGCLASS(XXLEQVOnes), VSRC))>;
41648bcb0991SDimitry Andric  }
41658bcb0991SDimitry Andric
41660b57cec5SDimitry Andric  let Predicates = [HasP9Vector] in {
41670b57cec5SDimitry Andric    // Endianness-neutral patterns for const splats with ISA 3.0 instructions.
41680b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector i32:$A)),
41690b57cec5SDimitry Andric              (v4i32 (MTVSRWS $A))>;
41700b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$A, i32:$A, i32:$A)),
41710b57cec5SDimitry Andric              (v4i32 (MTVSRWS $A))>;
41728bcb0991SDimitry Andric    def : Pat<(v16i8 (build_vector immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41738bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41748bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41758bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41768bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41778bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41788bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A,
41798bcb0991SDimitry Andric                                   immNonAllOneAnyExt8:$A, immNonAllOneAnyExt8:$A)),
41800b57cec5SDimitry Andric              (v16i8 (COPY_TO_REGCLASS (XXSPLTIB imm:$A), VSRC))>;
41810b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToIntLoad.A)),
41820b57cec5SDimitry Andric              (v4i32 (XVCVSPSXWS (LXVWSX xoaddr:$A)))>;
41830b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector FltToUIntLoad.A)),
41840b57cec5SDimitry Andric              (v4i32 (XVCVSPUXWS (LXVWSX xoaddr:$A)))>;
41850b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToIntLoadP9.A)),
41860b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
41870b57cec5SDimitry Andric                                (XSCVDPSXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>;
41880b57cec5SDimitry Andric    def : Pat<(v4i32 (scalar_to_vector DblToUIntLoadP9.A)),
41890b57cec5SDimitry Andric              (v4i32 (XXSPLTW (COPY_TO_REGCLASS
41900b57cec5SDimitry Andric                                (XSCVDPUXWS (DFLOADf64 iaddrX4:$A)), VSRC), 1))>;
41910b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToLongLoadP9.A)),
41920b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPSXDS (COPY_TO_REGCLASS
41930b57cec5SDimitry Andric                                              (DFLOADf32 iaddrX4:$A),
41940b57cec5SDimitry Andric                                              VSFRC)), 0))>;
41950b57cec5SDimitry Andric    def : Pat<(v2i64 (scalar_to_vector FltToULongLoadP9.A)),
41960b57cec5SDimitry Andric              (v2i64 (XXPERMDIs (XSCVDPUXDS (COPY_TO_REGCLASS
41970b57cec5SDimitry Andric                                              (DFLOADf32 iaddrX4:$A),
41980b57cec5SDimitry Andric                                              VSFRC)), 0))>;
41998bcb0991SDimitry Andric    def : Pat<(v4f32 (PPCldsplat xoaddr:$A)),
42008bcb0991SDimitry Andric              (v4f32 (LXVWSX xoaddr:$A))>;
42018bcb0991SDimitry Andric    def : Pat<(v4i32 (PPCldsplat xoaddr:$A)),
42028bcb0991SDimitry Andric              (v4i32 (LXVWSX xoaddr:$A))>;
42030b57cec5SDimitry Andric  }
42040b57cec5SDimitry Andric
42050b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasDirectMove, IsBigEndian] in {
42060b57cec5SDimitry Andric    def : Pat<(i64 (extractelt v2i64:$A, 1)),
42070b57cec5SDimitry Andric              (i64 (MFVSRLD $A))>;
42080b57cec5SDimitry Andric    // Better way to build integer vectors if we have MTVSRDD. Big endian.
42090b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$rB, i64:$rA)),
42100b57cec5SDimitry Andric              (v2i64 (MTVSRDD $rB, $rA))>;
42110b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
42120b57cec5SDimitry Andric              (MTVSRDD
42130b57cec5SDimitry Andric                (RLDIMI AnyExts.B, AnyExts.A, 32, 0),
42140b57cec5SDimitry Andric                (RLDIMI AnyExts.D, AnyExts.C, 32, 0))>;
42150b57cec5SDimitry Andric  }
42160b57cec5SDimitry Andric
42170b57cec5SDimitry Andric  let Predicates = [IsISA3_0, HasDirectMove, IsLittleEndian] in {
42180b57cec5SDimitry Andric    def : Pat<(i64 (extractelt v2i64:$A, 0)),
42190b57cec5SDimitry Andric              (i64 (MFVSRLD $A))>;
42200b57cec5SDimitry Andric    // Better way to build integer vectors if we have MTVSRDD. Little endian.
42210b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector i64:$rA, i64:$rB)),
42220b57cec5SDimitry Andric              (v2i64 (MTVSRDD $rB, $rA))>;
42230b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector i32:$A, i32:$B, i32:$C, i32:$D)),
42240b57cec5SDimitry Andric              (MTVSRDD
42250b57cec5SDimitry Andric                (RLDIMI AnyExts.C, AnyExts.D, 32, 0),
42260b57cec5SDimitry Andric                (RLDIMI AnyExts.A, AnyExts.B, 32, 0))>;
42270b57cec5SDimitry Andric  }
42280b57cec5SDimitry Andric  // P9 Altivec instructions that can be used to build vectors.
42290b57cec5SDimitry Andric  // Adding them to PPCInstrVSX.td rather than PPCAltivecVSX.td to compete
42300b57cec5SDimitry Andric  // with complexities of existing build vector patterns in this file.
42310b57cec5SDimitry Andric  let Predicates = [HasP9Altivec, IsLittleEndian] in {
42320b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector WordToDWord.LE_A0, WordToDWord.LE_A1)),
42330b57cec5SDimitry Andric              (v2i64 (VEXTSW2D $A))>;
42340b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector HWordToDWord.LE_A0, HWordToDWord.LE_A1)),
42350b57cec5SDimitry Andric              (v2i64 (VEXTSH2D $A))>;
42360b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector HWordToWord.LE_A0, HWordToWord.LE_A1,
42370b57cec5SDimitry Andric                      HWordToWord.LE_A2, HWordToWord.LE_A3)),
42380b57cec5SDimitry Andric              (v4i32 (VEXTSH2W $A))>;
42390b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ByteToWord.LE_A0, ByteToWord.LE_A1,
42400b57cec5SDimitry Andric                      ByteToWord.LE_A2, ByteToWord.LE_A3)),
42410b57cec5SDimitry Andric              (v4i32 (VEXTSB2W $A))>;
42420b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector ByteToDWord.LE_A0, ByteToDWord.LE_A1)),
42430b57cec5SDimitry Andric              (v2i64 (VEXTSB2D $A))>;
42440b57cec5SDimitry Andric  }
42450b57cec5SDimitry Andric
42460b57cec5SDimitry Andric  let Predicates = [HasP9Altivec, IsBigEndian] in {
42470b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector WordToDWord.BE_A0, WordToDWord.BE_A1)),
42480b57cec5SDimitry Andric              (v2i64 (VEXTSW2D $A))>;
42490b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector HWordToDWord.BE_A0, HWordToDWord.BE_A1)),
42500b57cec5SDimitry Andric              (v2i64 (VEXTSH2D $A))>;
42510b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector HWordToWord.BE_A0, HWordToWord.BE_A1,
42520b57cec5SDimitry Andric                      HWordToWord.BE_A2, HWordToWord.BE_A3)),
42530b57cec5SDimitry Andric              (v4i32 (VEXTSH2W $A))>;
42540b57cec5SDimitry Andric    def : Pat<(v4i32 (build_vector ByteToWord.BE_A0, ByteToWord.BE_A1,
42550b57cec5SDimitry Andric                      ByteToWord.BE_A2, ByteToWord.BE_A3)),
42560b57cec5SDimitry Andric              (v4i32 (VEXTSB2W $A))>;
42570b57cec5SDimitry Andric    def : Pat<(v2i64 (build_vector ByteToDWord.BE_A0, ByteToDWord.BE_A1)),
42580b57cec5SDimitry Andric              (v2i64 (VEXTSB2D $A))>;
42590b57cec5SDimitry Andric  }
42600b57cec5SDimitry Andric
42610b57cec5SDimitry Andric  let Predicates = [HasP9Altivec] in {
42620b57cec5SDimitry Andric    def: Pat<(v2i64 (PPCSExtVElems v16i8:$A)),
42630b57cec5SDimitry Andric              (v2i64 (VEXTSB2D $A))>;
42640b57cec5SDimitry Andric    def: Pat<(v2i64 (PPCSExtVElems v8i16:$A)),
42650b57cec5SDimitry Andric              (v2i64 (VEXTSH2D $A))>;
42660b57cec5SDimitry Andric    def: Pat<(v2i64 (PPCSExtVElems v4i32:$A)),
42670b57cec5SDimitry Andric              (v2i64 (VEXTSW2D $A))>;
42680b57cec5SDimitry Andric    def: Pat<(v4i32 (PPCSExtVElems v16i8:$A)),
42690b57cec5SDimitry Andric              (v4i32 (VEXTSB2W $A))>;
42700b57cec5SDimitry Andric    def: Pat<(v4i32 (PPCSExtVElems v8i16:$A)),
42710b57cec5SDimitry Andric              (v4i32 (VEXTSH2W $A))>;
42720b57cec5SDimitry Andric  }
42730b57cec5SDimitry Andric}
42740b57cec5SDimitry Andric
42750b57cec5SDimitry Andric// Put this P9Altivec related definition here since it's possible to be
42760b57cec5SDimitry Andric// selected to VSX instruction xvnegsp, avoid possible undef.
42770b57cec5SDimitry Andriclet Predicates = [HasP9Altivec] in {
42780b57cec5SDimitry Andric
42790b57cec5SDimitry Andric  def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 0))),
42800b57cec5SDimitry Andric            (v4i32 (VABSDUW $A, $B))>;
42810b57cec5SDimitry Andric
42820b57cec5SDimitry Andric  def : Pat<(v8i16 (PPCvabsd v8i16:$A, v8i16:$B, (i32 0))),
42830b57cec5SDimitry Andric            (v8i16 (VABSDUH $A, $B))>;
42840b57cec5SDimitry Andric
42850b57cec5SDimitry Andric  def : Pat<(v16i8 (PPCvabsd v16i8:$A, v16i8:$B, (i32 0))),
42860b57cec5SDimitry Andric            (v16i8 (VABSDUB $A, $B))>;
42870b57cec5SDimitry Andric
42880b57cec5SDimitry Andric  // As PPCVABSD description, the last operand indicates whether do the
42890b57cec5SDimitry Andric  // sign bit flip.
42900b57cec5SDimitry Andric  def : Pat<(v4i32 (PPCvabsd v4i32:$A, v4i32:$B, (i32 1))),
42910b57cec5SDimitry Andric            (v4i32 (VABSDUW (XVNEGSP $A), (XVNEGSP $B)))>;
42920b57cec5SDimitry Andric}
4293