mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-25 21:16:19 +00:00
parent
6528334ab7
commit
767ee95d29
@ -71,10 +71,17 @@ private:
|
||||
// immediately after the write. i.e. A register
|
||||
// that is defined but never used.
|
||||
|
||||
/// offset - Offset to address of global or external, only valid for
|
||||
/// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
|
||||
int offset;
|
||||
/// 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;
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user