llvm bug #1350, parts 1, 2, and 3.

llvm-svn: 36618
This commit is contained in:
Nate Begeman 2007-05-01 05:57:02 +00:00
parent 6528334ab7
commit 767ee95d29
6 changed files with 132 additions and 26 deletions

View File

@ -71,10 +71,17 @@ private:
// immediately after the write. i.e. A register
// that is defined but never used.
/// auxInfo - auxiliary information used by the MachineOperand
union {
/// offset - Offset to address of global or external, only valid for
/// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
int offset;
/// subReg - SubRegister number, only valid for MO_Register. A value of 0
/// indicates the MO_Register has no subReg.
unsigned subReg;
} auxInfo;
MachineOperand() {}
void print(std::ostream &os) const;
@ -95,7 +102,7 @@ public:
Op.IsImp = false;
Op.IsKill = false;
Op.IsDead = false;
Op.offset = 0;
Op.auxInfo.offset = 0;
return Op;
}
@ -106,7 +113,7 @@ public:
IsKill = MO.IsKill;
IsDead = MO.IsDead;
opType = MO.opType;
offset = MO.offset;
auxInfo = MO.auxInfo;
return *this;
}
@ -169,7 +176,11 @@ public:
int getOffset() const {
assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
"Wrong MachineOperand accessor");
return offset;
return auxInfo.offset;
}
unsigned getSubReg() const {
assert(isRegister() && "Wrong MachineOperand accessor");
return auxInfo.subReg;
}
const char *getSymbolName() const {
assert(isExternalSymbol() && "Wrong MachineOperand accessor");
@ -254,7 +265,11 @@ public:
assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
isJumpTableIndex()) &&
"Wrong MachineOperand accessor");
offset = Offset;
auxInfo.offset = Offset;
}
void setSubReg(unsigned subReg) {
assert(isRegister() && "Wrong MachineOperand accessor");
auxInfo.subReg = subReg;
}
void setConstantPoolIndex(unsigned Idx) {
assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
@ -433,7 +448,7 @@ public:
Op.IsKill = IsKill;
Op.IsDead = IsDead;
Op.contents.RegNo = Reg;
Op.offset = 0;
Op.auxInfo.subReg = 0;
}
/// addImmOperand - Add a zero extended constant argument to the
@ -443,14 +458,14 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_Immediate;
Op.contents.immedVal = Val;
Op.offset = 0;
Op.auxInfo.offset = 0;
}
void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_MachineBasicBlock;
Op.contents.MBB = MBB;
Op.offset = 0;
Op.auxInfo.offset = 0;
}
/// addFrameIndexOperand - Add an abstract frame index to the instruction
@ -459,7 +474,7 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_FrameIndex;
Op.contents.immedVal = Idx;
Op.offset = 0;
Op.auxInfo.offset = 0;
}
/// addConstantPoolndexOperand - Add a constant pool object index to the
@ -469,7 +484,7 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_ConstantPoolIndex;
Op.contents.immedVal = Idx;
Op.offset = Offset;
Op.auxInfo.offset = Offset;
}
/// addJumpTableIndexOperand - Add a jump table object index to the
@ -479,14 +494,14 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_JumpTableIndex;
Op.contents.immedVal = Idx;
Op.offset = 0;
Op.auxInfo.offset = 0;
}
void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_GlobalAddress;
Op.contents.GV = GV;
Op.offset = Offset;
Op.auxInfo.offset = Offset;
}
/// addExternalSymbolOperand - Add an external symbol operand to this instr
@ -495,7 +510,7 @@ public:
MachineOperand &Op = AddNewOperand();
Op.opType = MachineOperand::MO_ExternalSymbol;
Op.contents.SymbolName = SymName;
Op.offset = 0;
Op.auxInfo.offset = 0;
}
//===--------------------------------------------------------------------===//

View File

@ -41,7 +41,7 @@ class Type;
/// The SubRegs field is a zero terminated array of registers that are
/// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
/// The SuperRegs field is a zero terminated array of registers that are
/// super-registers of the specific register, e.g. RAX, EAX, are sub-registers
/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
/// of AX.
///
struct TargetRegisterDesc {
@ -354,6 +354,10 @@ public:
/// register scavenger to determine what registers are free.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
/// getSubReg - Returns the physical register number of sub-register "Index"
/// for physical register RegNo.
virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
//===--------------------------------------------------------------------===//
// Register Class Information
//

View File

@ -39,7 +39,7 @@ void MachineInstr::addImplicitDefUseOperands() {
Op.IsKill = false;
Op.IsDead = false;
Op.contents.RegNo = *ImpDefs;
Op.offset = 0;
Op.auxInfo.subReg = 0;
Operands.push_back(Op);
}
if (TID->ImplicitUses)
@ -51,7 +51,7 @@ void MachineInstr::addImplicitDefUseOperands() {
Op.IsKill = false;
Op.IsDead = false;
Op.contents.RegNo = *ImpUses;
Op.offset = 0;
Op.auxInfo.subReg = 0;
Operands.push_back(Op);
}
}

View File

@ -43,10 +43,16 @@ class VR<bits<5> num, string n> : PPCReg<n> {
}
// CR - One of the 8 4-bit condition registers
class CR<bits<5> num, string n> : PPCReg<n> {
class CR<bits<3> num, string n> : PPCReg<n> {
field bits<3> Num = num;
}
// CRBIT - One of the 32 1-bit condition register fields
class CRBIT<bits<5> num, string n> : PPCReg<n> {
field bits<5> Num = num;
}
// General-purpose registers
def R0 : GPR< 0, "r0">, DwarfRegNum<0>;
def R1 : GPR< 1, "r1">, DwarfRegNum<1>;
@ -193,6 +199,49 @@ def CR5 : CR<5, "cr5">, DwarfRegNum<73>;
def CR6 : CR<6, "cr6">, DwarfRegNum<74>;
def CR7 : CR<7, "cr7">, DwarfRegNum<75>;
// Condition register bits
def CR0LT : CRBIT< 0, "0">, DwarfRegNum<0>;
def CR0GT : CRBIT< 1, "1">, DwarfRegNum<0>;
def CR0EQ : CRBIT< 2, "2">, DwarfRegNum<0>;
def CR0UN : CRBIT< 3, "3">, DwarfRegNum<0>;
def CR1LT : CRBIT< 4, "4">, DwarfRegNum<0>;
def CR1GT : CRBIT< 5, "5">, DwarfRegNum<0>;
def CR1EQ : CRBIT< 6, "6">, DwarfRegNum<0>;
def CR1UN : CRBIT< 7, "7">, DwarfRegNum<0>;
def CR2LT : CRBIT< 8, "8">, DwarfRegNum<0>;
def CR2GT : CRBIT< 9, "9">, DwarfRegNum<0>;
def CR2EQ : CRBIT<10, "10">, DwarfRegNum<0>;
def CR2UN : CRBIT<11, "11">, DwarfRegNum<0>;
def CR3LT : CRBIT<12, "12">, DwarfRegNum<0>;
def CR3GT : CRBIT<13, "13">, DwarfRegNum<0>;
def CR3EQ : CRBIT<14, "14">, DwarfRegNum<0>;
def CR3UN : CRBIT<15, "15">, DwarfRegNum<0>;
def CR4LT : CRBIT<16, "16">, DwarfRegNum<0>;
def CR4GT : CRBIT<17, "17">, DwarfRegNum<0>;
def CR4EQ : CRBIT<18, "18">, DwarfRegNum<0>;
def CR4UN : CRBIT<19, "19">, DwarfRegNum<0>;
def CR5LT : CRBIT<20, "20">, DwarfRegNum<0>;
def CR5GT : CRBIT<21, "21">, DwarfRegNum<0>;
def CR5EQ : CRBIT<22, "22">, DwarfRegNum<0>;
def CR5UN : CRBIT<23, "23">, DwarfRegNum<0>;
def CR6LT : CRBIT<24, "24">, DwarfRegNum<0>;
def CR6GT : CRBIT<25, "25">, DwarfRegNum<0>;
def CR6EQ : CRBIT<26, "26">, DwarfRegNum<0>;
def CR6UN : CRBIT<27, "27">, DwarfRegNum<0>;
def CR7LT : CRBIT<28, "28">, DwarfRegNum<0>;
def CR7GT : CRBIT<29, "29">, DwarfRegNum<0>;
def CR7EQ : CRBIT<30, "30">, DwarfRegNum<0>;
def CR7UN : CRBIT<31, "31">, DwarfRegNum<0>;
def : SubRegSet<1, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
[CR0LT, CR1LT, CR2LT, CR3LT, CR4LT, CR5LT, CR6LT, CR7LT]>;
def : SubRegSet<2, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
[CR0GT, CR1GT, CR2GT, CR3GT, CR4GT, CR5GT, CR6GT, CR7GT]>;
def : SubRegSet<3, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
[CR0EQ, CR1EQ, CR2EQ, CR3EQ, CR4EQ, CR5EQ, CR6EQ, CR7EQ]>;
def : SubRegSet<4, [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7],
[CR0UN, CR1UN, CR2UN, CR3UN, CR4UN, CR5UN, CR6UN, CR7UN]>;
// Link register
def LR : SPR<8, "lr">, DwarfRegNum<65>;
//let Aliases = [LR] in

View File

@ -67,13 +67,15 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
}
// RegisterGroup - This can be used to define instances of Register which
// need to specify aliases.
// List "aliases" specifies which registers are aliased to this one. This
// allows the code generator to be careful not to put two values with
// overlapping live ranges into registers which alias.
class RegisterGroup<string n, list<Register> aliases> : Register<n> {
let Aliases = aliases;
// SubRegSet - This can be used to define a specific mapping of registers to
// indices, for use as named subregs of a particular physical register. Each
// register in 'subregs' becomes an addressable subregister at index 'n' of the
// corresponding register in 'regs'.
class SubRegSet<int n, list<Register> regs, list<Register> subregs> {
int index = n;
list<Register> From = regs;
list<Register> To = subregs;
}
// RegisterClass - Now that all of the registers are defined, and aliases

View File

@ -61,6 +61,7 @@ void RegisterInfoEmitter::runHeader(std::ostream &OS) {
<< " " << ClassName
<< "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
<< " int getDwarfRegNum(unsigned RegNum) const;\n"
<< " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
<< "};\n\n";
const std::vector<CodeGenRegisterClass> &RegisterClasses =
@ -322,6 +323,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
std::map<Record*, std::set<Record*> > RegisterSubRegs;
std::map<Record*, std::set<Record*> > RegisterSuperRegs;
std::map<Record*, std::set<Record*> > RegisterAliases;
std::map<Record*, std::vector<std::pair<int, Record*> > > SubRegVectors;
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
@ -441,6 +443,40 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
std::string ClassName = Target.getName() + "GenRegisterInfo";
// Calculate the mapping of subregister+index pairs to physical registers.
std::vector<Record*> SubRegs = Records.getAllDerivedDefinitions("SubRegSet");
for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
int subRegIndex = SubRegs[i]->getValueAsInt("index");
std::vector<Record*> From = SubRegs[i]->getValueAsListOfDefs("From");
std::vector<Record*> To = SubRegs[i]->getValueAsListOfDefs("To");
assert((From.size() == To.size()) &&
"SubRegSet has mismatched from/to size");
// For each entry in from/to vectors, insert the to register at index
for (unsigned ii = 0, ee = From.size(); ii != ee; ++ii)
SubRegVectors[From[ii]].push_back(std::make_pair(subRegIndex, To[ii]));
}
// Emit the subregister + index mapping function based on the information
// calculated above.
OS << "unsigned " << ClassName
<< "::getSubReg(unsigned RegNo, unsigned Index) const {\n"
<< " switch (RegNo) {\n"
<< " default: abort(); break;\n";
for (std::map<Record*, std::vector<std::pair<int, Record*> > >::iterator
I = SubRegVectors.begin(), E = SubRegVectors.end(); I != E; ++I) {
OS << " case " << getQualifiedName(I->first) << ":\n";
OS << " switch (Index) {\n";
OS << " default: abort(); break;\n";
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
OS << " case " << (I->second)[i].first << ": return "
<< getQualifiedName((I->second)[i].second) << ";\n";
OS << " }; break;\n";
}
OS << " };\n";
OS << "}\n\n";
// Emit the constructor of the class...
OS << ClassName << "::" << ClassName
<< "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"