summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCJITInfo.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-02-25 05:04:13 +0000
committerChris Lattner <sabre@nondot.org>2007-02-25 05:04:13 +0000
commit456bc87e78af18331b9579069a059c723da517d9 (patch)
tree3216ae115c8d1d10a684b0a24cfd3d8b570a9f14 /lib/Target/PowerPC/PPCJITInfo.cpp
parent0f07e55312d4b2be83061b27e8f5cc6bed606a16 (diff)
downloadllvm-456bc87e78af18331b9579069a059c723da517d9.tar.gz
llvm-456bc87e78af18331b9579069a059c723da517d9.tar.bz2
llvm-456bc87e78af18331b9579069a059c723da517d9.tar.xz
Improve JIT support for linux/ppc: Patch by Nicolas Geoffray!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34572 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCJITInfo.cpp')
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
index 02554ff730..a8497fe1c8 100644
--- a/lib/Target/PowerPC/PPCJITInfo.cpp
+++ b/lib/Target/PowerPC/PPCJITInfo.cpp
@@ -134,6 +134,71 @@ asm(
"mtlr r2\n"
"bctr\n"
);
+
+#elif defined(__PPC__) && !defined(__ppc64__)
+// Linux/PPC support
+
+// CompilationCallback stub - We can't use a C function with inline assembly in
+// it, because we the prolog/epilog inserted by GCC won't work for us. Instead,
+// write our own wrapper, which does things our way, so we have complete control
+// over register saving and restoring.
+asm(
+ ".text\n"
+ ".align 2\n"
+ ".globl PPC32CompilationCallback\n"
+"PPC32CompilationCallback:\n"
+ // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the
+ // FIXME: need to save v[0-19] for altivec?
+ // FIXME: could shrink frame
+ // Set up a proper stack frame
+ // FIXME Layout
+ // PowerPC64 ABI linkage - 24 bytes
+ // parameters - 32 bytes
+ // 13 double registers - 104 bytes
+ // 8 int registers - 32 bytes
+ "mflr 0\n"
+ "stw 0, 4(1)\n"
+ "stwu 1, -180(1)\n"
+ // Save all int arg registers
+ "stw 10, 176(1)\n" "stw 9, 172(1)\n"
+ "stw 8, 168(1)\n" "stw 7, 164(1)\n"
+ "stw 6, 160(1)\n" "stw 5, 156(1)\n"
+ "stw 4, 152(1)\n" "stw 3, 148(1)\n"
+ // Save all call-clobbered FP regs.
+ "stfd 10, 144(1)\n"
+ "stfd 9, 136(1)\n" "stfd 8, 128(1)\n"
+ "stfd 7, 120(1)\n" "stfd 6, 112(1)\n"
+ "stfd 5, 104(1)\n" "stfd 4, 96(1)\n"
+ "stfd 3, 88(1)\n" "stfd 2, 80(1)\n"
+ "stfd 1, 72(1)\n"
+ // Arguments to Compilation Callback:
+ // r3 - our lr (address of the call instruction in stub plus 4)
+ // r4 - stub's lr (address of instruction that called the stub plus 4)
+ // r5 - is64Bit - always 0.
+ "mr 3, 0\n"
+ "lwz 11, 180(1)\n" // stub's frame
+ "lwz 4, 4(11)\n" // stub's lr
+ "li 5, 0\n" // 0 == 32 bit
+ "bl PPCCompilationCallbackC\n"
+ "mtctr 3\n"
+ // Restore all int arg registers
+ "lwz 10, 176(1)\n" "lwz 9, 172(1)\n"
+ "lwz 8, 168(1)\n" "lwz 7, 164(1)\n"
+ "lwz 6, 160(1)\n" "lwz 5, 156(1)\n"
+ "lwz 4, 152(1)\n" "lwz 3, 148(1)\n"
+ // Restore all FP arg registers
+ "lfd 10, 144(1)\n"
+ "lfd 9, 136(1)\n" "lfd 8, 128(1)\n"
+ "lfd 7, 120(1)\n" "lfd 6, 112(1)\n"
+ "lfd 5, 104(1)\n" "lfd 4, 96(1)\n"
+ "lfd 3, 88(1)\n" "lfd 2, 80(1)\n"
+ "lfd 1, 72(1)\n"
+ // Pop 3 frames off the stack and branch to target
+ "lwz 1, 184(1)\n"
+ "lwz 11, 4(1)\n"
+ "mtlr 11\n"
+ "bctr\n"
+ );
#else
void PPC32CompilationCallback() {
assert(0 && "This is not a power pc, you can't execute this!");