#ifndef LLVM_TARGET_TARGETINSTRDESC_H
#define LLVM_TARGET_TARGETINSTRDESC_H
+#include "llvm/Support/DataTypes.h"
+
namespace llvm {
class TargetRegisterClass;
-
+class TargetRegisterInfo;
+
//===----------------------------------------------------------------------===//
// Machine Operand Flags and Description
//===----------------------------------------------------------------------===//
namespace TOI {
- // Operand constraints: only "tied_to" for now.
+ // Operand constraints
enum OperandConstraint {
- TIED_TO = 0 // Must be allocated the same register as.
+ TIED_TO = 0, // Must be allocated the same register as.
+ EARLY_CLOBBER // Operand is an early clobber register operand
};
/// OperandFlags - These are flags set on operands, but should be considered
class TargetOperandInfo {
public:
/// RegClass - This specifies the register class enumeration of the operand
- /// if the operand is a register. If not, this contains 0.
- unsigned short RegClass;
+ /// if the operand is a register. If isLookupPtrRegClass is set, then this is
+ /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
+ /// get a dynamic register class.
+ ///
+ /// NOTE: This member should be considered to be private, all access should go
+ /// through "getRegClass(TRI)" below.
+ short RegClass;
+
+ /// Flags - These are flags from the TOI::OperandFlags enum.
unsigned short Flags;
+
/// Lower 16 bits are used to specify which constraints are set. The higher 16
/// bits are used to specify the value of constraints (4 bits each).
- unsigned int Constraints;
+ unsigned Constraints;
/// Currently no other information.
+ /// getRegClass - Get the register class for the operand, handling resolution
+ /// of "symbolic" pointer register classes etc. If this is not a register
+ /// operand, this returns null.
+ const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const;
+
+
/// isLookupPtrRegClass - Set if this operand is a pointer value and it
/// requires a callback to look up its register class.
bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);}
Terminator,
Branch,
IndirectBranch,
- Predicable,
- NotDuplicable,
+ Compare,
+ MoveImm,
+ Bitcast,
DelaySlot,
FoldableAsLoad,
MayLoad,
MayStore,
+ Predicable,
+ NotDuplicable,
UnmodeledSideEffects,
Commutable,
ConvertibleTo3Addr,
- UsesCustomDAGSchedInserter,
+ UsesCustomInserter,
Rematerializable,
- CheapAsAMove
+ CheapAsAMove,
+ ExtraSrcRegAllocReq,
+ ExtraDefRegAllocReq
};
}
unsigned short SchedClass; // enum identifying instr sched class
const char * Name; // Name of the instruction record in td file
unsigned Flags; // Flags identifying machine instr class
- unsigned TSFlags; // Target Specific Flag values
+ uint64_t TSFlags; // Target Specific Flag values
const unsigned *ImplicitUses; // Registers implicitly read by this instr
const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
const TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered"
return -1;
}
- /// findTiedToSrcOperand - Returns the operand that is tied to the specified
- /// dest operand. Returns -1 if there isn't one.
- int findTiedToSrcOperand(unsigned OpNum) const;
-
+ /// getRegClass - Returns the register class constraint for OpNum, or NULL.
+ const TargetRegisterClass *getRegClass(unsigned OpNum,
+ const TargetRegisterInfo *TRI) const {
+ return OpNum < NumOperands ? OpInfo[OpNum].getRegClass(TRI) : 0;
+ }
+
/// getOpcode - Return the opcode number for this descriptor.
unsigned getOpcode() const {
return Opcode;
return ImplicitUses;
}
+ /// getNumImplicitUses - Return the number of implicit uses this instruction
+ /// has.
+ unsigned getNumImplicitUses() const {
+ if (ImplicitUses == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitUses[i]; ++i) /*empty*/;
+ return i;
+ }
+
+
/// getImplicitDefs - Return a list of registers that are potentially
/// written by any instance of this machine instruction. For example, on X86,
/// many instructions implicitly set the flags register. In this case, they
const unsigned *getImplicitDefs() const {
return ImplicitDefs;
}
+
+ /// getNumImplicitDefs - Return the number of implicit defs this instruction
+ /// has.
+ unsigned getNumImplicitDefs() const {
+ if (ImplicitDefs == 0) return 0;
+ unsigned i = 0;
+ for (; ImplicitDefs[i]; ++i) /*empty*/;
+ return i;
+ }
+
+ /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// uses the specified physical register.
+ bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpUses = ImplicitUses)
+ for (; *ImpUses; ++ImpUses)
+ if (*ImpUses == Reg) return true;
+ return false;
+ }
+
+ /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// defines the specified physical register.
+ bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpDefs = ImplicitDefs)
+ for (; *ImpDefs; ++ImpDefs)
+ if (*ImpDefs == Reg) return true;
+ return false;
+ }
/// getRegClassBarriers - Return a list of register classes that are
/// completely clobbered by this machine instruction. For example, on X86
bool isIndirectBranch() const {
return Flags & (1 << TID::IndirectBranch);
}
-
+
/// isConditionalBranch - Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
/// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
return Flags & (1 << TID::Predicable);
}
+ /// isCompare - Return true if this instruction is a comparison.
+ bool isCompare() const {
+ return Flags & (1 << TID::Compare);
+ }
+
+ /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// (including conditional moves) instruction.
+ bool isMoveImmediate() const {
+ return Flags & (1 << TID::MoveImm);
+ }
+
+ /// isBitcast - Return true if this instruction is a bitcast instruction.
+ ///
+ bool isBitcast() const {
+ return Flags & (1 << TID::Bitcast);
+ }
+
/// isNotDuplicable - Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors.
return Flags & (1 << TID::ConvertibleTo3Addr);
}
- /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires
+ /// usesCustomInsertionHook - Return true if this instruction requires
/// custom insertion support when the DAG scheduler is inserting it into a
/// machine basic block. If this is true for the instruction, it basically
/// means that it is a pseudo instruction used at SelectionDAG time that is
///
/// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
/// is used to insert this into the MachineBasicBlock.
- bool usesCustomDAGSchedInsertionHook() const {
- return Flags & (1 << TID::UsesCustomDAGSchedInserter);
+ bool usesCustomInsertionHook() const {
+ return Flags & (1 << TID::UsesCustomInserter);
}
/// isRematerializable - Returns true if this instruction is a candidate for
bool isAsCheapAsAMove() const {
return Flags & (1 << TID::CheapAsAMove);
}
+
+ /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::STRD's two source registers must be an
+ /// even / odd pair, ARM::STM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for sources of instructions with this flag.
+ bool hasExtraSrcRegAllocReq() const {
+ return Flags & (1 << TID::ExtraSrcRegAllocReq);
+ }
+
+ /// hasExtraDefRegAllocReq - Returns true if this instruction def operands
+ /// have special register allocation requirements that are not captured by the
+ /// operand register classes. e.g. ARM::LDRD's two def registers must be an
+ /// even / odd pair, ARM::LDM registers have to be in ascending order.
+ /// Post-register allocation passes should not attempt to change allocations
+ /// for definitions of instructions with this flag.
+ bool hasExtraDefRegAllocReq() const {
+ return Flags & (1 << TID::ExtraDefRegAllocReq);
+ }
};
} // end namespace llvm