1 /* src/vm/jit/m68k/asmpart.S
8 #include "vm/jit/m68k/offsets.h"
16 .globl asm_vm_call_method
17 .globl asm_vm_call_method_int
18 .globl asm_vm_call_method_long
19 .globl asm_vm_call_method_float
20 .globl asm_vm_call_method_double
21 .globl asm_vm_call_method_end
22 .globl asm_vm_call_method_exception_handler
24 .globl asm_call_jit_compiler
26 .globl asm_patcher_wrapper
28 .globl asm_getclassvalues_atomic
29 .globl asm_abstractmethoderror
30 .globl asm_criticalsections
32 .globl asm_handle_exception
35 * This functions implement the C prototyped funtion
36 * java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,vm_arg *vmargs);
37 * the _int, _long, _float, _double are used for different return types
39 * The function may still be uncompiled, so the jit compiler gets invoked.
44 /* this is the method header see src/vm/jit/methodheader.h */
46 .long 0 /* catch type all */
47 .long 0 /* handler pc */
49 .long 0 /* start pc */
50 .long 1 /* extable size */
51 .long 0 /* line number table start */
52 .long 0 /* line number table size */
57 .long 0 /* frame size */
58 .long 0 /* codeinfo pointer */
60 asm_vm_call_method_int:
61 asm_vm_call_method_long:
62 asm_vm_call_method_float:
63 asm_vm_call_method_double:
64 addal #(-11*4),%sp /* create stackframe to save registers */
65 moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
67 /* fetch arguments from vmargs data structure */
68 movel %sp@(11*4+1*4),%a2 /* methodinfo argument in atmp1 */
69 movel %sp@(11*4+3*4),%a3 /* args block */
70 movel %sp@(11*4+2*4),%d2 /* arg count */
72 moveal %sp, %a5 /* memorize stack */
73 tst %d2 /* do we have arguments ? */
74 beq L_asm_vm_call_method_copy_done
75 subql #1,%d2 /* simplifies offset calulation */
77 movel #(sizevmarg), %d0
80 addal %d0, %a0 /* %a0 points to last vmarg block */
83 L_asm_vm_call_copy_arg:
84 subql #1, %d2 /* why wasn't that here */
86 movel %a0@(offvmargdata+4), %d0
87 movel %d0,%sp@- /* push argument onto stack */
89 movel %a0@(offvmargtype), %d0 /* %d0 contains type of arg */
90 btstl #0, %d0 /* test if 2 word type */
91 beq L_asm_vm_call_copy_1_word_type
92 movel %a0@(offvmargdata), %d0 /* push second word onto stack */
94 L_asm_vm_call_copy_1_word_type:
97 tst %d2 /* arguments left ? */
98 bne L_asm_vm_call_copy_arg
100 L_asm_vm_call_method_copy_done:
102 leal asm_call_jit_compiler,%a4 /* we need to fake a invocation as it would happen from jit code */
103 movel %a4, call_jit_dummy /* we need a writeable memory location */
104 moveal call_jit_dummy, %a4 /* XXX do we have a race condition here ? */
107 L_asm_vm_call_method_return:
108 movel %a5, %sp /* pop arguments off stack */
109 moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
110 addal #(11*4),%sp /* restore stack */
111 rts /* return to c code */
112 jsr 0 /* never come back ? */
114 /* asm_vm_call_method_exception_handler
116 * calls void *builtin_throw_exception(java_objectheader *xptr) when no other handler is appropiate
117 * this functions gets called indirectly from asm_handle_exception, which back then moved xptr to %a3
118 * clear software design is in the eye of the beholder.
120 asm_vm_call_method_exception_handler:
121 movel %a3, %sp@- /* push xptr argument */
122 jsr builtin_throw_exception
123 lea %sp@(4), %sp /* pop arg off stack */
124 bra L_asm_vm_call_method_return
127 asm_vm_call_method_end: /* symbol needed to insert method into avl tree */
130 * Invokes compiler for untranslated java methods.
131 * C prototype: void asm_call_jit_compiler(void);
132 * BUT: this does not match reality, arguments _ARE_ passed via createcompilerstub and asm_vm_call_method...
133 * arguments passed via %a2(methodinfo) == REG_ATMP1
134 * %a3(mptr) == REG_ATMP2
136 asm_call_jit_compiler:
137 addal #(-4*4),%sp /* create stackframe to save registers */
138 moveml %a0/%a1/%d0/%d1,%sp@ /* save volatile registers */
140 movel %sp@(4*4),%sp@- /* push arguments onto stack (ra)*/
141 pea %sp@(4*4+4) /* the old stack pointer */
142 movel %a3,%sp@- /* mptr */
143 movel %a2,%sp@- /* methodinfo */
145 /* C prototype: u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra); */
146 jsr jit_asm_compile /* invoke compiler */
147 lea %sp@(4*4),%sp /* pop arguments off stack */
148 moveal %d0, %a2 /* to tmp register */
150 moveml %sp@,%a0/%a1/%d0/%d1 /* restore volatile registers */
151 addal #(4*4),%sp /* remove stackframe */
153 tstl %a2 /* check for exception */
154 beq L_asm_call_jit_compiler_exception
156 jmp %a2@ /* invoke java method */
157 jsr 0 /* we should not ever return here */
159 L_asm_call_jit_compiler_exception:
162 moveml %fp@(-4*4), %a0/%a1/%d0/%d1 /* restore registers */
163 unlk %fp /* FIXME: this is wrong */
166 /* asm_patcher_wrapper ********************************************************
168 prepares arguments on stack
169 calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
174 16 pointer to virtual java_objectheader
175 12 last byte of machine code (xmcode)
176 8 machine code (which is patched back later)
177 4 unresolved field reference
178 0 patcher function pointer to call
179 *******************************************************************************/
183 /* save scratch registers */
188 #if !defined(ENABLE_SOFTFLOAT)
193 clrl %sp@- /* pass ra */
194 clrl %sp@- /* pass pv, if null use findmethod */
195 movel %d0, %sp@- /* pass sp of patcher stub */
196 jsr patcher_wrapper /* return value in %d0 */
198 lea %sp@(3*4), %sp /* pop arguments off stack */
200 tst %d0 /* test if exception occured */
201 bne L_asm_patcher_wrapper_exception
203 #if !defined(ENABLE_SOFTFLOAT)
212 lea %sp@(6*4), %sp /* restore stack and remove patcher stub*/
213 rts /* back to jit code */
215 L_asm_patcher_wrapper_exception:
216 /* WARNING: the stack is still disturbed, look at asm_patcher_wrapper for details */
219 /********************************************************************************
220 Reads a few values atomically.
222 void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
227 ********************************************************************************/
228 asm_getclassvalues_atomic:
232 movel %a0@(offbaseval), %d0
233 movel %a0@(offdiffval), %d1
236 moveal %a0@(offbaseval), %a0
239 movel %d0, %a1@(offcast_super_baseval)
240 movel %d1, %a1@(offcast_super_diffval)
241 movel %a0, %a1@(offcast_sub_baseval)
245 asm_criticalsections:
246 #if defined(ENABLE_THREADS)
254 asm_abstractmethoderror:
256 /* asm_handle_exception ********************************************************
258 * This function handles an exception. It does not use the usual calling *
259 * conventions. The exception pointer is passed in REG_ATMP1 and the *
260 * pc from the exception raising position is passed in REG_ATMP2. It searches *
261 * the local exception table for a handler. If no one is found, it unwinds *
262 * stacks and continues searching the callers. *
264 * void asm_handle_exception (void);
265 * exception object pointer...%a2 exception raising address...%a3 *
267 *******************************************************************************/
268 asm_handle_exception:
269 asm_handle_nat_exception:
270 L_asm_handle_exception_stack_loop:
272 /* we need the dseg, figure it out */
273 movel %a3, %sp@- /* push ra argument */
274 jsr md_codegen_get_pv_from_pc /* pv in %d0 now */
275 movel %d0, %d2 /* move to safe register */
276 lea %sp@(4), %sp /* pop args off stack */
278 /* now call the following c function */
279 /* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
284 jsr exceptions_handle_exception /* %d0 is address of handler or 0 when not catched */
285 lea %sp@(4*4), %sp /* pop args off stack */
287 beq L_asm_handle_exception_not_catched
289 /* %d0 contains address of exception handler */
293 L_asm_handle_exception_not_catched: