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