diff options
author | Misha Brukman <brukman+llvm@gmail.com> | 2003-07-29 19:00:58 +0000 |
---|---|---|
committer | Misha Brukman <brukman+llvm@gmail.com> | 2003-07-29 19:00:58 +0000 |
commit | a1f1fea10511d811e45dc1ac1749a18931506494 (patch) | |
tree | 9dd40ae232bbefb3c1daa9a18ccbc7db96aebbd4 /lib/Target | |
parent | 89e8be00c5f410d2238d9ad771831684a2b3a314 (diff) | |
download | external_llvm-a1f1fea10511d811e45dc1ac1749a18931506494.zip external_llvm-a1f1fea10511d811e45dc1ac1749a18931506494.tar.gz external_llvm-a1f1fea10511d811e45dc1ac1749a18931506494.tar.bz2 |
* Correctly emit a far call if the target address does not fit into 30 bits
instead of assert()ing
* Fixed a nasty bug where '07' was used instead of register 'o7'
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7382 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/SparcV9/SparcV9CodeEmitter.cpp | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/lib/Target/SparcV9/SparcV9CodeEmitter.cpp b/lib/Target/SparcV9/SparcV9CodeEmitter.cpp index c82d33d..eab4835 100644 --- a/lib/Target/SparcV9/SparcV9CodeEmitter.cpp +++ b/lib/Target/SparcV9/SparcV9CodeEmitter.cpp @@ -286,22 +286,20 @@ uint64_t JITResolver::emitStubForFunction(Function *F) { int64_t CurrPC = MCE.getCurrentPCValue(); int64_t Addr = (int64_t)addFunctionReference(CurrPC, F); - int64_t CallTarget = (Addr-CurrPC) >> 2; if (CallTarget >= (1 << 30) || CallTarget <= -(1 << 30)) { - std::cerr << "Call target beyond 30 bit limit of CALL: " - << CallTarget << "\n"; - abort(); - } - // call CallTarget ;; invoke the callback - MachineInstr *Call = BuildMI(V9::CALL, 1).addSImm(CallTarget); - SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Call)); - delete Call; + SparcV9.emitFarCall(Addr); + } else { + // call CallTarget ;; invoke the callback + MachineInstr *Call = BuildMI(V9::CALL, 1).addSImm(CallTarget); + SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Call)); + delete Call; - // nop ;; call delay slot - MachineInstr *Nop = BuildMI(V9::NOP, 0); - SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Nop)); - delete Nop; + // nop ;; call delay slot + MachineInstr *Nop = BuildMI(V9::NOP, 0); + SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Nop)); + delete Nop; + } SparcV9.emitWord(0xDEADBEEF); // marker so that we know it's really a stub return (intptr_t)MCE.finishFunctionStub(*F); @@ -394,8 +392,8 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, // being accounted for, and the behavior will be incorrect!! inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target) { static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2, - i7 = SparcIntRegClass::i7, - o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0; + i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6, + o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0; // // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2 @@ -451,8 +449,8 @@ inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target) { emitWord(getBinaryCodeForInstr(*LDX)); delete LDX; - // jmpl %i2, %g0, %07 ;; indirect call on %i2 - MachineInstr *J = BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(07); + // jmpl %i2, %g0, %o7 ;; indirect call on %i2 + MachineInstr *J = BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(o7); emitWord(getBinaryCodeForInstr(*J)); delete J; |