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