1 /* src/vm/jit/m68k/asmpart.S
8 #include "vm/jit/m68k/offsets.h"
10 #include "vm/jit/methodheader.h"
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
26 .globl asm_call_jit_compiler
28 .globl asm_patcher_wrapper
30 .globl asm_getclassvalues_atomic
31 .globl asm_abstractmethoderror
32 .globl asm_criticalsections
34 .globl asm_handle_exception
35 .globl asm_handle_nat_exception
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
42 * The function may still be uncompiled, so the jit compiler gets invoked.
47 /* this is the method header see src/vm/jit/methodheader.h */
49 .long 0 /* catch type all */
50 .long 0 /* handler 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 */
60 .long 0 /* frame size */
61 .long 0 /* codeinfo pointer */
63 asm_vm_call_method_int:
64 asm_vm_call_method_long:
65 asm_vm_call_method_float:
66 asm_vm_call_method_double:
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 */
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 */
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 */
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 */
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 */
93 movel #(sizevmarg), %d0
96 addal %d0, %a0 /* %a0 points to last vmarg block */
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 */
103 cmpil #2, %d1 /* float type ? */
104 bne L_asm_vm_call_copy_int
106 movel %a0@(offvmargdata), %d0 /* float has different endianess as int */
108 bra L_asm_vm_call_copy_1_word_type
110 L_asm_vm_call_copy_int:
111 movel %a0@(offvmargdata+4), %d0
112 movel %d0,%sp@- /* push argument onto stack */
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 */
118 L_asm_vm_call_copy_1_word_type:
120 subl #(sizevmarg),%a0
121 tstl %d2 /* arguments left ? */
122 bne L_asm_vm_call_copy_arg
124 L_asm_vm_call_method_copy_done:
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 ? */
131 L_asm_vm_call_method_return:
132 movel %a5, %sp /* pop arguments off stack */
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 */
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 */
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 */
146 /* asm_vm_call_method_exception_handler ********************************************************************
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
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)
171 fmovemd %fp0/%fp1, %sp@
172 movel %sp@(8*4), %sp@-
175 movel %sp@(4*4), %sp@- /* push arguments onto stack (ra)*/
176 pea %sp@(4*4+8) /* the old stack pointer*/
178 movel %a3,%sp@- /* mptr */
179 movel %a2,%sp@- /* methodinfo */
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 */
186 #if !defined(ENABLE_SOFTFLOAT)
187 fmovemd %sp@, %fp0/%fp1
191 moveml %sp@,%a0/%a1/%d0/%d1 /* restore volatile registers */
192 addal #(4*4),%sp /* remove stackframe */
194 tstl %a2 /* check for exception */
195 beq L_asm_call_jit_compiler_exception
197 jmp %a2@ /* invoke java method */
198 jsr 0 /* we should not ever return here */
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 */
207 /* asm_patcher_wrapper ********************************************************
209 prepares arguments on stack
210 calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
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 *******************************************************************************/
223 /* save scratch registers */
229 #if defined(ENABLE_SOFTFLOAT)
230 /* calculate original value of sp */
235 fmovemd %fp0/%fp1, %sp@
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 */
246 lea %sp@(3*4), %sp /* pop arguments off stack */
247 tst %d0 /* test if exception occured */
248 bne L_asm_patcher_wrapper_exception
250 #if !defined(ENABLE_SOFTFLOAT)
251 fmovemd %sp@, %fp0/%fp1
259 lea %sp@(6*4), %sp /* restore stack and remove patcher stub*/
260 rts /* back to jit code */
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)
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 */
278 /********************************************************************************
279 Reads a few values atomically.
281 void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
286 ********************************************************************************/
287 asm_getclassvalues_atomic:
291 movel %a0@(offbaseval), %d0
292 movel %a0@(offdiffval), %d1
295 moveal %a0@(offbaseval), %a0
298 movel %d0, %a1@(offcast_super_baseval)
299 movel %d1, %a1@(offcast_super_diffval)
300 movel %a0, %a1@(offcast_sub_baseval)
304 asm_criticalsections:
305 #if defined(ENABLE_THREADS)
313 asm_abstractmethoderror:
315 /* asm_handle_exception ********************************************************
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. *
323 * void asm_handle_exception (void);
324 * exception object pointer...%a2 exception raising address...%a3 *
326 *******************************************************************************/
327 asm_handle_nat_exception:
329 asm_handle_exception:
330 L_asm_handle_exception_stack_loop:
332 /* we need the dseg, figure it out */
333 movel %a3, %sp@- /* push ra argument */
334 jsr md_codegen_get_pv_from_pc /* pv in %d0 now */
335 movel %d0, %d2 /* move to safe register */
336 lea %sp@(4), %sp /* pop args off stack */
338 /* now call the following c function */
339 /* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
344 jsr exceptions_handle_exception /* %d0 is address of handler or 0 when not catched */
345 lea %sp@(4*4), %sp /* pop args off stack */
347 beq L_asm_handle_exception_not_catched
349 /* %d0 contains address of exception handler */
351 moveal %a2, %a1 /* XXX FIXME, xptr is expected in %a1 by java code, whyever */
354 L_asm_handle_exception_not_catched:
355 /* we did not find an exception handler in this stackframe */
356 /* remove this frame and search in the one above */
357 /* %a2 containts exception object ptr, %d2 the actual pv */
359 movel %a3@(FrameSize), %d2
362 addal %d2, %a0 /* %a0 now points to top of stackframe, where saved regs are */
364 /* the saved registers have to be restored */
365 /* XXX ugly hack: intsave and adrsave share one field */
366 movel %a3@(IntSave), %d0
367 andil #0x0000ffff, %d0 /* this is IntSave */
369 beq L_asm_handle_ex_int_done
373 beq L_asm_handle_ex_int_done
377 beq L_asm_handle_ex_int_done
380 L_asm_handle_ex_int_done:
382 movel %a3@(IntSave), %d0
383 andil #0xffff0000, %d0 /* this is AdrSave */
385 beq L_handle_exception_nat_catched_no_adr
387 L_handle_exception_nat_catched_no_adr:
389 #if !defined(ENABLE_SOFTFLOAT)
390 movel %a3@(FltSave), %d0
392 beq L_asm_handle_ex_flt_done
393 fmovemd %a0@(-8), %fp7
396 beq L_asm_handle_ex_flt_done
397 fdmoved %a0@(-16), %fp6
400 beq L_asm_handle_ex_flt_done
401 fdmoved %a0@(-24), %fp5
403 L_asm_handle_ex_flt_done:
407 addal %d2, %sp /* remove old stackframe */
408 moveal %sp@+, %a3 /* make return address, new exception rasing address */
409 subal #2, %a3 /* it was a jsr %aX, which is 4 bytes long */
410 jmp L_asm_handle_exception_stack_loop
418 * These are local overrides for various environment variables in Emacs.
419 * Please do not remove this and leave it at the end of the file, where
420 * Emacs will automagically detect them.
421 * ---------------------------------------------------------------------
424 * indent-tabs-mode: t
428 * vim:noexpandtab:sw=4:ts=4: