2003-12-03 Zoltan Varga <vargaz@freemail.hu>
[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 + 8*8)
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 #if 0
214         /* This is the 'bl' instruction */
215         --code;
216         
217         if (((*code) >> 26) == 18) {
218                 ppc_ori (code, 0, 0, 0); /* nop */
219                 mono_arch_flush_icache (code, 4);
220                 return;
221         } else {
222                 g_assert_not_reached ();
223         }
224 #endif
225 }
226
227 static guchar*
228 create_trampoline_code (MonoTrampolineType tramp_type)
229 {
230         guint8 *buf, *code = NULL;
231         static guint8* generic_jump_trampoline = NULL;
232         static guint8 *generic_class_init_trampoline = NULL;
233         int i, offset;
234
235         switch (tramp_type) {
236         case MONO_TRAMPOLINE_GENERIC:
237                 if (mono_generic_trampoline_code)
238                         return mono_generic_trampoline_code;
239                 break;
240         case MONO_TRAMPOLINE_JUMP:
241                 if (generic_jump_trampoline)
242                         return generic_jump_trampoline;
243                 break;
244         case MONO_TRAMPOLINE_CLASS_INIT:
245                 if (generic_class_init_trampoline)
246                         return generic_class_init_trampoline;
247                 break;
248         }
249
250         if(!code) {
251                 /* Now we'll create in 'buf' the PowerPC trampoline code. This
252                  is the trampoline code common to all methods  */
253                 
254                 code = buf = g_malloc(512);
255                 
256                 /*-----------------------------------------------------------
257                 STEP 0: First create a non-standard function prologue with a
258                 stack size big enough to save our registers:
259                 
260                         lr              (We'll be calling functions here, so we
261                                         must save it)
262                         r0              (See ppc_magic_trampoline)
263                         r1 (sp)         (Stack pointer - must save)
264                         r3-r10          Function arguments.
265                         r11-r31         (See ppc_magic_trampoline)
266                         method in r11   (See ppc_magic_trampoline)
267                         
268                 This prologue is non-standard because r0 is not saved here - it
269                 was saved in the method-specific trampoline code
270                 -----------------------------------------------------------*/
271                 
272                 ppc_stwu (buf, ppc_r1, -STACK, ppc_r1);
273                 
274                 /* Save r0 before modifying it - we will need its contents in
275                 'ppc_magic_trampoline' */
276                 ppc_stw  (buf, ppc_r0,  STACK - 8,   ppc_r1);
277                 
278                 ppc_stw  (buf, ppc_r31, STACK - 4, ppc_r1);
279                 ppc_mr   (buf, ppc_r31, ppc_r1);
280                 
281                 /* Now save our registers. */
282                 ppc_stw  (buf, ppc_r3,  STACK - 12,  ppc_r1);
283                 ppc_stw  (buf, ppc_r4,  STACK - 16,  ppc_r1);
284                 ppc_stw  (buf, ppc_r5,  STACK - 20,  ppc_r1);
285                 ppc_stw  (buf, ppc_r6,  STACK - 24,  ppc_r1);
286                 ppc_stw  (buf, ppc_r7,  STACK - 28,  ppc_r1);
287                 ppc_stw  (buf, ppc_r8,  STACK - 32,  ppc_r1);
288                 ppc_stw  (buf, ppc_r9,  STACK - 36,  ppc_r1);
289                 ppc_stw  (buf, ppc_r10, STACK - 40,  ppc_r1);
290                 /* STACK - 44 contains r11, which is set in the method-specific
291                 part of the trampoline (see bellow this 'if' block) */
292                 ppc_stw  (buf, ppc_r12, STACK - 48,  ppc_r1);
293                 ppc_stw  (buf, ppc_r13, STACK - 52,  ppc_r1);
294                 ppc_stw  (buf, ppc_r14, STACK - 56,  ppc_r1);
295                 ppc_stw  (buf, ppc_r15, STACK - 60,  ppc_r1);
296                 ppc_stw  (buf, ppc_r16, STACK - 64,  ppc_r1);
297                 ppc_stw  (buf, ppc_r17, STACK - 68,  ppc_r1);
298                 ppc_stw  (buf, ppc_r18, STACK - 72,  ppc_r1);
299                 ppc_stw  (buf, ppc_r19, STACK - 76,  ppc_r1);
300                 ppc_stw  (buf, ppc_r20, STACK - 80,  ppc_r1);
301                 ppc_stw  (buf, ppc_r21, STACK - 84,  ppc_r1);
302                 ppc_stw  (buf, ppc_r22, STACK - 88,  ppc_r1);
303                 ppc_stw  (buf, ppc_r23, STACK - 92,  ppc_r1);
304                 ppc_stw  (buf, ppc_r24, STACK - 96,  ppc_r1);
305                 ppc_stw  (buf, ppc_r25, STACK - 100, ppc_r1);
306                 ppc_stw  (buf, ppc_r26, STACK - 104, ppc_r1);
307                 ppc_stw  (buf, ppc_r27, STACK - 108, ppc_r1);
308                 ppc_stw  (buf, ppc_r28, STACK - 112, ppc_r1);
309                 ppc_stw  (buf, ppc_r29, STACK - 116, ppc_r1);
310                 ppc_stw  (buf, ppc_r30, STACK - 120, ppc_r1);
311                 /* Save 'method' pseudo-parameter - the one passed in r11 */
312                 ppc_stw  (buf, ppc_r11, STACK - 124, ppc_r1);
313
314                 /* Save the FP registers */
315                 offset = 124 + 4 + 8;
316                 for (i = ppc_f1; i <= ppc_f8; ++i) {
317                         ppc_stfd  (buf, i, STACK - offset, ppc_r1);
318                         offset += 8;
319                 }
320
321                 /*----------------------------------------------------------
322                 STEP 1: call 'mono_get_lmf_addr()' to get the address of our
323                 LMF. We'll need to restore it after the call to
324                 'ppc_magic_trampoline' and before the call to the native
325                 method.
326                 ----------------------------------------------------------*/
327                                 
328                 /* Calculate the address and make the call. Keep in mind that
329                 we're using r0, so we'll have to restore it before calling
330                 'ppc_magic_trampoline' */
331                 ppc_lis  (buf, ppc_r0, (guint32) mono_get_lmf_addr >> 16);
332                 ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) mono_get_lmf_addr & 0xffff);
333                 ppc_mtlr (buf, ppc_r0);
334                 ppc_blrl (buf);
335
336                 /* XXX Update LMF !!! */
337                 
338                 /*----------------------------------------------------------
339                 STEP 2: call 'ppc_magic_trampoline()', who will compile the
340                 code and fix the method vtable entry for us
341                 ----------------------------------------------------------*/
342                                 
343                 /* Set arguments */
344                 
345                 /* Arg 1: MonoMethod *method. It was put in r11 by the
346                 method-specific trampoline code, and then saved before the call
347                 to mono_get_lmf_addr()'. Restore r11, by the way :-) */
348                 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
349                         ppc_li (buf, ppc_r3, 0);
350                 } else
351                         ppc_lwz  (buf, ppc_r3,  STACK - 124, ppc_r1);
352                 ppc_lwz  (buf, ppc_r11, STACK - 44,  ppc_r1);
353                 
354                 /* Arg 2: code (next address to the instruction that called us) */
355                 if (tramp_type == MONO_TRAMPOLINE_JUMP) {
356                         ppc_li (buf, ppc_r4, 0);
357                 } else
358                         ppc_lwz  (buf, ppc_r4, STACK + 4, ppc_r1);
359                 
360                 /* Arg 3: stack pointer */
361                 ppc_mr   (buf, ppc_r5, ppc_r1);
362                 
363                 /* Calculate call address, restore r0 and call
364                 'ppc_magic_trampoline'. Return value will be in r3 */
365                 if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT) {
366                         ppc_lis  (buf, ppc_r0, (guint32) ppc_class_init_trampoline >> 16);
367                         ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) ppc_class_init_trampoline & 0xffff);
368                 } else {
369                         ppc_lis  (buf, ppc_r0, (guint32) ppc_magic_trampoline >> 16);
370                         ppc_ori  (buf, ppc_r0, ppc_r0, (guint32) ppc_magic_trampoline & 0xffff);
371                 }
372                 ppc_mtlr (buf, ppc_r0);
373                 ppc_lwz  (buf, ppc_r0, STACK - 8,  ppc_r1);
374                 ppc_blrl (buf);
375                 
376                 /* OK, code address is now on r3. Move it to r0, so that we
377                 can restore r3 and use it from r0 later */
378                 ppc_mr   (buf, ppc_r0, ppc_r3);
379                 
380
381                 /*----------------------------------------------------------
382                 STEP 3: Restore the LMF
383                 ----------------------------------------------------------*/
384                 
385                 /* XXX Do it !!! */
386                 
387                 /*----------------------------------------------------------
388                 STEP 4: call the compiled method
389                 ----------------------------------------------------------*/
390                 
391                 /* Restore registers */
392
393                 ppc_lwz  (buf, ppc_r3,  STACK - 12,  ppc_r1);
394                 ppc_lwz  (buf, ppc_r4,  STACK - 16,  ppc_r1);
395                 ppc_lwz  (buf, ppc_r5,  STACK - 20,  ppc_r1);
396                 ppc_lwz  (buf, ppc_r6,  STACK - 24,  ppc_r1);
397                 ppc_lwz  (buf, ppc_r7,  STACK - 28,  ppc_r1);
398                 ppc_lwz  (buf, ppc_r8,  STACK - 32,  ppc_r1);
399                 ppc_lwz  (buf, ppc_r9,  STACK - 36,  ppc_r1);
400                 ppc_lwz  (buf, ppc_r10, STACK - 40,  ppc_r1);
401                 
402                 /* Restore the FP registers */
403                 offset = 124 + 4 + 8;
404                 for (i = ppc_f1; i <= ppc_f8; ++i) {
405                         ppc_lfd  (buf, i, STACK - offset, ppc_r1);
406                         offset += 8;
407                 }
408                 /* We haven't touched any of these, so there's no need to
409                 restore them */
410                 /*
411                 ppc_lwz  (buf, ppc_r14, STACK - 56,  ppc_r1);
412                 ppc_lwz  (buf, ppc_r15, STACK - 60,  ppc_r1);
413                 ppc_lwz  (buf, ppc_r16, STACK - 64,  ppc_r1);
414                 ppc_lwz  (buf, ppc_r17, STACK - 68,  ppc_r1);
415                 ppc_lwz  (buf, ppc_r18, STACK - 72,  ppc_r1);
416                 ppc_lwz  (buf, ppc_r19, STACK - 76,  ppc_r1);
417                 ppc_lwz  (buf, ppc_r20, STACK - 80,  ppc_r1);
418                 ppc_lwz  (buf, ppc_r21, STACK - 84,  ppc_r1);
419                 ppc_lwz  (buf, ppc_r22, STACK - 88,  ppc_r1);
420                 ppc_lwz  (buf, ppc_r23, STACK - 92,  ppc_r1);
421                 ppc_lwz  (buf, ppc_r24, STACK - 96,  ppc_r1);
422                 ppc_lwz  (buf, ppc_r25, STACK - 100, ppc_r1);
423                 ppc_lwz  (buf, ppc_r26, STACK - 104, ppc_r1);
424                 ppc_lwz  (buf, ppc_r27, STACK - 108, ppc_r1);
425                 ppc_lwz  (buf, ppc_r28, STACK - 112, ppc_r1);
426                 ppc_lwz  (buf, ppc_r29, STACK - 116, ppc_r1);
427                 ppc_lwz  (buf, ppc_r30, STACK - 120, ppc_r1);
428                 */
429
430                 /* Non-standard function epilogue. Instead of doing a proper
431                 return, we just call the compiled code, so
432                 that, when it finishes, the method returns here. */
433                 
434                 ppc_mtlr (buf, ppc_r0);
435                 ppc_blrl (buf);
436                 
437                 /* Restore stack pointer, r31, LR and return to caller */
438                 ppc_lwz  (buf, ppc_r11,  0, ppc_r1);
439                 ppc_lwz  (buf, ppc_r31, -4, ppc_r11);
440                 ppc_mr   (buf, ppc_r1, ppc_r11);
441                 ppc_lwz  (buf, ppc_r0, 4, ppc_r1);
442                 ppc_mtlr (buf, ppc_r0);
443                 ppc_blr  (buf); 
444                 
445                 /* Flush instruction cache, since we've generated code */
446                 mono_arch_flush_icache (code, buf - code);
447         
448                 /* Sanity check */
449                 g_assert ((buf - code) <= 512);
450         }
451
452         switch (tramp_type) {
453         case MONO_TRAMPOLINE_GENERIC:
454                 mono_generic_trampoline_code = code;
455                 break;
456         case MONO_TRAMPOLINE_JUMP:
457                 generic_jump_trampoline = code;
458                 break;
459         case MONO_TRAMPOLINE_CLASS_INIT:
460                 generic_class_init_trampoline = code;
461                 break;
462         }
463
464         return code;
465 }
466
467 /**
468  * arch_create_jit_trampoline:
469  * @method: pointer to the method info
470  *
471  * Creates a trampoline function for virtual methods. If the created
472  * code is called it first starts JIT compilation of method,
473  * and then calls the newly created method. It also replaces the
474  * corresponding vtable entry (see ppc_magic_trampoline).
475  *
476  * A trampoline consists of two parts: a main fragment, shared by all method
477  * trampolines, and some code specific to each method, which hard-codes a
478  * reference to that method and then calls the main fragment.
479  *
480  * The main fragment contains a call to 'ppc_magic_trampoline', which performs
481  * call to the JIT compiler and substitutes the method-specific fragment with
482  * some code that directly calls the JIT-compiled method.
483  * 
484  * Returns: a pointer to the newly created code 
485  */
486 gpointer
487 mono_arch_create_jit_trampoline (MonoMethod *method)
488 {
489         guint8 *code, *buf;
490         static guint8 *vc = NULL;
491
492         /* previously created trampoline code */
493         if (method->info)
494                 return method->info;
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         ppc_stw  (buf, ppc_r11, 8, ppc_r1);
516         
517         /* Prepare the jump to the generic trampoline code.*/
518         ppc_lis  (buf, ppc_r11, (guint32) vc >> 16);
519         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) vc & 0xffff);
520         ppc_mtlr (buf, ppc_r11);
521         
522         /* And finally put 'method' in r11 and fly! */
523         ppc_lis  (buf, ppc_r11, (guint32) method >> 16);
524         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) method & 0xffff);
525         ppc_blr  (buf);
526         
527         /* Flush instruction cache, since we've generated code */
528         mono_arch_flush_icache (code, buf - code);
529                 
530         /* Sanity check */
531         g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
532         
533         /* Store trampoline address */
534         method->info = code;
535
536         mono_jit_stats.method_trampolines++;
537
538         return code;
539 }
540
541 #if 0
542
543 /**
544  * x86_magic_trampoline:
545  * @eax: saved x86 register 
546  * @ecx: saved x86 register 
547  * @edx: saved x86 register 
548  * @esi: saved x86 register 
549  * @edi: saved x86 register 
550  * @ebx: saved x86 register
551  * @code: pointer into caller code
552  * @method: the method to translate
553  *
554  * This method is called by the trampoline functions for virtual
555  * methods. It inspects the caller code to find the address of the
556  * vtable slot, then calls the JIT compiler and writes the address
557  * of the compiled method back to the vtable. All virtual methods 
558  * are called with: x86_call_membase (inst, basereg, disp). We always
559  * use 32 bit displacement to ensure that the length of the call 
560  * instruction is 6 bytes. We need to get the value of the basereg 
561  * and the constant displacement.
562  */
563 static gpointer
564 x86_magic_trampoline (int eax, int ecx, int edx, int esi, int edi, 
565                       int ebx, guint8 *code, MonoMethod *m)
566 {
567         guint8 reg;
568         gint32 disp;
569         char *o;
570         gpointer addr;
571
572         addr = mono_compile_method (m);
573         g_assert (addr);
574
575         /* go to the start of the call instruction
576          *
577          * address_byte = (m << 6) | (o << 3) | reg
578          * call opcode: 0xff address_byte displacement
579          * 0xff m=1,o=2 imm8
580          * 0xff m=2,o=2 imm32
581          */
582         code -= 6;
583         if ((code [1] != 0xe8) && (code [3] == 0xff) && ((code [4] & 0x18) == 0x10) && ((code [4] >> 6) == 1)) {
584                 reg = code [4] & 0x07;
585                 disp = (signed char)code [5];
586         } else {
587                 if ((code [0] == 0xff) && ((code [1] & 0x18) == 0x10) && ((code [1] >> 6) == 2)) {
588                         reg = code [1] & 0x07;
589                         disp = *((gint32*)(code + 2));
590                 } else if ((code [1] == 0xe8)) {
591                         *((guint32*)(code + 2)) = (guint)addr - ((guint)code + 1) - 5; 
592                         return addr;
593                 } else if ((code [4] == 0xff) && (((code [5] >> 6) & 0x3) == 0) && (((code [5] >> 3) & 0x7) == 2)) {
594                         /*
595                          * This is a interface call: should check the above code can't catch it earlier 
596                          * 8b 40 30   mov    0x30(%eax),%eax
597                          * ff 10      call   *(%eax)
598                          */
599                         disp = 0;
600                         reg = code [5] & 0x07;
601                 } else {
602                         printf ("Invalid trampoline sequence: %x %x %x %x %x %x %x\n", code [0], code [1], code [2], code [3],
603                                 code [4], code [5], code [6]);
604                         g_assert_not_reached ();
605                 }
606         }
607
608         switch (reg) {
609         case X86_EAX:
610                 o = (gpointer)eax;
611                 break;
612         case X86_EDX:
613                 o = (gpointer)edx;
614                 break;
615         case X86_ECX:
616                 o = (gpointer)ecx;
617                 break;
618         case X86_ESI:
619                 o = (gpointer)esi;
620                 break;
621         case X86_EDI:
622                 o = (gpointer)edi;
623                 break;
624         case X86_EBX:
625                 o = (gpointer)ebx;
626                 break;
627         default:
628                 g_assert_not_reached ();
629         }
630
631         o += disp;
632
633         if (m->klass->valuetype) {
634                 return *((gpointer *)o) = get_unbox_trampoline (m, addr);
635         } else {
636                 return *((gpointer *)o) = addr;
637         }
638 }
639
640 /**
641  * mono_arch_create_jit_trampoline:
642  * @method: pointer to the method info
643  *
644  * Creates a trampoline function for virtual methods. If the created
645  * code is called it first starts JIT compilation of method,
646  * and then calls the newly created method. I also replaces the
647  * corresponding vtable entry (see x86_magic_trampoline).
648  * 
649  * Returns: a pointer to the newly created code 
650  */
651 gpointer
652 mono_arch_create_jit_trampoline (MonoMethod *method)
653 {
654         guint8 *code, *buf;
655
656         /* previously created trampoline code */
657         if (method->info)
658                 return method->info;
659
660         if (!mono_generic_trampoline_code) {
661                 mono_generic_trampoline_code = buf = g_malloc (256);
662                 /* save caller save regs because we need to do a call */ 
663                 x86_push_reg (buf, X86_EDX);
664                 x86_push_reg (buf, X86_EAX);
665                 x86_push_reg (buf, X86_ECX);
666
667                 /* save LMF begin */
668
669                 /* save the IP (caller ip) */
670                 x86_push_membase (buf, X86_ESP, 16);
671
672                 x86_push_reg (buf, X86_EBX);
673                 x86_push_reg (buf, X86_EDI);
674                 x86_push_reg (buf, X86_ESI);
675                 x86_push_reg (buf, X86_EBP);
676
677                 /* save method info */
678                 x86_push_membase (buf, X86_ESP, 32);
679                 /* get the address of lmf for the current thread */
680                 x86_call_code (buf, mono_get_lmf_addr);
681                 /* push lmf */
682                 x86_push_reg (buf, X86_EAX); 
683                 /* push *lfm (previous_lmf) */
684                 x86_push_membase (buf, X86_EAX, 0);
685                 /* *(lmf) = ESP */
686                 x86_mov_membase_reg (buf, X86_EAX, 0, X86_ESP, 4);
687                 /* save LFM end */
688
689                 /* push the method info */
690                 x86_push_membase (buf, X86_ESP, 44);
691                 /* push the return address onto the stack */
692                 x86_push_membase (buf, X86_ESP, 52);
693
694                 /* save all register values */
695                 x86_push_reg (buf, X86_EBX);
696                 x86_push_reg (buf, X86_EDI);
697                 x86_push_reg (buf, X86_ESI);
698                 x86_push_membase (buf, X86_ESP, 64); /* EDX */
699                 x86_push_membase (buf, X86_ESP, 64); /* ECX */
700                 x86_push_membase (buf, X86_ESP, 64); /* EAX */
701
702                 x86_call_code (buf, x86_magic_trampoline);
703                 x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 8*4);
704
705                 /* restore LMF start */
706                 /* ebx = previous_lmf */
707                 x86_pop_reg (buf, X86_EBX);
708                 /* edi = lmf */
709                 x86_pop_reg (buf, X86_EDI);
710                 /* *(lmf) = previous_lmf */
711                 x86_mov_membase_reg (buf, X86_EDI, 0, X86_EBX, 4);
712                 /* discard method info */
713                 x86_pop_reg (buf, X86_ESI);
714                 /* restore caller saved regs */
715                 x86_pop_reg (buf, X86_EBP);
716                 x86_pop_reg (buf, X86_ESI);
717                 x86_pop_reg (buf, X86_EDI);
718                 x86_pop_reg (buf, X86_EBX);
719                 /* discard save IP */
720                 x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 4);             
721                 /* restore LMF end */
722
723                 x86_alu_reg_imm (buf, X86_ADD, X86_ESP, 16);
724
725                 /* call the compiled method */
726                 x86_jump_reg (buf, X86_EAX);
727
728                 g_assert ((buf - mono_generic_trampoline_code) <= 256);
729         }
730
731         code = buf = g_malloc (16);
732         x86_push_imm (buf, method);
733         x86_jump_code (buf, mono_generic_trampoline_code);
734         g_assert ((buf - code) <= 16);
735
736         /* store trampoline address */
737         method->info = code;
738
739         //mono_jit_stats.method_trampolines++;
740
741         return code;
742 }
743
744 #endif
745
746 /**
747  * mono_arch_create_class_init_trampoline:
748  *  @vtable: the type to initialize
749  *
750  * Creates a trampoline function to run a type initializer. 
751  * If the trampoline is called, it calls mono_runtime_class_init with the
752  * given vtable, then patches the caller code so it does not get called any
753  * more.
754  * 
755  * Returns: a pointer to the newly created code 
756  */
757 gpointer
758 mono_arch_create_class_init_trampoline (MonoVTable *vtable)
759 {
760         guint8 *code, *buf, *tramp;
761
762         tramp = create_trampoline_code (MONO_TRAMPOLINE_CLASS_INIT);
763
764         /* This is the method-specific part of the trampoline. Its purpose is
765         to provide the generic part with the MonoMethod *method pointer. We'll
766         use r11 to keep that value, for instance. However, the generic part of
767         the trampoline relies on r11 having the same value it had before coming
768         here, so we must save it before. */
769         code = buf = g_malloc(METHOD_TRAMPOLINE_SIZE);
770
771 #if 1
772         ppc_mflr (buf, ppc_r4);
773         ppc_stw  (buf, ppc_r4, PPC_RET_ADDR_OFFSET, ppc_sp);
774         ppc_stwu (buf, ppc_sp, -32, ppc_sp);
775         ppc_load (buf, ppc_r3, vtable);
776         ppc_load (buf, ppc_r5, 0);
777
778         ppc_load (buf, ppc_r0, ppc_class_init_trampoline);
779         ppc_mtlr (buf, ppc_r0);
780         ppc_blrl (buf);
781
782         ppc_lwz (buf, ppc_r0, 32 + PPC_RET_ADDR_OFFSET, ppc_sp);
783         ppc_mtlr (buf, ppc_r0);
784         ppc_addic (buf, ppc_sp, ppc_sp, 32);
785         ppc_blr (buf);
786 #else
787         /* Save r11. There's nothing magic in the '44', its just an arbitrary
788         position - see above */
789         ppc_stw  (buf, ppc_r11, -44,  ppc_r1);
790         
791         /* Now save LR - we'll overwrite it now */
792         ppc_mflr (buf, ppc_r11);
793         ppc_stw  (buf, ppc_r11, 4, ppc_r1);
794         ppc_stw  (buf, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_r1);
795         
796         /* Prepare the jump to the generic trampoline code.*/
797         ppc_lis  (buf, ppc_r11, (guint32) tramp >> 16);
798         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) tramp & 0xffff);
799         ppc_mtlr (buf, ppc_r11);
800         
801         /* And finally put 'vtable' in r11 and fly! */
802         ppc_lis  (buf, ppc_r11, (guint32) vtable >> 16);
803         ppc_ori  (buf, ppc_r11, ppc_r11, (guint32) vtable & 0xffff);
804         ppc_blrl  (buf);
805         ppc_lwz (buf, ppc_r0, PPC_RET_ADDR_OFFSET, ppc_r1);
806         ppc_mtlr (buf, ppc_r0);
807         ppc_blr (buf);
808
809 #endif
810
811         /* Flush instruction cache, since we've generated code */
812         mono_arch_flush_icache (code, buf - code);
813                 
814         /* Sanity check */
815         g_assert ((buf - code) <= METHOD_TRAMPOLINE_SIZE);
816
817         mono_jit_stats.method_trampolines++;
818
819         return code;
820 }
821
822 /*
823  * This method is only called when running in the Mono Debugger.
824  */
825 gpointer
826 mono_debugger_create_notification_function (gpointer *notification_address)
827 {
828         guint8 *ptr, *buf;
829
830         ptr = buf = g_malloc0 (16);
831         ppc_break (buf);
832         if (notification_address)
833                 *notification_address = buf;
834         ppc_blr (buf);
835
836         return ptr;
837 }
838