diff options
author | Chris Lattner <sabre@nondot.org> | 2004-11-23 06:55:05 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-11-23 06:55:05 +0000 |
commit | e61198b3233f0c46900ced6d856534b11bd3d9f2 (patch) | |
tree | 74f09bd7a6564c159a682f01c234133ce45f889a /lib/Target/PowerPC/PPCJITInfo.cpp | |
parent | 4fa5fa8f61a9fe00c8b0880087d305736e207c47 (diff) | |
download | external_llvm-e61198b3233f0c46900ced6d856534b11bd3d9f2.zip external_llvm-e61198b3233f0c46900ced6d856534b11bd3d9f2.tar.gz external_llvm-e61198b3233f0c46900ced6d856534b11bd3d9f2.tar.bz2 |
Implement the first hunk of CompilationCallback. The pieces missing are the
ones noted, which require funny PPC specific inline assembly.
If some angel felt the desire to help me, I think this is that last bit missing
for JIT support (however, generic code emitter might night work right with
the constant pool yet).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18151 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCJITInfo.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCJITInfo.cpp | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp index 9bae398..01d9366 100644 --- a/lib/Target/PowerPC/PPCJITInfo.cpp +++ b/lib/Target/PowerPC/PPCJITInfo.cpp @@ -34,16 +34,6 @@ static TargetJITInfo::JITCompilerFn JITCompilerFunction; #define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9) #define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK) -static void CompilationCallback() { - //JITCompilerFunction - assert(0 && "CompilationCallback not implemented yet!"); -} - - -TargetJITInfo::LazyResolverFn -PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) { - return CompilationCallback; -} static void EmitBranchToAt(void *At, void *To, bool isCall) { intptr_t Addr = (intptr_t)To; @@ -57,6 +47,60 @@ static void EmitBranchToAt(void *At, void *To, bool isCall) { AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl } +static void CompilationCallback() { + // FIXME: Should save R3-R10 and F1-F13 onto the stack, just like the Sparc + // version does. + //int IntRegs[8]; + //uint64_t FPRegs[13]; + unsigned *CameFromStub = (unsigned*)__builtin_return_address(0); + unsigned *CameFromOrig = (unsigned*)__builtin_return_address(1); + + // Adjust our pointers to the branches, not the return addresses. + --CameFromStub; --CameFromOrig; + + void *Target = JITCompilerFunction(CameFromStub); + + // Check to see if CameFromOrig[-1] is a 'bl' instruction, and if we can + // rewrite it to branch directly to the destination. If so, rewrite it so it + // does not need to go through the stub anymore. + unsigned CameFromOrigInst = *CameFromOrig; + if ((CameFromOrigInst >> 26) == 18) { // Direct call. + intptr_t Offset = ((intptr_t)Target-(intptr_t)CameFromOrig) >> 2; + if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? + // FIXME: hasn't been tested at all. + // Clear the original target out: + CameFromOrigInst &= (63 << 26) | 3; + CameFromOrigInst |= Offset << 2; + *CameFromOrig = CameFromOrigInst; + } + } + + // Locate the start of the stub. If this is a short call, adjust backwards + // the short amount, otherwise the full amount. + bool isShortStub = (*CameFromStub >> 26) == 18; + CameFromStub -= isShortStub ? 3 : 7; + + // Rewrite the stub with an unconditional branch to the target, for any users + // who took the address of the stub. + EmitBranchToAt(CameFromStub, Target, false); + + + // FIXME: Need to restore the registers from IntRegs/FPRegs. + + // FIXME: Need to pop two frames off of the stack and return to a place where + // we magically reexecute the call, or jump directly to the caller. This + // requires inline asm majik. + assert(0 && "CompilationCallback not finished yet!"); +} + + + +TargetJITInfo::LazyResolverFn +PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) { + JITCompilerFunction = Fn; + return CompilationCallback; +} + void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { // If this is just a call to an external function, emit a branch instead of a // call. The code is the same except for one bit of the last instruction. |