* main.c (dis_nt_header): New. Dump pe_stack_reserve if different from the
[mono.git] / mono / mini / tramp-ppc.c
1 /*
2  * tramp-ppc.c: JIT trampoline code for PowerPC
3  *
4  * Authors:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *   Paolo Molaro (lupus@ximian.com)
7  *   Carlos Valiente <yo@virutass.net>
8  *
9  * (C) 2001 Ximian, Inc.
10  */
11
12 #include <config.h>
13 #include <glib.h>
14
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>
19 #include <mono/metadata/mono-debug-debugger.h>
20
21 #include "mini.h"
22 #include "mini-ppc.h"
23
24 /*
25  * get_unbox_trampoline:
26  * @m: method pointer
27  * @addr: pointer to native code for @m
28  *
29  * when value type methods are called through the vtable we need to unbox the
30  * this argument. This method returns a pointer to a trampoline which does
31  * unboxing before calling the method
32  */
33 static gpointer
34 get_unbox_trampoline (MonoMethod *m, gpointer addr)
35 {
36         guint8 *code, *start;
37         int this_pos = 3;
38
39         if (!mono_method_signature (m)->ret->byref && MONO_TYPE_ISSTRUCT (mono_method_signature (m)->ret))
40                 this_pos = 4;
41             
42         start = code = g_malloc (20);
43
44         ppc_load (code, ppc_r0, addr);
45         ppc_mtctr (code, ppc_r0);
46         ppc_addi (code, this_pos, this_pos, sizeof (MonoObject));
47         ppc_bcctr (code, 20, 0);
48         mono_arch_flush_icache (start, code - start);
49         g_assert ((code - start) <= 20);
50         /*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
51         g_print ("unbox code is at %p for method at %p\n", start, addr);*/
52
53         return start;
54 }
55
56 /* Stack size for trampoline function 
57  * PPC_MINIMAL_STACK_SIZE + 16 (args + alignment to ppc_magic_trampoline)
58  * + MonoLMF + 14 fp regs + 13 gregs + alignment
59  * #define STACK (PPC_MINIMAL_STACK_SIZE + 4 * sizeof (gulong) + sizeof (MonoLMF) + 14 * sizeof (double) + 13 * (sizeof (gulong)))
60  * STACK would be 444 for 32 bit darwin
61  */
62 #define STACK (448)
63
64 /* Method-specific trampoline code fragment size */
65 #define METHOD_TRAMPOLINE_SIZE 64
66
67 /* Jump-specific trampoline code fragment size */
68 #define JUMP_TRAMPOLINE_SIZE   64
69
70 /**
71  * ppc_magic_trampoline:
72  * @code: pointer into caller code
73  * @method: the method to translate
74  * @sp: stack pointer
75  *
76  * This method is called by the function 'arch_create_jit_trampoline', which in
77  * turn is called by the trampoline functions for virtual methods.
78  * After having called the JIT compiler to compile the method, it inspects the
79  * caller code to find the address of the method-specific part of the
80  * trampoline vtable slot for this method, updates it with a fragment that calls
81  * the newly compiled code and returns this address of the compiled code to
82  * 'arch_create_jit_trampoline' 
83  */
84 static gpointer
85 ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
86 {
87         char *o = NULL;
88         gpointer addr;
89         MonoJitInfo *ji, *target_ji;
90         int reg, offset = 0;
91
92         addr = mono_compile_method(method);
93         /*g_print ("method code at %p for %s:%s\n", addr, method->klass->name, method->name);*/
94         g_assert(addr);
95
96         if (!code){
97                 return addr;
98         }
99
100         /* We can't trampoline across domains */
101         ji = mono_jit_info_table_find (mono_domain_get (), code);
102         target_ji = mono_jit_info_table_find (mono_domain_get (), addr);
103         if (!mono_method_same_domain (ji, target_ji))
104                 return addr;
105
106         /* Locate the address of the method-specific trampoline. The call using
107         the vtable slot that took the processing flow to 'arch_create_jit_trampoline' 
108         looks something like this:
109         
110                 mtlr rA                 ; Move rA (a register containing the
111                                         ; target address) to LR
112                 blrl                    ; Call function at LR
113         
114         PowerPC instructions are 32-bit long, which means that a 32-bit target
115         address cannot be encoded as an immediate value (because we already
116         have spent some bits to encode the branch instruction!). That's why a
117         'b'ranch to the contents of the 'l'ink 'r'egister (with 'l'ink register
118         update) is needed, instead of a simpler 'branch immediate'. This
119         complicates our purpose here, because 'blrl' overwrites LR, which holds
120         the value we're interested in.
121         
122         Therefore, we need to locate the 'mtlr rA' instruction to know which
123         register LR was loaded from, and then retrieve the value from that
124         register */
125         
126         /* This is the 'blrl' instruction */
127         --code;
128         
129         /*
130          * Note that methods are called also with the bl opcode.
131          */
132         if (((*code) >> 26) == 18) {
133                 /*g_print ("direct patching\n");*/
134                 ppc_patch ((char*)code, addr);
135                 mono_arch_flush_icache ((char*)code, 4);
136                 return addr;
137         }
138         
139         /* Sanity check: instruction must be 'blrl' */
140         g_assert(*code == 0x4e800021);
141
142         /* the thunk-less direct call sequence: lis/ori/mtlr/blrl */
143         if ((code [-1] >> 26) == 31 && (code [-2] >> 26) == 24 && (code [-3] >> 26) == 15) {
144                 ppc_patch ((char*)code, addr);
145                 return addr;
146         }
147
148         /* OK, we're now at the 'blrl' instruction. Now walk backwards
149         till we get to a 'mtlr rA' */
150         for(; --code;) {
151                 if((*code & 0x7c0803a6) == 0x7c0803a6) {
152                         gint16 soff;
153                         gint reg_offset;
154                         /* Here we are: we reached the 'mtlr rA'.
155                         Extract the register from the instruction */
156                         reg = (*code & 0x03e00000) >> 21;
157                         --code;
158                         /* ok, this is a lwz reg, offset (vtreg) 
159                          * it is emitted with:
160                          * ppc_emit32 (c, (32 << 26) | ((D) << 21) | ((a) << 16) | (guint16)(d))
161                          */
162                         soff = (*code & 0xffff);
163                         offset = soff;
164                         reg = (*code >> 16) & 0x1f;
165                         g_assert (reg != ppc_r1);
166                         /*g_print ("patching reg is %d\n", reg);*/
167                         if (reg >= 13) {
168                                 /* saved in the MonoLMF structure */
169                                 reg_offset = STACK - sizeof (MonoLMF) + G_STRUCT_OFFSET (MonoLMF, iregs);
170                                 reg_offset += (reg - 13) * sizeof (gulong);
171                         } else {
172                                 /* saved in the stack, see frame diagram below */
173                                 reg_offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double)) - (13 * sizeof (gulong));
174                                 reg_offset += reg * sizeof (gulong);
175                         }
176                         /* o contains now the value of register reg */
177                         o = *((char**) (sp + reg_offset));
178                         break;
179                 }
180         }
181
182         /* this is not done for non-virtual calls, because in that case
183            we won't have an object, but the actual pointer to the 
184            valuetype as the this argument
185          */
186         if (method->klass->valuetype && !mono_aot_is_got_entry (code, o))
187                 addr = get_unbox_trampoline (method, addr);
188
189         o += offset;
190         if (mono_aot_is_got_entry (code, o) || mono_domain_owns_vtable_slot (mono_domain_get (), o))
191                 *((gpointer *)o) = addr;
192         return addr;
193 }
194
195 static void
196 ppc_class_init_trampoline (void *vtable, guint32 *code, char *sp)
197 {
198         mono_runtime_class_init (vtable);
199
200 #if 0
201         /* This is the 'bl' instruction */
202         --code;
203         
204         if (((*code) >> 26) == 18) {
205                 ppc_ori (code, 0, 0, 0); /* nop */
206                 mono_arch_flush_icache (code, 4);
207                 return;
208         } else {
209                 g_assert_not_reached ();
210         }
211 #endif
212 }
213
214 /*
215  * Stack frame description when the generic trampoline is called.
216  * caller frame
217  * --------------------
218  *  MonoLMF
219  *  -------------------
220  *  Saved FP registers 0-13
221  *  -------------------
222  *  Saved general registers 0-12
223  *  -------------------
224  *  param area for 3 args to ppc_magic_trampoline
225  *  -------------------
226  *  linkage area
227  *  -------------------
228  */
229 guchar*
230 mono_arch_create_trampoline_code (MonoTrampolineType tramp_type)
231 {
232         guint8 *buf, *code = NULL;
233         int i, offset;
234
235         if(!code) {
236                 /* Now we'll create in 'buf' the PowerPC trampoline code. This
237                  is the trampoline code common to all methods  */
238                 
239                 code = buf = g_malloc(512);
240                 
241                 ppc_stwu (buf, ppc_r1, -STACK, ppc_r1);
242
243                 /* start building the MonoLMF on the stack */
244                 offset = STACK - sizeof (double) * MONO_SAVED_FREGS;
245                 for (i = 14; i < 32; i++) {
246                         ppc_stfd (buf, i, offset, ppc_r1);
247                         offset += sizeof (double);
248                 }
249                 /* 
250                  * now the integer registers. r13 is already saved in the trampoline,
251                  * and at this point contains the method to compile, so we skip it.
252                  */
253                 offset = STACK - sizeof (MonoLMF) + G_STRUCT_OFFSET (MonoLMF, iregs) + sizeof (gulong);
254                 ppc_stmw (buf, ppc_r14, ppc_r1, offset);
255
256                 /* Now save the rest of the registers below the MonoLMF struct, first 14
257                  * fp regs and then the 13 gregs.
258                  */
259                 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double));
260                 for (i = 0; i < 14; i++) {
261                         ppc_stfd (buf, i, offset, ppc_r1);
262                         offset += sizeof (double);
263                 }
264                 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double)) - (13 * sizeof (gulong));
265                 for (i = 0; i < 13; i++) {
266                         ppc_stw (buf, i, offset, ppc_r1);
267                         offset += sizeof (gulong);
268                 }
269                 /* we got here through a jump to the ctr reg, we must save the lr
270                  * in the parent frame (we do it here to reduce the size of the
271                  * method-specific trampoline)
272                  */
273                 ppc_mflr (buf, ppc_r0);
274                 ppc_stw (buf, ppc_r0, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
275
276                 /* ok, now we can continue with the MonoLMF setup, mostly untouched 
277                  * from emit_prolog in mini-ppc.c
278                  */
279                 ppc_load (buf, ppc_r0, mono_get_lmf_addr);
280                 ppc_mtlr (buf, ppc_r0);
281                 ppc_blrl (buf);
282                 /* we build the MonoLMF structure on the stack - see mini-ppc.h
283                  * The pointer to the struct is put in ppc_r11.
284                  */
285                 ppc_addi (buf, ppc_r11, ppc_sp, STACK - sizeof (MonoLMF));
286                 ppc_stw (buf, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
287                 /* new_lmf->previous_lmf = *lmf_addr */
288                 ppc_lwz (buf, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
289                 ppc_stw (buf, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
290                 /* *(lmf_addr) = r11 */
291                 ppc_stw (buf, ppc_r11, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
292                 /* save method info (it's in r13) */
293                 ppc_stw (buf, ppc_r13, G_STRUCT_OFFSET(MonoLMF, method), ppc_r11);
294                 ppc_stw (buf, ppc_sp, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r11);
295                 /* save the IP (caller ip) */
296                 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
297                         ppc_li (buf, ppc_r0, 0);
298                 } else {
299                         ppc_lwz (buf, ppc_r0, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
300                 }
301                 ppc_stw (buf, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r11);
302
303                 /*
304                  * Now we're ready to call ppc_magic_trampoline ().
305                  */
306                 /* Arg 1: MonoMethod *method. It was put in r13 */
307                 ppc_mr  (buf, ppc_r3, ppc_r13);
308                 
309                 /* Arg 2: code (next address to the instruction that called us) */
310                 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
311                         ppc_li (buf, ppc_r4, 0);
312                 } else {
313                         ppc_lwz  (buf, ppc_r4, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
314                 }
315                 
316                 /* Arg 3: stack pointer so that the magic trampoline can access the
317                  * registers we saved above
318                  */
319                 ppc_mr   (buf, ppc_r5, ppc_r1);
320                 
321                 if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
322                         ppc_lis  (buf, ppc_r0, (guint32) ppc_class_init_trampoline >> 16);
323                         ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) ppc_class_init_trampoline & 0xffff);
324                 } else {
325                         ppc_lis  (buf, ppc_r0, (guint32) ppc_magic_trampoline >> 16);
326                         ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) ppc_magic_trampoline & 0xffff);
327                 }
328                 ppc_mtlr (buf, ppc_r0);
329                 ppc_blrl (buf);
330                 
331                 /* OK, code address is now on r3. Move it to the counter reg
332                  * so it will be ready for the final jump: this is safe since we
333                  * won't do any more calls.
334                  */
335                 ppc_mtctr (buf, ppc_r3);
336
337                 /*
338                  * Now we restore the MonoLMF (see emit_epilogue in mini-ppc.c)
339                  * and the rest of the registers, so the method called will see
340                  * the same state as before we executed.
341                  * The pointer to MonoLMF is in ppc_r11.
342                  */
343                 ppc_addi (buf, ppc_r11, ppc_r1, STACK - sizeof (MonoLMF));
344                 /* r5 = previous_lmf */
345                 ppc_lwz (buf, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
346                 /* r6 = lmf_addr */
347                 ppc_lwz (buf, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
348                 /* *(lmf_addr) = previous_lmf */
349                 ppc_stw (buf, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r6);
350                 /* restore iregs: this time include r13 */
351                 ppc_lmw (buf, ppc_r13, ppc_r11, G_STRUCT_OFFSET(MonoLMF, iregs));
352                 /* restore fregs */
353                 for (i = 14; i < 32; i++) {
354                         ppc_lfd (buf, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r11);
355                 }
356
357                 /* restore the volatile registers, we skip r1, of course */
358                 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double));
359                 for (i = 0; i < 14; i++) {
360                         ppc_lfd (buf, i, offset, ppc_r1);
361                         offset += sizeof (double);
362                 }
363                 offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double)) - (13 * sizeof (gulong));
364                 ppc_lwz (buf, ppc_r0, offset, ppc_r1);
365                 offset += 2 * sizeof (gulong);
366                 for (i = 2; i < 13; i++) {
367                         ppc_lwz (buf, i, offset, ppc_r1);
368                         offset += sizeof (gulong);
369                 }
370
371                 /* Non-standard function epilogue. Instead of doing a proper
372                  * return, we just hump to the compiled code.
373                  */
374                 /* Restore stack pointer and LR and jump to the code */
375                 ppc_lwz  (buf, ppc_r1,  0, ppc_r1);
376                 ppc_lwz  (buf, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_r1);
377                 ppc_mtlr (buf, ppc_r11);
378                 ppc_bcctr (buf, 20, 0);
379
380                 /* Flush instruction cache, since we've generated code */
381                 mono_arch_flush_icache (code, buf - code);
382         
383                 /* Sanity check */
384                 g_assert ((buf - code) <= 512);
385         }
386
387         return code;
388 }
389
390 static MonoJitInfo*
391 create_specific_tramp (MonoMethod *method, guint8* tramp, MonoDomain *domain) {
392         guint8 *code, *buf;
393         MonoJitInfo *ji;
394
395         mono_domain_lock (domain);
396         code = buf = mono_code_manager_reserve (domain->code_mp, 32);
397         mono_domain_unlock (domain);
398
399         /* Save r13 in the place it will have in the on-stack MonoLMF */
400         ppc_stw  (buf, ppc_r13, -(MONO_SAVED_FREGS * 8 + MONO_SAVED_GREGS * sizeof (gpointer)),  ppc_r1);
401         
402         /* Prepare the jump to the generic trampoline code.*/
403         ppc_lis  (buf, ppc_r13, (guint32) tramp >> 16);
404         ppc_ori  (buf, ppc_r13, ppc_r13, (guint32) tramp & 0xffff);
405         ppc_mtctr (buf, ppc_r13);
406         
407         /* And finally put 'method' in r13 and fly! */
408         ppc_lis  (buf, ppc_r13, (guint32) method >> 16);
409         ppc_ori  (buf, ppc_r13, ppc_r13, (guint32) method & 0xffff);
410         ppc_bcctr (buf, 20, 0);
411         
412         /* Flush instruction cache, since we've generated code */
413         mono_arch_flush_icache (code, buf - code);
414
415         g_assert ((buf - code) <= 32);
416
417         ji = g_new0 (MonoJitInfo, 1);
418         ji->method = method;
419         ji->code_start = code;
420         ji->code_size = buf - code;
421
422         mono_jit_stats.method_trampolines++;
423
424         return ji;
425 }
426
427 MonoJitInfo*
428 mono_arch_create_jump_trampoline (MonoMethod *method)
429 {
430         guint8 *tramp;
431         MonoDomain* domain = mono_domain_get ();
432         
433         tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_JUMP);
434         return create_specific_tramp (method, tramp, domain);
435 }
436
437 /**
438  * arch_create_jit_trampoline:
439  * @method: pointer to the method info
440  *
441  * Creates a trampoline function for virtual methods. If the created
442  * code is called it first starts JIT compilation of method,
443  * and then calls the newly created method. It also replaces the
444  * corresponding vtable entry (see ppc_magic_trampoline).
445  *
446  * A trampoline consists of two parts: a main fragment, shared by all method
447  * trampolines, and some code specific to each method, which hard-codes a
448  * reference to that method and then calls the main fragment.
449  *
450  * The main fragment contains a call to 'ppc_magic_trampoline', which performs
451  * call to the JIT compiler and substitutes the method-specific fragment with
452  * some code that directly calls the JIT-compiled method.
453  * 
454  * Returns: a pointer to the newly created code 
455  */
456 gpointer
457 mono_arch_create_jit_trampoline (MonoMethod *method)
458 {
459         guint8 *tramp;
460         MonoJitInfo *ji;
461         MonoDomain* domain = mono_domain_get ();
462         gpointer code_start;
463
464         tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_GENERIC);
465         /* FIXME: should pass the domain down to this function */
466         ji = create_specific_tramp (method, tramp, domain);
467         code_start = ji->code_start;
468         g_free (ji);
469
470         return code_start;
471 }
472
473 /**
474  * mono_arch_create_class_init_trampoline:
475  *  @vtable: the type to initialize
476  *
477  * Creates a trampoline function to run a type initializer. 
478  * If the trampoline is called, it calls mono_runtime_class_init with the
479  * given vtable, then patches the caller code so it does not get called any
480  * more.
481  * 
482  * Returns: a pointer to the newly created code 
483  */
484 gpointer
485 mono_arch_create_class_init_trampoline (MonoVTable *vtable)
486 {
487         guint8 *code, *buf, *tramp;
488
489         tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
490
491         /* This is the method-specific part of the trampoline. Its purpose is
492         to provide the generic part with the MonoMethod *method pointer. We'll
493         use r11 to keep that value, for instance. However, the generic part of
494         the trampoline relies on r11 having the same value it had before coming
495         here, so we must save it before. */
496         //code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
497         mono_domain_lock (vtable->domain);
498         code = buf = mono_code_manager_reserve (vtable->domain->code_mp, METHOD_TRAMPOLINE_SIZE);
499         mono_domain_unlock (vtable->domain);
500
501         ppc_mflr (buf, ppc_r4);
502         ppc_stw  (buf, ppc_r4, PPC_RET_ADDR_OFFSET, ppc_sp);
503         ppc_stwu (buf, ppc_sp, -64, ppc_sp);
504         ppc_load (buf, ppc_r3, vtable);
505         ppc_load (buf, ppc_r5, 0);
506
507         ppc_load (buf, ppc_r0, ppc_class_init_trampoline);
508         ppc_mtlr (buf, ppc_r0);
509         ppc_blrl (buf);
510
511         ppc_lwz (buf, ppc_r0, 64 + PPC_RET_ADDR_OFFSET, ppc_sp);
512         ppc_mtlr (buf, ppc_r0);
513         ppc_addic (buf, ppc_sp, ppc_sp, 64);
514         ppc_blr (buf);
515
516         /* Flush instruction cache, since we've generated code */
517         mono_arch_flush_icache (code, buf - code);
518                 
519         /* Sanity check */
520         g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
521
522         mono_jit_stats.method_trampolines++;
523
524         return code;
525 }
526
527 /*
528  * This method is only called when running in the Mono Debugger.
529  */
530 gpointer
531 mono_debugger_create_notification_function (gpointer *notification_address)
532 {
533         guint8 *ptr, *buf;
534
535         ptr = buf = g_malloc0 (16);
536         ppc_break (buf);
537         if (notification_address)
538                 *notification_address = buf;
539         ppc_blr (buf);
540         mono_arch_flush_icache (ptr, buf - ptr);
541
542         return ptr;
543 }
544