#ifndef LLVM_CODEGEN_MACHINEINSTR_H
#define LLVM_CODEGEN_MACHINEINSTR_H
-#include "llvm/Target/MRegisterInfo.h"
#include "Support/Annotation.h"
#include "Support/iterator"
+#include <vector>
namespace llvm {
class TargetMachine;
class GlobalValue;
-typedef int MachineOpCode;
+template <typename T> class ilist_traits;
+template <typename T> class ilist;
-//===----------------------------------------------------------------------===//
-/// Special flags on instructions that modify the opcode.
-/// These flags are unused for now, but having them enforces that some
-/// changes will be needed if they are used.
-///
-enum MachineOpCodeFlags {
- AnnulFlag, /// 1 if annul bit is set on a branch
- PredTakenFlag, /// 1 if branch should be predicted taken
- PredNotTakenFlag /// 1 if branch should be predicted not taken
-};
+typedef short MachineOpCode;
//===----------------------------------------------------------------------===//
/// MOTy - MachineOperandType - This namespace contains an enum that describes
int regNum; // register number for an explicit register
// will be set for a value after reg allocation
private:
- MachineOperand()
- : immedVal(0),
- flags(0),
- opType(MO_VirtualRegister),
- regNum(-1) {}
-
- MachineOperand(int64_t ImmVal, MachineOperandType OpTy)
+ MachineOperand(int64_t ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
: immedVal(ImmVal),
flags(0),
opType(OpTy),
return *this;
}
- // Accessor methods. Caller is responsible for checking the
- // operand type before invoking the corresponding accessor.
- //
+ /// getType - Returns the MachineOperandType for this operand.
+ ///
MachineOperandType getType() const { return opType; }
+ /// getUseType - Returns the MachineOperandUseType of this operand.
+ ///
+ MOTy::UseType getUseType() const {
+ return isUse() ^ isDef() ? MOTy::UseAndDef :
+ (isUse() ? MOTy::Use : MOTy::Def);
+ }
+
/// isPCRelative - This returns the value of the PCRELATIVE flag, which
/// indicates whether this operand should be emitted as a PC relative value
/// instead of a global address. This is used for operands of the forms:
///
bool isPCRelative() const { return (flags & PCRELATIVE) != 0; }
-
- // This is to finally stop caring whether we have a virtual or machine
- // register -- an easier interface is to simply call both virtual and machine
- // registers essentially the same, yet be able to distinguish when
- // necessary. Thus the instruction selector can just add registers without
- // abandon, and the register allocator won't be confused.
- bool isVirtualRegister() const {
- return (opType == MO_VirtualRegister || opType == MO_MachineRegister)
- && regNum >= MRegisterInfo::FirstVirtualRegister;
- }
- bool isPhysicalRegister() const {
- return (opType == MO_VirtualRegister || opType == MO_MachineRegister)
- && (unsigned)regNum < MRegisterInfo::FirstVirtualRegister;
+ /// isRegister - Return true if this operand is a register operand. The X86
+ /// backend currently can't decide whether to use MO_MR or MO_VR to represent
+ /// them, so we accept both.
+ ///
+ /// Note: The sparc backend should not use this method.
+ ///
+ bool isRegister() const {
+ return opType == MO_MachineRegister || opType == MO_VirtualRegister;
}
- bool isRegister() const { return isVirtualRegister() || isPhysicalRegister();}
- bool isMachineRegister() const { return !isVirtualRegister(); }
+
bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
bool isPCRelativeDisp() const { return opType == MO_PCRelativeDisp; }
bool isImmediate() const {
return *SymbolName;
}
- bool isUse () const { return flags & USEFLAG; }
- bool isDef () const { return flags & DEFFLAG; }
- bool isHiBits32 () const { return flags & HIFLAG32; }
- bool isLoBits32 () const { return flags & LOFLAG32; }
- bool isHiBits64 () const { return flags & HIFLAG64; }
- bool isLoBits64 () const { return flags & LOFLAG64; }
+ bool isUse () const { return flags & USEFLAG; }
+ MachineOperand& setUse () { flags |= USEFLAG; return *this; }
+ bool isDef () const { return flags & DEFFLAG; }
+ MachineOperand& setDef () { flags |= DEFFLAG; return *this; }
+ bool isHiBits32 () const { return flags & HIFLAG32; }
+ bool isLoBits32 () const { return flags & LOFLAG32; }
+ bool isHiBits64 () const { return flags & HIFLAG64; }
+ bool isLoBits64 () const { return flags & LOFLAG64; }
// used to check if a machine register has been allocated to this operand
bool hasAllocatedReg() const {
}
// used to get the reg number if when one is allocated
- int getAllocatedRegNum() const {
+ unsigned getReg() const {
assert(hasAllocatedReg());
return regNum;
}
// ********** TODO: get rid of this duplicate code! ***********
- unsigned getReg() const {
- return getAllocatedRegNum();
- }
void setReg(unsigned Reg) {
assert(hasAllocatedReg() && "This operand cannot have a register number!");
regNum = Reg;
//===----------------------------------------------------------------------===//
class MachineInstr {
- int opCode; // the opcode
- unsigned opCodeFlags; // flags modifying instrn behavior
+ short Opcode; // the opcode
+ unsigned char numImplicitRefs; // number of implicit operands
std::vector<MachineOperand> operands; // the operands
- unsigned numImplicitRefs; // number of implicit operands
-
+ MachineInstr* prev, *next; // links for our intrusive list
+ MachineBasicBlock* parent; // pointer to the owning basic block
// OperandComplete - Return true if it's illegal to add a new operand
bool OperandsComplete() const;
MachineInstr(const MachineInstr &); // DO NOT IMPLEMENT
void operator=(const MachineInstr&); // DO NOT IMPLEMENT
+
+private:
+ // Intrusive list support
+ //
+ friend class ilist_traits<MachineInstr>;
+
public:
- MachineInstr(int Opcode, unsigned numOperands);
+ MachineInstr(short Opcode, unsigned numOperands);
/// MachineInstr ctor - This constructor only does a _reserve_ of the
/// operands, not a resize for them. It is expected that if you use this that
/// you call add* methods below to fill up the operands, instead of the Set
/// methods. Eventually, the "resizing" ctors will be phased out.
///
- MachineInstr(int Opcode, unsigned numOperands, bool XX, bool YY);
+ MachineInstr(short Opcode, unsigned numOperands, bool XX, bool YY);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic
/// block.
///
- MachineInstr(MachineBasicBlock *MBB, int Opcode, unsigned numOps);
+ MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps);
+ ~MachineInstr();
- // The opcode.
- //
- const int getOpcode() const { return opCode; }
- const int getOpCode() const { return opCode; }
+ const MachineBasicBlock* getParent() const { return parent; }
+ MachineBasicBlock* getParent() { return parent; }
- // Opcode flags.
- //
- unsigned getOpCodeFlags() const { return opCodeFlags; }
+ /// Accessors for opcode.
+ ///
+ const int getOpcode() const { return Opcode; }
- //
- // Access to explicit operands of the instruction
- //
+ /// Access to explicit operands of the instruction.
+ ///
unsigned getNumOperands() const { return operands.size() - numImplicitRefs; }
const MachineOperand& getOperand(unsigned i) const {
/// simply replace() and then set new operands with Set.*Operand methods
/// below.
///
- void replace(int Opcode, unsigned numOperands);
+ void replace(short Opcode, unsigned numOperands);
/// setOpcode - Replace the opcode of the current instruction with a new one.
///
- void setOpcode(unsigned Op) { opCode = Op; }
+ void setOpcode(unsigned Op) { Opcode = Op; }
/// RemoveOperand - Erase an operand from an instruction, leaving it with one
/// fewer operand than it started with.
}
};
-
//===----------------------------------------------------------------------===//
// Debugging Support