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