* Merged in twisti-branch.
[cacao.git] / src / vm / jit / m68k / asmpart.S
1 /*      src/vm/jit/m68k/asmpart.S
2  *      for cacao 
3  *      Roland Lezuo
4  */
5
6 #include "config.h"
7
8 #include "vm/jit/m68k/offsets.h"
9
10 .data
11 call_jit_dummy:
12         .long 0xdeadbeef
13
14 .text
15
16 .globl asm_vm_call_method
17 .globl asm_vm_call_method_int
18 .globl asm_vm_call_method_long
19 .globl asm_vm_call_method_float
20 .globl asm_vm_call_method_double
21 .globl asm_vm_call_method_end
22 .globl asm_vm_call_method_exception_handler
23
24 .globl asm_call_jit_compiler
25
26 .globl asm_patcher_wrapper
27
28 .globl asm_getclassvalues_atomic
29 .globl asm_abstractmethoderror
30 .globl asm_criticalsections
31
32 .globl asm_handle_exception
33
34 /*
35  *      This functions implement the C prototyped funtion
36  *      java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,vm_arg *vmargs);
37  *      the _int, _long, _float, _double are used for different return types
38  *
39  *      The function may still be uncompiled, so the jit compiler gets invoked.
40  *
41  *
42  */
43
44         /* this is the method header see src/vm/jit/methodheader.h */
45         .align  4
46         .long   0                           /* catch type all                     */
47         .long   0                           /* handler pc                         */
48         .long   0                           /* end pc                             */
49         .long   0                           /* start pc                           */
50         .long   1                           /* extable size                       */
51         .long   0                           /* line number table start            */
52         .long   0                           /* line number table size             */
53         .long   0                           /* fltsave                            */
54         .long   0                           /* intsave                            */
55         .long   0                           /* isleaf                             */
56         .long   0                           /* IsSync                             */
57         .long   0                           /* frame size                         */
58         .long   0                           /* codeinfo pointer                   */
59 asm_vm_call_method:
60 asm_vm_call_method_int:
61 asm_vm_call_method_long:
62 asm_vm_call_method_float:
63 asm_vm_call_method_double:
64         addal   #(-11*4),%sp                                            /* create stackframe to save registers */
65         moveml  %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@        /* save registers */
66
67         /* fetch arguments from vmargs data structure */
68         movel   %sp@(11*4+1*4),%a2                              /* methodinfo argument in atmp1 */
69         movel   %sp@(11*4+3*4),%a3                              /* args block */
70         movel   %sp@(11*4+2*4),%d2                              /* arg count */
71
72         moveal  %sp, %a5                                        /* memorize stack */
73         tst     %d2                                             /* do we have arguments ? */
74         beq     L_asm_vm_call_method_copy_done
75         subql   #1,%d2                                          /* simplifies offset calulation */
76
77         movel   #(sizevmarg), %d0
78         mulsl   %d2, %d0                                        
79         moveal  %a3, %a0
80         addal   %d0, %a0                                        /* %a0 points to last vmarg block */
81
82         addql   #1, %d2
83 L_asm_vm_call_copy_arg:
84         subql   #1, %d2                                         /* why wasn't that here */
85
86         movel   %a0@(offvmargdata+4), %d0
87         movel   %d0,%sp@-                                       /* push argument onto stack */
88
89         movel   %a0@(offvmargtype), %d0                         /* %d0 contains type of arg */  
90         btstl   #0, %d0                                         /* test if 2 word type */
91         beq     L_asm_vm_call_copy_1_word_type
92         movel   %a0@(offvmargdata), %d0                         /* push second word onto stack */
93         movel   %d0,%sp@-
94 L_asm_vm_call_copy_1_word_type:
95
96         subl    #(sizevmarg),%a0
97         tst     %d2                                             /* arguments left ? */
98         bne     L_asm_vm_call_copy_arg
99
100 L_asm_vm_call_method_copy_done:
101
102         leal    asm_call_jit_compiler,%a4                       /* we need to fake a invocation as it would happen from jit code */
103         movel   %a4, call_jit_dummy                             /* we need a writeable memory location */
104         moveal  call_jit_dummy, %a4                             /* XXX do we have a race condition here ? */
105         jsr     %a4@
106
107 L_asm_vm_call_method_return:
108         movel   %a5, %sp                                                /* pop arguments off stack */
109         moveml  %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp       /* restore registers */
110         addal   #(11*4),%sp                                             /* restore stack */
111         rts                                                             /* return to c code */
112         jsr 0   /* never come back ? */
113
114 /* asm_vm_call_method_exception_handler 
115  *
116  * calls void *builtin_throw_exception(java_objectheader *xptr) when no other handler is appropiate
117  * this functions gets called indirectly from asm_handle_exception, which back then moved xptr to %a3
118  * clear software design is in the eye of the beholder.
119  */
120 asm_vm_call_method_exception_handler:
121         movel   %a3, %sp@-                      /* push xptr argument */
122         jsr     builtin_throw_exception
123         lea     %sp@(4), %sp                    /* pop arg off stack */
124         bra     L_asm_vm_call_method_return
125
126
127 asm_vm_call_method_end:                                         /* symbol needed to insert method into avl tree */
128         rts
129 /*
130  *      Invokes compiler for untranslated java methods.
131  *      C prototype: void asm_call_jit_compiler(void);
132  *      BUT: this does not match reality, arguments _ARE_ passed via createcompilerstub and asm_vm_call_method...
133  *      arguments passed via %a2(methodinfo) == REG_ATMP1
134  *                           %a3(mptr)       == REG_ATMP2
135  */
136 asm_call_jit_compiler:
137         addal   #(-4*4),%sp                                             /* create stackframe to save registers */
138         moveml  %a0/%a1/%d0/%d1,%sp@                                    /* save volatile registers */
139
140         movel   %sp@(4*4),%sp@-                                         /* push arguments onto stack (ra)*/
141         pea     %sp@(4*4+4)                                             /* the old stack pointer */
142         movel   %a3,%sp@-                                               /* mptr */
143         movel   %a2,%sp@-                                               /* methodinfo */
144
145         /* C prototype: u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra); */
146         jsr     jit_asm_compile                                         /* invoke compiler */
147         lea     %sp@(4*4),%sp                                           /* pop arguments off stack */
148         moveal  %d0, %a2                                                /* to tmp register */
149
150         moveml %sp@,%a0/%a1/%d0/%d1                                     /* restore volatile registers */
151         addal   #(4*4),%sp                                              /* remove stackframe */
152
153         tstl    %a2                                                     /* check for exception */
154         beq     L_asm_call_jit_compiler_exception
155
156         jmp     %a2@                                                    /* invoke java method */
157         jsr     0                                                       /* we should not ever return here */
158
159 L_asm_call_jit_compiler_exception:
160         jsr     0                                                       /* TODO */
161
162         moveml  %fp@(-4*4), %a0/%a1/%d0/%d1                             /* restore registers */
163         unlk    %fp                                                     /* FIXME: this is wrong */
164         rts
165
166 /* asm_patcher_wrapper ********************************************************
167         
168   prepares arguments on stack
169   calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
170
171   Stack layout:
172      24   return address
173      20   REG_ITMP3
174      16   pointer to virtual java_objectheader
175      12   last byte of machine code (xmcode)
176       8   machine code (which is patched back later)
177       4   unresolved field reference
178       0   patcher function pointer to call
179 *******************************************************************************/
180 asm_patcher_wrapper:
181
182   movel %sp, %d0
183   /* save scratch registers */
184   movel %a0, %sp@-
185   movel %a1, %sp@-
186   movel %d0, %sp@-
187   movel %d1, %sp@-
188 #if !defined(ENABLE_SOFTFLOAT)
189   movel %f0, %sp@-
190   movel %f1, %sp@-
191 #endif
192
193   clrl  %sp@-                           /* pass ra */
194   clrl  %sp@-                           /* pass pv, if null use findmethod */
195   movel %d0, %sp@-                      /* pass sp of patcher stub */
196   jsr   patcher_wrapper                 /* return value in %d0 */
197
198   lea   %sp@(3*4), %sp                  /* pop arguments off stack */
199
200   tst   %d0                             /* test if exception occured */
201   bne   L_asm_patcher_wrapper_exception
202
203 #if !defined(ENABLE_SOFTFLOAT)
204   movel %sp@+, %f0
205   movel %sp@+, %f1
206 #endif
207   movel %sp@+, %d1
208   movel %sp@+, %d0
209   movel %sp@+, %a1
210   movel %sp@+, %a0
211
212   lea   %sp@(6*4), %sp                  /* restore stack and remove patcher stub*/
213   rts                                   /* back to jit code */
214
215 L_asm_patcher_wrapper_exception:
216   /* WARNING: the stack is still disturbed, look at asm_patcher_wrapper for details */
217   jsr 0                                 /* TODO */
218
219 /********************************************************************************
220         Reads a few values atomically. 
221         C signature:
222         void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
223
224         super ... sp@(4)
225         sub   ... sp@(8)
226         out   ... sp@(12)
227 ********************************************************************************/
228 asm_getclassvalues_atomic:
229 _crit_restart:
230 _crit_begin:
231         moveal  %sp@(4), %a0
232         movel   %a0@(offbaseval), %d0
233         movel   %a0@(offdiffval), %d1
234         
235         moveal  %sp@(8), %a0
236         moveal  %a0@(offbaseval), %a0
237 _crit_end:
238         moveal  %sp@(12), %a1
239         movel   %d0, %a1@(offcast_super_baseval)
240         movel   %d1, %a1@(offcast_super_diffval)
241         movel   %a0, %a1@(offcast_sub_baseval)
242
243         rts
244 .data
245 asm_criticalsections:
246 #if defined(ENABLE_THREADS)
247         .long _crit_begin
248         .long _crit_end
249         .long _crit_restart
250 #endif
251         .long 0
252 .text
253
254 asm_abstractmethoderror:
255
256 /* asm_handle_exception ********************************************************
257 *                                                                              *
258 *   This function handles an exception. It does not use the usual calling      *
259 *   conventions. The exception pointer is passed in REG_ATMP1 and the          *
260 *   pc from the exception raising position is passed in REG_ATMP2. It searches *
261 *   the local exception table for a handler. If no one is found, it unwinds    *
262 *   stacks and continues searching the callers.                                *
263 *                                                                              *
264 *   void asm_handle_exception (void);
265 *   exception object pointer...%a2   exception raising address...%a3           *
266 *                                                                              *
267 *******************************************************************************/
268 asm_handle_exception:
269 asm_handle_nat_exception:
270 L_asm_handle_exception_stack_loop:
271         
272         /* we need the dseg, figure it out */
273         movel   %a3, %sp@-                              /* push ra argument */
274         jsr     md_codegen_get_pv_from_pc               /* pv in %d0 now */
275         movel   %d0, %d2                                /* move to safe register */
276         lea     %sp@(4), %sp                            /* pop args off stack */
277
278         /* now call the following c function */
279         /* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
280         movel   %sp,%sp@-
281         movel   %d2,%sp@-
282         movel   %a3,%sp@-
283         movel   %a2,%sp@-
284         jsr     exceptions_handle_exception             /* %d0 is address of handler or 0 when not catched */
285         lea     %sp@(4*4), %sp                          /* pop args off stack */
286         tstl    %d0
287         beq     L_asm_handle_exception_not_catched
288
289         /* %d0 contains address of exception handler */
290         moveal  %d0, %a0
291         jsr     %a0@
292
293 L_asm_handle_exception_not_catched:
294         jsr 0
295 illegal
296 .long 0x23234242