/* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
- Copyright (C) 1996-2005 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
+ Copyright (C) 1996-2005, 2006 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.
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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Andreas Krall
Changes: Christian Thalinger
+ Edwin Steiner
- $Id: asmpart.S 3930 2005-12-09 14:39:10Z twisti $
+ $Id: asmpart.S 4654 2006-03-19 19:46:11Z edwin $
*/
.set noat
-/* exported functions and variables *******************************************/
+/* export functions ***********************************************************/
- .globl asm_calljavafunction
- .globl asm_calljavafunction_int
-
- .globl asm_calljavafunction2
- .globl asm_calljavafunction2int
- .globl asm_calljavafunction2long
- .globl asm_calljavafunction2float
- .globl asm_calljavafunction2double
+ .globl asm_vm_call_method
+ .globl asm_vm_call_method_int
+ .globl asm_vm_call_method_long
+ .globl asm_vm_call_method_float
+ .globl asm_vm_call_method_double
.globl asm_call_jit_compiler
.globl asm_handle_exception
.globl asm_wrapper_patcher
+ .globl asm_replacement_out
+ .globl asm_replacement_in
+
.globl asm_perform_threadswitch
.globl asm_initialize_thread_stack
.globl asm_switchstackandcall
* *
*******************************************************************************/
- .ent asm_calljavafunction
-
- .align 3
-
- .dword 0 /* catch type all */
- .dword calljava_xhandler /* handler pc */
- .dword calljava_xhandler /* end pc */
- .dword asm_calljavafunction /* start pc */
- .word 1 /* extable size */
- .word 0 /* 4-byte ALIGNMENT PADDING */
- .dword 0 /* line number table start */
- .dword 0 /* line number table size */
- .word 0 /* 4-byte ALIGNMENT PADDING */
- .word 0 /* fltsave */
- .word 0 /* intsave */
- .word 0 /* isleaf */
- .word 0 /* IsSync */
- .word 0 /* frame size */
- .dword 0 /* method pointer (pointer to name) */
-
-asm_calljavafunction:
-asm_calljavafunction_int:
- .set noreorder /* XXX we need to recompute pv */
-
- aaddiu sp,sp,-10*8 /* allocate stack space */
- ast ra,0(sp) /* save return address */
-
- bal call_java_pc
- ast pv,3*8(sp) /* procedure vector (delay slot) */
-call_java_pc:
- aaddiu pv,ra,-4*4
-
- sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */
- sdc1 fss1,5*8(sp)
- sdc1 fss2,6*8(sp)
- sdc1 fss3,7*8(sp)
- sdc1 fss4,8*8(sp)
- sdc1 fss5,9*8(sp)
-
- move itmp1,a0 /* pass method pointer via tmp1 */
-
- move a0,a1 /* pass the remaining parameters */
- move a1,a2
- move a2,a3
- move a3,a4
-
- ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
- ast mptr,1*8(sp) /* store function address */
- move mptr,sp /* set method pointer */
-
- ald pv,1*8(mptr) /* method call as in Java */
- jalr pv /* call JIT compiler */
- nop
-L_asm_calljavafunction_recompute:
-/* aaddiu pv,ra,(asm_calljavafunction - L_asm_calljavafunction_recompute)*/
- aaddiu pv,ra,-22*4
-
- .set reorder /* XXX we need to recompute pv */
-
-calljava_return:
- ald ra,0(sp) /* restore return address */
- ald pv,3*8(sp) /* restore procedure vector */
-
- ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */
- ldc1 fss1,5*8(sp)
- ldc1 fss2,6*8(sp)
- ldc1 fss3,7*8(sp)
- ldc1 fss4,8*8(sp)
- ldc1 fss5,9*8(sp)
-
- aaddiu sp,sp,10*8 /* free stack space */
- j ra /* return */
-
-calljava_xhandler:
- move a0,itmp1
- jal builtin_throw_exception
- move v0,zero /* clear return value for exception */
- b calljava_return
-
- .end asm_calljavafunction
-
-
- .ent asm_calljavafunction2
+ .ent asm_vm_call_method
.align 3
.dword 0 /* catch type all */
.dword calljava_xhandler2 /* handler pc */
.dword calljava_xhandler2 /* end pc */
- .dword asm_calljavafunction2 /* start pc */
+ .dword asm_vm_call_method /* start pc */
.word 1 /* extable size */
.word 0 /* 4-byte ALIGNMENT PADDING */
.dword 0 /* line number table start */
.word 0 /* frame size */
.dword 0 /* method pointer (pointer to name) */
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
+asm_vm_call_method:
+asm_vm_call_method_int:
+asm_vm_call_method_long:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
.set noreorder /* XXX we need to recompute pv */
aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
ast ra,0(sp) /* save return address */
- bal call_java_pc2
+ bal L_asm_vm_call_method_compute_pv
ast pv,1*8(sp) /* procedure vector */
-call_java_pc2:
+L_asm_vm_call_method_compute_pv:
aaddiu pv,ra,-4*4
ast s7,3*8(sp)
ast a0,4*8(sp) /* save method pointer for compiler */
- move t0,a3
+ move t0,a2
move s7,a1
blez s7,calljava_argsloaded
nop
- ald a0,offjniitem(t0)
- ldc1 fa0,offjniitem(t0)
+ ald a0,offvmargdata(t0)
+ ldc1 fa0,offvmargdata(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a1,offjniitem+sizejniblock*1(t0)
- ldc1 fa1,offjniitem+sizejniblock*1(t0)
+ ald a1,offvmargdata+sizevmarg*1(t0)
+ ldc1 fa1,offvmargdata+sizevmarg*1(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a2,offjniitem+sizejniblock*2(t0)
- ldc1 fa2,offjniitem+sizejniblock*2(t0)
+ ald a2,offvmargdata+sizevmarg*2(t0)
+ ldc1 fa2,offvmargdata+sizevmarg*2(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a3,offjniitem+sizejniblock*3(t0)
- ldc1 fa3,offjniitem+sizejniblock*3(t0)
+ ald a3,offvmargdata+sizevmarg*3(t0)
+ ldc1 fa3,offvmargdata+sizevmarg*3(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a4,offjniitem+sizejniblock*4(t0)
- ldc1 fa4,offjniitem+sizejniblock*4(t0)
+ ald a4,offvmargdata+sizevmarg*4(t0)
+ ldc1 fa4,offvmargdata+sizevmarg*4(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a5,offjniitem+sizejniblock*5(t0)
- ldc1 fa5,offjniitem+sizejniblock*5(t0)
+ ald a5,offvmargdata+sizevmarg*5(t0)
+ ldc1 fa5,offvmargdata+sizevmarg*5(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a6,offjniitem+sizejniblock*6(t0)
- ldc1 fa6,offjniitem+sizejniblock*6(t0)
+ ald a6,offvmargdata+sizevmarg*6(t0)
+ ldc1 fa6,offvmargdata+sizevmarg*6(t0)
daddi s7,s7,-1
blez s7,calljava_argsloaded
nop
- ald a7,offjniitem+sizejniblock*7(t0)
- ldc1 fa7,offjniitem+sizejniblock*7(t0)
+ ald a7,offvmargdata+sizevmarg*7(t0)
+ ldc1 fa7,offvmargdata+sizevmarg*7(t0)
daddi s7,s7,-1
calljava_argsloaded:
aaddu t2,t2,t8
calljava_copyloop:
- ald t3,offjniitem+sizejniblock*8(t0)
+ ald t3,offvmargdata+sizevmarg*8(t0)
ast t3,0(t2)
ala t1,1(t1)
- ala t0,sizejniblock(t0)
+ ala t0,sizevmarg(t0)
ala t2,8(t2)
bnez t1,calljava_copyloop
nop
ald pv,1*8(mptr) /* method call as in Java */
jalr pv /* call JIT compiler */
nop
-L_asm_calljavafunction2_recompute:
-/* aaddiu pv,ra,(asm_calljavafunction2 - L_asm_calljavafunction2_recompute)*/
+L_asm_vm_call_method_recompute_pv:
+/* aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)*/
aaddiu pv,ra,-76*4 /* recompute procedure vector */
.set reorder /* XXX we need to recompute pv */
jal builtin_throw_exception
b calljava_return2
- .end asm_calljavafunction2
+ .end asm_vm_call_method
/****************** function asm_call_jit_compiler *****************************
.end asm_wrapper_patcher
+/* asm_replacement_out *********************************************************
+
+ This code is jumped to from the replacement-out stubs that are executed
+ when a thread reaches an activated replacement point.
+
+ The purpose of asm_replacement_out is to read out the parts of the
+ execution state that cannot be accessed from C code, store this state,
+ and then call the C function replace_me.
+
+ Stack layout:
+ 16 start of stack inside method to replace
+ 0 rplpoint * info on the replacement point that was reached
+
+ NOTE: itmp3 has been clobbered by the replacement-out stub!
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+ /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM 512
+
+#define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
+
+ .ent asm_replacement_out
+
+asm_replacement_out:
+ /* create stack frame */
+ daddiu sp,sp,-REPLACEMENT_STACK_OFFSET
+
+ /* save registers in execution state */
+ sd $0 ,( 0*8+offes_intregs)(sp)
+ sd $1 ,( 1*8+offes_intregs)(sp)
+ sd $2 ,( 2*8+offes_intregs)(sp)
+ sd $3 ,( 3*8+offes_intregs)(sp)
+ sd $4 ,( 4*8+offes_intregs)(sp)
+ sd $5 ,( 5*8+offes_intregs)(sp)
+ sd $6 ,( 6*8+offes_intregs)(sp)
+ sd $7 ,( 7*8+offes_intregs)(sp)
+ sd $8 ,( 8*8+offes_intregs)(sp)
+ sd $9 ,( 9*8+offes_intregs)(sp)
+ sd $10,(10*8+offes_intregs)(sp)
+ sd $11,(11*8+offes_intregs)(sp)
+ sd $12,(12*8+offes_intregs)(sp)
+ sd $13,(13*8+offes_intregs)(sp)
+ sd $14,(14*8+offes_intregs)(sp)
+ sd $15,(15*8+offes_intregs)(sp)
+ sd $16,(16*8+offes_intregs)(sp)
+ sd $17,(17*8+offes_intregs)(sp)
+ sd $18,(18*8+offes_intregs)(sp)
+ sd $19,(19*8+offes_intregs)(sp)
+ sd $20,(20*8+offes_intregs)(sp)
+ sd $21,(21*8+offes_intregs)(sp)
+ sd $22,(22*8+offes_intregs)(sp)
+ sd $23,(23*8+offes_intregs)(sp)
+ sd $24,(24*8+offes_intregs)(sp)
+ sd $25,(25*8+offes_intregs)(sp)
+ sd $26,(26*8+offes_intregs)(sp)
+ sd $27,(27*8+offes_intregs)(sp)
+ sd $28,(28*8+offes_intregs)(sp)
+ sd $29,(29*8+offes_intregs)(sp)
+ sd $30,(30*8+offes_intregs)(sp)
+ sd $31,(31*8+offes_intregs)(sp)
+
+ sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
+ sdc1 $f1 ,( 1*8+offes_fltregs)(sp)
+ sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
+ sdc1 $f3 ,( 3*8+offes_fltregs)(sp)
+ sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
+ sdc1 $f5 ,( 5*8+offes_fltregs)(sp)
+ sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
+ sdc1 $f7 ,( 7*8+offes_fltregs)(sp)
+ sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
+ sdc1 $f9 ,( 9*8+offes_fltregs)(sp)
+ sdc1 $f10,(10*8+offes_fltregs)(sp)
+ sdc1 $f11,(11*8+offes_fltregs)(sp)
+ sdc1 $f12,(12*8+offes_fltregs)(sp)
+ sdc1 $f13,(13*8+offes_fltregs)(sp)
+ sdc1 $f14,(14*8+offes_fltregs)(sp)
+ sdc1 $f15,(15*8+offes_fltregs)(sp)
+ sdc1 $f16,(16*8+offes_fltregs)(sp)
+ sdc1 $f17,(17*8+offes_fltregs)(sp)
+ sdc1 $f18,(18*8+offes_fltregs)(sp)
+ sdc1 $f19,(19*8+offes_fltregs)(sp)
+ sdc1 $f20,(20*8+offes_fltregs)(sp)
+ sdc1 $f21,(21*8+offes_fltregs)(sp)
+ sdc1 $f22,(22*8+offes_fltregs)(sp)
+ sdc1 $f23,(23*8+offes_fltregs)(sp)
+ sdc1 $f24,(24*8+offes_fltregs)(sp)
+ sdc1 $f25,(25*8+offes_fltregs)(sp)
+ sdc1 $f26,(26*8+offes_fltregs)(sp)
+ sdc1 $f27,(27*8+offes_fltregs)(sp)
+ sdc1 $f28,(28*8+offes_fltregs)(sp)
+ sdc1 $f29,(29*8+offes_fltregs)(sp)
+ sdc1 $f30,(30*8+offes_fltregs)(sp)
+ sdc1 $f31,(31*8+offes_fltregs)(sp)
+
+ /* calculate sp of method */
+ daddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
+ sd itmp1,(offes_sp)(sp)
+
+ /* store pv */
+ sd pv,(offes_pv)(sp)
+
+ /* call replace_me */
+ ld a0,-(2*8)(itmp1) /* arg0: rplpoint * */
+ move a1,sp /* arg1: execution state */
+ jal replace_me /* call C function replace_me */
+ jal abort /* NEVER REACHED */
+
+ .end asm_replacement_out
+
+/* asm_replacement_in **********************************************************
+
+ This code writes the given execution state and jumps to the replacement
+ code.
+
+ This function never returns!
+
+ NOTE: itmp3 is not restored!
+
+ C prototype:
+ void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+ .ent asm_replacement_in
+
+asm_replacement_in:
+ /* a0 == executionstate *es */
+
+ /* set new sp and pv */
+ ld sp,(offes_sp)(a0)
+ ld pv,(offes_pv)(a0)
+
+ /* copy registers from execution state */
+ /* $0 is zero */
+ ld $1 ,( 1*8+offes_intregs)(a0)
+ ld $2 ,( 2*8+offes_intregs)(a0)
+ ld $3 ,( 2*8+offes_intregs)(a0)
+ /* a0 is loaded below */
+ ld $5 ,( 5*8+offes_intregs)(a0)
+ ld $6 ,( 6*8+offes_intregs)(a0)
+ ld $7 ,( 7*8+offes_intregs)(a0)
+ ld $8 ,( 8*8+offes_intregs)(a0)
+ ld $9 ,( 9*8+offes_intregs)(a0)
+ ld $10,(10*8+offes_intregs)(a0)
+ ld $11,(11*8+offes_intregs)(a0)
+ ld $12,(12*8+offes_intregs)(a0)
+ ld $13,(13*8+offes_intregs)(a0)
+ ld $14,(14*8+offes_intregs)(a0)
+ ld $15,(15*8+offes_intregs)(a0)
+ ld $16,(16*8+offes_intregs)(a0)
+ ld $17,(17*8+offes_intregs)(a0)
+ ld $18,(18*8+offes_intregs)(a0)
+ ld $19,(19*8+offes_intregs)(a0)
+ ld $20,(20*8+offes_intregs)(a0)
+ ld $21,(21*8+offes_intregs)(a0)
+ ld $22,(22*8+offes_intregs)(a0)
+ ld $23,(23*8+offes_intregs)(a0)
+ ld $24,(24*8+offes_intregs)(a0)
+ ld $25,(25*8+offes_intregs)(a0)
+ ld $26,(26*8+offes_intregs)(a0)
+ ld $27,(27*8+offes_intregs)(a0)
+ ld $28,(28*8+offes_intregs)(a0)
+ /* $29 is sp */
+ /* $30 is pv */
+ ld $31,(31*8+offes_intregs)(a0)
+
+ ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
+ ldc1 $f1 ,( 1*8+offes_fltregs)(a0)
+ ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
+ ldc1 $f3 ,( 3*8+offes_fltregs)(a0)
+ ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
+ ldc1 $f5 ,( 5*8+offes_fltregs)(a0)
+ ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
+ ldc1 $f7 ,( 7*8+offes_fltregs)(a0)
+ ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
+ ldc1 $f9 ,( 9*8+offes_fltregs)(a0)
+ ldc1 $f10,(10*8+offes_fltregs)(a0)
+ ldc1 $f11,(11*8+offes_fltregs)(a0)
+ ldc1 $f12,(12*8+offes_fltregs)(a0)
+ ldc1 $f13,(13*8+offes_fltregs)(a0)
+ ldc1 $f14,(14*8+offes_fltregs)(a0)
+ ldc1 $f15,(15*8+offes_fltregs)(a0)
+ ldc1 $f16,(16*8+offes_fltregs)(a0)
+ ldc1 $f17,(17*8+offes_fltregs)(a0)
+ ldc1 $f18,(18*8+offes_fltregs)(a0)
+ ldc1 $f19,(19*8+offes_fltregs)(a0)
+ ldc1 $f20,(20*8+offes_fltregs)(a0)
+ ldc1 $f21,(21*8+offes_fltregs)(a0)
+ ldc1 $f22,(22*8+offes_fltregs)(a0)
+ ldc1 $f23,(23*8+offes_fltregs)(a0)
+ ldc1 $f24,(24*8+offes_fltregs)(a0)
+ ldc1 $f25,(25*8+offes_fltregs)(a0)
+ ldc1 $f26,(26*8+offes_fltregs)(a0)
+ ldc1 $f27,(27*8+offes_fltregs)(a0)
+ ldc1 $f28,(28*8+offes_fltregs)(a0)
+ ldc1 $f29,(29*8+offes_fltregs)(a0)
+ ldc1 $f30,(30*8+offes_fltregs)(a0)
+ ldc1 $f31,(31*8+offes_fltregs)(a0)
+
+ /* load new pc */
+
+ ld itmp3,offes_pc(a0)
+
+ /* load a0 */
+
+ ld a0,(4*8+offes_intregs)(a0)
+
+ /* jump to new code */
+
+ jr itmp3
+
+ .end asm_replacement_in
+
/******************* function asm_initialize_thread_stack **********************
* *
* u1* asm_initialize_thread_stack (void *func, u1 *stack); *
.end compare_and_swap
+/* Disable exec-stacks, required for Gentoo ***********************************/
+
+#if defined(__GCC__) && defined(__ELF__)
+ .section .note.GNU-stack,"",@progbits
+#endif
+
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/