mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
Add sub-registers sets.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a92d62c15f
commit
3cafbf7e5f
@ -41,9 +41,14 @@ class Register<string n> {
|
|||||||
// Aliases - A list of registers that this register overlaps with. A read or
|
// Aliases - A list of registers that this register overlaps with. A read or
|
||||||
// modification of this register can potentially read or modify the aliased
|
// modification of this register can potentially read or modify the aliased
|
||||||
// registers.
|
// registers.
|
||||||
//
|
|
||||||
list<Register> Aliases = [];
|
list<Register> Aliases = [];
|
||||||
|
|
||||||
|
// SubRegs - A list of registers that are parts of this register. Note these
|
||||||
|
// are "immediate" sub-registers and the registers within the list do not
|
||||||
|
// themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX],
|
||||||
|
// not [AX, AH, AL].
|
||||||
|
list<Register> SubRegs = [];
|
||||||
|
|
||||||
// DwarfNumber - Number used internally by gcc/gdb to identify the register.
|
// DwarfNumber - Number used internally by gcc/gdb to identify the register.
|
||||||
// These values can be determined by locating the <target>.h file in the
|
// These values can be determined by locating the <target>.h file in the
|
||||||
// directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The
|
// directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The
|
||||||
@ -52,6 +57,16 @@ class Register<string n> {
|
|||||||
int DwarfNumber = -1;
|
int DwarfNumber = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterWithSubRegs - This can be used to define instances of Register which
|
||||||
|
// need to specify sub-registers.
|
||||||
|
// List "subregs" specifies which registers are sub-registers to this one. This
|
||||||
|
// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc.
|
||||||
|
// This allows the code generator to be careful not to put two values with
|
||||||
|
// overlapping live ranges into registers which alias.
|
||||||
|
class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
|
||||||
|
let SubRegs = subregs;
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterGroup - This can be used to define instances of Register which
|
// RegisterGroup - This can be used to define instances of Register which
|
||||||
// need to specify aliases.
|
// need to specify aliases.
|
||||||
// List "aliases" specifies which registers are aliased to this one. This
|
// List "aliases" specifies which registers are aliased to this one. This
|
||||||
|
@ -107,6 +107,27 @@ bool isSubRegisterClass(const CodeGenRegisterClass &RC,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void addSubReg(Record *R, Record *S,
|
||||||
|
std::map<Record*, std::set<Record*> > &SubRegs,
|
||||||
|
std::map<Record*, std::set<Record*> > &Aliases,
|
||||||
|
RegisterInfoEmitter &RIE) {
|
||||||
|
if (R == S) {
|
||||||
|
cerr << "Error: recursive sub-register relationship between"
|
||||||
|
<< " register " << RIE.getQualifiedName(R)
|
||||||
|
<< " and its sub-registers?\n";
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SubRegs[R].insert(S).second)
|
||||||
|
return;
|
||||||
|
Aliases[R].insert(S);
|
||||||
|
Aliases[S].insert(R);
|
||||||
|
if (SubRegs.count(S))
|
||||||
|
for (std::set<Record*>::iterator I = SubRegs[S].begin(),
|
||||||
|
E = SubRegs[S].end(); I != E; ++I)
|
||||||
|
addSubReg(R, *I, SubRegs, Aliases, RIE);
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterInfoEmitter::run - Main register file description emitter.
|
// RegisterInfoEmitter::run - Main register file description emitter.
|
||||||
//
|
//
|
||||||
void RegisterInfoEmitter::run(std::ostream &OS) {
|
void RegisterInfoEmitter::run(std::ostream &OS) {
|
||||||
@ -273,7 +294,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
<< "RegClass,\n";
|
<< "RegClass,\n";
|
||||||
OS << " };\n";
|
OS << " };\n";
|
||||||
|
|
||||||
// Emit register class aliases...
|
// Emit register sub-registers / aliases...
|
||||||
|
std::map<Record*, std::set<Record*> > RegisterSubRegs;
|
||||||
std::map<Record*, std::set<Record*> > RegisterAliases;
|
std::map<Record*, std::set<Record*> > RegisterAliases;
|
||||||
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
|
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
|
||||||
|
|
||||||
@ -298,6 +320,20 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
||||||
|
Record *R = Regs[i].TheDef;
|
||||||
|
std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("SubRegs");
|
||||||
|
// Process sub-register set and add aliases information.
|
||||||
|
for (unsigned j = 0, e = LI.size(); j != e; ++j) {
|
||||||
|
Record *SubReg = LI[j];
|
||||||
|
if (RegisterSubRegs[R].count(SubReg))
|
||||||
|
cerr << "Warning: register " << getQualifiedName(SubReg)
|
||||||
|
<< " specified as a sub-register of " << getQualifiedName(R)
|
||||||
|
<< " multiple times!\n";
|
||||||
|
addSubReg(R, SubReg, RegisterSubRegs, RegisterAliases, *this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!RegisterAliases.empty())
|
if (!RegisterAliases.empty())
|
||||||
OS << "\n\n // Register Alias Sets...\n";
|
OS << "\n\n // Register Alias Sets...\n";
|
||||||
|
|
||||||
@ -314,12 +350,27 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
OS << "0 };\n";
|
OS << "0 };\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!RegisterSubRegs.empty())
|
||||||
|
OS << "\n\n // Register Sub-registers Sets...\n";
|
||||||
|
|
||||||
|
// Emit the empty sub-registers list
|
||||||
|
OS << " const unsigned Empty_SubRegsSet[] = { 0 };\n";
|
||||||
|
// Loop over all of the registers which have sub-registers, emitting the
|
||||||
|
// sub-registers list to memory.
|
||||||
|
for (std::map<Record*, std::set<Record*> >::iterator
|
||||||
|
I = RegisterSubRegs.begin(), E = RegisterSubRegs.end(); I != E; ++I) {
|
||||||
|
OS << " const unsigned " << I->first->getName() << "_SubRegsSet[] = { ";
|
||||||
|
for (std::set<Record*>::iterator ASI = I->second.begin(),
|
||||||
|
E = I->second.end(); ASI != E; ++ASI)
|
||||||
|
OS << getQualifiedName(*ASI) << ", ";
|
||||||
|
OS << "0 };\n";
|
||||||
|
}
|
||||||
OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
|
OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
|
||||||
OS << " { \"NOREG\",\t0 },\n";
|
OS << " { \"NOREG\",\t0,\t0 },\n";
|
||||||
|
|
||||||
|
|
||||||
// Now that register alias sets have been emitted, emit the register
|
// Now that register alias and sub-registers sets have been emitted, emit the
|
||||||
// descriptors now.
|
// register descriptors now.
|
||||||
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
|
||||||
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
|
||||||
const CodeGenRegister &Reg = Registers[i];
|
const CodeGenRegister &Reg = Registers[i];
|
||||||
@ -330,9 +381,13 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
OS << Reg.getName();
|
OS << Reg.getName();
|
||||||
OS << "\",\t";
|
OS << "\",\t";
|
||||||
if (RegisterAliases.count(Reg.TheDef))
|
if (RegisterAliases.count(Reg.TheDef))
|
||||||
OS << Reg.getName() << "_AliasSet },\n";
|
OS << Reg.getName() << "_AliasSet,\t";
|
||||||
else
|
else
|
||||||
OS << "Empty_AliasSet },\n";
|
OS << "Empty_AliasSet,\t";
|
||||||
|
if (RegisterSubRegs.count(Reg.TheDef))
|
||||||
|
OS << Reg.getName() << "_SubRegsSet },\n";
|
||||||
|
else
|
||||||
|
OS << "Empty_SubRegsSet },\n";
|
||||||
}
|
}
|
||||||
OS << " };\n"; // End of register descriptors...
|
OS << " };\n"; // End of register descriptors...
|
||||||
OS << "}\n\n"; // End of anonymous namespace...
|
OS << "}\n\n"; // End of anonymous namespace...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user