X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetSelectionDAG.td;h=38a604653f5d56e4c603476494bf32e6cfdb02a6;hb=4a307ecce68f90e0eebf1ded52b947816cdc2304;hp=83f559300d925877e67fd094cf250cf45d17fa20;hpb=d2c339cca70db6dcb4496c1db5ec53c732ea4b60;p=oota-llvm.git diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td index 83f559300d9..38a604653f5 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -51,6 +51,22 @@ class SDTCisOpSmallerThanOp : SDTypeConstraint{ int BigOperandNum = BigOp; } +/// SDTCisIntVectorOfSameSize - This indicates that ThisOp and OtherOp are +/// vector types, and that ThisOp is the result of +/// MVT::getIntVectorWithNumElements with the number of elements +/// that ThisOp has. +class SDTCisIntVectorOfSameSize + : SDTypeConstraint { + int OtherOpNum = OtherOp; +} + +/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same +/// type as the element type of OtherOp, which is a vector type. +class SDTCisEltOfVec + : SDTypeConstraint { + int OtherOpNum = OtherOp; +} + //===----------------------------------------------------------------------===// // Selection DAG Type Profile definitions. // @@ -70,9 +86,12 @@ class SDTypeProfile]>; // for 'imm'. +def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. +def SDTUnaryOp : SDTypeProfile<1, 1, []>; // bitconvert + def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> ]>; @@ -82,6 +101,12 @@ def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> ]>; +def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. + SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> +]>; +def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. + SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> +]>; def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz SDTCisSameAs<0, 1>, SDTCisInt<0> ]>; @@ -128,16 +153,15 @@ def SDTBr : SDTypeProfile<0, 1, [ // br SDTCisVT<0, OtherVT> ]>; -def SDTBrCond : SDTypeProfile<0, 2, [ // brcond +def SDTBrcond : SDTypeProfile<0, 2, [ // brcond SDTCisInt<0>, SDTCisVT<1, OtherVT> ]>; -def SDTRet : SDTypeProfile<0, 0, [ // ret +def SDTBrind : SDTypeProfile<0, 1, [ // brind + SDTCisPtrTy<0> ]>; -def SDTWritePort : SDTypeProfile<0, 2, [ // writeport - SDTCisInt<0>, SDTCisInt<1> -]>; +def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap def SDTLoad : SDTypeProfile<1, 1, [ // load SDTCisPtrTy<1> @@ -147,6 +171,40 @@ def SDTStore : SDTypeProfile<0, 2, [ // store SDTCisPtrTy<1> ]>; +def SDTIStore : SDTypeProfile<1, 3, [ // indexed store + SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3> +]>; + +def SDTVecShuffle : SDTypeProfile<1, 3, [ + SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisIntVectorOfSameSize<3, 0> +]>; +def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract + SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2> +]>; +def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert + SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3> +]>; + +def STDPrefetch : SDTypeProfile<0, 3, [ // prefetch + SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisInt<1> +]>; + +def STDMemBarrier : SDTypeProfile<0, 5, [ // memory barier + SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, + SDTCisInt<0> +]>; +def STDAtomic3 : SDTypeProfile<1, 3, [ + SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> +]>; +def STDAtomic2 : SDTypeProfile<1, 2, [ + SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> +]>; + +class SDCallSeqStart constraints> : + SDTypeProfile<0, 1, constraints>; +class SDCallSeqEnd constraints> : + SDTypeProfile<0, 2, constraints>; + //===----------------------------------------------------------------------===// // Selection DAG Node Properties. // @@ -156,6 +214,12 @@ class SDNodeProperty; def SDNPCommutative : SDNodeProperty; // X op Y == Y op X def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) def SDNPHasChain : SDNodeProperty; // R/W chain operand and result +def SDNPOutFlag : SDNodeProperty; // Write a flag result +def SDNPInFlag : SDNodeProperty; // Read a flag operand +def SDNPOptInFlag : SDNodeProperty; // Optionally read a flag operand +def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. +def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. +def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. //===----------------------------------------------------------------------===// // Selection DAG Node definitions. @@ -169,19 +233,42 @@ class SDNode; +def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; -def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], +def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], "GlobalAddressSDNode">; -def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], - "GlobalAddressSDNode">; -def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], - "ConstantPoolSDNode">; +def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [], + "GlobalAddressSDNode">; +def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [], + "ConstantPoolSDNode">; +def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], + "ConstantPoolSDNode">; +def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [], + "JumpTableSDNode">; +def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [], + "JumpTableSDNode">; +def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [], + "FrameIndexSDNode">; +def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [], + "FrameIndexSDNode">; +def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], + "ExternalSymbolSDNode">; +def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], + "ExternalSymbolSDNode">; + def add : SDNode<"ISD::ADD" , SDTIntBinOp , [SDNPCommutative, SDNPAssociative]>; def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; @@ -196,14 +283,25 @@ def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>; def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>; def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>; +def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>; +def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>; def and : SDNode<"ISD::AND" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; def or : SDNode<"ISD::OR" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; def xor : SDNode<"ISD::XOR" , SDTIntBinOp, [SDNPCommutative, SDNPAssociative]>; +def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, + [SDNPCommutative, SDNPOutFlag]>; +def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, + [SDNPCommutative, SDNPOutFlag, SDNPInFlag]>; +def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, + [SDNPOutFlag]>; +def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, + [SDNPOutFlag, SDNPInFlag]>; def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; +def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>; def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>; def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>; @@ -211,6 +309,10 @@ def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; +def bitconvert : SDNode<"ISD::BIT_CONVERT", SDTUnaryOp>; +def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; +def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; + def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; @@ -220,9 +322,12 @@ def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; +def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; +def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; +def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; @@ -232,15 +337,81 @@ def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; def select : SDNode<"ISD::SELECT" , SDTSelect>; def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; +def vsetcc : SDNode<"ISD::VSETCC" , SDTSetCC>; +def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; +def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; -def brcond : SDNode<"ISD::BRCOND" , SDTBrCond, [SDNPHasChain]>; -def ret : SDNode<"ISD::RET" , SDTRet, [SDNPHasChain]>; - -def writeport : SDNode<"ISD::WRITEPORT" , SDTWritePort, [SDNPHasChain]>; +def ret : SDNode<"ISD::RET" , SDTNone, [SDNPHasChain]>; +def trap : SDNode<"ISD::TRAP" , SDTNone, + [SDNPHasChain, SDNPSideEffect]>; + +def prefetch : SDNode<"ISD::PREFETCH" , STDPrefetch, + [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; + +def membarrier : SDNode<"ISD::MEMBARRIER" , STDMemBarrier, + [SDNPHasChain, SDNPSideEffect]>; + +// Do not use atomic_* directly, use atomic_*_size (see below) +def atomic_lcs : SDNode<"ISD::ATOMIC_LCS" , STDAtomic3, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_las : SDNode<"ISD::ATOMIC_LAS" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_lss : SDNode<"ISD::ATOMIC_LSS" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_or : SDNode<"ISD::ATOMIC_LOAD_OR" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; +def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", STDAtomic2, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; + +// Do not use ld, st directly. Use load, extload, sextload, zextload, store, +// and truncst (see below). +def ld : SDNode<"ISD::LOAD" , SDTLoad, + [SDNPHasChain, SDNPMayLoad]>; +def st : SDNode<"ISD::STORE" , SDTStore, + [SDNPHasChain, SDNPMayStore]>; +def ist : SDNode<"ISD::STORE" , SDTIStore, + [SDNPHasChain, SDNPMayStore]>; + +def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; +def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, 0, []>, []>; +def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>, + []>; +def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", + SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; +def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", + SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; + +def extract_subreg : SDNode<"ISD::EXTRACT_SUBREG", + SDTypeProfile<1, 2, []>>; +def insert_subreg : SDNode<"ISD::INSERT_SUBREG", + SDTypeProfile<1, 3, []>>; + +// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use +// these internally. Don't reference these directly. +def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", + SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>, + [SDNPHasChain]>; +def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN", + SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, + [SDNPHasChain]>; +def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", + SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>; -def load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>; -def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>; //===----------------------------------------------------------------------===// // Selection DAG Condition Codes @@ -298,16 +469,377 @@ class PatLeaf // Leaf fragments. +def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; +def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; + def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>; +def immAllOnesV: PatLeaf<(build_vector), [{ + return ISD::isBuildVectorAllOnes(N); +}]>; +def immAllOnesV_bc: PatLeaf<(bitconvert), [{ + return ISD::isBuildVectorAllOnes(N); +}]>; +def immAllZerosV: PatLeaf<(build_vector), [{ + return ISD::isBuildVectorAllZeros(N); +}]>; +def immAllZerosV_bc: PatLeaf<(bitconvert), [{ + return ISD::isBuildVectorAllZeros(N); +}]>; -def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>; -def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>; -// Other helper fragments. +// Other helper fragments. def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; +def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; +def vnot_conv : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV_bc)>; def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; +// load fragments. +def load : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::NON_EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; + +// extending load fragments. +def extloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i1; + return false; +}]>; +def extloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i8; + return false; +}]>; +def extloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i16; + return false; +}]>; +def extloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i32; + return false; +}]>; +def extloadf32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::f32; + return false; +}]>; +def extloadf64 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::EXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::f64; + return false; +}]>; + +def sextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::SEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i1; + return false; +}]>; +def sextloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::SEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i8; + return false; +}]>; +def sextloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::SEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i16; + return false; +}]>; +def sextloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::SEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i32; + return false; +}]>; + +def zextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::ZEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i1; + return false; +}]>; +def zextloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::ZEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i8; + return false; +}]>; +def zextloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::ZEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i16; + return false; +}]>; +def zextloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{ + if (LoadSDNode *LD = dyn_cast(N)) + return LD->getExtensionType() == ISD::ZEXTLOAD && + LD->getAddressingMode() == ISD::UNINDEXED && + LD->getMemoryVT() == MVT::i32; + return false; +}]>; + +// store fragments. +def store : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + if (StoreSDNode *ST = dyn_cast(N)) + return !ST->isTruncatingStore() && + ST->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; + +// truncstore fragments. +def truncstorei8 : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + if (StoreSDNode *ST = dyn_cast(N)) + return ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i8 && + ST->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; +def truncstorei16 : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + if (StoreSDNode *ST = dyn_cast(N)) + return ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i16 && + ST->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; +def truncstorei32 : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + if (StoreSDNode *ST = dyn_cast(N)) + return ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i32 && + ST->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; +def truncstoref32 : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + if (StoreSDNode *ST = dyn_cast(N)) + return ST->isTruncatingStore() && ST->getMemoryVT() == MVT::f32 && + ST->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; +def truncstoref64 : PatFrag<(ops node:$val, node:$ptr), + (st node:$val, node:$ptr), [{ + if (StoreSDNode *ST = dyn_cast(N)) + return ST->isTruncatingStore() && ST->getMemoryVT() == MVT::f64 && + ST->getAddressingMode() == ISD::UNINDEXED; + return false; +}]>; + +// indexed store fragments. +def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) && + !ST->isTruncatingStore(); + } + return false; +}]>; + +def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i1; + } + return false; +}]>; +def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i8; + } + return false; +}]>; +def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i16; + } + return false; +}]>; +def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i32; + } + return false; +}]>; +def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::f32; + } + return false; +}]>; + +def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset), + (ist node:$val, node:$ptr, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return !ST->isTruncatingStore() && + (AM == ISD::POST_INC || AM == ISD::POST_DEC); + } + return false; +}]>; + +def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::POST_INC || AM == ISD::POST_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i1; + } + return false; +}]>; +def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::POST_INC || AM == ISD::POST_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i8; + } + return false; +}]>; +def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::POST_INC || AM == ISD::POST_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i16; + } + return false; +}]>; +def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::POST_INC || AM == ISD::POST_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::i32; + } + return false; +}]>; +def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), + (ist node:$val, node:$base, node:$offset), [{ + if (StoreSDNode *ST = dyn_cast(N)) { + ISD::MemIndexedMode AM = ST->getAddressingMode(); + return (AM == ISD::POST_INC || AM == ISD::POST_DEC) && + ST->isTruncatingStore() && ST->getMemoryVT() == MVT::f32; + } + return false; +}]>; + +//Atomic patterns +def atomic_lcs_8 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp), + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i8; + return false; +}]>; +def atomic_lcs_16 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp), + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i16; + return false; +}]>; +def atomic_lcs_32 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp), + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i32; + return false; +}]>; +def atomic_lcs_64 : PatFrag<(ops node:$ptr, node:$cmp, node:$swp), + (atomic_lcs node:$ptr, node:$cmp, node:$swp), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i64; + return false; +}]>; + +def atomic_las_8 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_las node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i8; + return false; +}]>; +def atomic_las_16 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_las node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i16; + return false; +}]>; +def atomic_las_32 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_las node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i32; + return false; +}]>; +def atomic_las_64 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_las node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i64; + return false; +}]>; + +def atomic_swap_8 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_swap node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i8; + return false; +}]>; +def atomic_swap_16 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_swap node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i16; + return false; +}]>; +def atomic_swap_32 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_swap node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i32; + return false; +}]>; +def atomic_swap_64 : PatFrag<(ops node:$ptr, node:$inc), + (atomic_swap node:$ptr, node:$inc), [{ + if (AtomicSDNode* V = dyn_cast(N)) + return V->getVT() == MVT::i64; + return false; +}]>; + + // setcc convenience fragments. def setoeq : PatFrag<(ops node:$lhs, node:$rhs), @@ -363,8 +895,10 @@ def setne : PatFrag<(ops node:$lhs, node:$rhs), // class Pattern resultInstrs> { - dag PatternToMatch = patternToMatch; - list ResultInstrs = resultInstrs; + dag PatternToMatch = patternToMatch; + list ResultInstrs = resultInstrs; + list Predicates = []; // See class Instruction in Target.td. + int AddedComplexity = 0; // See class Instruction in Target.td. } // Pat - A simple (but common) form of a pattern, which produces a simple result @@ -374,15 +908,32 @@ class Pat : Pattern; //===----------------------------------------------------------------------===// // Complex pattern definitions. // + +class CPAttribute; +// Pass the parent Operand as root to CP function rather +// than the root of the sub-DAG +def CPAttrParentAsRoot : CPAttribute; + // Complex patterns, e.g. X86 addressing mode, requires pattern matching code // in C++. NumOperands is the number of operands returned by the select function; // SelectFunc is the name of the function used to pattern match the max. pattern; // RootNodes are the list of possible root nodes of the sub-dags to match. // e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>; // -class ComplexPattern roots = []> { +class ComplexPattern roots = [], list props = [], + list attrs = []> { ValueType Ty = ty; int NumOperands = numops; string SelectFunc = fn; list RootNodes = roots; + list Properties = props; + list Attributes = attrs; } + +//===----------------------------------------------------------------------===// +// Dwarf support. +// +def SDT_dwarf_loc : SDTypeProfile<0, 3, + [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>; +def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;