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