* src/vm/jit/m68k/emit.c (emit_verbosecall_enter): Fixed for 8 byte stack slots.
[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 .text
13
14 .globl asm_vm_call_method
15 .globl asm_vm_call_method_int
16 .globl asm_vm_call_method_long
17 .globl asm_vm_call_method_float
18 .globl asm_vm_call_method_double
19 .globl asm_vm_call_method_end
20 .globl asm_vm_call_method_exception_handler
21
22 .globl asm_call_jit_compiler
23
24 .globl asm_patcher_wrapper
25
26 .globl asm_getclassvalues_atomic
27 .globl asm_abstractmethoderror
28 .globl asm_criticalsections
29
30 .globl asm_handle_exception
31 .globl asm_handle_nat_exception
32
33 /*
34  *      This functions implement the C prototyped funtion
35  *      java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,vm_arg *vmargs);
36  *      the _int, _long, _float, _double are used for different return types
37  *
38  *      The function may still be uncompiled, so the jit compiler gets invoked.
39  *
40  *
41  */
42
43         /* this is the method header see src/vm/jit/methodheader.h */
44         .align  4
45         .long   0                           /* catch type all                     */
46         .long   0                           /* handler pc                         */
47         .long   0                           /* end pc                             */
48         .long   0                           /* start pc                           */
49         .long   1                           /* extable size                       */
50         .long   0                           /* line number table start            */
51         .long   0                           /* line number table size             */
52         .long   0                           /* fltsave                            */
53         .long   0                           /* intsave                            */
54         .long   0                           /* isleaf                             */
55         .long   0                           /* IsSync                             */
56         .long   0                           /* frame size                         */
57         .long   0                           /* codeinfo pointer                   */
58
59
60 /*
61         This method gets called with 3 arguments:
62         1st arg: addres of method to call (fake invokevirtual here)
63         2nd arg: uint64_t array of argument registers followed by stack 
64         3rd arg: number of 8 byte stack slots to be copied.
65
66         coldifire does not use any argument registers, so just the stack has to be copied
67 */
68 asm_vm_call_method:
69 asm_vm_call_method_int:
70 asm_vm_call_method_long:
71 asm_vm_call_method_float:
72 asm_vm_call_method_double:
73
74 #if defined(ENABLE_SOFTFLOAT)
75         addal   #(-12*4),%sp                                            /* create stackframe to save registers, and 1 slot for method invocation */
76         moveml  %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@        /* save registers */
77
78         /* fetch arguments from vmargs data structure */
79         movel   %sp@(12*4+1*4),%a3                              /* method */
80         movel   %sp@(12*4+2*4),%a2                              /* arg array */
81         movel   %sp@(12*4+3*4),%d2                              /* arg count */
82
83         movel   %a3, %sp@(12*4)                                 /* copy method address to stackslot */
84         leal    %sp@(12*4), %a3                                 /* and store that address in %a3 */
85 #else
86         addal #(-12*4-6*8), %sp
87         moveml  %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@        /* save registers */
88         fmovemd %fp2/%fp3/%fp4/%fp5/%fp6/%fp7,%sp@(11*4)                        /* save registers */
89
90         /* fetch arguments from vmargs data structure */
91         movel   %sp@(12*4+6*8+1*4),%a3                          /* method */
92         movel   %sp@(12*4+6*8+2*4),%a2                          /* arg array */
93         movel   %sp@(12*4+6*8+3*4),%d2                          /* arg count */
94
95         movel   %a3, %sp@(11*4+6*8)                                     /* copy method address to stackslot */
96         leal    %sp@(11*4+6*8), %a3                                     /* and store that address in %a3 */
97 #endif
98
99         moveal  %sp, %a5                                        /* memorize stack */
100
101         tstl    %d2                                                     /* do we have arguments ? */
102         beq     L_asm_vm_call_method_copy_done
103         movel   %d2, %d3                                                /* create stackframe */
104         asll    #3,  %d3                                                /* number args * 8 */
105         subal   %d3, %sp                        
106         moveal  %sp, %a4                                                /* %a4 is temp stack pointer */
107
108 L_asm_vm_call_method_copy_loop:
109         movel   %a2@(0), %d3
110         movel   %d3, %a4@(0)                                    /* copy 4 bytes */
111         movel   %a2@(4), %d3
112         movel   %d3, %a4@(4)                                    /* a whole stack slot has been copied */
113
114         addal   #8, %a2
115         addal   #8, %a4
116         addl    #-1, %d2
117         tstl    %d2                                                             /* do we have more arguments ? */
118         beq     L_asm_vm_call_method_copy_done
119         br      L_asm_vm_call_method_copy_loop
120
121
122 L_asm_vm_call_method_copy_done:
123         /* now we fake method invocation as it would happen from invokevirtual */
124         /* this is needed as we patch the caller site, so we need a writeable slot */
125         /* %a3 points to the address containing the method, %a3 == REG_METHODPTR */
126
127         moveal  %a3@(0), %a4
128         jsr     %a4@
129
130 L_asm_vm_call_method_return:
131         movel   %a5, %sp                                                /* pop arguments off stack */
132
133 #if defined(ENABLE_SOFTFLOAT)
134         moveml  %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp       /* restore registers */
135         addal   #(12*4),%sp                                             /* restore stack */
136 #else
137         fmovemd %sp@(12*4), %fp2/%fp3/%fp4/%fp5/%fp6/%fp7                       /* restore registers */
138         moveml  %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp       /* restore registers */
139         addal   #(12*4+6*8),%sp                                         /* restore stack */
140 #endif
141         moveal  %d0, %a0                                                /* XXX return value in %a0, too, gcc sometimes expects addresses in %a0, wired */
142 asm_vm_call_method_end:                                         /* symbol needed to insert method into avl tree */
143         rts                                                                             /* return to c code */
144
145 /* asm_vm_call_method_exception_handler ********************************************************************
146  *
147  * calls void *builtin_throw_exception(java_objectheader *xptr) when no other handler is appropiate
148  * this functions gets called indirectly from asm_handle_exception, which back then moved xptr to %a2
149  * clear software design is in the eye of the beholder.
150  ************************************************************************************************************/
151 asm_vm_call_method_exception_handler:
152         movel   %a2, %sp@-                      /* push xptr argument */
153         jsr     builtin_throw_exception
154         lea     %sp@(4), %sp                    /* pop arg off stack */
155         jmp     L_asm_vm_call_method_return
156
157
158 /* asm_call_jit_compiler ************************************************************************************
159  *      Invokes compiler for untranslated java methods.
160  *      C prototype: void asm_call_jit_compiler(void);
161  *      BUT: this does not match reality, arguments _ARE_ passed via createcompilerstub and asm_vm_call_method...
162  *      arguments passed via %a2(methodinfo) == REG_ATMP1
163  *                       %a3(mptr)       == REG_ATMP2
164  ************************************************************************************************************/
165 asm_call_jit_compiler:
166         addal   #(-4*4),%sp                                             /* create stackframe to save registers */
167         moveml  %a0/%a1/%d0/%d1,%sp@                    /* save volatile registers */
168 #if !defined(ENABLE_SOFTFLOAT)
169         addal   #-8*2, %sp
170         fmovemd %fp0/%fp1, %sp@
171         movel   %sp@(8*4), %sp@-
172         pea             %sp@(8*4+8)
173 #else
174         movel   %sp@(4*4), %sp@-                                /* push arguments onto stack (ra)*/
175         pea     %sp@(4*4+8)                                             /* the old stack pointer*/
176 #endif
177         movel   %a3,%sp@-                                               /* mptr */
178         movel   %a2,%sp@-                                               /* methodinfo */
179
180         /* C prototype: u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra); */
181         jsr     jit_asm_compile                                         /* invoke compiler */
182         addal   #(4*4),%sp                                              /* pop arguments off stack */
183         moveal  %d0, %a2                                                /* to tmp register */
184
185 #if !defined(ENABLE_SOFTFLOAT)
186         fmovemd %sp@, %fp0/%fp1
187         addal   #8*2, %sp
188 #endif
189
190         moveml %sp@,%a0/%a1/%d0/%d1                             /* restore volatile registers */
191         addal   #(4*4),%sp                                              /* remove stackframe */
192
193         tstl    %a2                                                             /* check for exception */
194         beq     L_asm_call_jit_compiler_exception
195
196         jmp     %a2@                                                            /* invoke java method */
197         jsr     0                                                               /* we should not ever return here */
198
199 L_asm_call_jit_compiler_exception:
200         jsr             exceptions_get_and_clear_exception              /* exception object in %d0 now */
201         moveal  %d0, %a2                                                                /* move exception object into sptr register */
202         moveal  %sp@+, %a3                                                              /* pop return address into exception address reg */
203         jmp asm_handle_exception                                                /* handle exception */
204
205
206 /* asm_patcher_wrapper ********************************************************
207         
208   prepares arguments on stack
209   calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
210
211   Stack layout:
212      24   return address
213      20   REG_ITMP3
214      16   pointer to virtual java_objectheader
215      12   last byte of machine code (xmcode)
216       8   machine code (which is patched back later)
217       4   unresolved field reference
218       0   patcher function pointer to call
219 *******************************************************************************/
220 asm_patcher_wrapper:
221
222   /* save scratch registers */
223   movel %a0, %sp@-
224   movel %a1, %sp@-
225   movel %d0, %sp@-
226   movel %d1, %sp@-
227
228 #if defined(ENABLE_SOFTFLOAT)
229   /* calculate original value of sp */
230   movel %sp, %d0
231   addil #4*4, %d0
232 #else
233   addal #-8*2, %sp
234   fmovemd %fp0/%fp1, %sp@
235
236   movel %sp, %d0
237   addil #8*4, %d0
238 #endif
239
240   clrl  %sp@-                           /* pass ra */
241   clrl  %sp@-                           /* pass pv, if null use findmethod */
242   movel %d0, %sp@-                      /* pass sp of patcher stub */
243   jsr   patcher_wrapper         /* return value in %d0 */
244
245   lea   %sp@(3*4), %sp          /* pop arguments off stack */
246   tst   %d0                                     /* test if exception occured */
247   bne   L_asm_patcher_wrapper_exception
248
249 #if !defined(ENABLE_SOFTFLOAT)
250   fmovemd %sp@, %fp0/%fp1
251   addal #8*2, %sp
252 #endif
253   movel %sp@+, %d1
254   movel %sp@+, %d0
255   movel %sp@+, %a1
256   movel %sp@+, %a0
257
258   lea   %sp@(6*4), %sp                  /* restore stack and remove patcher stub*/
259   rts                                                   /* back to jit code */
260
261 L_asm_patcher_wrapper_exception:
262   /* WARNING: the stack is still disturbed, look at asm_patcher_wrapper for details */
263   /* we do not need to restore the content of the registers, I hope */
264 #if !defined(ENABLE_SOFTFLOAT)
265         lea             %sp@(8*4), %sp
266 #else
267         lea             %sp@(4*4), %sp
268 #endif
269
270   lea           %sp@(5*4), %sp                          /* restore stack and remove patcher stub*/
271   movel         %sp@+, %d4                                      /* restore REG_ITMP3, stored in emit_patcher_stubs */
272   moveal        %d0, %a2                                        /* xptr, pointer to exception object */
273   moveal        %sp@+, %a3                                      /* pop return address into exception address register */
274   jmp           asm_handle_exception            /* handle exception */
275   illegal                                                               /* XXX: we never come back */
276
277 /********************************************************************************
278         Reads a few values atomically. 
279         C signature:
280         void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
281
282         super ... sp@(4)
283         sub   ... sp@(8)
284         out   ... sp@(12)
285 ********************************************************************************/
286 asm_getclassvalues_atomic:
287 _crit_restart:
288 _crit_begin:
289         moveal  %sp@(4), %a0
290         movel   %a0@(offbaseval), %d0
291         movel   %a0@(offdiffval), %d1
292         
293         moveal  %sp@(8), %a0
294         moveal  %a0@(offbaseval), %a0
295 _crit_end:
296         moveal  %sp@(12), %a1
297         movel   %d0, %a1@(offcast_super_baseval)
298         movel   %d1, %a1@(offcast_super_diffval)
299         movel   %a0, %a1@(offcast_sub_baseval)
300
301         rts
302 .data
303 asm_criticalsections:
304 #if defined(ENABLE_THREADS)
305         .long _crit_begin
306         .long _crit_end
307         .long _crit_restart
308 #endif
309         .long 0
310 .text
311
312 asm_abstractmethoderror:
313
314 /* asm_handle_exception ********************************************************
315 *                                                                              *
316 *   This function handles an exception. It does not use the usual calling      *
317 *   conventions. The exception pointer is passed in REG_ATMP1 and the          *
318 *   pc from the exception raising position is passed in REG_ATMP2. It searches *
319 *   the local exception table for a handler. If no one is found, it unwinds    *
320 *   stacks and continues searching the callers.                                *
321 *                                                                              *
322 *   void asm_handle_exception (void);
323 *   exception object pointer...%a2   exception raising address...%a3           *
324 *                                                                              *
325 *******************************************************************************/
326 asm_handle_nat_exception:
327         lea     %sp@(4), %sp
328 asm_handle_exception:
329 L_asm_handle_exception_stack_loop:
330         /* save temporary registers */
331         movel   %d0, %sp@-
332         movel   %d1, %sp@-
333         movel   %a0, %sp@-
334         movel   %a1, %sp@-
335 #if !defined(ENABLE_SOFTFLOAT)
336         addal   #-8*2, %sp
337         fmovemd %fp0, %sp@(0)
338         fmovemd %fp1, %sp@(8)
339 #endif
340
341         /* we need the dseg, figure it out */
342         movel   %a3, %sp@-                              /* push ra argument */
343         jsr     md_codegen_get_pv_from_pc       /* pv in %d0 now */
344         movel   %d0, %d2                                /* move to safe register */
345         lea     %sp@(4), %sp                            /* pop args off stack */
346
347         /* now call the following c function */
348         /* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
349 #if !defined(ENABLE_SOFTFLOAT)
350         pea             %sp@(4*4 + 8*2)
351 #else
352         pea             %sp@(4*4)
353 #endif
354         movel   %d2,%sp@-
355         movel   %a3,%sp@-
356         movel   %a2,%sp@-
357         jsr     exceptions_handle_exception             /* %d0 is address of handler or 0 when not catched */
358         lea     %sp@(4*4), %sp                          /* pop args off stack */
359         tstl    %d0
360         beq     L_asm_handle_exception_not_catched
361
362         /* %d0 contains address of exception handler */
363         moveal  %d0, %a3
364
365         /* restore temporary registers */
366         moveal  %sp@+, %a1
367         moveal  %sp@+, %a0
368         movel   %sp@+, %d1
369         movel   %sp@+, %d0
370 #if !defined(ENABLE_SOFTFLOAT)
371         fmovemd %fp0, %sp@(0)
372         fmovemd %fp1, %sp@(8)
373         addal   #8*2, %sp
374 #endif
375
376         jmp     %a3@
377
378 L_asm_handle_exception_not_catched:
379         /* we did not find an exception handler in this stackframe */
380         /* remove this frame and search in the one above */
381         /* %a2 containts exception object ptr, %d2 the actual pv */
382
383         /* remove temporary registers stored */
384 #if !defined(ENABLE_SOFTFLOAT)
385         addal   #4*4 + 8*2, %sp
386 #else
387         addal   #4*4, %sp
388 #endif
389
390         moveal  %d2, %a3
391         movel   %a3@(FrameSize), %d2
392
393         moveal  %sp, %a0
394         addal   %d2, %a0        /* %a0 now points to top of stackframe, where saved regs are */
395
396         /* the saved registers have to be restored */
397         /* XXX ugly hack: intsave and adrsave share one field */
398         movel   %a3@(IntSave), %d0
399         andil   #0x0000ffff, %d0        /* this is IntSave */
400         cmpb    #0,%d0
401         beq     L_asm_handle_ex_int_done
402         movel   -(%a0), %d7
403
404         cmpb    #1,%d0
405         beq     L_asm_handle_ex_int_done
406         movel   -(%a0), %d6
407
408         cmpb    #2,%d0 
409         beq     L_asm_handle_ex_int_done
410         movel   -(%a0), %d5
411
412 L_asm_handle_ex_int_done:
413
414         movel   %a3@(IntSave), %d0
415         andil   #0xffff0000, %d0        /* this is AdrSave */
416         lsrl    #8, %d0
417         lsrl    #8, %d0
418
419 #if 0
420         cmpb    #0, %d0
421         beq     L_asm_handle_ex_adr_done
422         moveal  -(%a0), %a5
423 #else
424         cmpb    #0, %d0
425         beq     L_asm_handle_ex_adr_done
426         moveal  -(%a0), %fp
427
428         cmpb    #1,%d0
429         beq     L_asm_handle_ex_adr_done
430         moveal  -(%a0), %a5
431 #endif
432
433 L_asm_handle_ex_adr_done:
434
435 #if !defined(ENABLE_SOFTFLOAT)
436         movel   %a3@(FltSave), %d0
437         cmpb    #0,%d0
438         beq     L_asm_handle_ex_flt_done
439         fmovemd %a0@(-8), %fp7
440
441         cmpb    #1,%d0
442         beq     L_asm_handle_ex_flt_done
443         fdmoved %a0@(-16), %fp6
444         
445         cmpb    #2,%d0
446         beq     L_asm_handle_ex_flt_done
447         fdmoved %a0@(-24), %fp5
448
449 L_asm_handle_ex_flt_done:
450 #else
451         /* nothing to do */
452 #endif
453         addal   %d2, %sp                /* remove old stackframe */
454         moveal  %sp@+, %a3              /* make return address, new exception rasing address */
455         subal   #2, %a3                 /* it was a jsr %aX, which is 4 bytes long */
456         jmp     L_asm_handle_exception_stack_loop
457
458
459 illegal
460 .long 0x23234242
461
462
463 /*
464  * These are local overrides for various environment variables in Emacs.
465  * Please do not remove this and leave it at the end of the file, where
466  * Emacs will automagically detect them.
467  * ---------------------------------------------------------------------
468  * Local variables:
469  * mode: c
470  * indent-tabs-mode: t
471  * c-basic-offset: 4
472  * tab-width: 4
473  * End:
474  * vim:noexpandtab:sw=4:ts=4:
475  */