summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCJITInfo.cpp
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 /lib/Target/PowerPC/PPCJITInfo.cpp
parent4fa5fa8f61a9fe00c8b0880087d305736e207c47 (diff)
downloadllvm-e61198b3233f0c46900ced6d856534b11bd3d9f2.tar.gz
llvm-e61198b3233f0c46900ced6d856534b11bd3d9f2.tar.bz2
llvm-e61198b3233f0c46900ced6d856534b11bd3d9f2.tar.xz
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.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.