mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-12 17:25:49 +00:00
Allow machine operands to represent global variables with offsets. This is
useful when you have a reference like: int A[100]; void foo() { A[10] = 1; } In this case, &A[10] is a single constant and should be treated as such. Only MO_GlobalAddress and MO_ExternalSymbol are allowed to use this field, no other operand type is. This is another fine patch contributed by Jeff Cohen!! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17007 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -126,48 +126,60 @@ private:
|
|||||||
|
|
||||||
char flags; // see bit field definitions above
|
char flags; // see bit field definitions above
|
||||||
MachineOperandType opType:8; // Pack into 8 bits efficiently after flags.
|
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
|
// 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 () {
|
void zeroContents () {
|
||||||
memset (&contents, 0, sizeof (contents));
|
memset (&contents, 0, sizeof (contents));
|
||||||
|
memset (&extra, 0, sizeof (extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
|
MachineOperand(int ImmVal = 0, MachineOperandType OpTy = MO_VirtualRegister)
|
||||||
: flags(0), opType(OpTy), regNum(-1) {
|
: flags(0), opType(OpTy) {
|
||||||
zeroContents ();
|
zeroContents ();
|
||||||
contents.immedVal = ImmVal;
|
contents.immedVal = ImmVal;
|
||||||
|
extra.regNum = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
|
MachineOperand(int Reg, MachineOperandType OpTy, UseType UseTy)
|
||||||
: flags(UseTy), opType(OpTy), regNum(Reg) {
|
: flags(UseTy), opType(OpTy) {
|
||||||
zeroContents ();
|
zeroContents ();
|
||||||
|
extra.regNum = Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
|
MachineOperand(Value *V, MachineOperandType OpTy, UseType UseTy,
|
||||||
bool isPCRelative = false)
|
bool isPCRelative = false, int Offset = 0)
|
||||||
: flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy), regNum(-1) {
|
: flags(UseTy | (isPCRelative?PCRELATIVE:0)), opType(OpTy) {
|
||||||
zeroContents ();
|
zeroContents ();
|
||||||
contents.value = V;
|
contents.value = V;
|
||||||
|
extra.offset = Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineOperand(MachineBasicBlock *mbb)
|
MachineOperand(MachineBasicBlock *mbb)
|
||||||
: flags(0), opType(MO_MachineBasicBlock), regNum(-1) {
|
: flags(0), opType(MO_MachineBasicBlock) {
|
||||||
zeroContents ();
|
zeroContents ();
|
||||||
contents.MBB = mbb;
|
contents.MBB = mbb;
|
||||||
|
extra.regNum = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineOperand(const std::string &SymName, bool isPCRelative)
|
MachineOperand(const std::string &SymName, bool isPCRelative, int Offset)
|
||||||
: flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol), regNum(-1) {
|
: flags(isPCRelative?PCRELATIVE:0), opType(MO_ExternalSymbol) {
|
||||||
zeroContents ();
|
zeroContents ();
|
||||||
contents.SymbolName = new std::string (SymName);
|
contents.SymbolName = new std::string (SymName);
|
||||||
|
extra.offset = Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MachineOperand(const MachineOperand &M)
|
MachineOperand(const MachineOperand &M)
|
||||||
: flags(M.flags), opType(M.opType), regNum(M.regNum) {
|
: flags(M.flags), opType(M.opType) {
|
||||||
zeroContents ();
|
zeroContents ();
|
||||||
contents = M.contents;
|
contents = M.contents;
|
||||||
|
extra = M.extra;
|
||||||
if (isExternalSymbol())
|
if (isExternalSymbol())
|
||||||
contents.SymbolName = new std::string(M.getSymbolName());
|
contents.SymbolName = new std::string(M.getSymbolName());
|
||||||
}
|
}
|
||||||
@@ -184,7 +196,7 @@ public:
|
|||||||
contents = MO.contents;
|
contents = MO.contents;
|
||||||
flags = MO.flags;
|
flags = MO.flags;
|
||||||
opType = MO.opType;
|
opType = MO.opType;
|
||||||
regNum = MO.regNum;
|
extra = MO.extra;
|
||||||
if (isExternalSymbol())
|
if (isExternalSymbol())
|
||||||
contents.SymbolName = new std::string(MO.getSymbolName());
|
contents.SymbolName = new std::string(MO.getSymbolName());
|
||||||
return *this;
|
return *this;
|
||||||
@@ -245,7 +257,7 @@ public:
|
|||||||
}
|
}
|
||||||
int getMachineRegNum() const {
|
int getMachineRegNum() const {
|
||||||
assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
|
assert(opType == MO_MachineRegister && "Wrong MachineOperand accessor");
|
||||||
return regNum;
|
return extra.regNum;
|
||||||
}
|
}
|
||||||
int getImmedValue() const {
|
int getImmedValue() const {
|
||||||
assert(isImmediate() && "Wrong MachineOperand accessor");
|
assert(isImmediate() && "Wrong MachineOperand accessor");
|
||||||
@@ -271,6 +283,11 @@ public:
|
|||||||
assert(isGlobalAddress() && "Wrong MachineOperand accessor");
|
assert(isGlobalAddress() && "Wrong MachineOperand accessor");
|
||||||
return (GlobalValue*)contents.value;
|
return (GlobalValue*)contents.value;
|
||||||
}
|
}
|
||||||
|
int getOffset() const {
|
||||||
|
assert((isGlobalAddress() || isExternalSymbol()) &&
|
||||||
|
"Wrong MachineOperand accessor");
|
||||||
|
return extra.offset;
|
||||||
|
}
|
||||||
const std::string &getSymbolName() const {
|
const std::string &getSymbolName() const {
|
||||||
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
|
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
|
||||||
return *contents.SymbolName;
|
return *contents.SymbolName;
|
||||||
@@ -292,7 +309,7 @@ public:
|
|||||||
/// allocated to this operand.
|
/// allocated to this operand.
|
||||||
///
|
///
|
||||||
bool hasAllocatedReg() const {
|
bool hasAllocatedReg() const {
|
||||||
return (regNum >= 0 &&
|
return (extra.regNum >= 0 &&
|
||||||
(opType == MO_VirtualRegister || opType == MO_CCRegister ||
|
(opType == MO_VirtualRegister || opType == MO_CCRegister ||
|
||||||
opType == MO_MachineRegister));
|
opType == MO_MachineRegister));
|
||||||
}
|
}
|
||||||
@@ -302,7 +319,7 @@ public:
|
|||||||
///
|
///
|
||||||
unsigned getReg() const {
|
unsigned getReg() const {
|
||||||
assert(hasAllocatedReg());
|
assert(hasAllocatedReg());
|
||||||
return regNum;
|
return extra.regNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MachineOperand mutators...
|
/// MachineOperand mutators...
|
||||||
@@ -311,7 +328,7 @@ public:
|
|||||||
// This method's comment used to say: 'TODO: get rid of this duplicate
|
// This method's comment used to say: 'TODO: get rid of this duplicate
|
||||||
// code.' It's not clear where the duplication is.
|
// code.' It's not clear where the duplication is.
|
||||||
assert(hasAllocatedReg() && "This operand cannot have a register number!");
|
assert(hasAllocatedReg() && "This operand cannot have a register number!");
|
||||||
regNum = Reg;
|
extra.regNum = Reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValueReg(Value *val) {
|
void setValueReg(Value *val) {
|
||||||
@@ -324,6 +341,12 @@ public:
|
|||||||
contents.immedVal = immVal;
|
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);
|
friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
|
||||||
|
|
||||||
/// markHi32, markLo32, etc. - These methods are deprecated and only used by
|
/// markHi32, markLo32, etc. - These methods are deprecated and only used by
|
||||||
@@ -342,7 +365,7 @@ private:
|
|||||||
void setRegForValue(int reg) {
|
void setRegForValue(int reg) {
|
||||||
assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
|
assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
|
||||||
opType == MO_MachineRegister);
|
opType == MO_MachineRegister);
|
||||||
regNum = reg;
|
extra.regNum = reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class MachineInstr;
|
friend class MachineInstr;
|
||||||
@@ -615,18 +638,18 @@ public:
|
|||||||
operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex));
|
operands.push_back(MachineOperand(I, MachineOperand::MO_ConstantPoolIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative) {
|
void addGlobalAddressOperand(GlobalValue *GV, bool isPCRelative, int Offset) {
|
||||||
assert(!OperandsComplete() &&
|
assert(!OperandsComplete() &&
|
||||||
"Trying to add an operand to a machine instr that is already done!");
|
"Trying to add an operand to a machine instr that is already done!");
|
||||||
operands.push_back(
|
operands.push_back(
|
||||||
MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress,
|
MachineOperand((Value*)GV, MachineOperand::MO_GlobalAddress,
|
||||||
MachineOperand::Use, isPCRelative));
|
MachineOperand::Use, isPCRelative, Offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// addExternalSymbolOperand - Add an external symbol operand to this instr
|
/// addExternalSymbolOperand - Add an external symbol operand to this instr
|
||||||
///
|
///
|
||||||
void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) {
|
void addExternalSymbolOperand(const std::string &SymName, bool isPCRelative) {
|
||||||
operands.push_back(MachineOperand(SymName, isPCRelative));
|
operands.push_back(MachineOperand(SymName, isPCRelative, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
@@ -124,8 +124,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
|
const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
|
||||||
bool isPCRelative = false) const {
|
bool isPCRelative = false, int Offset = 0) const {
|
||||||
MI->addGlobalAddressOperand(GV, isPCRelative);
|
MI->addGlobalAddressOperand(GV, isPCRelative, Offset);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -127,7 +127,7 @@ void MachineInstr::SetMachineOperandVal(unsigned i,
|
|||||||
assert(i < operands.size()); // may be explicit or implicit op
|
assert(i < operands.size()); // may be explicit or implicit op
|
||||||
operands[i].opType = opTy;
|
operands[i].opType = opTy;
|
||||||
operands[i].contents.value = V;
|
operands[i].contents.value = V;
|
||||||
operands[i].regNum = -1;
|
operands[i].extra.regNum = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -141,7 +141,7 @@ MachineInstr::SetMachineOperandConst(unsigned i,
|
|||||||
operands[i].opType = opTy;
|
operands[i].opType = opTy;
|
||||||
operands[i].contents.value = NULL;
|
operands[i].contents.value = NULL;
|
||||||
operands[i].contents.immedVal = intValue;
|
operands[i].contents.immedVal = intValue;
|
||||||
operands[i].regNum = -1;
|
operands[i].extra.regNum = -1;
|
||||||
operands[i].flags = 0;
|
operands[i].flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ void MachineInstr::SetMachineOperandReg(unsigned i, int regNum) {
|
|||||||
|
|
||||||
operands[i].opType = MachineOperand::MO_MachineRegister;
|
operands[i].opType = MachineOperand::MO_MachineRegister;
|
||||||
operands[i].contents.value = NULL;
|
operands[i].contents.value = NULL;
|
||||||
operands[i].regNum = regNum;
|
operands[i].extra.regNum = regNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used only by the SPARC back-end.
|
// Used only by the SPARC back-end.
|
||||||
@@ -302,10 +302,14 @@ static void print(const MachineOperand &MO, std::ostream &OS,
|
|||||||
OS << "<cp#" << MO.getConstantPoolIndex() << ">";
|
OS << "<cp#" << MO.getConstantPoolIndex() << ">";
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
OS << "<ga:" << ((Value*)MO.getGlobal())->getName() << ">";
|
OS << "<ga:" << ((Value*)MO.getGlobal())->getName();
|
||||||
|
if (MO.getOffset()) OS << "+" << MO.getOffset();
|
||||||
|
OS << ">";
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_ExternalSymbol:
|
case MachineOperand::MO_ExternalSymbol:
|
||||||
OS << "<es:" << MO.getSymbolName() << ">";
|
OS << "<es:" << MO.getSymbolName();
|
||||||
|
if (MO.getOffset()) OS << "+" << MO.getOffset();
|
||||||
|
OS << ">";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "Unrecognized operand type");
|
assert(0 && "Unrecognized operand type");
|
||||||
|
Reference in New Issue
Block a user