aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-11-23 06:55:05 +0000
committerChris Lattner <sabre@nondot.org>2004-11-23 06:55:05 +0000
commite61198b3233f0c46900ced6d856534b11bd3d9f2 (patch)
tree74f09bd7a6564c159a682f01c234133ce45f889a
parent4fa5fa8f61a9fe00c8b0880087d305736e207c47 (diff)
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
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp64
1 files changed, 54 insertions, 10 deletions
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
index 9bae398ecf..01d9366ce7 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.