-/* src/vm/jit/m68k/asmpart.S
- * for cacao
- * Roland Lezuo
- */
+/* src/vm/jit/m68k/asmpart.S - Java-C interface functions for m68k
+
+ Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
#include "config.h"
-#include "vm/jit/m68k/offsets.h"
#include "md-abi.h"
+
#include "vm/jit/methodheader.h"
-.data
-call_jit_dummy:
- .long 0xdeadbeef
.text
.globl asm_call_jit_compiler
-.globl asm_patcher_wrapper
-
-.globl asm_getclassvalues_atomic
.globl asm_abstractmethoderror
-.globl asm_criticalsections
.globl asm_handle_exception
.globl asm_handle_nat_exception
*/
/* this is the method header see src/vm/jit/methodheader.h */
+
.align 4
- .long 0 /* catch type all */
- .long 0 /* handler pc */
- .long 0 /* end pc */
- .long 0 /* start pc */
- .long 1 /* extable size */
+
.long 0 /* line number table start */
.long 0 /* line number table size */
.long 0 /* fltsave */
.long 0 /* intsave */
.long 0 /* isleaf */
- .long 0 /* IsSync */
.long 0 /* frame size */
.long 0 /* codeinfo pointer */
+
+
+/*
+ This method gets called with 3 arguments:
+ 1st arg: addres of method to call (fake invokevirtual here)
+ 2nd arg: uint64_t array of argument registers followed by stack
+ 3rd arg: number of 8 byte stack slots to be copied.
+
+ coldifire does not use any argument registers, so just the stack has to be copied
+*/
asm_vm_call_method:
asm_vm_call_method_int:
asm_vm_call_method_long:
asm_vm_call_method_double:
#if defined(ENABLE_SOFTFLOAT)
- addal #(-11*4),%sp /* create stackframe to save registers */
+ addal #(-12*4),%sp /* create stackframe to save registers, and 1 slot for method invocation */
moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
/* fetch arguments from vmargs data structure */
- movel %sp@(11*4+1*4),%a2 /* methodinfo argument in atmp1 */
- movel %sp@(11*4+3*4),%a3 /* args block */
- movel %sp@(11*4+2*4),%d2 /* arg count */
+ movel %sp@(12*4+1*4),%a3 /* method */
+ movel %sp@(12*4+2*4),%a2 /* arg array */
+ movel %sp@(12*4+3*4),%d2 /* arg count */
+
+ movel %a3, %sp@(12*4) /* copy method address to stackslot */
+ leal %sp@(12*4), %a3 /* and store that address in %a3 */
#else
- addal #(-11*4-6*8), %sp
+ addal #(-12*4-6*8), %sp
moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
fmovemd %fp2/%fp3/%fp4/%fp5/%fp6/%fp7,%sp@(11*4) /* save registers */
/* fetch arguments from vmargs data structure */
- movel %sp@(11*4+6*8+1*4),%a2 /* methodinfo argument in atmp1 */
- movel %sp@(11*4+6*8+3*4),%a3 /* args block */
- movel %sp@(11*4+6*8+2*4),%d2 /* arg count */
-#endif
+ movel %sp@(12*4+6*8+1*4),%a3 /* method */
+ movel %sp@(12*4+6*8+2*4),%a2 /* arg array */
+ movel %sp@(12*4+6*8+3*4),%d2 /* arg count */
+ movel %a3, %sp@(11*4+6*8) /* copy method address to stackslot */
+ leal %sp@(11*4+6*8), %a3 /* and store that address in %a3 */
+#endif
moveal %sp, %a5 /* memorize stack */
+
tstl %d2 /* do we have arguments ? */
beq L_asm_vm_call_method_copy_done
- subql #1,%d2 /* simplifies offset calulation */
-
- movel #(sizevmarg), %d0
- mulsl %d2, %d0
- moveal %a3, %a0
- addal %d0, %a0 /* %a0 points to last vmarg block */
-
- addql #1, %d2
-L_asm_vm_call_copy_arg:
- subql #1, %d2 /* decrement argument counter */
- movel %a0@(offvmargtype+4), %d1 /* %d1 contains type of arg, vmargtype is u8 */
-
- cmpil #2, %d1 /* float type ? */
- bne L_asm_vm_call_copy_int
-
- movel %a0@(offvmargdata), %d0 /* float has different endianess as int */
- movel %d0, %sp@-
- bra L_asm_vm_call_copy_1_word_type
-
-L_asm_vm_call_copy_int:
- movel %a0@(offvmargdata+4), %d0
- movel %d0,%sp@- /* push argument onto stack */
-
- btstl #0, %d1 /* test if 2 word type */
- beq L_asm_vm_call_copy_1_word_type
- movel %a0@(offvmargdata), %d0 /* push second word onto stack */
- movel %d0,%sp@-
-L_asm_vm_call_copy_1_word_type:
+ movel %d2, %d3 /* create stackframe */
+ asll #3, %d3 /* number args * 8 */
+ subal %d3, %sp
+ moveal %sp, %a4 /* %a4 is temp stack pointer */
+
+L_asm_vm_call_method_copy_loop:
+ movel %a2@(0), %d3
+ movel %d3, %a4@(0) /* copy 4 bytes */
+ movel %a2@(4), %d3
+ movel %d3, %a4@(4) /* a whole stack slot has been copied */
+
+ addal #8, %a2
+ addal #8, %a4
+ addl #-1, %d2
+ tstl %d2 /* do we have more arguments ? */
+ beq L_asm_vm_call_method_copy_done
+ br L_asm_vm_call_method_copy_loop
- subl #(sizevmarg),%a0
- tstl %d2 /* arguments left ? */
- bne L_asm_vm_call_copy_arg
L_asm_vm_call_method_copy_done:
+ /* now we fake method invocation as it would happen from invokevirtual */
+ /* this is needed as we patch the caller site, so we need a writeable slot */
+ /* %a3 points to the address containing the method, %a3 == REG_METHODPTR */
- leal asm_call_jit_compiler,%a4 /* we need to fake a invocation as it would happen from jit code */
- movel %a4, call_jit_dummy /* we need a writeable memory location */
- moveal call_jit_dummy, %a4 /* XXX do we have a race condition here ? */
+ moveal %a3@(0), %a4
jsr %a4@
L_asm_vm_call_method_return:
#if defined(ENABLE_SOFTFLOAT)
moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
- addal #(11*4),%sp /* restore stack */
+ addal #(12*4),%sp /* restore stack */
#else
- fmovemd %sp@(11*4), %fp2/%fp3/%fp4/%fp5/%fp6/%fp7 /* restore registers */
+ fmovemd %sp@(12*4), %fp2/%fp3/%fp4/%fp5/%fp6/%fp7 /* restore registers */
moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
- addal #(11*4+6*8),%sp /* restore stack */
+ addal #(12*4+6*8),%sp /* restore stack */
#endif
- moveal %d0, %a0 /* return value in %a0, too */
+ moveal %d0, %a0 /* XXX return value in %a0, too, gcc sometimes expects addresses in %a0, wired */
asm_vm_call_method_end: /* symbol needed to insert method into avl tree */
rts /* return to c code */
jmp asm_handle_exception /* handle exception */
-/* asm_patcher_wrapper ********************************************************
-
- prepares arguments on stack
- calls patcher_wrapper signature: java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra);
-
- Stack layout:
- 24 return address
- 20 REG_ITMP3
- 16 pointer to virtual java_objectheader
- 12 last byte of machine code (xmcode)
- 8 machine code (which is patched back later)
- 4 unresolved field reference
- 0 patcher function pointer to call
-*******************************************************************************/
-asm_patcher_wrapper:
-
- /* save scratch registers */
- movel %a0, %sp@-
- movel %a1, %sp@-
- movel %d0, %sp@-
- movel %d1, %sp@-
-
-#if defined(ENABLE_SOFTFLOAT)
- /* calculate original value of sp */
- movel %sp, %d0
- addil #4*4, %d0
-#else
- addal #-8*2, %sp
- fmovemd %fp0/%fp1, %sp@
-
- movel %sp, %d0
- addil #8*4, %d0
-#endif
-
- clrl %sp@- /* pass ra */
- clrl %sp@- /* pass pv, if null use findmethod */
- movel %d0, %sp@- /* pass sp of patcher stub */
- jsr patcher_wrapper /* return value in %d0 */
-
- lea %sp@(3*4), %sp /* pop arguments off stack */
- tst %d0 /* test if exception occured */
- bne L_asm_patcher_wrapper_exception
-
-#if !defined(ENABLE_SOFTFLOAT)
- fmovemd %sp@, %fp0/%fp1
- addal #8*2, %sp
-#endif
- movel %sp@+, %d1
- movel %sp@+, %d0
- movel %sp@+, %a1
- movel %sp@+, %a0
-
- lea %sp@(6*4), %sp /* restore stack and remove patcher stub*/
- rts /* back to jit code */
-
-L_asm_patcher_wrapper_exception:
- /* WARNING: the stack is still disturbed, look at asm_patcher_wrapper for details */
- /* we do not need to restore the content of the registers, I hope */
-#if !defined(ENABLE_SOFTFLOAT)
- lea %sp@(8*4), %sp
-#else
- lea %sp@(4*4), %sp
-#endif
-
- lea %sp@(5*4), %sp /* restore stack and remove patcher stub*/
- movel %sp@+, %d4 /* restore REG_ITMP3, stored in emit_patcher_stubs */
- moveal %d0, %a2 /* xptr, pointer to exception object */
- moveal %sp@+, %a3 /* pop return address into exception address register */
- jmp asm_handle_exception /* handle exception */
- illegal /* XXX: we never come back */
-
-/********************************************************************************
- Reads a few values atomically.
- C signature:
- void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
-
- super ... sp@(4)
- sub ... sp@(8)
- out ... sp@(12)
-********************************************************************************/
-asm_getclassvalues_atomic:
-_crit_restart:
-_crit_begin:
- moveal %sp@(4), %a0
- movel %a0@(offbaseval), %d0
- movel %a0@(offdiffval), %d1
-
- moveal %sp@(8), %a0
- moveal %a0@(offbaseval), %a0
-_crit_end:
- moveal %sp@(12), %a1
- movel %d0, %a1@(offcast_super_baseval)
- movel %d1, %a1@(offcast_super_diffval)
- movel %a0, %a1@(offcast_sub_baseval)
-
- rts
-.data
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
- .long _crit_begin
- .long _crit_end
- .long _crit_restart
-#endif
- .long 0
-.text
asm_abstractmethoderror:
lea %sp@(4), %sp
asm_handle_exception:
L_asm_handle_exception_stack_loop:
-
+ /* save temporary registers */
+ movel %d0, %sp@-
+ movel %d1, %sp@-
+ movel %a0, %sp@-
+ movel %a1, %sp@-
+#if !defined(ENABLE_SOFTFLOAT)
+ addal #-8*2, %sp
+ fmovemd %fp0, %sp@(0)
+ fmovemd %fp1, %sp@(8)
+#endif
+
/* we need the dseg, figure it out */
movel %a3, %sp@- /* push ra argument */
jsr md_codegen_get_pv_from_pc /* pv in %d0 now */
/* now call the following c function */
/* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
- movel %sp,%sp@-
+#if !defined(ENABLE_SOFTFLOAT)
+ pea %sp@(4*4 + 8*2)
+#else
+ pea %sp@(4*4)
+#endif
movel %d2,%sp@-
movel %a3,%sp@-
movel %a2,%sp@-
beq L_asm_handle_exception_not_catched
/* %d0 contains address of exception handler */
- moveal %d0, %a0
- moveal %a2, %a1 /* XXX FIXME, xptr is expected in %a1 by java code, whyever */
- jmp %a0@
+ moveal %d0, %a3
+
+ /* restore temporary registers */
+ moveal %sp@+, %a1
+ moveal %sp@+, %a0
+ movel %sp@+, %d1
+ movel %sp@+, %d0
+#if !defined(ENABLE_SOFTFLOAT)
+ fmovemd %fp0, %sp@(0)
+ fmovemd %fp1, %sp@(8)
+ addal #8*2, %sp
+#endif
+
+ jmp %a3@
L_asm_handle_exception_not_catched:
/* we did not find an exception handler in this stackframe */
/* remove this frame and search in the one above */
/* %a2 containts exception object ptr, %d2 the actual pv */
+
+ /* remove temporary registers stored */
+#if !defined(ENABLE_SOFTFLOAT)
+ addal #4*4 + 8*2, %sp
+#else
+ addal #4*4, %sp
+#endif
+
moveal %d2, %a3
movel %a3@(FrameSize), %d2
movel %a3@(IntSave), %d0
andil #0xffff0000, %d0 /* this is AdrSave */
- tstl %d0
- beq L_handle_exception_nat_catched_no_adr
+ lsrl #8, %d0
+ lsrl #8, %d0
+
+#if 0
+ cmpb #0, %d0
+ beq L_asm_handle_ex_adr_done
moveal -(%a0), %a5
-L_handle_exception_nat_catched_no_adr:
+#else
+ cmpb #0, %d0
+ beq L_asm_handle_ex_adr_done
+ moveal -(%a0), %fp
+
+ cmpb #1,%d0
+ beq L_asm_handle_ex_adr_done
+ moveal -(%a0), %a5
+#endif
+
+L_asm_handle_ex_adr_done:
#if !defined(ENABLE_SOFTFLOAT)
movel %a3@(FltSave), %d0