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