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