/*
- * trampoline.c: JIT trampoline code
+ * tramp-ppc.c: JIT trampoline code for PowerPC
*
* Authors:
* Dietmar Maurer (dietmar@ximian.com)
start = code = g_malloc (20);
- ppc_load (code, ppc_r11, addr);
- ppc_mtctr (code, ppc_r11);
+ ppc_load (code, ppc_r0, addr);
+ ppc_mtctr (code, ppc_r0);
ppc_addi (code, this_pos, this_pos, sizeof (MonoObject));
ppc_bcctr (code, 20, 0);
g_assert ((code - start) <= 20);
}
/* Stack size for trampoline function */
-#define STACK 144
+#define STACK (144 + 8*8)
/* Method-specific trampoline code framgment size */
#define METHOD_TRAMPOLINE_SIZE 64
compiled method */
start = o;
+#if 1
+ /* FIXME: make the patching thread safe */
+ ppc_b (o, 0);
+ ppc_patch (o - 4, addr);
+#else
ppc_stwu (o, ppc_r1, -16, ppc_r1);
ppc_mflr (o, ppc_r0);
ppc_stw (o, ppc_r31, 12, ppc_r1);
ppc_lwz (o, ppc_r31, -4, ppc_r11);
ppc_mr (o, ppc_r1, ppc_r11);
ppc_blr (o);
-
+#endif
mono_arch_flush_icache (start, o - start);
g_assert(o - start < METHOD_TRAMPOLINE_SIZE);
guint8 *buf, *code = NULL;
static guint8* generic_jump_trampoline = NULL;
static guint8 *generic_class_init_trampoline = NULL;
+ int i, offset;
switch (tramp_type) {
case MONO_TRAMPOLINE_GENERIC:
/* Save 'method' pseudo-parameter - the one passed in r11 */
ppc_stw (buf, ppc_r11, STACK - 124, ppc_r1);
+ /* Save the FP registers */
+ offset = 124 + 4 + 8;
+ for (i = ppc_f1; i <= ppc_f8; ++i) {
+ ppc_stfd (buf, i, STACK - offset, ppc_r1);
+ offset += 8;
+ }
+
/*----------------------------------------------------------
STEP 1: call 'mono_get_lmf_addr()' to get the address of our
LMF. We'll need to restore it after the call to
if (tramp_type == MONO_TRAMPOLINE_JUMP) {
ppc_li (buf, ppc_r4, 0);
} else
- ppc_lwz (buf, ppc_r4, STACK + 4, ppc_r1);
+ ppc_lwz (buf, ppc_r4, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
/* Arg 3: stack pointer */
ppc_mr (buf, ppc_r5, ppc_r1);
ppc_lwz (buf, ppc_r9, STACK - 36, ppc_r1);
ppc_lwz (buf, ppc_r10, STACK - 40, ppc_r1);
+ /* Restore the FP registers */
+ offset = 124 + 4 + 8;
+ for (i = ppc_f1; i <= ppc_f8; ++i) {
+ ppc_lfd (buf, i, STACK - offset, ppc_r1);
+ offset += 8;
+ }
/* We haven't touched any of these, so there's no need to
restore them */
/*
/* Non-standard function epilogue. Instead of doing a proper
return, we just call the compiled code, so
that, when it finishes, the method returns here. */
-
+
+#if 1
+ /* Restore stack pointer, r31, LR and jump to the code */
+ ppc_lwz (buf, ppc_r1, 0, ppc_r1);
+ ppc_lwz (buf, ppc_r31, -4, ppc_r1);
+ ppc_lwz (buf, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_r1);
+ ppc_mtlr (buf, ppc_r11);
+ ppc_mtctr (buf, ppc_r0);
+ ppc_bcctr (buf, 20, 0);
+#else
ppc_mtlr (buf, ppc_r0);
ppc_blrl (buf);
ppc_lwz (buf, ppc_r0, 4, ppc_r1);
ppc_mtlr (buf, ppc_r0);
ppc_blr (buf);
+#endif
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (code, buf - code);
the trampoline relies on r11 having the same value it had before coming
here, so we must save it before. */
code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
-
+
/* Save r11. There's nothing magic in the '44', its just an arbitrary
position - see above */
ppc_stw (buf, ppc_r11, -44, ppc_r1);
/* Now save LR - we'll overwrite it now */
ppc_mflr (buf, ppc_r11);
- ppc_stw (buf, ppc_r11, 4, ppc_r1);
- ppc_stw (buf, ppc_r11, 8, ppc_r1);
+ ppc_stw (buf, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_r1);
/* Prepare the jump to the generic trampoline code.*/
ppc_lis (buf, ppc_r11, (guint32) vc >> 16);