mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Apparently, the "regType" and "regClass" used in the Sparc backend are not both
correct: empirically, "regType" is wrong for a number of registers. Thus, one can only rely on the "regClass" to figure out what kind of register one is dealing with. This change switches to using only "regClass" and adds a few extra DEBUG() print statements and a few clean-ups in comments and code, mostly minor. llvm-svn: 7103
This commit is contained in:
parent
b1a109f9e9
commit
20fcdbc808
@ -334,9 +334,9 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
|
|||||||
unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
|
unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
|
||||||
regType = TM.getRegInfo().getRegType(fakeReg);
|
regType = TM.getRegInfo().getRegType(fakeReg);
|
||||||
// At least map fakeReg into its class
|
// At least map fakeReg into its class
|
||||||
fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
|
// fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
|
||||||
if (regClass == UltraSparcRegInfo::FPSingleRegType ||
|
if (regType == UltraSparcRegInfo::FPSingleRegType ||
|
||||||
regClass == UltraSparcRegInfo::FPDoubleRegType)
|
regType == UltraSparcRegInfo::FPDoubleRegType)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,9 +344,9 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
SparcV9CodeEmitter::getRealRegNumByType(unsigned fakeReg, unsigned regType,
|
||||||
MachineInstr &MI) {
|
MachineInstr &MI) {
|
||||||
switch (regClass) {
|
switch (regType) {
|
||||||
case UltraSparcRegInfo::IntRegType: {
|
case UltraSparcRegInfo::IntRegType: {
|
||||||
// Sparc manual, p31
|
// Sparc manual, p31
|
||||||
static const unsigned IntRegMap[] = {
|
static const unsigned IntRegMap[] = {
|
||||||
@ -354,10 +354,8 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||||||
8, 9, 10, 11, 12, 13, 15,
|
8, 9, 10, 11, 12, 13, 15,
|
||||||
// "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
// "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
||||||
16, 17, 18, 19, 20, 21, 22, 23,
|
16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
// "i0", "i1", "i2", "i3", "i4", "i5",
|
// "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
|
||||||
24, 25, 26, 27, 28, 29,
|
24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
// "i6", "i7",
|
|
||||||
30, 31,
|
|
||||||
// "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
// "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
||||||
0, 1, 2, 3, 4, 5, 6, 7,
|
0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
// "o6"
|
// "o6"
|
||||||
@ -368,15 +366,17 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UltraSparcRegInfo::FPSingleRegType: {
|
case UltraSparcRegInfo::FPSingleRegType: {
|
||||||
|
DEBUG(std::cerr << "FP single reg: " << fakeReg << "\n");
|
||||||
return fakeReg;
|
return fakeReg;
|
||||||
}
|
}
|
||||||
case UltraSparcRegInfo::FPDoubleRegType: {
|
case UltraSparcRegInfo::FPDoubleRegType: {
|
||||||
|
DEBUG(std::cerr << "FP double reg: " << fakeReg << "\n");
|
||||||
return fakeReg;
|
return fakeReg;
|
||||||
}
|
}
|
||||||
case UltraSparcRegInfo::FloatCCRegType: {
|
case UltraSparcRegInfo::FloatCCRegType: {
|
||||||
/* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
|
/* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
|
||||||
|
DEBUG(std::cerr << "FP CC reg: " << fakeReg << "\n");
|
||||||
return fakeReg;
|
return fakeReg;
|
||||||
|
|
||||||
}
|
}
|
||||||
case UltraSparcRegInfo::IntCCRegType: {
|
case UltraSparcRegInfo::IntCCRegType: {
|
||||||
static const unsigned FPInstrIntCCReg[] = { 6 /* xcc */, 4 /* icc */ };
|
static const unsigned FPInstrIntCCReg[] = { 6 /* xcc */, 4 /* icc */ };
|
||||||
@ -384,11 +384,13 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||||||
|
|
||||||
if (isFPInstr(MI)) {
|
if (isFPInstr(MI)) {
|
||||||
assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
|
assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
|
||||||
&& "Int CC register out of bounds for FPInstr IntCCReg map");
|
&& "FP CC register out of bounds for FPInstr IntCCReg map");
|
||||||
|
DEBUG(std::cerr << "FP instr, IntCC reg: " << FPInstrIntCCReg[fakeReg] << "\n");
|
||||||
return FPInstrIntCCReg[fakeReg];
|
return FPInstrIntCCReg[fakeReg];
|
||||||
} else {
|
} else {
|
||||||
assert(fakeReg < sizeof(IntInstrIntCCReg)/sizeof(IntInstrIntCCReg[0])
|
assert(fakeReg < sizeof(IntInstrIntCCReg)/sizeof(IntInstrIntCCReg[0])
|
||||||
&& "Int CC register out of bounds for IntInstr IntCCReg map");
|
&& "Int CC register out of bounds for IntInstr IntCCReg map");
|
||||||
|
DEBUG(std::cerr << "FP instr, IntCC reg: " << IntInstrIntCCReg[fakeReg] << "\n");
|
||||||
return IntInstrIntCCReg[fakeReg];
|
return IntInstrIntCCReg[fakeReg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,6 +400,60 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
SparcV9CodeEmitter::getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
|
||||||
|
MachineInstr &MI) {
|
||||||
|
switch (regClass) {
|
||||||
|
case UltraSparcRegInfo::IntRegClassID: {
|
||||||
|
// Sparc manual, p31
|
||||||
|
static const unsigned IntRegMap[] = {
|
||||||
|
// "o0", "o1", "o2", "o3", "o4", "o5", "o7",
|
||||||
|
8, 9, 10, 11, 12, 13, 15,
|
||||||
|
// "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
|
// "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
|
||||||
|
24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
// "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
|
// "o6"
|
||||||
|
14
|
||||||
|
};
|
||||||
|
|
||||||
|
return IntRegMap[fakeReg];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UltraSparcRegInfo::FloatRegClassID: {
|
||||||
|
DEBUG(std::cerr << "FP reg: " << fakeReg << "\n");
|
||||||
|
return fakeReg;
|
||||||
|
}
|
||||||
|
case UltraSparcRegInfo::IntCCRegClassID: {
|
||||||
|
static const unsigned FPInstrIntCCReg[] = { 6 /* xcc */, 4 /* icc */ };
|
||||||
|
static const unsigned IntInstrIntCCReg[] = { 2 /* xcc */, 0 /* icc */ };
|
||||||
|
|
||||||
|
if (isFPInstr(MI)) {
|
||||||
|
assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
|
||||||
|
&& "FP CC register out of bounds for FPInstr IntCCReg map");
|
||||||
|
DEBUG(std::cerr << "FP instr, IntCC reg: " << FPInstrIntCCReg[fakeReg] << "\n");
|
||||||
|
return FPInstrIntCCReg[fakeReg];
|
||||||
|
} else {
|
||||||
|
assert(fakeReg < sizeof(IntInstrIntCCReg)/sizeof(IntInstrIntCCReg[0])
|
||||||
|
&& "Int CC register out of bounds for IntInstr IntCCReg map");
|
||||||
|
DEBUG(std::cerr << "FP instr, IntCC reg: " << IntInstrIntCCReg[fakeReg] << "\n");
|
||||||
|
return IntInstrIntCCReg[fakeReg];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case UltraSparcRegInfo::FloatCCRegClassID: {
|
||||||
|
/* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
|
||||||
|
DEBUG(std::cerr << "FP CC reg: " << fakeReg << "\n");
|
||||||
|
return fakeReg;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(0 && "Invalid unified register number in getRegType");
|
||||||
|
return fakeReg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
|
int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
|
||||||
MachineOperand &MO) {
|
MachineOperand &MO) {
|
||||||
int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
|
int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
|
||||||
@ -477,19 +533,22 @@ int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
|
|||||||
} else if (MO.isPhysicalRegister() ||
|
} else if (MO.isPhysicalRegister() ||
|
||||||
MO.getType() == MachineOperand::MO_CCRegister)
|
MO.getType() == MachineOperand::MO_CCRegister)
|
||||||
{
|
{
|
||||||
// This is necessary because the Sparc doesn't actually lay out registers
|
// This is necessary because the Sparc backend doesn't actually lay out
|
||||||
// in the real fashion -- it skips those that it chooses not to allocate,
|
// registers in the real fashion -- it skips those that it chooses not to
|
||||||
// i.e. those that are the SP, etc.
|
// allocate, i.e. those that are the FP, SP, etc.
|
||||||
unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
|
unsigned fakeReg = MO.getAllocatedRegNum(), regClass, regType;
|
||||||
regType = TM.getRegInfo().getRegType(fakeReg);
|
unsigned realRegByClass; //realRegByType,
|
||||||
|
const TargetRegInfo &RI = TM.getRegInfo();
|
||||||
|
DEBUG(std::cerr << std::dec << "LLC: " << fakeReg << " => "
|
||||||
|
<< RI.getUnifiedRegName(fakeReg) << "\n");
|
||||||
|
regType = RI.getRegType(fakeReg);
|
||||||
// At least map fakeReg into its class
|
// At least map fakeReg into its class
|
||||||
fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
|
fakeReg = RI.getClassRegNum(fakeReg, regClass);
|
||||||
// Find the real register number for use in an instruction
|
//realRegByType = getRealRegNumByType(fakeReg, regType, MI);
|
||||||
/////realReg = getRealRegNum(fakeReg, regClass, MI);
|
realRegByClass = getRealRegNumByClass(fakeReg, regClass, MI);
|
||||||
realReg = getRealRegNum(fakeReg, regType, MI);
|
DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] = by class: "
|
||||||
DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] = "
|
<< realRegByClass << "\n");
|
||||||
<< realReg << "\n");
|
rv = realRegByClass;
|
||||||
rv = realReg;
|
|
||||||
} else if (MO.isImmediate()) {
|
} else if (MO.isImmediate()) {
|
||||||
rv = MO.getImmedValue();
|
rv = MO.getImmedValue();
|
||||||
DEBUG(std::cerr << "immed: " << rv << "\n");
|
DEBUG(std::cerr << "immed: " << rv << "\n");
|
||||||
@ -561,8 +620,7 @@ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
{
|
{
|
||||||
Constant *C = (Constant*)*I;
|
Constant *C = (Constant*)*I;
|
||||||
unsigned idx = MCP.getConstantPoolIndex(C);
|
unsigned idx = MCP.getConstantPoolIndex(C);
|
||||||
DEBUG(std::cerr << "Mapping constant 0x" << (intptr_t)C << " to "
|
DEBUG(std::cerr << "Constant[" << idx << "] = 0x" << (intptr_t)C << "\n");
|
||||||
<< idx << "\n");
|
|
||||||
ConstantMap[C] = idx;
|
ConstantMap[C] = idx;
|
||||||
}
|
}
|
||||||
MCE.emitConstantPool(&MCP);
|
MCE.emitConstantPool(&MCP);
|
||||||
@ -571,31 +629,24 @@ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
emitBasicBlock(*I);
|
emitBasicBlock(*I);
|
||||||
MCE.finishFunction(MF);
|
MCE.finishFunction(MF);
|
||||||
|
|
||||||
DEBUG(std::cerr << "Finishing function " << MF.getFunction()->getName()
|
DEBUG(std::cerr << "Finishing fn " << MF.getFunction()->getName() << "\n");
|
||||||
<< "\n");
|
|
||||||
ConstantMap.clear();
|
ConstantMap.clear();
|
||||||
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
|
|
||||||
long Location = BBLocations[BBRefs[i].first];
|
|
||||||
unsigned *Ref = BBRefs[i].second.first;
|
|
||||||
MachineInstr *MI = BBRefs[i].second.second;
|
|
||||||
DEBUG(std::cerr << "Fixup @" << std::hex << Ref << " to " << Location
|
|
||||||
<< " in instr: " << std::dec << *MI << "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve branches to BasicBlocks for the entire function
|
// Resolve branches to BasicBlocks for the entire function
|
||||||
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
|
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
|
||||||
long Location = BBLocations[BBRefs[i].first];
|
long Location = BBLocations[BBRefs[i].first];
|
||||||
unsigned *Ref = BBRefs[i].second.first;
|
unsigned *Ref = BBRefs[i].second.first;
|
||||||
MachineInstr *MI = BBRefs[i].second.second;
|
MachineInstr *MI = BBRefs[i].second.second;
|
||||||
DEBUG(std::cerr << "attempting to resolve BB: " << i << "\n");
|
DEBUG(std::cerr << "Fixup @ " << std::hex << Ref << " to 0x" << Location
|
||||||
|
<< " in instr: " << std::dec << *MI);
|
||||||
for (unsigned ii = 0, ee = MI->getNumOperands(); ii != ee; ++ii) {
|
for (unsigned ii = 0, ee = MI->getNumOperands(); ii != ee; ++ii) {
|
||||||
MachineOperand &op = MI->getOperand(ii);
|
MachineOperand &op = MI->getOperand(ii);
|
||||||
if (op.isPCRelativeDisp()) {
|
if (op.isPCRelativeDisp()) {
|
||||||
// the instruction's branch target is made such that it branches to
|
// the instruction's branch target is made such that it branches to
|
||||||
// PC + (br target * 4), so undo that arithmetic here:
|
// PC + (branchTarget * 4), so undo that arithmetic here:
|
||||||
// Location is the target of the branch
|
// Location is the target of the branch
|
||||||
// Ref is the location of the instruction, and hence the PC
|
// Ref is the location of the instruction, and hence the PC
|
||||||
unsigned branchTarget = (Location - (long)Ref) >> 2;
|
int64_t branchTarget = (Location - (long)Ref) >> 2;
|
||||||
// Save the flags.
|
// Save the flags.
|
||||||
bool loBits32=false, hiBits32=false, loBits64=false, hiBits64=false;
|
bool loBits32=false, hiBits32=false, loBits64=false, hiBits64=false;
|
||||||
if (op.opLoBits32()) { loBits32=true; }
|
if (op.opLoBits32()) { loBits32=true; }
|
||||||
|
@ -43,12 +43,14 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
|
int64_t getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
|
||||||
unsigned getValueBit(int64_t Val, unsigned bit);
|
inline unsigned getValueBit(int64_t Val, unsigned bit);
|
||||||
void emitBasicBlock(MachineBasicBlock &MBB);
|
void emitBasicBlock(MachineBasicBlock &MBB);
|
||||||
void* getGlobalAddress(GlobalValue *V, MachineInstr &MI,
|
void* getGlobalAddress(GlobalValue *V, MachineInstr &MI,
|
||||||
bool isPCRelative);
|
bool isPCRelative);
|
||||||
bool isFPInstr(MachineInstr &MI);
|
bool isFPInstr(MachineInstr &MI);
|
||||||
unsigned getRealRegNum(unsigned fakeReg, unsigned regClass,
|
unsigned getRealRegNumByType(unsigned fakeReg, unsigned regType,
|
||||||
|
MachineInstr &MI);
|
||||||
|
unsigned getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
|
||||||
MachineInstr &MI);
|
MachineInstr &MI);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user