From bb956054482e227b0ece8d9b699c44dd164f37c7 Mon Sep 17 00:00:00 2001 From: Misha Brukman Date: Thu, 3 Jul 2003 18:36:47 +0000 Subject: [PATCH] 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 --- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp | 129 +++++++++++++------ llvm/lib/Target/Sparc/SparcV9CodeEmitter.h | 8 +- 2 files changed, 95 insertions(+), 42 deletions(-) diff --git a/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp b/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp index 619a014b4168..91a8adea1258 100644 --- a/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp +++ b/llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp @@ -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, - MachineInstr &MI) { - switch (regClass) { +SparcV9CodeEmitter::getRealRegNumByType(unsigned fakeReg, unsigned regType, + MachineInstr &MI) { + switch (regType) { case UltraSparcRegInfo::IntRegType: { // Sparc manual, p31 static const unsigned IntRegMap[] = { @@ -354,11 +354,9 @@ 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, - // "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", + // "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 @@ -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; } diff --git a/llvm/lib/Target/Sparc/SparcV9CodeEmitter.h b/llvm/lib/Target/Sparc/SparcV9CodeEmitter.h index d9a03e5b2314..7f11a7b439e4 100644 --- a/llvm/lib/Target/Sparc/SparcV9CodeEmitter.h +++ b/llvm/lib/Target/Sparc/SparcV9CodeEmitter.h @@ -43,13 +43,15 @@ 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, - MachineInstr &MI); + unsigned getRealRegNumByType(unsigned fakeReg, unsigned regType, + MachineInstr &MI); + unsigned getRealRegNumByClass(unsigned fakeReg, unsigned regClass, + MachineInstr &MI); };