#include "llvm/Support/Allocator.h"
#include "llvm/Support/RecyclingAllocator.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/CodeGen/DebugLoc.h"
+#include "llvm/Support/DebugLoc.h"
#include <cassert>
#include <climits>
// remainder result.
SDIVREM, UDIVREM,
+ // CARRY_FALSE - This node is used when folding other nodes,
+ // like ADDC/SUBC, which indicate the carry result is always false.
+ CARRY_FALSE,
+
// Carry-setting nodes for multiple precision addition and subtraction.
// These nodes take two operands of the same value type, and produce two
// results. The first result is the normal add or sub result, the second
- // result is the carry flag result (type i1 or whatever it got expanded to
- // for the target, value 0 or 1).
+ // result is the carry flag result.
ADDC, SUBC,
// Carry-using nodes for multiple precision addition and subtraction. These
// produce two results; the normal result of the add or sub, and the output
// carry flag. These nodes both read and write a carry flag to allow them
// to them to be chained together for add and sub of arbitrarily large
- // values. The carry flag (input and output) has type i1 or whatever it
- // got expanded to for the target, and has value 0 or 1.
+ // values.
ADDE, SUBE,
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
INSERT_VECTOR_ELT,
/// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
- /// identified by the (potentially variable) element number IDX.
+ /// identified by the (potentially variable) element number IDX. If the
+ /// return type is an integer type larger than the element type of the
+ /// vector, the result is extended to the width of the return type.
EXTRACT_VECTOR_ELT,
/// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
// them with (op #2) as a CondCodeSDNode.
SETCC,
- // Vector SetCC operator - This evaluates to a vector of integer elements
- // with the high bit in each element set to true if the comparison is true
- // and false if the comparison is false. All other bits in each element
- // are undefined. The operands to this are the left and right operands
- // to compare (ops #0, and #1) and the condition code to compare them with
- // (op #2) as a CondCodeSDNode.
+ // RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of
+ // integer elements with all bits of the result elements set to true if the
+ // comparison is true or all cleared if the comparison is false. The
+ // operands to this are the left and right operands to compare (LHS/RHS) and
+ // the condition code to compare them with (COND) as a CondCodeSDNode.
VSETCC,
// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
class GlobalAddressSDNode : public SDNode {
GlobalValue *TheGlobal;
int64_t Offset;
+ unsigned char TargetFlags;
friend class SelectionDAG;
- GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT VT,
- int64_t o = 0);
+ GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA, MVT VT,
+ int64_t o, unsigned char TargetFlags);
public:
GlobalValue *getGlobal() const { return TheGlobal; }
int64_t getOffset() const { return Offset; }
+ unsigned char getTargetFlags() const { return TargetFlags; }
// Return the address space this GlobalAddress belongs to.
unsigned getAddressSpace() const;
class JumpTableSDNode : public SDNode {
int JTI;
+ unsigned char TargetFlags;
friend class SelectionDAG;
- JumpTableSDNode(int jti, MVT VT, bool isTarg)
+ JumpTableSDNode(int jti, MVT VT, bool isTarg, unsigned char TF)
: SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
- DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti) {
+ DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) {
}
public:
int getIndex() const { return JTI; }
+ unsigned char getTargetFlags() const { return TargetFlags; }
static bool classof(const JumpTableSDNode *) { return true; }
static bool classof(const SDNode *N) {
} Val;
int Offset; // It's a MachineConstantPoolValue if top bit is set.
unsigned Alignment; // Minimum alignment requirement of CP (not log2 value).
+ unsigned char TargetFlags;
friend class SelectionDAG;
- ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o=0)
- : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
- DebugLoc::getUnknownLoc(),
- getSDVTList(VT)), Offset(o), Alignment(0) {
- assert((int)Offset >= 0 && "Offset is too large");
- Val.ConstVal = c;
- }
- ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align)
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align,
+ unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
- getSDVTList(VT)), Offset(o), Alignment(Align) {
+ getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
assert((int)Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
}
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
- MVT VT, int o=0)
- : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
- DebugLoc::getUnknownLoc(),
- getSDVTList(VT)), Offset(o), Alignment(0) {
- assert((int)Offset >= 0 && "Offset is too large");
- Val.MachineCPVal = v;
- Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
- }
- ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
- MVT VT, int o, unsigned Align)
+ MVT VT, int o, unsigned Align, unsigned char TF)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
DebugLoc::getUnknownLoc(),
- getSDVTList(VT)), Offset(o), Alignment(Align) {
+ getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
assert((int)Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
}
public:
+
bool isMachineConstantPoolEntry() const {
return (int)Offset < 0;
// Return the alignment of this constant pool object, which is either 0 (for
// default alignment) or the desired value.
unsigned getAlignment() const { return Alignment; }
+ unsigned char getTargetFlags() const { return TargetFlags; }
const Type *getType() const;
class ExternalSymbolSDNode : public SDNode {
const char *Symbol;
+ unsigned char TargetFlags;
+
friend class SelectionDAG;
- ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT VT)
+ ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, MVT VT)
: SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
DebugLoc::getUnknownLoc(),
- getSDVTList(VT)), Symbol(Sym) {
+ getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) {
}
public:
const char *getSymbol() const { return Symbol; }
+ unsigned char getTargetFlags() const { return TargetFlags; }
static bool classof(const ExternalSymbolSDNode *) { return true; }
static bool classof(const SDNode *N) {
unsigned CallingConv;
bool IsVarArg;
bool IsTailCall;
+ unsigned NumFixedArgs;
// We might eventually want a full-blown Attributes for the result; that
// will expand the size of the representation. At the moment we only
// need Inreg.
friend class SelectionDAG;
CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall,
bool isinreg, SDVTList VTs, const SDValue *Operands,
- unsigned numOperands)
+ unsigned numOperands, unsigned numFixedArgs)
: SDNode(ISD::CALL, dl, VTs, Operands, numOperands),
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
- Inreg(isinreg) {}
+ NumFixedArgs(numFixedArgs), Inreg(isinreg) {}
public:
unsigned getCallingConv() const { return CallingConv; }
unsigned isVarArg() const { return IsVarArg; }
SDValue getCallee() const { return getOperand(1); }
unsigned getNumArgs() const { return (getNumOperands() - 2) / 2; }
+ unsigned getNumFixedArgs() const {
+ if (isVarArg())
+ return NumFixedArgs;
+ else
+ return getNumArgs();
+ }
SDValue getArg(unsigned i) const { return getOperand(2+2*i); }
SDValue getArgFlagsVal(unsigned i) const {
return getOperand(3+2*i);