2003-10-09 Dick Porter <dick@ximian.com>
[mono.git] / mono / mini / tramp-ppc.c
1 /*
2  * trampoline.c: JIT trampoline code
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 typedef enum {
25         MONO_TRAMPOLINE_GENERIC,
26         MONO_TRAMPOLINE_JUMP,
27         MONO_TRAMPOLINE_CLASS_INIT
28 } MonoTrampolineType;
29
30 /* adapt to mini later... */
31 #define mono_jit_share_code (1)
32
33 /*
34  * Address of the x86 trampoline code.  This is used by the debugger to check
35  * whether a method is a trampoline.
36  */
37 guint8 *mono_generic_trampoline_code = NULL;
38
39 /*
40  * get_unbox_trampoline:
41  * @m: method pointer
42  * @addr: pointer to native code for @m
43  *
44  * when value type methods are called through the vtable we need to unbox the
45  * this argument. This method returns a pointer to a trampoline which does
46  * unboxing before calling the method
47  */
48 static gpointer
49 get_unbox_trampoline (MonoMethod *m, gpointer addr)
50 {
51         guint8 *code, *start;
52         int this_pos = 3;
53
54         if (!m->signature->ret->byref && MONO_TYPE_ISSTRUCT (m->signature->ret))
55                 this_pos = 4;
56             
57         start = code = g_malloc (20);
58
59         ppc_load (code, ppc_r11, addr);
60         ppc_mtctr (code, ppc_r11);
61         ppc_addi (code, this_pos, this_pos, sizeof (MonoObject));
62         ppc_bcctr (code, 20, 0);
63         g_assert ((code - start) <= 20);
64
65         return start;
66 }
67
68 /* Stack size for trampoline function */
69 #define STACK 144
70
71 /* Method-specific trampoline code framgment size */
72 #define METHOD_TRAMPOLINE_SIZE 64
73
74 /**
75  * ppc_magic_trampoline:
76  * @code: pointer into caller code
77  * @method: the method to translate
78  * @sp: stack pointer
79  *
80  * This method is called by the function 'arch_create_jit_trampoline', which in
81  * turn is called by the trampoline functions for virtual methods.
82  * After having called the JIT compiler to compile the method, it inspects the
83  * caller code to find the address of the method-specific part of the
84  * trampoline vtable slot for this method, updates it with a fragment that calls
85  * the newly compiled code and returns this address of the compiled code to
86  * 'arch_create_jit_trampoline' 
87  */
88 static gpointer
89 ppc_magic_trampoline (MonoMethod *method, guint32 *code, char *sp)
90 {
91         char *o, *start;
92         gpointer addr;
93         int reg;
94
95         addr = mono_compile_method(method);
96         g_assert(addr);
97
98         /* Locate the address of the method-specific trampoline. The call using
99         the vtable slot that took the processing flow to 'arch_create_jit_trampoline' 
100         looks something like this:
101         
102                 mtlr rA                 ; Move rA (a register containing the
103                                         ; target address) to LR
104                 blrl                    ; Call function at LR
105         
106         PowerPC instructions are 32-bit long, which means that a 32-bit target
107         address cannot be encoded as an immediate value (because we already
108         have spent some bits to encode the branch instruction!). That's why a
109         'b'ranch to the contents of the 'l'ink 'r'egister (with 'l'ink register
110         update) is needed, instead of a simpler 'branch immediate'. This
111         complicates our purpose here, because 'blrl' overwrites LR, which holds
112         the value we're interested in.
113         
114         Therefore, we need to locate the 'mtlr rA' instruction to know which
115         register LR was loaded from, and then retrieve the value from that
116         register */
117         
118         /* This is the 'blrl' instruction */
119         --code;
120         
121         /*
122          * Note that methods are called also with the bl opcode.
123          */
124         if (((*code) >> 26) == 18) {
125                 ppc_patch (code, addr);
126                 mono_arch_flush_icache (code, 4);
127                 return addr;
128         }
129         
130         /* Sanity check: instruction must be 'blrl' */
131         g_assert(*code == 0x4e800021);
132         
133         /* OK, we're now at the 'blrl' instruction. Now walk backwards
134         till we get to a 'mtlr rA' */
135         for(; --code;) {
136                 if((*code & 0x7c0803a6) == 0x7c0803a6) {
137                         /* Here we are: we reached the 'mtlr rA'.
138                         Extract the register from the instruction */
139                         reg = (*code & 0x03e00000) >> 21;
140                         switch(reg) {
141                                 case 0 : o = *((int *) (sp + STACK - 8));   break;
142                                 case 11: o = *((int *) (sp + STACK - 24));  break;
143                                 case 12: o = *((int *) (sp + STACK - 28));  break;
144                                 case 13: o = *((int *) (sp + STACK - 32));  break;
145                                 case 14: o = *((int *) (sp + STACK - 36));  break;
146                                 case 15: o = *((int *) (sp + STACK - 40));  break;
147                                 case 16: o = *((int *) (sp + STACK - 44));  break;
148                                 case 17: o = *((int *) (sp + STACK - 48));  break;
149                                 case 18: o = *((int *) (sp + STACK - 52));  break;
150                                 case 19: o = *((int *) (sp + STACK - 56));  break;
151                                 case 20: o = *((int *) (sp + STACK - 60));  break;
152                                 case 21: o = *((int *) (sp + STACK - 64));  break;
153                                 case 22: o = *((int *) (sp + STACK - 68));  break;
154                                 case 23: o = *((int *) (sp + STACK - 72));  break;
155                                 case 24: o = *((int *) (sp + STACK - 76));  break;
156                                 case 25: o = *((int *) (sp + STACK - 80));  break;
157                                 case 26: o = *((int *) (sp + STACK - 84));  break;
158                                 case 27: o = *((int *) (sp + STACK - 88));  break;
159                                 case 28: o = *((int *) (sp + STACK - 92));  break;
160                                 case 29: o = *((int *) (sp + STACK - 96));  break;
161                                 case 30: o = *((int *) (sp + STACK - 100)); break;
162                                 case 31: o = *((int *) (sp + STACK - 4));   break;
163                                 default:
164                                         printf("%s: Unexpected register %d\n",
165                                                 __FUNCTION__, reg);
166                                         g_assert_not_reached();
167                         }
168                         break;
169                 }
170         }
171
172         /* this is not done for non-virtual calls, because in that case
173            we won't have an object, but the actual pointer to the 
174            valuetype as the this argument
175          */
176         if (method->klass->valuetype)
177                 addr = get_unbox_trampoline (method, addr);
178         
179         /* Finally, replace the method-specific trampoline code (which called
180         the generic trampoline code) with a fragment that calls directly the
181         compiled method */
182         
183         start = o;
184         ppc_stwu (o, ppc_r1, -16, ppc_r1);
185         ppc_mflr (o, ppc_r0);
186         ppc_stw  (o, ppc_r31, 12, ppc_r1);
187         ppc_stw  (o, ppc_r0,  20, ppc_r1);
188         ppc_mr   (o, ppc_r31, ppc_r1);
189         
190         ppc_lis  (o, ppc_r0, (guint32) addr >> 16);
191         ppc_ori  (o, ppc_r0, ppc_r0, (guint32) addr & 0xffff);
192         ppc_mtlr (o, ppc_r0);
193         ppc_blrl (o);
194         
195         ppc_lwz  (o, ppc_r11, 0,  ppc_r1);
196         ppc_lwz  (o, ppc_r0,  4,  ppc_r11);
197         ppc_mtlr (o, ppc_r0);
198         ppc_lwz  (o, ppc_r31, -4, ppc_r11);
199         ppc_mr   (o, ppc_r1, ppc_r11);
200         ppc_blr  (o);
201         
202         mono_arch_flush_icache (start, o - start);
203         g_assert(o - start < METHOD_TRAMPOLINE_SIZE);
204         
205         return addr;
206 }
207
208 static void
209 ppc_class_init_trampoline (void *vtable, guint32 *code, char *sp)
210 {
211         mono_runtime_class_init (vtable);
212
213         /* This is the 'bl' instruction */
214         --code;
215         
216         if (((*code) >> 26) == 18) {
217                 ppc_ori (code, 0, 0, 0); /* nop */
218                 mono_arch_flush_icache (code, 4);
219                 return;
220         } else {
221                 g_assert_not_reached ();
222         }
223 }
224
225 static guchar*
226 create_trampoline_code (MonoTrampolineType tramp_type)
227 {
228         guint8 *buf, *code = NULL;
229         static guint8* generic_jump_trampoline = NULL;
230         static guint8 *generic_class_init_trampoline = NULL;
231
232         switch (tramp_type) {
233         case MONO_TRAMPOLINE_GENERIC:
234                 if (mono_generic_trampoline_code)
235                         return mono_generic_trampoline_code;
236                 break;
237         case MONO_TRAMPOLINE_JUMP:
238                 if (generic_jump_trampoline)
239                         return generic_jump_trampoline;
240                 break;
241         case MONO_TRAMPOLINE_CLASS_INIT:
242                 if (generic_class_init_trampoline)
243                         return generic_class_init_trampoline;
244                 break;
245         }
246
247         if(!code) {
248                 /* Now we'll create in 'buf' the PowerPC trampoline code. This
249                  is the trampoline code common to all methods  */
250                 
251                 code = buf = g_malloc(512);
252                 
253                 /*-----------------------------------------------------------
254                 STEP 0: First create a non-standard function prologue with a
255                 stack size big enough to save our registers:
256                 
257                         lr              (We'll be calling functions here, so we
258                                         must save it)
259                         r0              (See ppc_magic_trampoline)
260                         r1 (sp)         (Stack pointer - must save)
261                         r3-r10          Function arguments.
262                         r11-r31         (See ppc_magic_trampoline)
263                         method in r11   (See ppc_magic_trampoline)
264                         
265                 This prologue is non-standard because r0 is not saved here - it
266                 was saved in the method-specific trampoline code
267                 -----------------------------------------------------------*/
268                 
269                 ppc_stwu (buf, ppc_r1, -STACK, ppc_r1);
270                 
271                 /* Save r0 before modifying it - we will need its contents in
272                 'ppc_magic_trampoline' */
273                 ppc_stw  (buf, ppc_r0,  STACK - 8,   ppc_r1);
274                 
275                 ppc_stw  (buf, ppc_r31, STACK - 4, ppc_r1);
276                 ppc_mr   (buf, ppc_r31, ppc_r1);
277                 
278                 /* Now save our registers. */
279                 ppc_stw  (buf, ppc_r3,  STACK - 12,  ppc_r1);
280                 ppc_stw  (buf, ppc_r4,  STACK - 16,  ppc_r1);
281                 ppc_stw  (buf, ppc_r5,  STACK - 20,  ppc_r1);
282                 ppc_stw  (buf, ppc_r6,  STACK - 24,  ppc_r1);
283                 ppc_stw  (buf, ppc_r7,  STACK - 28,  ppc_r1);
284                 ppc_stw  (buf, ppc_r8,  STACK - 32,  ppc_r1);
285                 ppc_stw  (buf, ppc_r9,  STACK - 36,  ppc_r1);
286                 ppc_stw  (buf, ppc_r10, STACK - 40,  ppc_r1);
287                 /* STACK - 44 contains r11, which is set in the method-specific
288                 part of the trampoline (see bellow this 'if' block) */
289                 ppc_stw  (buf, ppc_r12, STACK - 48,  ppc_r1);
290                 ppc_stw  (buf, ppc_r13, STACK - 52,  ppc_r1);
291                 ppc_stw  (buf, ppc_r14, STACK - 56,  ppc_r1);
292                 ppc_stw  (buf, ppc_r15, STACK - 60,  ppc_r1);
293                 ppc_stw  (buf, ppc_r16, STACK - 64,  ppc_r1);
294                 ppc_stw  (buf, ppc_r17, STACK - 68,  ppc_r1);
295                 ppc_stw  (buf, ppc_r18, STACK - 72,  ppc_r1);
296                 ppc_stw  (buf, ppc_r19, STACK - 76,  ppc_r1);
297                 ppc_stw  (buf, ppc_r20, STACK - 80,  ppc_r1);
298                 ppc_stw  (buf, ppc_r21, STACK - 84,  ppc_r1);
299                 ppc_stw  (buf, ppc_r22, STACK - 88,  ppc_r1);
300                 ppc_stw  (buf, ppc_r23, STACK - 92,  ppc_r1);
301                 ppc_stw  (buf, ppc_r24, STACK - 96,  ppc_r1);
302                 ppc_stw  (buf, ppc_r25, STACK - 100, ppc_r1);
303                 ppc_stw  (buf, ppc_r26, STACK - 104, ppc_r1);
304                 ppc_stw  (buf, ppc_r27, STACK - 108, ppc_r1);
305                 ppc_stw  (buf, ppc_r28, STACK - 112, ppc_r1);
306                 ppc_stw  (buf, ppc_r29, STACK - 116, ppc_r1);
307                 ppc_stw  (buf, ppc_r30, STACK - 120, ppc_r1);
308                 /* Save 'method' pseudo-parameter - the one passed in r11 */
309                 ppc_stw  (buf, ppc_r11, STACK - 124, ppc_r1);
310
311                 /*----------------------------------------------------------
312                 STEP 1: call 'mono_get_lmf_addr()' to get the address of our
313                 LMF. We'll need to restore it after the call to
314                 'ppc_magic_trampoline' and before the call to the native
315                 method.
316                 ----------------------------------------------------------*/
317                                 
318                 /* Calculate the address and make the call. Keep in mind that
319                 we're using r0, so we'll have to restore it before calling
320                 'ppc_magic_trampoline' */
321                 ppc_lis  (buf, ppc_r0, (guint32) mono_get_lmf_addr >> 16);
322                 ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) mono_get_lmf_addr & 0xffff);
323                 ppc_mtlr (buf, ppc_r0);
324                 ppc_blrl (buf);
325
326                 /* XXX Update LMF !!! */
327                 
328                 /*----------------------------------------------------------
329                 STEP 2: call 'ppc_magic_trampoline()', who will compile the
330                 code and fix the method vtable entry for us
331                 ----------------------------------------------------------*/
332                                 
333                 /* Set arguments */
334                 
335                 /* Arg 1: MonoMethod *method. It was put in r11 by the
336                 method-specific trampoline code, and then saved before the call
337                 to mono_get_lmf_addr()'. Restore r11, by the way :-) */
338                 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
339                         ppc_li (buf, ppc_r3, 0);
340                 } else
341                         ppc_lwz  (buf, ppc_r3,  STACK - 124, ppc_r1);
342                 ppc_lwz  (buf, ppc_r11, STACK - 44,  ppc_r1);
343                 
344                 /* Arg 2: code (next address to the instruction that called us) */
345                 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
346                         ppc_li (buf, ppc_r4, 0);
347                 } else
348                         ppc_lwz  (buf, ppc_r4, STACK + 4, ppc_r1);
349                 
350                 /* Arg 3: stack pointer */
351                 ppc_mr   (buf, ppc_r5, ppc_r1);
352                 
353                 /* Calculate call address, restore r0 and call
354                 'ppc_magic_trampoline'. Return value will be in r3 */
355                 if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
356                         ppc_lis  (buf, ppc_r0, (guint32) ppc_class_init_trampoline >> 16);
357                         ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) ppc_class_init_trampoline & 0xffff);
358                 } else {
359                         ppc_lis  (buf, ppc_r0, (guint32) ppc_magic_trampoline >> 16);
360                         ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) ppc_magic_trampoline & 0xffff);
361                 }
362                 ppc_mtlr (buf, ppc_r0);
363                 ppc_lwz  (buf, ppc_r0, STACK - 8,  ppc_r1);
364                 ppc_blrl (buf);
365                 
366                 /* OK, code address is now on r3. Move it to r0, so that we
367                 can restore r3 and use it from r0 later */
368                 ppc_mr   (buf, ppc_r0, ppc_r3);
369                 
370
371                 /*----------------------------------------------------------
372                 STEP 3: Restore the LMF
373                 ----------------------------------------------------------*/
374                 
375                 /* XXX Do it !!! */
376                 
377                 /*----------------------------------------------------------
378                 STEP 4: call the compiled method
379                 ----------------------------------------------------------*/
380                 
381                 /* Restore registers */
382
383                 ppc_lwz  (buf, ppc_r3,  STACK - 12,  ppc_r1);
384                 ppc_lwz  (buf, ppc_r4,  STACK - 16,  ppc_r1);
385                 ppc_lwz  (buf, ppc_r5,  STACK - 20,  ppc_r1);
386                 ppc_lwz  (buf, ppc_r6,  STACK - 24,  ppc_r1);
387                 ppc_lwz  (buf, ppc_r7,  STACK - 28,  ppc_r1);
388                 ppc_lwz  (buf, ppc_r8,  STACK - 32,  ppc_r1);
389                 ppc_lwz  (buf, ppc_r9,  STACK - 36,  ppc_r1);
390                 ppc_lwz  (buf, ppc_r10, STACK - 40,  ppc_r1);
391                 
392                 /* We haven't touched any of these, so there's no need to
393                 restore them */
394                 /*
395                 ppc_lwz  (buf, ppc_r14, STACK - 56,  ppc_r1);
396                 ppc_lwz  (buf, ppc_r15, STACK - 60,  ppc_r1);
397                 ppc_lwz  (buf, ppc_r16, STACK - 64,  ppc_r1);
398                 ppc_lwz  (buf, ppc_r17, STACK - 68,  ppc_r1);
399                 ppc_lwz  (buf, ppc_r18, STACK - 72,  ppc_r1);
400                 ppc_lwz  (buf, ppc_r19, STACK - 76,  ppc_r1);
401                 ppc_lwz  (buf, ppc_r20, STACK - 80,  ppc_r1);
402                 ppc_lwz  (buf, ppc_r21, STACK - 84,  ppc_r1);
403                 ppc_lwz  (buf, ppc_r22, STACK - 88,  ppc_r1);
404                 ppc_lwz  (buf, ppc_r23, STACK - 92,  ppc_r1);
405                 ppc_lwz  (buf, ppc_r24, STACK - 96,  ppc_r1);
406                 ppc_lwz  (buf, ppc_r25, STACK - 100, ppc_r1);
407                 ppc_lwz  (buf, ppc_r26, STACK - 104, ppc_r1);
408                 ppc_lwz  (buf, ppc_r27, STACK - 108, ppc_r1);
409                 ppc_lwz  (buf, ppc_r28, STACK - 112, ppc_r1);
410                 ppc_lwz  (buf, ppc_r29, STACK - 116, ppc_r1);
411                 ppc_lwz  (buf, ppc_r30, STACK - 120, ppc_r1);
412                 */
413
414                 /* Non-standard function epilogue. Instead of doing a proper
415                 return, we just call the compiled code, so
416                 that, when it finishes, the method returns here. */
417                 
418                 ppc_mtlr (buf, ppc_r0);
419                 ppc_blrl (buf);
420                 
421                 /* Restore stack pointer, r31, LR and return to caller */
422                 ppc_lwz  (buf, ppc_r11,  0, ppc_r1);
423                 ppc_lwz  (buf, ppc_r31, -4, ppc_r11);
424                 ppc_mr   (buf, ppc_r1, ppc_r11);
425                 ppc_lwz  (buf, ppc_r0, 4, ppc_r1);
426                 ppc_mtlr (buf, ppc_r0);
427                 ppc_blr  (buf); 
428                 
429                 /* Flush instruction cache, since we've generated code */
430                 mono_arch_flush_icache (code, buf - code);
431         
432                 /* Sanity check */
433                 g_assert ((buf - code) <= 512);
434         }
435
436         switch (tramp_type) {
437         case MONO_TRAMPOLINE_GENERIC:
438                 mono_generic_trampoline_code = code;
439                 break;
440         case MONO_TRAMPOLINE_JUMP:
441                 generic_jump_trampoline = code;
442                 break;
443         case MONO_TRAMPOLINE_CLASS_INIT:
444                 generic_class_init_trampoline = code;
445                 break;
446         }
447
448         return code;
449 }
450
451 /**
452  * arch_create_jit_trampoline:
453  * @method: pointer to the method info
454  *
455  * Creates a trampoline function for virtual methods. If the created
456  * code is called it first starts JIT compilation of method,
457  * and then calls the newly created method. It also replaces the
458  * corresponding vtable entry (see ppc_magic_trampoline).
459  *
460  * A trampoline consists of two parts: a main fragment, shared by all method
461  * trampolines, and some code specific to each method, which hard-codes a
462  * reference to that method and then calls the main fragment.
463  *
464  * The main fragment contains a call to 'ppc_magic_trampoline', which performs
465  * call to the JIT compiler and substitutes the method-specific fragment with
466  * some code that directly calls the JIT-compiled method.
467  * 
468  * Returns: a pointer to the newly created code 
469  */
470 gpointer
471 mono_arch_create_jit_trampoline (MonoMethod *method)
472 {
473         guint8 *code, *buf;
474         static guint8 *vc = NULL;
475
476         /* previously created trampoline code */
477         if (method->info)
478                 return method->info;
479
480         /* we immediately compile runtime provided functions */
481         if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
482                 method->info = mono_compile_method (method);
483                 return method->info;
484         }
485
486         /* icalls use method->addr */
487         if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
488             (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
489                 MonoMethod *nm;
490                 
491                 nm = mono_marshal_get_native_wrapper (method);
492                 method->info = mono_compile_method (nm);
493                 return method->info;
494         }
495
496         if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
497                 return mono_arch_create_jit_trampoline (mono_marshal_get_synchronized_wrapper (method));
498
499         vc = create_trampoline_code (MONO_TRAMPOLINE_GENERIC);
500
501         /* This is the method-specific part of the trampoline. Its purpose is
502         to provide the generic part with the MonoMethod *method pointer. We'll
503         use r11 to keep that value, for instance. However, the generic part of
504         the trampoline relies on r11 having the same value it had before coming
505         here, so we must save it before. */
506         code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
507         
508         /* Save r11. There's nothing magic in the '44', its just an arbitrary
509         position - see above */
510         ppc_stw  (buf, ppc_r11, -44,  ppc_r1);
511         
512         /* Now save LR - we'll overwrite it now */
513         ppc_mflr (buf, ppc_r11);
514         ppc_stw  (buf, ppc_r11, 4, ppc_r1);
515         
516         /* Prepare the jump to the generic trampoline code.*/
517         ppc_lis  (buf, ppc_r11, (guint32) vc >> 16);
518         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) vc & 0xffff);
519         ppc_mtlr (buf, ppc_r11);
520         
521         /* And finally put 'method' in r11 and fly! */
522         ppc_lis  (buf, ppc_r11, (guint32) method >> 16);
523         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) method & 0xffff);
524         ppc_blr  (buf);
525         
526         /* Flush instruction cache, since we've generated code */
527         mono_arch_flush_icache (code, buf - code);
528                 
529         /* Sanity check */
530         g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
531         
532         /* Store trampoline address */
533         method->info = code;
534
535         mono_jit_stats.method_trampolines++;
536
537         return code;
538 }
539
540 #if 0
541
542 /**
543  * x86_magic_trampoline:
544  * @eax: saved x86 register 
545  * @ecx: saved x86 register 
546  * @edx: saved x86 register 
547  * @esi: saved x86 register 
548  * @edi: saved x86 register 
549  * @ebx: saved x86 register
550  * @code: pointer into caller code
551  * @method: the method to translate
552  *
553  * This method is called by the trampoline functions for virtual
554  * methods. It inspects the caller code to find the address of the
555  * vtable slot, then calls the JIT compiler and writes the address
556  * of the compiled method back to the vtable. All virtual methods 
557  * are called with: x86_call_membase (inst, basereg, disp). We always
558  * use 32 bit displacement to ensure that the length of the call 
559  * instruction is 6 bytes. We need to get the value of the basereg 
560  * and the constant displacement.
561  */
562 static gpointer
563 x86_magic_trampoline (int eax, int ecx, int edx, int esi, int edi, 
564                       int ebx, guint8 *code, MonoMethod *m)
565 {
566         guint8 reg;
567         gint32 disp;
568         char *o;
569         gpointer addr;
570
571         addr = mono_compile_method (m);
572         g_assert (addr);
573
574         /* go to the start of the call instruction
575          *
576          * address_byte = (m << 6) | (o << 3) | reg
577          * call opcode: 0xff address_byte displacement
578          * 0xff m=1,o=2 imm8
579          * 0xff m=2,o=2 imm32
580          */
581         code -= 6;
582         if ((code [1] != 0xe8) && (code [3] == 0xff) && ((code [4] & 0x18) == 0x10) && ((code [4] >> 6) == 1)) {
583                 reg = code [4] & 0x07;
584                 disp = (signed char)code [5];
585         } else {
586                 if ((code [0] == 0xff) && ((code [1] & 0x18) == 0x10) && ((code [1] >> 6) == 2)) {
587                         reg = code [1] & 0x07;
588                         disp = *((gint32*)(code + 2));
589                 } else if ((code [1] == 0xe8)) {
590                         *((guint32*)(code + 2)) = (guint)addr - ((guint)code + 1) - 5; 
591                         return addr;
592                 } else if ((code [4] == 0xff) && (((code [5] >> 6) & 0x3) == 0) && (((code [5] >> 3) & 0x7) == 2)) {
593                         /*
594                          * This is a interface call: should check the above code can't catch it earlier 
595                          * 8b 40 30   mov    0x30(%eax),%eax
596                          * ff 10      call   *(%eax)
597                          */
598                         disp = 0;
599                         reg = code [5] & 0x07;
600                 } else {
601                         printf ("Invalid trampoline sequence: %x %x %x %x %x %x %x\n", code [0], code [1], code [2], code [3],
602                                 code [4], code [5], code [6]);
603                         g_assert_not_reached ();
604                 }
605         }
606
607         switch (reg) {
608         case X86_EAX:
609                 o = (gpointer)eax;
610                 break;
611         case X86_EDX:
612                 o = (gpointer)edx;
613                 break;
614         case X86_ECX:
615                 o = (gpointer)ecx;
616                 break;
617         case X86_ESI:
618                 o = (gpointer)esi;
619                 break;
620         case X86_EDI:
621                 o = (gpointer)edi;
622                 break;
623         case X86_EBX:
624                 o = (gpointer)ebx;
625                 break;
626         default:
627                 g_assert_not_reached ();
628         }
629
630         o += disp;
631
632         if (m->klass->valuetype) {
633                 return *((gpointer *)o) = get_unbox_trampoline (m, addr);
634         } else {
635                 return *((gpointer *)o) = addr;
636         }
637 }
638
639 /**
640  * mono_arch_create_jit_trampoline:
641  * @method: pointer to the method info
642  *
643  * Creates a trampoline function for virtual methods. If the created
644  * code is called it first starts JIT compilation of method,
645  * and then calls the newly created method. I also replaces the
646  * corresponding vtable entry (see x86_magic_trampoline).
647  * 
648  * Returns: a pointer to the newly created code 
649  */
650 gpointer
651 mono_arch_create_jit_trampoline (MonoMethod *method)
652 {
653         guint8 *code, *buf;
654
655         /* previously created trampoline code */
656         if (method->info)
657                 return method->info;
658
659         /* we immediately compile runtime provided functions */
660         if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
661                 method->info = mono_compile_method (method);
662                 return method->info;
663         }
664
665         /* icalls use method->addr */
666         if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
667             (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
668                 MonoMethod *nm;
669                 
670                 nm = mono_marshal_get_native_wrapper (method);
671                 method->info = mono_compile_method (nm);
672                 return method->info;
673         }
674
675         if (!mono_generic_trampoline_code) {
676                 mono_generic_trampoline_code = buf = g_malloc (256);
677                 /* save caller save regs because we need to do a call */ 
678                 x86_push_reg (buf, X86_EDX);
679                 x86_push_reg (buf, X86_EAX);
680                 x86_push_reg (buf, X86_ECX);
681
682                 /* save LMF begin */
683
684                 /* save the IP (caller ip) */
685                 x86_push_membase (buf, X86_ESP, 16);
686
687                 x86_push_reg (buf, X86_EBX);
688                 x86_push_reg (buf, X86_EDI);
689                 x86_push_reg (buf, X86_ESI);
690                 x86_push_reg (buf, X86_EBP);
691
692                 /* save method info */
693                 x86_push_membase (buf, X86_ESP, 32);
694                 /* get the address of lmf for the current thread */
695                 x86_call_code (buf, mono_get_lmf_addr);
696                 /* push lmf */
697                 x86_push_reg (buf, X86_EAX); 
698                 /* push *lfm (previous_lmf) */
699                 x86_push_membase (buf, X86_EAX, 0);
700                 /* *(lmf) = ESP */
701                 x86_mov_membase_reg (buf, X86_EAX, 0, X86_ESP, 4);
702                 /* save LFM end */
703
704                 /* push the method info */
705                 x86_push_membase (buf, X86_ESP, 44);
706                 /* push the return address onto the stack */
707                 x86_push_membase (buf, X86_ESP, 52);
708
709                 /* save all register values */
710                 x86_push_reg (buf, X86_EBX);
711                 x86_push_reg (buf, X86_EDI);
712                 x86_push_reg (buf, X86_ESI);
713                 x86_push_membase (buf, X86_ESP, 64); /* EDX */
714                 x86_push_membase (buf, X86_ESP, 64); /* ECX */
715                 x86_push_membase (buf, X86_ESP, 64); /* EAX */
716
717                 x86_call_code (buf, x86_magic_trampoline);
718                 x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 8*4);
719
720                 /* restore LMF start */
721                 /* ebx = previous_lmf */
722                 x86_pop_reg (buf, X86_EBX);
723                 /* edi = lmf */
724                 x86_pop_reg (buf, X86_EDI);
725                 /* *(lmf) = previous_lmf */
726                 x86_mov_membase_reg (buf, X86_EDI, 0, X86_EBX, 4);
727                 /* discard method info */
728                 x86_pop_reg (buf, X86_ESI);
729                 /* restore caller saved regs */
730                 x86_pop_reg (buf, X86_EBP);
731                 x86_pop_reg (buf, X86_ESI);
732                 x86_pop_reg (buf, X86_EDI);
733                 x86_pop_reg (buf, X86_EBX);
734                 /* discard save IP */
735                 x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);             
736                 /* restore LMF end */
737
738                 x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 16);
739
740                 /* call the compiled method */
741                 x86_jump_reg (buf, X86_EAX);
742
743                 g_assert ((buf - mono_generic_trampoline_code) <= 256);
744         }
745
746         code = buf = g_malloc (16);
747         x86_push_imm (buf, method);
748         x86_jump_code (buf, mono_generic_trampoline_code);
749         g_assert ((buf - code) <= 16);
750
751         /* store trampoline address */
752         method->info = code;
753
754         //mono_jit_stats.method_trampolines++;
755
756         return code;
757 }
758
759 #endif
760
761 /**
762  * mono_arch_create_class_init_trampoline:
763  *  @vtable: the type to initialize
764  *
765  * Creates a trampoline function to run a type initializer. 
766  * If the trampoline is called, it calls mono_runtime_class_init with the
767  * given vtable, then patches the caller code so it does not get called any
768  * more.
769  * 
770  * Returns: a pointer to the newly created code 
771  */
772 gpointer
773 mono_arch_create_class_init_trampoline (MonoVTable *vtable)
774 {
775         guint8 *code, *buf, *tramp;
776
777         tramp = create_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
778
779         /* This is the method-specific part of the trampoline. Its purpose is
780         to provide the generic part with the MonoMethod *method pointer. We'll
781         use r11 to keep that value, for instance. However, the generic part of
782         the trampoline relies on r11 having the same value it had before coming
783         here, so we must save it before. */
784         code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
785         
786         /* Save r11. There's nothing magic in the '44', its just an arbitrary
787         position - see above */
788         ppc_stw  (buf, ppc_r11, -44,  ppc_r1);
789         
790         /* Now save LR - we'll overwrite it now */
791         ppc_mflr (buf, ppc_r11);
792         ppc_stw  (buf, ppc_r11, 4, ppc_r1);
793         
794         /* Prepare the jump to the generic trampoline code.*/
795         ppc_lis  (buf, ppc_r11, (guint32) tramp >> 16);
796         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) tramp & 0xffff);
797         ppc_mtlr (buf, ppc_r11);
798         
799         /* And finally put 'vtable' in r11 and fly! */
800         ppc_lis  (buf, ppc_r11, (guint32) vtable >> 16);
801         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) vtable & 0xffff);
802         ppc_blr  (buf);
803         
804         /* Flush instruction cache, since we've generated code */
805         mono_arch_flush_icache (code, buf - code);
806                 
807         /* Sanity check */
808         g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
809
810         mono_jit_stats.method_trampolines++;
811
812         return code;
813 }
814
815 /*
816  * This method is only called when running in the Mono Debugger.
817  */
818 gpointer
819 mono_debugger_create_notification_function (gpointer *notification_address)
820 {
821         guint8 *ptr, *buf;
822
823         ptr = buf = g_malloc0 (16);
824         ppc_break (buf);
825         if (notification_address)
826                 *notification_address = buf;
827         ppc_blr (buf);
828
829         return ptr;
830 }
831