//
// 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.
//
//===----------------------------------------------------------------------===//
//
/// 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.
+/// MVT::getIntVectorWithNumElements with the number of elements
+/// that ThisOp has.
class SDTCisIntVectorOfSameSize<int ThisOp, int OtherOp>
: SDTypeConstraint<ThisOp> {
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<int ThisOp, int OtherOp>
+ : SDTypeConstraint<ThisOp> {
+ int OtherOpNum = OtherOp;
+}
+
//===----------------------------------------------------------------------===//
// Selection DAG Type Profile definitions.
//
SDTCisPtrTy<0>
]>;
-def SDTRet : SDTypeProfile<0, 0, []>; // ret
+def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap
def SDTLoad : SDTypeProfile<1, 1, [ // load
SDTCisPtrTy<1>
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<list<SDTypeConstraint> constraints> :
SDTypeProfile<0, 1, constraints>;
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'.
+def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
//===----------------------------------------------------------------------===//
// Selection DAG Node definitions.
def srcvalue;
def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">;
-def fpimm : SDNode<"ISD::TargetConstantFP",
- SDTFPLeaf, [], "ConstantFPSDNode">;
+def timm : SDNode<"ISD::TargetConstant", SDTIntLeaf , [], "ConstantSDNode">;
+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 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>;
def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>;
def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>;
def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>;
+def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>;
+def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>;
+def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>;
+def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>;
+def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>;
def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>;
def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>;
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 ret : SDNode<"ISD::RET" , SDTRet, [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]>;
+
+def atomic_cmp_swap_8 : SDNode<"ISD::ATOMIC_CMP_SWAP_8" , STDAtomic3,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_8 : SDNode<"ISD::ATOMIC_LOAD_ADD_8" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_8 : SDNode<"ISD::ATOMIC_SWAP_8", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_8 : SDNode<"ISD::ATOMIC_LOAD_SUB_8" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_8 : SDNode<"ISD::ATOMIC_LOAD_AND_8" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_8 : SDNode<"ISD::ATOMIC_LOAD_OR_8" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_8 : SDNode<"ISD::ATOMIC_LOAD_XOR_8" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_8: SDNode<"ISD::ATOMIC_LOAD_NAND_8", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_8 : SDNode<"ISD::ATOMIC_LOAD_MIN_8", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_8 : SDNode<"ISD::ATOMIC_LOAD_MAX_8", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_8 : SDNode<"ISD::ATOMIC_LOAD_UMIN_8", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_8 : SDNode<"ISD::ATOMIC_LOAD_UMAX_8", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_cmp_swap_16 : SDNode<"ISD::ATOMIC_CMP_SWAP_16" , STDAtomic3,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_16 : SDNode<"ISD::ATOMIC_LOAD_ADD_16" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_16 : SDNode<"ISD::ATOMIC_SWAP_16", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_16 : SDNode<"ISD::ATOMIC_LOAD_SUB_16" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_16 : SDNode<"ISD::ATOMIC_LOAD_AND_16" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_16 : SDNode<"ISD::ATOMIC_LOAD_OR_16" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_16 : SDNode<"ISD::ATOMIC_LOAD_XOR_16" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_16: SDNode<"ISD::ATOMIC_LOAD_NAND_16", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_16 : SDNode<"ISD::ATOMIC_LOAD_MIN_16", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_16 : SDNode<"ISD::ATOMIC_LOAD_MAX_16", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_16 : SDNode<"ISD::ATOMIC_LOAD_UMIN_16", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_16 : SDNode<"ISD::ATOMIC_LOAD_UMAX_16", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_cmp_swap_32 : SDNode<"ISD::ATOMIC_CMP_SWAP_32" , STDAtomic3,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_32 : SDNode<"ISD::ATOMIC_LOAD_ADD_32" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_32 : SDNode<"ISD::ATOMIC_SWAP_32", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_32 : SDNode<"ISD::ATOMIC_LOAD_SUB_32" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_32 : SDNode<"ISD::ATOMIC_LOAD_AND_32" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_32 : SDNode<"ISD::ATOMIC_LOAD_OR_32" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_32 : SDNode<"ISD::ATOMIC_LOAD_XOR_32" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_32: SDNode<"ISD::ATOMIC_LOAD_NAND_32", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_32 : SDNode<"ISD::ATOMIC_LOAD_MIN_32", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_32 : SDNode<"ISD::ATOMIC_LOAD_MAX_32", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_32 : SDNode<"ISD::ATOMIC_LOAD_UMIN_32", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_32 : SDNode<"ISD::ATOMIC_LOAD_UMAX_32", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_cmp_swap_64 : SDNode<"ISD::ATOMIC_CMP_SWAP_64" , STDAtomic3,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_add_64 : SDNode<"ISD::ATOMIC_LOAD_ADD_64" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_swap_64 : SDNode<"ISD::ATOMIC_SWAP_64", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_sub_64 : SDNode<"ISD::ATOMIC_LOAD_SUB_64" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_and_64 : SDNode<"ISD::ATOMIC_LOAD_AND_64" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_or_64 : SDNode<"ISD::ATOMIC_LOAD_OR_64" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_xor_64 : SDNode<"ISD::ATOMIC_LOAD_XOR_64" , STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_nand_64: SDNode<"ISD::ATOMIC_LOAD_NAND_64", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_min_64 : SDNode<"ISD::ATOMIC_LOAD_MIN_64", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_max_64 : SDNode<"ISD::ATOMIC_LOAD_MAX_64", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umin_64 : SDNode<"ISD::ATOMIC_LOAD_UMIN_64", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
+def atomic_load_umax_64 : SDNode<"ISD::ATOMIC_LOAD_UMAX_64", STDAtomic2,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
// Do not use ld, st directly. Use load, extload, sextload, zextload, store,
// and truncst (see below).
-def ld : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>;
-def st : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>;
-def ist : SDNode<"ISD::STORE" , SDTIStore, [SDNPHasChain]>;
+def ld : SDNode<"ISD::LOAD" , SDTLoad,
+ [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
+def st : SDNode<"ISD::STORE" , SDTStore,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
+def ist : SDNode<"ISD::STORE" , SDTIStore,
+ [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>;
-def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, 0, []>, []>;
+def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>;
def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>,
[]>;
def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT",
// Leaf fragments.
-def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>;
-def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>;
+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), [{
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<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::NON_EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED;
- return false;
+def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
+ return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
+def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
}]>;
// extending load fragments.
-def extloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i1;
- return false;
-}]>;
-def extloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i8;
- return false;
-}]>;
-def extloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i16;
- return false;
-}]>;
-def extloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i32;
- return false;
-}]>;
-def extloadf32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::f32;
- return false;
-}]>;
-def extloadf64 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::EXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::f64;
- return false;
-}]>;
-
-def sextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::SEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i1;
- return false;
-}]>;
-def sextloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::SEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i8;
- return false;
-}]>;
-def sextloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::SEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i16;
- return false;
-}]>;
-def sextloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::SEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i32;
- return false;
-}]>;
-
-def zextloadi1 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::ZEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i1;
- return false;
-}]>;
-def zextloadi8 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::ZEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i8;
- return false;
-}]>;
-def zextloadi16 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::ZEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i16;
- return false;
-}]>;
-def zextloadi32 : PatFrag<(ops node:$ptr), (ld node:$ptr), [{
- if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N))
- return LD->getExtensionType() == ISD::ZEXTLOAD &&
- LD->getAddressingMode() == ISD::UNINDEXED &&
- LD->getLoadedVT() == MVT::i32;
- return false;
+def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+}]>;
+def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+}]>;
+def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+}]>;
+
+def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f32;
+}]>;
+def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::f64;
+}]>;
+
+def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
+}]>;
+
+def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i1;
+}]>;
+def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;
+}]>;
+def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;
+}]>;
+def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr), [{
+ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32;
}]>;
// store fragments.
+def unindexedstore : PatFrag<(ops node:$val, node:$ptr),
+ (st node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+}]>;
def store : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return !ST->isTruncatingStore() &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+ (unindexedstore node:$val, node:$ptr), [{
+ return !cast<StoreSDNode>(N)->isTruncatingStore();
}]>;
// truncstore fragments.
-def truncstorei1 : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return ST->isTruncatingStore() && ST->getStoredVT() == MVT::i1 &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+def truncstore : PatFrag<(ops node:$val, node:$ptr),
+ (unindexedstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->isTruncatingStore();
}]>;
def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return ST->isTruncatingStore() && ST->getStoredVT() == MVT::i8 &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
}]>;
def truncstorei16 : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return ST->isTruncatingStore() && ST->getStoredVT() == MVT::i16 &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
}]>;
def truncstorei32 : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return ST->isTruncatingStore() && ST->getStoredVT() == MVT::i32 &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
}]>;
def truncstoref32 : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return ST->isTruncatingStore() && ST->getStoredVT() == MVT::f32 &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
}]>;
def truncstoref64 : PatFrag<(ops node:$val, node:$ptr),
- (st node:$val, node:$ptr), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
- return ST->isTruncatingStore() && ST->getStoredVT() == MVT::f64 &&
- ST->getAddressingMode() == ISD::UNINDEXED;
- return false;
+ (truncstore node:$val, node:$ptr), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f64;
}]>;
// indexed store fragments.
+def istore : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (ist node:$val, node:$base, node:$offset), [{
+ return !cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+
def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) &&
- !ST->isTruncatingStore();
- }
- return false;
+ (istore node:$val, node:$base, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
}]>;
+def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (ist node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->isTruncatingStore();
+}]>;
+def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (itruncstore node:$val, node:$base, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::PRE_INC || AM == ISD::PRE_DEC;
+}]>;
def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i1;
- }
- return false;
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
}]>;
def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i8;
- }
- return false;
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
}]>;
def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i16;
- }
- return false;
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
}]>;
def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i32;
- }
- return false;
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
}]>;
def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::PRE_INC || AM == ISD::PRE_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::f32;
- }
- return false;
+ (pre_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
}]>;
def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset),
- (ist node:$val, node:$ptr, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return !ST->isTruncatingStore() &&
- (AM == ISD::POST_INC || AM == ISD::POST_DEC);
- }
- return false;
+ (istore node:$val, node:$ptr, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::POST_INC || AM == ISD::POST_DEC;
}]>;
+def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset),
+ (itruncstore node:$val, node:$base, node:$offset), [{
+ ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode();
+ return AM == ISD::POST_INC || AM == ISD::POST_DEC;
+}]>;
def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::POST_INC || AM == ISD::POST_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i1;
- }
- return false;
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i1;
}]>;
def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::POST_INC || AM == ISD::POST_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i8;
- }
- return false;
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
}]>;
def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::POST_INC || AM == ISD::POST_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i16;
- }
- return false;
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
}]>;
def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::POST_INC || AM == ISD::POST_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::i32;
- }
- return false;
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i32;
}]>;
def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset),
- (ist node:$val, node:$base, node:$offset), [{
- if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
- ISD::MemIndexedMode AM = ST->getAddressingMode();
- return (AM == ISD::POST_INC || AM == ISD::POST_DEC) &&
- ST->isTruncatingStore() && ST->getStoredVT() == MVT::f32;
- }
- return false;
+ (post_truncst node:$val, node:$base, node:$offset), [{
+ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::f32;
}]>;
// setcc convenience fragments.
//===----------------------------------------------------------------------===//
// 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;
// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
//
class ComplexPattern<ValueType ty, int numops, string fn,
- list<SDNode> roots = [], list<SDNodeProperty> props = []> {
+ list<SDNode> roots = [], list<SDNodeProperty> props = [],
+ list<CPAttribute> attrs = []> {
ValueType Ty = ty;
int NumOperands = numops;
string SelectFunc = fn;
list<SDNode> RootNodes = roots;
list<SDNodeProperty> Properties = props;
+ list<CPAttribute> Attributes = attrs;
}
//===----------------------------------------------------------------------===//
def SDT_dwarf_loc : SDTypeProfile<0, 3,
[SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
def dwarf_loc : SDNode<"ISD::DEBUG_LOC", SDT_dwarf_loc,[SDNPHasChain]>;
-
-
-