mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
* Added support for the %ccr register
* FP double registers are now coded correctly * Removed function which converted registers based on register types, it was broken (because regTypes are broken) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7175 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1ba3138cdc
commit
173e250548
@ -344,65 +344,13 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
SparcV9CodeEmitter::getRealRegNumByType(unsigned fakeReg, unsigned regType,
|
SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg,
|
||||||
MachineInstr &MI) {
|
MachineInstr &MI) {
|
||||||
switch (regType) {
|
const TargetRegInfo &RI = TM.getRegInfo();
|
||||||
case UltraSparcRegInfo::IntRegType: {
|
unsigned regClass, regType = RI.getRegType(fakeReg);
|
||||||
// Sparc manual, p31
|
// At least map fakeReg into its class
|
||||||
static const unsigned IntRegMap[] = {
|
fakeReg = RI.getClassRegNum(fakeReg, regClass);
|
||||||
// "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::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 */ };
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
assert(0 && "Invalid unified register number in getRegType");
|
|
||||||
return fakeReg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned
|
|
||||||
SparcV9CodeEmitter::getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
|
|
||||||
MachineInstr &MI) {
|
|
||||||
switch (regClass) {
|
switch (regClass) {
|
||||||
case UltraSparcRegInfo::IntRegClassID: {
|
case UltraSparcRegInfo::IntRegClassID: {
|
||||||
// Sparc manual, p31
|
// Sparc manual, p31
|
||||||
@ -424,11 +372,23 @@ SparcV9CodeEmitter::getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
|
|||||||
}
|
}
|
||||||
case UltraSparcRegInfo::FloatRegClassID: {
|
case UltraSparcRegInfo::FloatRegClassID: {
|
||||||
DEBUG(std::cerr << "FP reg: " << fakeReg << "\n");
|
DEBUG(std::cerr << "FP reg: " << fakeReg << "\n");
|
||||||
|
if (regType == UltraSparcRegInfo::FPSingleRegType) {
|
||||||
|
// only numbered 0-31, hence can already fit into 5 bits (and 6)
|
||||||
|
DEBUG(std::cerr << "FP single reg, returning: " << fakeReg << "\n");
|
||||||
|
} else if (regType == UltraSparcRegInfo::FPDoubleRegType) {
|
||||||
|
// FIXME: This assumes that we only have 5-bit register fiels!
|
||||||
|
// From Sparc Manual, page 40.
|
||||||
|
// The bit layout becomes: b[4], b[3], b[2], b[1], b[5]
|
||||||
|
fakeReg |= (fakeReg >> 5) & 1;
|
||||||
|
fakeReg &= 0x1f;
|
||||||
|
DEBUG(std::cerr << "FP double reg, returning: " << fakeReg << "\n");
|
||||||
|
}
|
||||||
return fakeReg;
|
return fakeReg;
|
||||||
}
|
}
|
||||||
case UltraSparcRegInfo::IntCCRegClassID: {
|
case UltraSparcRegInfo::IntCCRegClassID: {
|
||||||
static const unsigned FPInstrIntCCReg[] = { 6 /* xcc */, 4 /* icc */ };
|
/* xcc, icc, ccr */
|
||||||
static const unsigned IntInstrIntCCReg[] = { 2 /* xcc */, 0 /* icc */ };
|
static const unsigned FPInstrIntCCReg[] = { 6, 4, 2 };
|
||||||
|
static const unsigned IntInstrIntCCReg[] = { 2, 0, 2 };
|
||||||
|
|
||||||
if (isFPInstr(MI)) {
|
if (isFPInstr(MI)) {
|
||||||
assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
|
assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
|
||||||
@ -536,17 +496,9 @@ int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
|
|||||||
// This is necessary because the Sparc backend doesn't actually lay out
|
// 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
|
// registers in the real fashion -- it skips those that it chooses not to
|
||||||
// allocate, i.e. those that are the FP, SP, etc.
|
// allocate, i.e. those that are the FP, SP, etc.
|
||||||
unsigned fakeReg = MO.getAllocatedRegNum(), regClass, regType;
|
unsigned fakeReg = MO.getAllocatedRegNum();
|
||||||
unsigned realRegByClass; //realRegByType,
|
unsigned realRegByClass = getRealRegNum(fakeReg, MI);
|
||||||
const TargetRegInfo &RI = TM.getRegInfo();
|
DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] => "
|
||||||
DEBUG(std::cerr << std::dec << "LLC: " << fakeReg << " => "
|
|
||||||
<< RI.getUnifiedRegName(fakeReg) << "\n");
|
|
||||||
regType = RI.getRegType(fakeReg);
|
|
||||||
// At least map fakeReg into its class
|
|
||||||
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");
|
<< realRegByClass << "\n");
|
||||||
rv = realRegByClass;
|
rv = realRegByClass;
|
||||||
} else if (MO.isImmediate()) {
|
} else if (MO.isImmediate()) {
|
||||||
@ -719,4 +671,3 @@ void* SparcV9CodeEmitter::getGlobalAddress(GlobalValue *V, MachineInstr &MI,
|
|||||||
|
|
||||||
|
|
||||||
#include "SparcV9CodeEmitter.inc"
|
#include "SparcV9CodeEmitter.inc"
|
||||||
|
|
||||||
|
@ -48,11 +48,7 @@ private:
|
|||||||
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 getRealRegNumByType(unsigned fakeReg, unsigned regType,
|
unsigned getRealRegNum(unsigned fakeReg, MachineInstr &MI);
|
||||||
MachineInstr &MI);
|
|
||||||
unsigned getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
|
|
||||||
MachineInstr &MI);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user