2 * tramp-ppc.c: JIT trampoline code for PowerPC
5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Carlos Valiente <yo@virutass.net>
9 * (C) 2001 Ximian, Inc.
15 #include <mono/metadata/appdomain.h>
16 #include <mono/metadata/marshal.h>
17 #include <mono/metadata/tabledefs.h>
18 #include <mono/arch/ppc/ppc-codegen.h>
24 * get_unbox_trampoline:
26 * @addr: pointer to native code for @m
28 * when value type methods are called through the vtable we need to unbox the
29 * this argument. This method returns a pointer to a trampoline which does
30 * unboxing before calling the method
33 get_unbox_trampoline (MonoMethod *m, gpointer addr)
38 if (!mono_method_signature (m)->ret->byref && MONO_TYPE_ISSTRUCT (mono_method_signature (m)->ret))
41 start = code = g_malloc (20);
43 ppc_load (code, ppc_r0, addr);
44 ppc_mtctr (code, ppc_r0);
45 ppc_addi (code, this_pos, this_pos, sizeof (MonoObject));
46 ppc_bcctr (code, 20, 0);
47 mono_arch_flush_icache (start, code - start);
48 g_assert ((code - start) <= 20);
49 /*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
50 g_print ("unbox code is at %p for method at %p\n", start, addr);*/
55 /* Stack size for trampoline function
56 * PPC_MINIMAL_STACK_SIZE + 16 (args + alignment to ppc_magic_trampoline)
57 * + MonoLMF + 14 fp regs + 13 gregs + alignment
58 * #define STACK (PPC_MINIMAL_STACK_SIZE + 4 * sizeof (gulong) + sizeof (MonoLMF) + 14 * sizeof (double) + 13 * (sizeof (gulong)))
59 * STACK would be 444 for 32 bit darwin
63 /* Method-specific trampoline code fragment size */
64 #define METHOD_TRAMPOLINE_SIZE 64
66 /* Jump-specific trampoline code fragment size */
67 #define JUMP_TRAMPOLINE_SIZE 64
70 * ppc_magic_trampoline:
71 * @code: pointer into caller code
72 * @method: the method to translate
75 * This method is called by the function 'arch_create_jit_trampoline', which in
76 * turn is called by the trampoline functions for virtual methods.
77 * After having called the JIT compiler to compile the method, it inspects the
78 * caller code to find the address of the method-specific part of the
79 * trampoline vtable slot for this method, updates it with a fragment that calls
80 * the newly compiled code and returns this address of the compiled code to
81 * 'arch_create_jit_trampoline'
84 ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
88 MonoJitInfo *ji, *target_ji;
91 addr = mono_compile_method(method);
92 /*g_print ("method code at %p for %s:%s\n", addr, method->klass->name, method->name);*/
99 /* We can't trampoline across domains */
100 ji = mono_jit_info_table_find (mono_domain_get (), code);
101 target_ji = mono_jit_info_table_find (mono_domain_get (), addr);
102 if (!mono_method_same_domain (ji, target_ji))
105 /* Locate the address of the method-specific trampoline. The call using
106 the vtable slot that took the processing flow to 'arch_create_jit_trampoline'
107 looks something like this:
109 mtlr rA ; Move rA (a register containing the
110 ; target address) to LR
111 blrl ; Call function at LR
113 PowerPC instructions are 32-bit long, which means that a 32-bit target
114 address cannot be encoded as an immediate value (because we already
115 have spent some bits to encode the branch instruction!). That's why a
116 'b'ranch to the contents of the 'l'ink 'r'egister (with 'l'ink register
117 update) is needed, instead of a simpler 'branch immediate'. This
118 complicates our purpose here, because 'blrl' overwrites LR, which holds
119 the value we're interested in.
121 Therefore, we need to locate the 'mtlr rA' instruction to know which
122 register LR was loaded from, and then retrieve the value from that
125 /* This is the 'blrl' instruction */
129 * Note that methods are called also with the bl opcode.
131 if (((*code) >> 26) == 18) {
132 /*g_print ("direct patching\n");*/
133 ppc_patch ((char*)code, addr);
134 mono_arch_flush_icache ((char*)code, 4);
138 /* Sanity check: instruction must be 'blrl' */
139 g_assert(*code == 0x4e800021);
141 /* the thunk-less direct call sequence: lis/ori/mtlr/blrl */
142 if ((code [-1] >> 26) == 31 && (code [-2] >> 26) == 24 && (code [-3] >> 26) == 15) {
143 ppc_patch ((char*)code, addr);
147 /* OK, we're now at the 'blrl' instruction. Now walk backwards
148 till we get to a 'mtlr rA' */
150 if((*code & 0x7c0803a6) == 0x7c0803a6) {
153 /* Here we are: we reached the 'mtlr rA'.
154 Extract the register from the instruction */
155 reg = (*code & 0x03e00000) >> 21;
157 /* ok, this is a lwz reg, offset (vtreg)
158 * it is emitted with:
159 * ppc_emit32 (c, (32 << 26) | ((D) << 21) | ((a) << 16) | (guint16)(d))
161 soff = (*code & 0xffff);
163 reg = (*code >> 16) & 0x1f;
164 g_assert (reg != ppc_r1);
165 /*g_print ("patching reg is %d\n", reg);*/
167 /* saved in the MonoLMF structure */
168 reg_offset = STACK - sizeof (MonoLMF) + G_STRUCT_OFFSET (MonoLMF, iregs);
169 reg_offset += (reg - 13) * sizeof (gulong);
171 /* saved in the stack, see frame diagram below */
172 reg_offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double)) - (13 * sizeof (gulong));
173 reg_offset += reg * sizeof (gulong);
175 /* o contains now the value of register reg */
176 o = *((char**) (sp + reg_offset));
181 /* this is not done for non-virtual calls, because in that case
182 we won't have an object, but the actual pointer to the
183 valuetype as the this argument
185 if (method->klass->valuetype && !mono_aot_is_got_entry (code, o))
186 addr = get_unbox_trampoline (method, addr);
189 if (mono_aot_is_got_entry (code, o) || mono_domain_owns_vtable_slot (mono_domain_get (), o))
190 *((gpointer *)o) = addr;
195 ppc_class_init_trampoline (void *vtable, guint32 *code, char *sp)
197 mono_runtime_class_init (vtable);
200 /* This is the 'bl' instruction */
203 if (((*code) >> 26) == 18) {
204 ppc_ori (code, 0, 0, 0); /* nop */
205 mono_arch_flush_icache (code, 4);
208 g_assert_not_reached ();
214 * Stack frame description when the generic trampoline is called.
216 * --------------------
218 * -------------------
219 * Saved FP registers 0-13
220 * -------------------
221 * Saved general registers 0-12
222 * -------------------
223 * param area for 3 args to ppc_magic_trampoline
224 * -------------------
226 * -------------------
229 mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
231 guint8 *buf, *code = NULL;
235 /* Now we'll create in 'buf' the PowerPC trampoline code. This
236 is the trampoline code common to all methods */
238 code = buf = g_malloc(512);
240 ppc_stwu (buf, ppc_r1, -STACK, ppc_r1);
242 /* start building the MonoLMF on the stack */
243 offset = STACK - sizeof (double) * MONO_SAVED_FREGS;
244 for (i = 14; i < 32; i++) {
245 ppc_stfd (buf, i, offset, ppc_r1);
246 offset += sizeof (double);
249 * now the integer registers. r13 is already saved in the trampoline,
250 * and at this point contains the method to compile, so we skip it.
252 offset = STACK - sizeof (MonoLMF) + G_STRUCT_OFFSET (MonoLMF, iregs) + sizeof (gulong);
253 ppc_stmw (buf, ppc_r14, ppc_r1, offset);
255 /* Now save the rest of the registers below the MonoLMF struct, first 14
256 * fp regs and then the 13 gregs.
258 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double));
259 for (i = 0; i < 14; i++) {
260 ppc_stfd (buf, i, offset, ppc_r1);
261 offset += sizeof (double);
263 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double)) - (13 * sizeof (gulong));
264 for (i = 0; i < 13; i++) {
265 ppc_stw (buf, i, offset, ppc_r1);
266 offset += sizeof (gulong);
268 /* we got here through a jump to the ctr reg, we must save the lr
269 * in the parent frame (we do it here to reduce the size of the
270 * method-specific trampoline)
272 ppc_mflr (buf, ppc_r0);
273 ppc_stw (buf, ppc_r0, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
275 /* ok, now we can continue with the MonoLMF setup, mostly untouched
276 * from emit_prolog in mini-ppc.c
278 ppc_load (buf, ppc_r0, mono_get_lmf_addr);
279 ppc_mtlr (buf, ppc_r0);
281 /* we build the MonoLMF structure on the stack - see mini-ppc.h
282 * The pointer to the struct is put in ppc_r11.
284 ppc_addi (buf, ppc_r11, ppc_sp, STACK - sizeof (MonoLMF));
285 ppc_stw (buf, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
286 /* new_lmf->previous_lmf = *lmf_addr */
287 ppc_lwz (buf, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
288 ppc_stw (buf, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
289 /* *(lmf_addr) = r11 */
290 ppc_stw (buf, ppc_r11, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
291 /* save method info (it's in r13) */
292 ppc_stw (buf, ppc_r13, G_STRUCT_OFFSET(MonoLMF, method), ppc_r11);
293 ppc_stw (buf, ppc_sp, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r11);
294 /* save the IP (caller ip) */
295 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
296 ppc_li (buf, ppc_r0, 0);
298 ppc_lwz (buf, ppc_r0, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
300 ppc_stw (buf, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r11);
303 * Now we're ready to call ppc_magic_trampoline ().
305 /* Arg 1: MonoMethod *method. It was put in r13 */
306 ppc_mr (buf, ppc_r3, ppc_r13);
308 /* Arg 2: code (next address to the instruction that called us) */
309 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
310 ppc_li (buf, ppc_r4, 0);
312 ppc_lwz (buf, ppc_r4, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
315 /* Arg 3: stack pointer so that the magic trampoline can access the
316 * registers we saved above
318 ppc_mr (buf, ppc_r5, ppc_r1);
320 if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
321 ppc_lis (buf, ppc_r0, (guint32) ppc_class_init_trampoline >> 16);
322 ppc_ori (buf, ppc_r0, ppc_r0, (guint32) ppc_class_init_trampoline & 0xffff);
324 ppc_lis (buf, ppc_r0, (guint32) ppc_magic_trampoline >> 16);
325 ppc_ori (buf, ppc_r0, ppc_r0, (guint32) ppc_magic_trampoline & 0xffff);
327 ppc_mtlr (buf, ppc_r0);
330 /* OK, code address is now on r3. Move it to the counter reg
331 * so it will be ready for the final jump: this is safe since we
332 * won't do any more calls.
334 ppc_mtctr (buf, ppc_r3);
337 * Now we restore the MonoLMF (see emit_epilogue in mini-ppc.c)
338 * and the rest of the registers, so the method called will see
339 * the same state as before we executed.
340 * The pointer to MonoLMF is in ppc_r11.
342 ppc_addi (buf, ppc_r11, ppc_r1, STACK - sizeof (MonoLMF));
343 /* r5 = previous_lmf */
344 ppc_lwz (buf, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
346 ppc_lwz (buf, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
347 /* *(lmf_addr) = previous_lmf */
348 ppc_stw (buf, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r6);
349 /* restore iregs: this time include r13 */
350 ppc_lmw (buf, ppc_r13, ppc_r11, G_STRUCT_OFFSET(MonoLMF, iregs));
352 for (i = 14; i < 32; i++) {
353 ppc_lfd (buf, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r11);
356 /* restore the volatile registers, we skip r1, of course */
357 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double));
358 for (i = 0; i < 14; i++) {
359 ppc_lfd (buf, i, offset, ppc_r1);
360 offset += sizeof (double);
362 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double)) - (13 * sizeof (gulong));
363 ppc_lwz (buf, ppc_r0, offset, ppc_r1);
364 offset += 2 * sizeof (gulong);
365 for (i = 2; i < 13; i++) {
366 ppc_lwz (buf, i, offset, ppc_r1);
367 offset += sizeof (gulong);
370 /* Non-standard function epilogue. Instead of doing a proper
371 * return, we just hump to the compiled code.
373 /* Restore stack pointer and LR and jump to the code */
374 ppc_lwz (buf, ppc_r1, 0, ppc_r1);
375 ppc_lwz (buf, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_r1);
376 ppc_mtlr (buf, ppc_r11);
377 ppc_bcctr (buf, 20, 0);
379 /* Flush instruction cache, since we've generated code */
380 mono_arch_flush_icache (code, buf - code);
383 g_assert ((buf - code) <= 512);
390 create_specific_tramp (MonoMethod *method, guint8* tramp, MonoDomain *domain) {
394 mono_domain_lock (domain);
395 code = buf = mono_code_manager_reserve (domain->code_mp, 32);
396 mono_domain_unlock (domain);
398 /* Save r13 in the place it will have in the on-stack MonoLMF */
399 ppc_stw (buf, ppc_r13, -(MONO_SAVED_FREGS * 8 + MONO_SAVED_GREGS * sizeof (gpointer)), ppc_r1);
401 /* Prepare the jump to the generic trampoline code.*/
402 ppc_lis (buf, ppc_r13, (guint32) tramp >> 16);
403 ppc_ori (buf, ppc_r13, ppc_r13, (guint32) tramp & 0xffff);
404 ppc_mtctr (buf, ppc_r13);
406 /* And finally put 'method' in r13 and fly! */
407 ppc_lis (buf, ppc_r13, (guint32) method >> 16);
408 ppc_ori (buf, ppc_r13, ppc_r13, (guint32) method & 0xffff);
409 ppc_bcctr (buf, 20, 0);
411 /* Flush instruction cache, since we've generated code */
412 mono_arch_flush_icache (code, buf - code);
414 g_assert ((buf - code) <= 32);
416 ji = g_new0 (MonoJitInfo, 1);
418 ji->code_start = code;
419 ji->code_size = buf - code;
421 mono_jit_stats.method_trampolines++;
427 mono_arch_create_jump_trampoline (MonoMethod *method)
430 MonoDomain* domain = mono_domain_get ();
432 tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_JUMP);
433 return create_specific_tramp (method, tramp, domain);
437 * arch_create_jit_trampoline:
438 * @method: pointer to the method info
440 * Creates a trampoline function for virtual methods. If the created
441 * code is called it first starts JIT compilation of method,
442 * and then calls the newly created method. It also replaces the
443 * corresponding vtable entry (see ppc_magic_trampoline).
445 * A trampoline consists of two parts: a main fragment, shared by all method
446 * trampolines, and some code specific to each method, which hard-codes a
447 * reference to that method and then calls the main fragment.
449 * The main fragment contains a call to 'ppc_magic_trampoline', which performs
450 * call to the JIT compiler and substitutes the method-specific fragment with
451 * some code that directly calls the JIT-compiled method.
453 * Returns: a pointer to the newly created code
456 mono_arch_create_jit_trampoline (MonoMethod *method)
460 MonoDomain* domain = mono_domain_get ();
463 tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC);
464 /* FIXME: should pass the domain down to this function */
465 ji = create_specific_tramp (method, tramp, domain);
466 code_start = ji->code_start;
473 * mono_arch_create_class_init_trampoline:
474 * @vtable: the type to initialize
476 * Creates a trampoline function to run a type initializer.
477 * If the trampoline is called, it calls mono_runtime_class_init with the
478 * given vtable, then patches the caller code so it does not get called any
481 * Returns: a pointer to the newly created code
484 mono_arch_create_class_init_trampoline (MonoVTable *vtable)
486 guint8 *code, *buf, *tramp;
488 tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
490 /* This is the method-specific part of the trampoline. Its purpose is
491 to provide the generic part with the MonoMethod *method pointer. We'll
492 use r11 to keep that value, for instance. However, the generic part of
493 the trampoline relies on r11 having the same value it had before coming
494 here, so we must save it before. */
495 //code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
496 mono_domain_lock (vtable->domain);
497 code = buf = mono_code_manager_reserve (vtable->domain->code_mp, METHOD_TRAMPOLINE_SIZE);
498 mono_domain_unlock (vtable->domain);
500 ppc_mflr (buf, ppc_r4);
501 ppc_stw (buf, ppc_r4, PPC_RET_ADDR_OFFSET, ppc_sp);
502 ppc_stwu (buf, ppc_sp, -64, ppc_sp);
503 ppc_load (buf, ppc_r3, vtable);
504 ppc_load (buf, ppc_r5, 0);
506 ppc_load (buf, ppc_r0, ppc_class_init_trampoline);
507 ppc_mtlr (buf, ppc_r0);
510 ppc_lwz (buf, ppc_r0, 64 + PPC_RET_ADDR_OFFSET, ppc_sp);
511 ppc_mtlr (buf, ppc_r0);
512 ppc_addic (buf, ppc_sp, ppc_sp, 64);
515 /* Flush instruction cache, since we've generated code */
516 mono_arch_flush_icache (code, buf - code);
519 g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
521 mono_jit_stats.method_trampolines++;
527 * This method is only called when running in the Mono Debugger.
530 mono_debugger_create_notification_function (gpointer *notification_address)
534 ptr = buf = g_malloc0 (16);
536 if (notification_address)
537 *notification_address = buf;
539 mono_arch_flush_icache (ptr, buf - ptr);