#ifndef LLVM_CODEGEN_MACHINEINSTR_H
#define LLVM_CODEGEN_MACHINEINSTR_H
-#include "Support/iterator"
-#include <string>
+#include "llvm/ADT/iterator"
#include <vector>
#include <cassert>
class TargetMachine;
class GlobalValue;
-template <typename T> class ilist_traits;
-template <typename T> class ilist;
+template <typename T> struct ilist_traits;
+template <typename T> struct ilist;
typedef short MachineOpCode;
int immedVal; // Constant value for an explicit constant
MachineBasicBlock *MBB; // For MO_MachineBasicBlock type
- std::string *SymbolName; // For MO_ExternalSymbol type
+ const char *SymbolName; // For MO_ExternalSymbol type
} contents;
char flags; // see bit field definitions above
MachineOperandType opType:8; // Pack into 8 bits efficiently after flags.
- int regNum; // register number for an explicit register
+ union {
+ int regNum; // register number for an explicit register
// will be set for a value after reg allocation
-private:
+
+ int offset; // Offset to address of global or external, only
+ // valid for MO_GlobalAddress and MO_ExternalSym
+ } extra;
+
void zeroContents () {
memset (&contents, 0, sizeof (contents));
+ memset (&extra, 0, sizeof (extra));
}
MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
- : flags(0), opType(OpTy), regNum(-1) {
+ : flags(0), opType(OpTy) {
zeroContents ();
contents.immedVal = ImmVal;
+ extra.regNum = -1;
}
MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
- : flags(UseTy), opType(OpTy), regNum(Reg) {
+ : flags(UseTy), opType(OpTy) {
zeroContents ();
+ extra.regNum = Reg;
}
MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
bool isPCRelative = false)
- : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) {
- zeroContents ();
+ : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
+ assert(OpTy != MachineOperand::MO_GlobalAddress);
+ zeroContents();
contents.value = V;
+ extra.regNum = -1;
+ }
+
+ MachineOperand(GlobalValue *V, MachineOperandType OpTy, UseType UseTy,
+ bool isPCRelative = false, int Offset = 0)
+ : flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
+ assert(OpTy == MachineOperand::MO_GlobalAddress);
+ zeroContents ();
+ contents.value = (Value*)V;
+ extra.offset = Offset;
}
MachineOperand(MachineBasicBlock *mbb)
- : flags(0), opType(MO_MachineBasicBlock), regNum(-1) {
+ : flags(0), opType(MO_MachineBasicBlock) {
zeroContents ();
contents.MBB = mbb;
+ extra.regNum = -1;
}
- MachineOperand(const std::string &SymName, bool isPCRelative)
- : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) {
+ MachineOperand(const char *SymName, bool isPCRelative, int Offset)
+ : flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol) {
zeroContents ();
- contents.SymbolName = new std::string (SymName);
+ contents.SymbolName = SymName;
+ extra.offset = Offset;
}
public:
MachineOperand(const MachineOperand &M)
- : flags(M.flags), opType(M.opType), regNum(M.regNum) {
+ : flags(M.flags), opType(M.opType) {
zeroContents ();
contents = M.contents;
- if (isExternalSymbol())
- contents.SymbolName = new std::string(M.getSymbolName());
+ extra = M.extra;
}
- ~MachineOperand() {
- if (isExternalSymbol())
- delete contents.SymbolName;
- }
+ ~MachineOperand() {}
const MachineOperand &operator=(const MachineOperand &MO) {
- if (isExternalSymbol()) // if old operand had a symbol name,
- delete contents.SymbolName; // release old memory
contents = MO.contents;
flags = MO.flags;
opType = MO.opType;
- regNum = MO.regNum;
- if (isExternalSymbol())
- contents.SymbolName = new std::string(MO.getSymbolName());
+ extra = MO.extra;
return *this;
}
}
int getMachineRegNum() const {
assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
- return regNum;
+ return extra.regNum;
}
int getImmedValue() const {
assert(isImmediate() && "Wrong MachineOperand accessor");
assert(isGlobalAddress() && "Wrong MachineOperand accessor");
return (GlobalValue*)contents.value;
}
- const std::string &getSymbolName() const {
+ int getOffset() const {
+ assert((isGlobalAddress() || isExternalSymbol()) &&
+ "Wrong MachineOperand accessor");
+ return extra.offset;
+ }
+ const char *getSymbolName() const {
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
- return *contents.SymbolName;
+ return contents.SymbolName;
}
/// MachineOperand methods for testing that work on any kind of
/// allocated to this operand.
///
bool hasAllocatedReg() const {
- return (regNum >= 0 &&
+ return (extra.regNum >= 0 &&
(opType == MO_VirtualRegister || opType == MO_CCRegister ||
opType == MO_MachineRegister));
}
///
unsigned getReg() const {
assert(hasAllocatedReg());
- return regNum;
+ return extra.regNum;
}
/// MachineOperand mutators...
// This method's comment used to say: 'TODO: get rid of this duplicate
// code.' It's not clear where the duplication is.
assert(hasAllocatedReg() && "This operand cannot have a register number!");
- regNum = Reg;
+ extra.regNum = Reg;
}
void setValueReg(Value *val) {
contents.immedVal = immVal;
}
+ void setOffset(int Offset) {
+ assert((isGlobalAddress() || isExternalSymbol()) &&
+ "Wrong MachineOperand accessor");
+ extra.offset = Offset;
+ }
+
friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
/// markHi32, markLo32, etc. - These methods are deprecated and only used by
void setRegForValue(int reg) {
assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
opType == MO_MachineRegister);
- regNum = reg;
+ extra.regNum = reg;
}
friend class MachineInstr;
// Intrusive list support
//
- friend class ilist_traits<MachineInstr>;
+ friend struct ilist_traits<MachineInstr>;
public:
MachineInstr(short Opcode, unsigned numOperands);
operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex));
}
- void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative) {
+ void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative, int Offset) {
assert(!OperandsComplete() &&
"Trying to add an operand to a machine instr that is already done!");
operands.push_back(
- MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress,
- MachineOperand::Use, isPCRelative));
+ MachineOperand(GV, MachineOperand::MO_GlobalAddress,
+ MachineOperand::Use, isPCRelative, Offset));
}
/// addExternalSymbolOperand - Add an external symbol operand to this instr
///
- void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) {
- operands.push_back(MachineOperand(SymName, isPCRelative));
+ void addExternalSymbolOperand(const char *SymName, bool isPCRelative) {
+ operands.push_back(MachineOperand(SymName, isPCRelative, 0));
}
//===--------------------------------------------------------------------===//