1 /* src/vm/jit/m68k/asmpart.S
8 #include "vm/jit/m68k/offsets.h"
10 #include "vm/jit/methodheader.h"
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
22 .globl asm_call_jit_compiler
24 .globl asm_patcher_wrapper
26 .globl asm_getclassvalues_atomic
27 .globl asm_abstractmethoderror
28 .globl asm_criticalsections
30 .globl asm_handle_exception
31 .globl asm_handle_nat_exception
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
38 * The function may still be uncompiled, so the jit compiler gets invoked.
43 /* this is the method header see src/vm/jit/methodheader.h */
45 .long 0 /* catch type all */
46 .long 0 /* handler 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 */
56 .long 0 /* frame size */
57 .long 0 /* codeinfo pointer */
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.
66 coldifire does not use any argument registers, so just the stack has to be copied
69 asm_vm_call_method_int:
70 asm_vm_call_method_long:
71 asm_vm_call_method_float:
72 asm_vm_call_method_double:
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 */
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 */
83 movel %a3, %sp@(12*4) /* copy method address to stackslot */
84 leal %sp@(12*4), %a3 /* and store that address in %a3 */
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 */
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 */
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 */
99 moveal %sp, %a5 /* memorize stack */
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 */
106 moveal %sp, %a4 /* %a4 is temp stack pointer */
108 L_asm_vm_call_method_copy_loop:
110 movel %d3, %a4@(0) /* copy 4 bytes */
112 movel %d3, %a4@(4) /* a whole stack slot has been copied */
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
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 */
130 L_asm_vm_call_method_return:
131 movel %a5, %sp /* pop arguments off stack */
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 */
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 */
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 */
145 /* asm_vm_call_method_exception_handler ********************************************************************
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
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)
170 fmovemd %fp0/%fp1, %sp@
171 movel %sp@(8*4), %sp@-
174 movel %sp@(4*4), %sp@- /* push arguments onto stack (ra)*/
175 pea %sp@(4*4+8) /* the old stack pointer*/
177 movel %a3,%sp@- /* mptr */
178 movel %a2,%sp@- /* methodinfo */
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 */
185 #if !defined(ENABLE_SOFTFLOAT)
186 fmovemd %sp@, %fp0/%fp1
190 moveml %sp@,%a0/%a1/%d0/%d1 /* restore volatile registers */
191 addal #(4*4),%sp /* remove stackframe */
193 tstl %a2 /* check for exception */
194 beq L_asm_call_jit_compiler_exception
196 jmp %a2@ /* invoke java method */
197 jsr 0 /* we should not ever return here */
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 */
206 /* asm_patcher_wrapper ********************************************************
208 prepares arguments on stack
209 calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
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 *******************************************************************************/
222 /* save scratch registers */
228 #if defined(ENABLE_SOFTFLOAT)
229 /* calculate original value of sp */
234 fmovemd %fp0/%fp1, %sp@
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 */
245 lea %sp@(3*4), %sp /* pop arguments off stack */
246 tst %d0 /* test if exception occured */
247 bne L_asm_patcher_wrapper_exception
249 #if !defined(ENABLE_SOFTFLOAT)
250 fmovemd %sp@, %fp0/%fp1
258 lea %sp@(6*4), %sp /* restore stack and remove patcher stub*/
259 rts /* back to jit code */
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)
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 */
277 /********************************************************************************
278 Reads a few values atomically.
280 void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
285 ********************************************************************************/
286 asm_getclassvalues_atomic:
290 movel %a0@(offbaseval), %d0
291 movel %a0@(offdiffval), %d1
294 moveal %a0@(offbaseval), %a0
297 movel %d0, %a1@(offcast_super_baseval)
298 movel %d1, %a1@(offcast_super_diffval)
299 movel %a0, %a1@(offcast_sub_baseval)
303 asm_criticalsections:
304 #if defined(ENABLE_THREADS)
312 asm_abstractmethoderror:
314 /* asm_handle_exception ********************************************************
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. *
322 * void asm_handle_exception (void);
323 * exception object pointer...%a2 exception raising address...%a3 *
325 *******************************************************************************/
326 asm_handle_nat_exception:
328 asm_handle_exception:
329 L_asm_handle_exception_stack_loop:
330 /* save temporary registers */
335 #if !defined(ENABLE_SOFTFLOAT)
337 fmovemd %fp0, %sp@(0)
338 fmovemd %fp1, %sp@(8)
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 */
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)
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 */
360 beq L_asm_handle_exception_not_catched
362 /* %d0 contains address of exception handler */
365 /* restore temporary registers */
370 #if !defined(ENABLE_SOFTFLOAT)
371 fmovemd %fp0, %sp@(0)
372 fmovemd %fp1, %sp@(8)
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 */
383 /* remove temporary registers stored */
384 #if !defined(ENABLE_SOFTFLOAT)
385 addal #4*4 + 8*2, %sp
391 movel %a3@(FrameSize), %d2
394 addal %d2, %a0 /* %a0 now points to top of stackframe, where saved regs are */
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 */
401 beq L_asm_handle_ex_int_done
405 beq L_asm_handle_ex_int_done
409 beq L_asm_handle_ex_int_done
412 L_asm_handle_ex_int_done:
414 movel %a3@(IntSave), %d0
415 andil #0xffff0000, %d0 /* this is AdrSave */
421 beq L_asm_handle_ex_adr_done
425 beq L_asm_handle_ex_adr_done
429 beq L_asm_handle_ex_adr_done
433 L_asm_handle_ex_adr_done:
435 #if !defined(ENABLE_SOFTFLOAT)
436 movel %a3@(FltSave), %d0
438 beq L_asm_handle_ex_flt_done
439 fmovemd %a0@(-8), %fp7
442 beq L_asm_handle_ex_flt_done
443 fdmoved %a0@(-16), %fp6
446 beq L_asm_handle_ex_flt_done
447 fdmoved %a0@(-24), %fp5
449 L_asm_handle_ex_flt_done:
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
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 * ---------------------------------------------------------------------
470 * indent-tabs-mode: t
474 * vim:noexpandtab:sw=4:ts=4: