}
// SDTCisVT - The specified operand has exactly this VT.
-class SDTCisVT <int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
+class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
ValueType VT = vt;
}
+class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>;
+
// SDTCisInt - The specified operand is has integer type.
class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>;
// SDTCisFP - The specified operand is has floating point type.
-class SDTCisFP <int OpNum> : SDTypeConstraint<OpNum>;
+class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>;
// SDTCisSameAs - The two specified operands have identical types.
class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
// Builtin profiles.
def SDTImm : SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'.
-def SDTVT : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'
+def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'.
+def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'.
def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc.
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>
]>;
+def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl
+ SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2>
+]>;
def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc.
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0>
]>;
def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // ctlz
SDTCisSameAs<0, 1>, SDTCisInt<0>
]>;
+def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>
+]>;
+def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc
+ SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>
+]>;
def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc
SDTCisSameAs<0, 1>, SDTCisFP<0>
]>;
def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fextend
SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>
]>;
+def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp
+ SDTCisFP<0>, SDTCisInt<1>
+]>;
+def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int
+ SDTCisInt<0>, SDTCisFP<1>
+]>;
def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg
SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>,
SDTCisVTSmallerThanOp<2, 1>
]>;
+def SDTSetCC : SDTypeProfile<1, 3, [ // setcc
+ SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>
+]>;
+
+def SDTSelect : SDTypeProfile<1, 3, [ // select
+ SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>
+]>;
+
+def SDTBr : SDTypeProfile<0, 1, [ // br
+ SDTCisVT<0, OtherVT>
+]>;
+
+def SDTBrCond : SDTypeProfile<0, 2, [ // brcond
+ SDTCisInt<0>, SDTCisVT<1, OtherVT>
+]>;
+
+def SDTRet : SDTypeProfile<0, 0, [ // ret
+]>;
+
+def SDTWritePort : SDTypeProfile<0, 2, [ // writeport
+ SDTCisInt<0>, SDTCisInt<1>
+]>;
+
+def SDTLoad : SDTypeProfile<1, 1, [ // load
+ SDTCisPtrTy<1>
+]>;
+
+def SDTStore : SDTypeProfile<0, 2, [ // store
+ SDTCisPtrTy<1>
+]>;
+
//===----------------------------------------------------------------------===//
// Selection DAG Node Properties.
//
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
//===----------------------------------------------------------------------===//
// Selection DAG Node definitions.
def node;
def imm : SDNode<"ISD::Constant" , SDTImm , [], "ConstantSDNode">;
-def vt : SDNode<"ISD::VALUETYPE" , SDTVT , [], "VTSDNode">;
+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", SDTImm, [],
+ "GlobalAddressSDNode">;
+def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTImm, [],
+ "GlobalAddressSDNode">;
+def tconstpool : SDNode<"ISD::TargetConstantPool", SDTImm, [],
+ "ConstantPoolSDNode">;
def add : SDNode<"ISD::ADD" , SDTIntBinOp ,
[SDNPCommutative, SDNPAssociative]>;
def sub : SDNode<"ISD::SUB" , SDTIntBinOp>;
def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>;
def srem : SDNode<"ISD::SREM" , SDTIntBinOp>;
def urem : SDNode<"ISD::UREM" , SDTIntBinOp>;
-def srl : SDNode<"ISD::SRL" , SDTIntBinOp>;
-def sra : SDNode<"ISD::SRA" , SDTIntBinOp>;
-def shl : SDNode<"ISD::SHL" , SDTIntBinOp>;
+def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>;
+def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>;
+def shl : SDNode<"ISD::SHL" , 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 sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
+def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
+def cttz : SDNode<"ISD::CTTZ" , SDTIntUnaryOp>;
+def ctpop : SDNode<"ISD::CTPOP" , SDTIntUnaryOp>;
+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 fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>;
def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>;
def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>;
def fround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>;
def fextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>;
-def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
-def ctlz : SDNode<"ISD::CTLZ" , SDTIntUnaryOp>;
+def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>;
+def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>;
+def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>;
+def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>;
+
+def setcc : SDNode<"ISD::SETCC" , SDTSetCC>;
+def select : SDNode<"ISD::SELECT" , SDTSelect>;
+
+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 load : SDNode<"ISD::LOAD" , SDTLoad, [SDNPHasChain]>;
+def store : SDNode<"ISD::STORE" , SDTStore, [SDNPHasChain]>;
+
+//===----------------------------------------------------------------------===//
+// Selection DAG Condition Codes
+
+class CondCode; // ISD::CondCode enums
+def SETOEQ : CondCode; def SETOGT : CondCode;
+def SETOGE : CondCode; def SETOLT : CondCode; def SETOLE : CondCode;
+def SETONE : CondCode; def SETO : CondCode; def SETUO : CondCode;
+def SETUEQ : CondCode; def SETUGT : CondCode; def SETUGE : CondCode;
+def SETULT : CondCode; def SETULE : CondCode; def SETUNE : CondCode;
+
+def SETEQ : CondCode; def SETGT : CondCode; def SETGE : CondCode;
+def SETLT : CondCode; def SETLE : CondCode; def SETNE : CondCode;
+
//===----------------------------------------------------------------------===//
// Selection DAG Node Transformation Functions.
// Leaf fragments.
def immAllOnes : PatLeaf<(imm), [{ return N->isAllOnesValue(); }]>;
-def immZero : PatLeaf<(imm), [{ return N->isNullValue(); }]>;
def vtInt : PatLeaf<(vt), [{ return MVT::isInteger(N->getVT()); }]>;
def vtFP : PatLeaf<(vt), [{ return MVT::isFloatingPoint(N->getVT()); }]>;
// Other helper fragments.
def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>;
-def ineg : PatFrag<(ops node:$in), (sub immZero, node:$in)>;
+def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>;
+
+
+// setcc convenience fragments.
+def setoeq : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOEQ)>;
+def setogt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOGT)>;
+def setoge : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOGE)>;
+def setolt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOLT)>;
+def setole : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETOLE)>;
+def setone : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETONE)>;
+def seto : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETO)>;
+def setuo : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUO)>;
+def setueq : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUEQ)>;
+def setugt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUGT)>;
+def setuge : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUGE)>;
+def setult : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETULT)>;
+def setule : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETULE)>;
+def setune : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETUNE)>;
+def seteq : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETEQ)>;
+def setgt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETGT)>;
+def setge : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETGE)>;
+def setlt : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETLT)>;
+def setle : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETLE)>;
+def setne : PatFrag<(ops node:$lhs, node:$rhs),
+ (setcc node:$lhs, node:$rhs, SETNE)>;
//===----------------------------------------------------------------------===//
// Selection DAG Pattern Support.
// not needing a full list.
class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
+//===----------------------------------------------------------------------===//
+// Complex pattern definitions.
+//
+// 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<ValueType ty, int numops, string fn, list<SDNode> roots = []> {
+ ValueType Ty = ty;
+ int NumOperands = numops;
+ string SelectFunc = fn;
+ list<SDNode> RootNodes = roots;
+}