- if (MO.isPhysicalRegister()) {
- // 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);
- // 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);
- std::cerr << "Reg[" << fakeReg << "] = " << realReg << "\n";
- return realReg;
+ int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
+ // or things that get fixed up later by the JIT.
+ if (MO.isPCRelativeDisp() || MO.isGlobalAddress()) {
+ DEBUG(std::cerr << "PCRelativeDisp: ");
+ Value *V = MO.getVRegValue();
+ if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
+ DEBUG(std::cerr << "Saving reference to BB (VReg)\n");
+ unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
+ BBRefs.push_back(std::make_pair(BB, std::make_pair(CurrPC, &MI)));
+ } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
+ // The real target of the branch is CI = PC + (rv * 4)
+ // So undo that: give the instruction (CI - PC) / 4
+ rv = (CI->getRawValue() - MCE.getCurrentPCValue()) / 4;
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ unsigned Reloc = 0;
+ if (MI.getOpcode() == V9::CALL) {
+ Reloc = V9::reloc_pcrel_call;
+ } else if (MI.getOpcode() == V9::SETHI) {
+ if (MO.isHiBits64())
+ Reloc = V9::reloc_sethi_hh;
+ else if (MO.isHiBits32())
+ Reloc = V9::reloc_sethi_lm;
+ else
+ assert(0 && "Unknown relocation!");
+ } else if (MI.getOpcode() == V9::ORi) {
+ if (MO.isLoBits32())
+ Reloc = V9::reloc_or_lo;
+ else if (MO.isLoBits64())
+ Reloc = V9::reloc_or_hm;
+ else
+ assert(0 && "Unknown relocation!");
+ } else {
+ assert(0 && "Unknown relocation!");
+ }
+
+ MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), Reloc, GV));
+ rv = 0;
+ } else {
+ std::cerr << "ERROR: PC relative disp unhandled:" << MO << "\n";
+ abort();
+ }
+ } else if (MO.isRegister() || MO.getType() == MachineOperand::MO_CCRegister)
+ {
+ // This is necessary because the SparcV9 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.getReg();
+ unsigned realRegByClass = getRealRegNum(fakeReg, MI);
+ DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] => "
+ << realRegByClass << " (LLC: "
+ << TM.getRegInfo()->getUnifiedRegName(fakeReg) << ")\n");
+ rv = realRegByClass;