1 /* src/vm/jit/m68k/asmpart.S - Java-C interface functions for m68k
3 Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: asmpart.S 8210 2007-07-18 12:51:00Z twisti $
34 #include "vm/jit/methodheader.h"
39 .globl asm_vm_call_method
40 .globl asm_vm_call_method_int
41 .globl asm_vm_call_method_long
42 .globl asm_vm_call_method_float
43 .globl asm_vm_call_method_double
44 .globl asm_vm_call_method_end
45 .globl asm_vm_call_method_exception_handler
47 .globl asm_call_jit_compiler
49 .globl asm_patcher_wrapper
51 .globl asm_abstractmethoderror
53 .globl asm_handle_exception
54 .globl asm_handle_nat_exception
57 * This functions implement the C prototyped funtion
58 * java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,vm_arg *vmargs);
59 * the _int, _long, _float, _double are used for different return types
61 * The function may still be uncompiled, so the jit compiler gets invoked.
66 /* this is the method header see src/vm/jit/methodheader.h */
68 .long 0 /* catch type all */
69 .long 0 /* handler pc */
71 .long 0 /* start pc */
72 .long 1 /* extable size */
73 .long 0 /* line number table start */
74 .long 0 /* line number table size */
79 .long 0 /* frame size */
80 .long 0 /* codeinfo pointer */
84 This method gets called with 3 arguments:
85 1st arg: addres of method to call (fake invokevirtual here)
86 2nd arg: uint64_t array of argument registers followed by stack
87 3rd arg: number of 8 byte stack slots to be copied.
89 coldifire does not use any argument registers, so just the stack has to be copied
92 asm_vm_call_method_int:
93 asm_vm_call_method_long:
94 asm_vm_call_method_float:
95 asm_vm_call_method_double:
97 #if defined(ENABLE_SOFTFLOAT)
98 addal #(-12*4),%sp /* create stackframe to save registers, and 1 slot for method invocation */
99 moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
101 /* fetch arguments from vmargs data structure */
102 movel %sp@(12*4+1*4),%a3 /* method */
103 movel %sp@(12*4+2*4),%a2 /* arg array */
104 movel %sp@(12*4+3*4),%d2 /* arg count */
106 movel %a3, %sp@(12*4) /* copy method address to stackslot */
107 leal %sp@(12*4), %a3 /* and store that address in %a3 */
109 addal #(-12*4-6*8), %sp
110 moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
111 fmovemd %fp2/%fp3/%fp4/%fp5/%fp6/%fp7,%sp@(11*4) /* save registers */
113 /* fetch arguments from vmargs data structure */
114 movel %sp@(12*4+6*8+1*4),%a3 /* method */
115 movel %sp@(12*4+6*8+2*4),%a2 /* arg array */
116 movel %sp@(12*4+6*8+3*4),%d2 /* arg count */
118 movel %a3, %sp@(11*4+6*8) /* copy method address to stackslot */
119 leal %sp@(11*4+6*8), %a3 /* and store that address in %a3 */
122 moveal %sp, %a5 /* memorize stack */
124 tstl %d2 /* do we have arguments ? */
125 beq L_asm_vm_call_method_copy_done
126 movel %d2, %d3 /* create stackframe */
127 asll #3, %d3 /* number args * 8 */
129 moveal %sp, %a4 /* %a4 is temp stack pointer */
131 L_asm_vm_call_method_copy_loop:
133 movel %d3, %a4@(0) /* copy 4 bytes */
135 movel %d3, %a4@(4) /* a whole stack slot has been copied */
140 tstl %d2 /* do we have more arguments ? */
141 beq L_asm_vm_call_method_copy_done
142 br L_asm_vm_call_method_copy_loop
145 L_asm_vm_call_method_copy_done:
146 /* now we fake method invocation as it would happen from invokevirtual */
147 /* this is needed as we patch the caller site, so we need a writeable slot */
148 /* %a3 points to the address containing the method, %a3 == REG_METHODPTR */
153 L_asm_vm_call_method_return:
154 movel %a5, %sp /* pop arguments off stack */
156 #if defined(ENABLE_SOFTFLOAT)
157 moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
158 addal #(12*4),%sp /* restore stack */
160 fmovemd %sp@(12*4), %fp2/%fp3/%fp4/%fp5/%fp6/%fp7 /* restore registers */
161 moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
162 addal #(12*4+6*8),%sp /* restore stack */
164 moveal %d0, %a0 /* XXX return value in %a0, too, gcc sometimes expects addresses in %a0, wired */
165 asm_vm_call_method_end: /* symbol needed to insert method into avl tree */
166 rts /* return to c code */
168 /* asm_vm_call_method_exception_handler ********************************************************************
170 * calls void *builtin_throw_exception(java_objectheader *xptr) when no other handler is appropiate
171 * this functions gets called indirectly from asm_handle_exception, which back then moved xptr to %a2
172 * clear software design is in the eye of the beholder.
173 ************************************************************************************************************/
174 asm_vm_call_method_exception_handler:
175 movel %a2, %sp@- /* push xptr argument */
176 jsr builtin_throw_exception
177 lea %sp@(4), %sp /* pop arg off stack */
178 jmp L_asm_vm_call_method_return
181 /* asm_call_jit_compiler ************************************************************************************
182 * Invokes compiler for untranslated java methods.
183 * C prototype: void asm_call_jit_compiler(void);
184 * BUT: this does not match reality, arguments _ARE_ passed via createcompilerstub and asm_vm_call_method...
185 * arguments passed via %a2(methodinfo) == REG_ATMP1
186 * %a3(mptr) == REG_ATMP2
187 ************************************************************************************************************/
188 asm_call_jit_compiler:
189 addal #(-4*4),%sp /* create stackframe to save registers */
190 moveml %a0/%a1/%d0/%d1,%sp@ /* save volatile registers */
191 #if !defined(ENABLE_SOFTFLOAT)
193 fmovemd %fp0/%fp1, %sp@
194 movel %sp@(8*4), %sp@-
197 movel %sp@(4*4), %sp@- /* push arguments onto stack (ra)*/
198 pea %sp@(4*4+8) /* the old stack pointer*/
200 movel %a3,%sp@- /* mptr */
201 movel %a2,%sp@- /* methodinfo */
203 /* C prototype: u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra); */
204 jsr jit_asm_compile /* invoke compiler */
205 addal #(4*4),%sp /* pop arguments off stack */
206 moveal %d0, %a2 /* to tmp register */
208 #if !defined(ENABLE_SOFTFLOAT)
209 fmovemd %sp@, %fp0/%fp1
213 moveml %sp@,%a0/%a1/%d0/%d1 /* restore volatile registers */
214 addal #(4*4),%sp /* remove stackframe */
216 tstl %a2 /* check for exception */
217 beq L_asm_call_jit_compiler_exception
219 jmp %a2@ /* invoke java method */
220 jsr 0 /* we should not ever return here */
222 L_asm_call_jit_compiler_exception:
223 jsr exceptions_get_and_clear_exception /* exception object in %d0 now */
224 moveal %d0, %a2 /* move exception object into sptr register */
225 moveal %sp@+, %a3 /* pop return address into exception address reg */
226 jmp asm_handle_exception /* handle exception */
229 /* asm_patcher_wrapper ********************************************************
231 prepares arguments on stack
232 calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
237 16 pointer to virtual java_objectheader
238 12 last byte of machine code (xmcode)
239 8 machine code (which is patched back later)
240 4 unresolved field reference
241 0 patcher function pointer to call
242 *******************************************************************************/
245 /* save scratch registers */
251 #if defined(ENABLE_SOFTFLOAT)
252 /* calculate original value of sp */
257 fmovemd %fp0/%fp1, %sp@
263 clrl %sp@- /* pass ra */
264 clrl %sp@- /* pass pv, if null use findmethod */
265 movel %d0, %sp@- /* pass sp of patcher stub */
266 jsr patcher_wrapper /* return value in %d0 */
268 lea %sp@(3*4), %sp /* pop arguments off stack */
269 tst %d0 /* test if exception occured */
270 bne L_asm_patcher_wrapper_exception
272 #if !defined(ENABLE_SOFTFLOAT)
273 fmovemd %sp@, %fp0/%fp1
281 lea %sp@(6*4), %sp /* restore stack and remove patcher stub*/
282 rts /* back to jit code */
284 L_asm_patcher_wrapper_exception:
285 /* WARNING: the stack is still disturbed, look at asm_patcher_wrapper for details */
286 /* we do not need to restore the content of the registers, I hope */
287 #if !defined(ENABLE_SOFTFLOAT)
293 lea %sp@(5*4), %sp /* restore stack and remove patcher stub*/
294 movel %sp@+, %d4 /* restore REG_ITMP3, stored in emit_patcher_stubs */
295 moveal %d0, %a2 /* xptr, pointer to exception object */
296 moveal %sp@+, %a3 /* pop return address into exception address register */
297 jmp asm_handle_exception /* handle exception */
298 illegal /* XXX: we never come back */
301 asm_abstractmethoderror:
303 /* asm_handle_exception ********************************************************
305 * This function handles an exception. It does not use the usual calling *
306 * conventions. The exception pointer is passed in REG_ATMP1 and the *
307 * pc from the exception raising position is passed in REG_ATMP2. It searches *
308 * the local exception table for a handler. If no one is found, it unwinds *
309 * stacks and continues searching the callers. *
311 * void asm_handle_exception (void);
312 * exception object pointer...%a2 exception raising address...%a3 *
314 *******************************************************************************/
315 asm_handle_nat_exception:
317 asm_handle_exception:
318 L_asm_handle_exception_stack_loop:
319 /* save temporary registers */
324 #if !defined(ENABLE_SOFTFLOAT)
326 fmovemd %fp0, %sp@(0)
327 fmovemd %fp1, %sp@(8)
330 /* we need the dseg, figure it out */
331 movel %a3, %sp@- /* push ra argument */
332 jsr md_codegen_get_pv_from_pc /* pv in %d0 now */
333 movel %d0, %d2 /* move to safe register */
334 lea %sp@(4), %sp /* pop args off stack */
336 /* now call the following c function */
337 /* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
338 #if !defined(ENABLE_SOFTFLOAT)
346 jsr exceptions_handle_exception /* %d0 is address of handler or 0 when not catched */
347 lea %sp@(4*4), %sp /* pop args off stack */
349 beq L_asm_handle_exception_not_catched
351 /* %d0 contains address of exception handler */
354 /* restore temporary registers */
359 #if !defined(ENABLE_SOFTFLOAT)
360 fmovemd %fp0, %sp@(0)
361 fmovemd %fp1, %sp@(8)
367 L_asm_handle_exception_not_catched:
368 /* we did not find an exception handler in this stackframe */
369 /* remove this frame and search in the one above */
370 /* %a2 containts exception object ptr, %d2 the actual pv */
372 /* remove temporary registers stored */
373 #if !defined(ENABLE_SOFTFLOAT)
374 addal #4*4 + 8*2, %sp
380 movel %a3@(FrameSize), %d2
383 addal %d2, %a0 /* %a0 now points to top of stackframe, where saved regs are */
385 /* the saved registers have to be restored */
386 /* XXX ugly hack: intsave and adrsave share one field */
387 movel %a3@(IntSave), %d0
388 andil #0x0000ffff, %d0 /* this is IntSave */
390 beq L_asm_handle_ex_int_done
394 beq L_asm_handle_ex_int_done
398 beq L_asm_handle_ex_int_done
401 L_asm_handle_ex_int_done:
403 movel %a3@(IntSave), %d0
404 andil #0xffff0000, %d0 /* this is AdrSave */
410 beq L_asm_handle_ex_adr_done
414 beq L_asm_handle_ex_adr_done
418 beq L_asm_handle_ex_adr_done
422 L_asm_handle_ex_adr_done:
424 #if !defined(ENABLE_SOFTFLOAT)
425 movel %a3@(FltSave), %d0
427 beq L_asm_handle_ex_flt_done
428 fmovemd %a0@(-8), %fp7
431 beq L_asm_handle_ex_flt_done
432 fdmoved %a0@(-16), %fp6
435 beq L_asm_handle_ex_flt_done
436 fdmoved %a0@(-24), %fp5
438 L_asm_handle_ex_flt_done:
442 addal %d2, %sp /* remove old stackframe */
443 moveal %sp@+, %a3 /* make return address, new exception rasing address */
444 subal #2, %a3 /* it was a jsr %aX, which is 4 bytes long */
445 jmp L_asm_handle_exception_stack_loop
453 * These are local overrides for various environment variables in Emacs.
454 * Please do not remove this and leave it at the end of the file, where
455 * Emacs will automagically detect them.
456 * ---------------------------------------------------------------------
459 * indent-tabs-mode: t
463 * vim:noexpandtab:sw=4:ts=4: