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