forked from OSchip/llvm-project
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
2b30ecdb77
commit
bb95605448
|
@ -334,9 +334,9 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
|
|||
unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
|
||||
regType = TM.getRegInfo().getRegType(fakeReg);
|
||||
// At least map fakeReg into its class
|
||||
fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
|
||||
if (regClass == UltraSparcRegInfo::FPSingleRegType ||
|
||||
regClass == UltraSparcRegInfo::FPDoubleRegType)
|
||||
// fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
|
||||
if (regType == UltraSparcRegInfo::FPSingleRegType ||
|
||||
regType == UltraSparcRegInfo::FPDoubleRegType)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -344,9 +344,9 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
|
|||
}
|
||||
|
||||
unsigned
|
||||
SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
||||
SparcV9CodeEmitter::getRealRegNumByType(unsigned fakeReg, unsigned regType,
|
||||
MachineInstr &MI) {
|
||||
switch (regClass) {
|
||||
switch (regType) {
|
||||
case UltraSparcRegInfo::IntRegType: {
|
||||
// Sparc manual, p31
|
||||
static const unsigned IntRegMap[] = {
|
||||
|
@ -354,10 +354,8 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||
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",
|
||||
24, 25, 26, 27, 28, 29,
|
||||
// "i6", "i7",
|
||||
30, 31,
|
||||
// "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"
|
||||
|
@ -368,15 +366,17 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||
break;
|
||||
}
|
||||
case UltraSparcRegInfo::FPSingleRegType: {
|
||||
DEBUG(std::cerr << "FP single reg: " << fakeReg << "\n");
|
||||
return fakeReg;
|
||||
}
|
||||
case UltraSparcRegInfo::FPDoubleRegType: {
|
||||
DEBUG(std::cerr << "FP double reg: " << fakeReg << "\n");
|
||||
return fakeReg;
|
||||
}
|
||||
case UltraSparcRegInfo::FloatCCRegType: {
|
||||
/* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
|
||||
DEBUG(std::cerr << "FP CC reg: " << fakeReg << "\n");
|
||||
return fakeReg;
|
||||
|
||||
}
|
||||
case UltraSparcRegInfo::IntCCRegType: {
|
||||
static const unsigned FPInstrIntCCReg[] = { 6 /* xcc */, 4 /* icc */ };
|
||||
|
@ -384,11 +384,13 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
|
|||
|
||||
if (isFPInstr(MI)) {
|
||||
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];
|
||||
} 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];
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
MachineOperand &MO) {
|
||||
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() ||
|
||||
MO.getType() == MachineOperand::MO_CCRegister)
|
||||
{
|
||||
// This is necessary because the Sparc doesn't actually lay out registers
|
||||
// in the real fashion -- it skips those that it chooses not to allocate,
|
||||
// i.e. those that are the SP, etc.
|
||||
unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
|
||||
regType = TM.getRegInfo().getRegType(fakeReg);
|
||||
// This is necessary because the Sparc backend doesn't actually lay out
|
||||
// registers in the real fashion -- it skips those that it chooses not to
|
||||
// allocate, i.e. those that are the FP, SP, etc.
|
||||
unsigned fakeReg = MO.getAllocatedRegNum(), regClass, regType;
|
||||
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
|
||||
fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
|
||||
// Find the real register number for use in an instruction
|
||||
/////realReg = getRealRegNum(fakeReg, regClass, MI);
|
||||
realReg = getRealRegNum(fakeReg, regType, MI);
|
||||
DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] = "
|
||||
<< realReg << "\n");
|
||||
rv = realReg;
|
||||
fakeReg = RI.getClassRegNum(fakeReg, regClass);
|
||||
//realRegByType = getRealRegNumByType(fakeReg, regType, MI);
|
||||
realRegByClass = getRealRegNumByClass(fakeReg, regClass, MI);
|
||||
DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] = by class: "
|
||||
<< realRegByClass << "\n");
|
||||
rv = realRegByClass;
|
||||
} else if (MO.isImmediate()) {
|
||||
rv = MO.getImmedValue();
|
||||
DEBUG(std::cerr << "immed: " << rv << "\n");
|
||||
|
@ -561,8 +620,7 @@ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
|||
{
|
||||
Constant *C = (Constant*)*I;
|
||||
unsigned idx = MCP.getConstantPoolIndex(C);
|
||||
DEBUG(std::cerr << "Mapping constant 0x" << (intptr_t)C << " to "
|
||||
<< idx << "\n");
|
||||
DEBUG(std::cerr << "Constant[" << idx << "] = 0x" << (intptr_t)C << "\n");
|
||||
ConstantMap[C] = idx;
|
||||
}
|
||||
MCE.emitConstantPool(&MCP);
|
||||
|
@ -571,31 +629,24 @@ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
|||
emitBasicBlock(*I);
|
||||
MCE.finishFunction(MF);
|
||||
|
||||
DEBUG(std::cerr << "Finishing function " << MF.getFunction()->getName()
|
||||
<< "\n");
|
||||
DEBUG(std::cerr << "Finishing fn " << MF.getFunction()->getName() << "\n");
|
||||
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
|
||||
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 << "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) {
|
||||
MachineOperand &op = MI->getOperand(ii);
|
||||
if (op.isPCRelativeDisp()) {
|
||||
// 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
|
||||
// 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.
|
||||
bool loBits32=false, hiBits32=false, loBits64=false, hiBits64=false;
|
||||
if (op.opLoBits32()) { loBits32=true; }
|
||||
|
|
|
@ -43,12 +43,14 @@ public:
|
|||
|
||||
private:
|
||||
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* getGlobalAddress(GlobalValue *V, MachineInstr &MI,
|
||||
bool isPCRelative);
|
||||
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);
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue