Changes: Christian Thalinger
Edwin Steiner
- $Id: asmpart.S 6265 2007-01-02 20:40:57Z edwin $
+ $Id: asmpart.S 7206 2007-01-11 22:39:52Z twisti $
*/
.globl compare_and_swap
-/********************* function asm_calljavafunction ***************************
+/* asm_vm_call_method **********************************************************
* *
* This function calls a Java-method (which possibly needs compilation) *
* with up to 4 address parameters. *
.align 3
+#if SIZEOF_VOID_P == 8
+
.dword 0 /* catch type all */
.dword 0 /* handler pc */
.dword 0 /* end pc */
.word 0 /* frame size */
.dword 0 /* codeinfo pointer */
+#else /* SIZEOF_VOID_P == 8 */
+
+ .word 0 /* catch type all */
+ .word 0 /* handler pc */
+ .word 0 /* end pc */
+ .word 0 /* start pc */
+ .word 1 /* extable size */
+ .word 0 /* line number table start */
+ .word 0 /* line number table size */
+ .word 0 /* fltsave */
+ .word 0 /* intsave */
+ .word 0 /* isleaf */
+ .word 0 /* IsSync */
+ .word 0 /* frame size */
+ .word 0 /* method pointer (pointer to name) */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
asm_vm_call_method:
asm_vm_call_method_int:
asm_vm_call_method_long:
ast pv,1*8(sp) /* procedure vector */
L_asm_vm_call_method_compute_pv:
aaddiu pv,ra,-4*4
+
ast s7,3*8(sp)
+#if SIZEOF_VOID_P == 8
sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
sdc1 fss1,6*8(sp)
sdc1 fss2,7*8(sp)
sdc1 fss3,8*8(sp)
sdc1 fss4,9*8(sp)
sdc1 fss5,10*8(sp)
+#endif
ast a0,4*8(sp) /* save method pointer for compiler */
- move t0,a2
- move s7,a1
+ move t0,a2 /* address of first block */
+ move s7,a1 /* argument count */
blez s7,calljava_argsloaded
nop
+#if SIZEOF_VOID_P == 8
+
ald a0,offvmargdata(t0)
ldc1 fa0,offvmargdata(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a1,offvmargdata+sizevmarg*1(t0)
ldc1 fa1,offvmargdata+sizevmarg*1(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a2,offvmargdata+sizevmarg*2(t0)
ldc1 fa2,offvmargdata+sizevmarg*2(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a3,offvmargdata+sizevmarg*3(t0)
ldc1 fa3,offvmargdata+sizevmarg*3(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a4,offvmargdata+sizevmarg*4(t0)
ldc1 fa4,offvmargdata+sizevmarg*4(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a5,offvmargdata+sizevmarg*5(t0)
ldc1 fa5,offvmargdata+sizevmarg*5(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a6,offvmargdata+sizevmarg*6(t0)
ldc1 fa6,offvmargdata+sizevmarg*6(t0)
- daddi s7,s7,-1
+ aaddi s7,s7,-1
blez s7,calljava_argsloaded
nop
ald a7,offvmargdata+sizevmarg*7(t0)
ldc1 fa7,offvmargdata+sizevmarg*7(t0)
- daddi s7,s7,-1
-
+ aaddi s7,s7,-1
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#if WORDS_BIGENDIAN == 1
+ ald a0,offvmargdata+4(t0)
+#else
+ ald a0,offvmargdata(t0)
+#endif
+#if !defined(ENABLE_SOFT_FLOAT)
+ ldc1 fa0,offvmargdata(t0)
+#endif
+ aaddi s7,s7,-1
+ blez s7,calljava_argsloaded
+
+#if WORDS_BIGENDIAN == 1
+ ald a1,offvmargdata+4+sizevmarg*1(t0)
+#else
+ ald a1,offvmargdata+sizevmarg*1(t0)
+#endif
+#if !defined(ENABLE_SOFT_FLOAT)
+ ldc1 fa1,offvmargdata+sizevmarg*1(t0)
+#endif
+ aaddi s7,s7,-1
+ blez s7,calljava_argsloaded
+
+#if WORDS_BIGENDIAN == 1
+ ald a2,offvmargdata+4+sizevmarg*2(t0)
+#else
+ ald a2,offvmargdata+sizevmarg*2(t0)
+#endif
+ aaddi s7,s7,-1
+ blez s7,calljava_argsloaded
+
+#if WORDS_BIGENDIAN == 1
+ ald a3,offvmargdata+4+sizevmarg*3(t0)
+#else
+ ald a3,offvmargdata+sizevmarg*3(t0)
+#endif
+ aaddi s7,s7,-1
+ blez s7,calljava_argsloaded
+
+#endif /* SIZEOF_VOID_P == 8 */
+
calljava_argsloaded:
- move t4,sp /* save stack pointer */
+ move t4,sp /* save stack pointer */
blez s7,calljava_nocopy
nop
- subu t1,zero,s7 /* create argument stack frame */
- sll t2,t1,3
- aaddu sp,sp,t2
- aaddu t2,t2,t4
+
+#if SIZEOF_VOID_P == 4
+ aaddiu s7,s7,4 /* add stack space for 4 arguments */
+#endif
+ subu t1,zero,s7 /* remaining argument count (negative) */
+ sll t2,t1,3 /* calculate stackframe size */
+ aaddu sp,sp,t2 /* create stackframe */
+ aaddu t2,t2,t4 /* also set temp sp */
+#if SIZEOF_VOID_P == 4
+ aaddiu t2,t2,4*8 /* skip stack space for 4 arguments */
+ addiu t1,t1,4
+#endif
calljava_copyloop:
- ald t3,offvmargdata+sizevmarg*8(t0)
- ast t3,0(t2)
- aaddi t1,t1,1
- aaddi t0,t0,sizevmarg
- aaddi t2,t2,8
- bnez t1,calljava_copyloop
+#if SIZEOF_VOID_P == 8
+ ald t3,offvmargdata+sizevmarg*8(t0)
+#else
+# if WORDS_BIGENDIAN == 1
+ ald t3,offvmargdata+4+sizevmarg*4(t0)
+# else
+ ald t3,offvmargdata+sizevmarg*4(t0)
+# endif
+#endif
+ ast t3,0(t2) /* store argument on stack */
+ addi t1,t1,1 /* count 1 argument */
+ aaddi t0,t0,sizevmarg /* load address of next block */
+ aaddi t2,t2,8 /* increase stack position */
+ bnez t1,calljava_copyloop /* all arguments copied? */
nop
calljava_nocopy:
jalr pv /* call JIT compiler */
nop
L_asm_vm_call_method_recompute_pv:
-/* aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)*/
+#if SIZEOF_VOID_P == 8
aaddiu pv,ra,-76*4 /* recompute procedure vector */
+#else
+ aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
+#endif
.set reorder /* XXX we need to recompute pv */
- asll s7,s7,3 /* remove argument stack frame */
- aaddu sp,sp,s7
+ sll t1,s7,3 /* remove argument stackframe */
+ aaddu sp,sp,t1
calljava_return2:
- ald ra,0(sp) /* restore return address */
- ald pv,8(sp) /* restore procedure vector */
+ ald ra,0*8(sp) /* restore return address */
+ ald pv,1*8(sp) /* restore procedure vector */
ald s7,3*8(sp)
+#if SIZEOF_VOID_P == 8
ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
ldc1 fss1,6*8(sp)
ldc1 fss2,7*8(sp)
ldc1 fss3,8*8(sp)
ldc1 fss4,9*8(sp)
ldc1 fss5,10*8(sp)
+#endif
aaddiu sp,sp,12*8 /* free stack space */
j ra /* return */
asm_vm_call_method_exception_handler:
- asll s7,s7,3 /* remove argument stack frame */
- aaddu sp,sp,s7
+ sll t1,s7,3 /* remove stackframe */
+ aaddu sp,sp,t1
+#if SIZEOF_VOID_P == 4
+ aaddiu sp,sp,-4*4 /* reserve space for 1 argument */
+#endif
move a0,itmp1
jal builtin_throw_exception
+#if SIZEOF_VOID_P == 4
+ aaddiu sp,sp,4*4
+#endif
b calljava_return2
.end asm_vm_call_method
* *
*******************************************************************************/
-
.ent asm_call_jit_compiler
asm_call_jit_compiler:
- aaddiu sp,sp,-(ARG_CNT+2)*8 /* allocate stack space */
+#if SIZEOF_VOID_P == 8
+
+ aaddiu sp,sp,-(ARG_CNT+2)*8 /* +2: keep stack 16-bytes aligned */
ast ra,0*8(sp) /* save return address */
aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
+#else /* SIZEOF_VOID_P == 8 */
+
+ aaddiu sp,sp,-(ARG_CNT+2)*8 /* +4: keep stack 16-bytes aligned */
+
+ ast ra,4*4+0*4(sp) /* save return address */
+
+ SAVE_ARGUMENT_REGISTERS(6)
+
+ move a0,itmp1 /* pass methodinfo pointer */
+ move a1,mptr /* pass method pointer */
+ aaddiu a2,sp,(ARG_CNT+2)*8 /* pass java sp */
+ move a3,ra
+ jal jit_asm_compile /* call jit compiler */
+ move pv,v0
+
+ ald ra,4*4+0*4(sp) /* restore return address */
+
+ RESTORE_ARGUMENT_REGISTERS(6)
+
+ aaddiu sp,sp,(ARG_CNT+2)*8 /* remove stack frame */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
beqz pv,L_asm_call_jit_compiler_exception
jr pv /* and call method. The method returns */
asm_handle_nat_exception:
L_asm_handle_exception_stack_loop:
+#if SIZEOF_VOID_P == 8
aaddiu sp,sp,-6*8 /* keep stack 16-byte aligned */
ast xptr,0*8(sp) /* save exception pointer */
ast xpc,1*8(sp) /* save exception pc */
ast ra,3*8(sp) /* save RA */
ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
+#else
+ aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
+ ast xptr,4*4+0*8(sp) /* save exception pointer */
+ ast xpc,4*4+1*8(sp) /* save exception pc */
+ ast ra,4*4+3*8(sp) /* save return address */
+ ast zero,4*4+4*8(sp) /* save maybe-leaf flag (cleared) */
+#endif
move a0,ra /* pass RA */
jal md_codegen_get_pv_from_pc /* get PV from RA */
+
+#if SIZEOF_VOID_P == 8
ast v0,2*8(sp) /* save PV */
ald a0,0*8(sp) /* pass xptr */
ald a1,1*8(sp) /* pass xpc */
move a2,v0 /* pass PV */
aaddiu a3,sp,6*8 /* pass Java SP */
+#else
+ ast v0,4*4+2*8(sp) /* save data segment pointer */
+
+ ald a0,4*4+0*8(sp) /* pass exception pointer */
+ ald a1,4*4+1*8(sp) /* pass exception pc */
+ move a2,v0 /* pass data segment pointer */
+ aaddiu a3,sp,(4*4+6*8) /* pass Java stack pointer */
+#endif
b L_asm_handle_exception_continue
SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
+#if SIZEOF_VOID_P == 8
aaddiu sp,sp,-6*8 /* allocate stack */
ast xptr,0*8(sp) /* save exception pointer */
ast pv,2*8(sp) /* save PV */
ast ra,3*8(sp) /* save RA */
addu t0,zero,1 /* set maybe-leaf flag */
ast t0,4*8(sp) /* save maybe-leaf flag */
+#else
+ aaddiu sp,sp,-(4*4+6*8) /* allocate stack */
+ ast xptr,4*4+0*8(sp) /* save exception pointer */
+ ast xpc,4*4+1*8(sp) /* save exception pc */
+ ast pv,4*4+2*8(sp) /* save data segment pointer */
+ ast ra,4*4+3*8(sp) /* save return address */
+ addu t0,zero,1 /* set maybe-leaf flag */
+ ast t0,4*4+4*8(sp) /* save maybe-leaf flag */
+#endif
move a0,xptr /* pass xptr */
move a1,xpc /* pass xpc */
move a2,pv /* pass PV */
+
+#if SIZEOF_VOID_P == 8
aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP */
+#else
+ aaddiu a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
+#endif
L_asm_handle_exception_continue:
jal exceptions_handle_exception
beqz v0,L_asm_handle_exception_not_catched
move xpc,v0 /* move handlerpc into xpc */
+
+#if SIZEOF_VOID_P == 8
ald xptr,0*8(sp) /* restore exception pointer */
ald pv,2*8(sp) /* restore PV */
ald ra,3*8(sp) /* restore RA */
ald t0,4*8(sp) /* get maybe-leaf flag */
aaddiu sp,sp,6*8 /* free stackframe */
+#else
+ ald xptr,4*4+0*8(sp) /* restore exception pointer */
+ ald pv,4*4+2*8(sp) /* restore data segment pointer */
+ ald ra,4*4+3*8(sp) /* restore return address */
+ ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
+ aaddiu sp,sp,4*4+6*8 /* free stackframe */
+#endif
beqz t0,L_asm_handle_exception_no_leaf
jr xpc /* jump to the handler */
L_asm_handle_exception_not_catched:
+#if SIZEOF_VOID_P == 8
ald xptr,0*8(sp) /* restore xptr */
ald pv,2*8(sp) /* restore PV */
ald ra,3*8(sp) /* restore RA */
ald t0,4*8(sp) /* get maybe-leaf flag */
aaddiu sp,sp,6*8 /* free stackframe */
+#else
+ ald xptr,4*4+0*8(sp) /* restore xptr */
+ ald pv,4*4+2*8(sp) /* restore PV */
+ ald ra,4*4+3*8(sp) /* restore RA */
+ ald t0,4*4+4*8(sp) /* get maybe-leaf flag */
+ aaddiu sp,sp,4*4+6*8 /* free stackframe */
+#endif
beqz t0,L_asm_handle_exception_no_leaf_stack
ald s5,-3*8(t1)
ald s6,-2*8(t1)
ald s7,-1*8(t1)
+
ex_int2:
sll t2,t2,1 /* t2 = register count * 4 * 2 */
asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
jr t3 /* jump to save position */
+#if SIZEOF_VOID_P == 8
+ ldc1 fs0,-4*8(t1)
+ ldc1 fs1,-3*8(t1)
+ ldc1 fs2,-2*8(t1)
+ ldc1 fs3,-1*8(t1)
+#else /* SIZEOF_VOID_P == 8 */
+# if !defined(ENABLE_SOFT_FLOAT)
ldc1 fs0,-4*8(t1)
ldc1 fs1,-3*8(t1)
ldc1 fs2,-2*8(t1)
ldc1 fs3,-1*8(t1)
+ ldc1 fs4,-1*8(t1)
+ ldc1 fs5,-1*8(t1)
+# endif /* !defined(ENABLE_SOFT_FLOAT) */
+#endif /* SIZEOF_VOID_P == 8 */
ex_flt2:
lw t1,FrameSize(pv) /* get frame size */
.ent asm_patcher_wrapper
asm_patcher_wrapper:
+#if SIZEOF_VOID_P == 8
+
aaddiu sp,sp,-((2+16+22+4)*8)/* create stack frame */
SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */
move xptr,itmp3 /* get exception */
ald xpc,(7+2+16+22+4)*8(sp) /* xpc is RA */
aaddiu sp,sp,(8+2+16+22+4)*8 /* remove stack frame */
+
+#else /* SIZEOF_VOID_P == 8 */
+
+ aaddiu sp,sp,-((5+4+4+8+7)*4) /* create stack frame */
+ /* +7 keeps the SP 16-bytes aligned */
+
+ SAVE_RETURN_REGISTERS(5) /* save 2 int / 2 float return registers */
+ SAVE_ARGUMENT_REGISTERS(9) /* save 4 int argument registers */
+ SAVE_TEMPORARY_REGISTERS(13) /* save 8 int temporary registers */
+
+ ast itmp1,(5+4+4+8+0)*4(sp) /* save itmp1 */
+ ast itmp2,(5+4+4+8+1)*4(sp) /* save itmp2 */
+ ast ra,(5+4+4+8+2)*4(sp) /* save method return address (for leafs) */
+ ast pv,(5+4+4+8+3)*4(sp) /* save pv of calling java function */
+
+ aaddiu a0,sp,(5+4+4+8+7)*4 /* pass SP of patcher stub */
+ move a1,pv /* pass PV */
+ move a2,ra /* pass RA (correct for leafs) */
+ jal patcher_wrapper
+ move itmp3,v0
+
+ RESTORE_RETURN_REGISTERS(5) /* restore 2 int / 2 float return registers */
+ RESTORE_ARGUMENT_REGISTERS(9) /* restore 4 int argument registers */
+ RESTORE_TEMPORARY_REGISTERS(13) /* restore 9 int temporary registers */
+
+ ald itmp1,(5+4+4+8+0)*4(sp) /* restore itmp1 */
+ ald itmp2,(5+4+4+8+1)*4(sp) /* restore itmp2 */
+ ald ra,(5+4+4+8+2)*4(sp) /* restore method return address (for leafs)*/
+ ald pv,(5+4+4+8+3)*4(sp) /* restore pv of calling java function */
+
+ bnez itmp3,L_asm_wrapper_patcher_exception
+
+ ald itmp3,7*8+(5+4+4+8+7)*4(sp) /* load RA */
+ aaddiu sp,sp,8*8+(5+4+4+8+7)*4 /* remove stack frame */
+
+ jr itmp3 /* jump to new patched code */
+
+L_asm_wrapper_patcher_exception:
+ move xptr,itmp3 /* get exception */
+ ald xpc,7*8+(5+4+4+8+7)*4(sp) /* xpc is RA */
+ aaddiu sp,sp,8*8+(5+4+4+8+7)*4 /* remove stack frame */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
b asm_handle_exception
.end asm_patcher_wrapper
asm_replacement_out:
/* create stack frame */
- daddiu sp,sp,-REPLACEMENT_STACK_OFFSET
+ aaddiu 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)
-
+ ast $0 ,( 0*8+offes_intregs)(sp)
+ ast $1 ,( 1*8+offes_intregs)(sp)
+ ast $2 ,( 2*8+offes_intregs)(sp)
+ ast $3 ,( 3*8+offes_intregs)(sp)
+ ast $4 ,( 4*8+offes_intregs)(sp)
+ ast $5 ,( 5*8+offes_intregs)(sp)
+ ast $6 ,( 6*8+offes_intregs)(sp)
+ ast $7 ,( 7*8+offes_intregs)(sp)
+ ast $8 ,( 8*8+offes_intregs)(sp)
+ ast $9 ,( 9*8+offes_intregs)(sp)
+ ast $10,(10*8+offes_intregs)(sp)
+ ast $11,(11*8+offes_intregs)(sp)
+ ast $12,(12*8+offes_intregs)(sp)
+ ast $13,(13*8+offes_intregs)(sp)
+ ast $14,(14*8+offes_intregs)(sp)
+ ast $15,(15*8+offes_intregs)(sp)
+ ast $16,(16*8+offes_intregs)(sp)
+ ast $17,(17*8+offes_intregs)(sp)
+ ast $18,(18*8+offes_intregs)(sp)
+ ast $19,(19*8+offes_intregs)(sp)
+ ast $20,(20*8+offes_intregs)(sp)
+ ast $21,(21*8+offes_intregs)(sp)
+ ast $22,(22*8+offes_intregs)(sp)
+ ast $23,(23*8+offes_intregs)(sp)
+ ast $24,(24*8+offes_intregs)(sp)
+ ast $25,(25*8+offes_intregs)(sp)
+ ast $26,(26*8+offes_intregs)(sp)
+ ast $27,(27*8+offes_intregs)(sp)
+ ast $28,(28*8+offes_intregs)(sp)
+ ast $29,(29*8+offes_intregs)(sp)
+ ast $30,(30*8+offes_intregs)(sp)
+ ast $31,(31*8+offes_intregs)(sp)
+
+#if SIZEOF_VOID_P == 8
+
sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
sdc1 $f1 ,( 1*8+offes_fltregs)(sp)
sdc1 $f2 ,( 2*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)
+
+#else /* SIZEOF_VOID_P == 8 */
+
+ sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
+ sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
+ sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
+ sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
+ sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
+ sdc1 $f10,(10*8+offes_fltregs)(sp)
+ sdc1 $f12,(12*8+offes_fltregs)(sp)
+ sdc1 $f14,(14*8+offes_fltregs)(sp)
+ sdc1 $f16,(16*8+offes_fltregs)(sp)
+ sdc1 $f18,(18*8+offes_fltregs)(sp)
+ sdc1 $f20,(20*8+offes_fltregs)(sp)
+ sdc1 $f22,(22*8+offes_fltregs)(sp)
+ sdc1 $f24,(24*8+offes_fltregs)(sp)
+ sdc1 $f26,(26*8+offes_fltregs)(sp)
+ sdc1 $f28,(28*8+offes_fltregs)(sp)
+ sdc1 $f30,(30*8+offes_fltregs)(sp)
+
+#endif /* SIZEOF_VOID_P == 8 */
/* calculate sp of method */
- daddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
- sd itmp1,(offes_sp)(sp)
+ aaddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
+ ast itmp1,(offes_sp)(sp)
/* store pv */
- sd pv,(offes_pv)(sp)
+ ast pv,(offes_pv)(sp)
/* call replace_me */
- ld a0,-(2*8)(itmp1) /* arg0: rplpoint * */
+ ald a0,-(2*8)(itmp1) /* arg0: rplpoint * */
move a1,sp /* arg1: execution state */
jal replace_me /* call C function replace_me */
jal abort /* NEVER REACHED */
/* a0 == executionstate *es */
/* set new sp and pv */
- ld sp,(offes_sp)(a0)
- ld pv,(offes_pv)(a0)
+ ald sp,(offes_sp)(a0)
+ ald 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)
+ ald $1 ,( 1*8+offes_intregs)(a0)
+ ald $2 ,( 2*8+offes_intregs)(a0)
+ ald $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)
+ ald $5 ,( 5*8+offes_intregs)(a0)
+ ald $6 ,( 6*8+offes_intregs)(a0)
+ ald $7 ,( 7*8+offes_intregs)(a0)
+ ald $8 ,( 8*8+offes_intregs)(a0)
+ ald $9 ,( 9*8+offes_intregs)(a0)
+ ald $10,(10*8+offes_intregs)(a0)
+ ald $11,(11*8+offes_intregs)(a0)
+ ald $12,(12*8+offes_intregs)(a0)
+ ald $13,(13*8+offes_intregs)(a0)
+ ald $14,(14*8+offes_intregs)(a0)
+ ald $15,(15*8+offes_intregs)(a0)
+ ald $16,(16*8+offes_intregs)(a0)
+ ald $17,(17*8+offes_intregs)(a0)
+ ald $18,(18*8+offes_intregs)(a0)
+ ald $19,(19*8+offes_intregs)(a0)
+ ald $20,(20*8+offes_intregs)(a0)
+ ald $21,(21*8+offes_intregs)(a0)
+ ald $22,(22*8+offes_intregs)(a0)
+ ald $23,(23*8+offes_intregs)(a0)
+ ald $24,(24*8+offes_intregs)(a0)
+ ald $25,(25*8+offes_intregs)(a0)
+ ald $26,(26*8+offes_intregs)(a0)
+ ald $27,(27*8+offes_intregs)(a0)
+ ald $28,(28*8+offes_intregs)(a0)
/* $29 is sp */
/* $30 is pv */
- ld $31,(31*8+offes_intregs)(a0)
+ ald $31,(31*8+offes_intregs)(a0)
+#if SIZEOF_VOID_P == 8
+
ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
ldc1 $f1 ,( 1*8+offes_fltregs)(a0)
ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
ldc1 $f30,(30*8+offes_fltregs)(a0)
ldc1 $f31,(31*8+offes_fltregs)(a0)
+#else /* SIZEOF_VOID_P == 8 */
+
+ ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
+ ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
+ ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
+ ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
+ ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
+ ldc1 $f10,(10*8+offes_fltregs)(a0)
+ ldc1 $f12,(12*8+offes_fltregs)(a0)
+ ldc1 $f14,(14*8+offes_fltregs)(a0)
+ ldc1 $f16,(16*8+offes_fltregs)(a0)
+ ldc1 $f18,(18*8+offes_fltregs)(a0)
+ ldc1 $f20,(20*8+offes_fltregs)(a0)
+ ldc1 $f22,(22*8+offes_fltregs)(a0)
+ ldc1 $f24,(24*8+offes_fltregs)(a0)
+ ldc1 $f26,(26*8+offes_fltregs)(a0)
+ ldc1 $f28,(28*8+offes_fltregs)(a0)
+ ldc1 $f30,(30*8+offes_fltregs)(a0)
+
+#endif /* SIZEOF_VOID_P == 8 */
+
/* load new pc */
- ld itmp3,offes_pc(a0)
+ ald itmp3,offes_pc(a0)
/* load a0 */
- ld a0,(4*8+offes_intregs)(a0)
+ ald a0,(4*8+offes_intregs)(a0)
/* jump to new code */
This module generates MIPS machine code for a sequence of
intermediate code commands (ICMDs).
- $Id: codegen.c 6286 2007-01-10 10:03:38Z twisti $
+ $Id: codegen.c 7206 2007-01-11 22:39:52Z twisti $
*/
#if defined(ENABLE_THREADS)
/* space to save argument of monitor_enter */
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+# if SIZEOF_VOID_P == 8
cd->stackframesize++;
+# else
+ rd->memuse++;
+ cd->stackframesize += 2;
+# endif
+ }
#endif
/* keep stack 16-byte aligned */
s1 = md->params[p].regoff;
if (IS_INT_LNG_TYPE(t)) { /* integer args */
if (!md->params[p].inmemory) { /* register arguments */
+#if SIZEOF_VOID_P == 8
s2 = rd->argintregs[s1];
if (!(var->flags & INMEMORY)) { /* reg arg -> register */
M_INTMOVE(s2, var->vv.regoff);
} else { /* reg arg -> spilled */
M_LST(s2, REG_SP, var->vv.regoff * 8);
}
-
+#else
+ if (IS_2_WORD_TYPE(t)) {
+ s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ if (!(var->flags & INMEMORY)) /* reg arg -> register */
+ M_LNGMOVE(s2, var->vv.regoff);
+ else /* reg arg -> spilled */
+ M_LST(s2, REG_SP, var->vv.regoff * 8);
+ }
+ else {
+ s2 = rd->argintregs[s1];
+ if (!(var->flags & INMEMORY)) /* reg arg -> register */
+ M_INTMOVE(s2, var->vv.regoff);
+ else /* reg arg -> spilled */
+ M_IST(s2, REG_SP, var->vv.regoff * 8);
+ }
+#endif
} else { /* stack arguments */
if (!(var->flags & INMEMORY)) { /* stack arg -> register */
+#if SIZEOF_VOID_P == 8
M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+#else
+ if (IS_2_WORD_TYPE(t))
+ M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+ else
+ M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+#endif
} else { /* stack arg -> spilled */
var->vv.regoff = cd->stackframesize + s1;
}
} else { /* floating args */
if (!md->params[p].inmemory) { /* register arguments */
+#if SIZEOF_VOID_P == 8
s2 = rd->argfltregs[s1];
if (!(var->flags & INMEMORY)) { /* reg arg -> register */
if (IS_2_WORD_TYPE(t))
else
M_FST(s2, REG_SP, var->vv.regoff * 8);
}
+#else
+ if ((p == 0) ||
+ ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
+ s2 = rd->argfltregs[s1];
+ if (!(var->flags & INMEMORY)) { /* reg arg -> register */
+ if (IS_2_WORD_TYPE(t))
+ M_DBLMOVE(s2, var->vv.regoff);
+ else
+ M_FLTMOVE(s2, var->vv.regoff);
+ }
+ else { /* reg arg -> spilled */
+ if (IS_2_WORD_TYPE(t))
+ M_DST(s2, REG_SP, var->vv.regoff * 8);
+ else
+ M_FST(s2, REG_SP, var->vv.regoff * 8);
+ }
+ }
+ else {
+ if (IS_2_WORD_TYPE(t)) {
+ s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ if (!(var->flags & INMEMORY)) {
+ M_MTC1(GET_LOW_REG(s2), var->vv.regoff);
+ M_MTC1(GET_HIGH_REG(s2), var->vv.regoff + 1);
+ M_NOP;
+ }
+ else
+ M_LST(s2, REG_SP, var->vv.regoff * 8);
+ }
+ else {
+ s2 = rd->argintregs[s1];
+ if (!(var->flags & INMEMORY)) {
+ M_MTC1(s2, var->vv.regoff);
+ M_NOP;
+ }
+ else
+ M_IST(s2, REG_SP, var->vv.regoff * 8);
+ }
+ }
+#endif
} else { /* stack arguments */
if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
for (p = 0; p < INT_ARG_CNT; p++)
- M_LST(rd->argintregs[p], REG_SP, p * 8);
+ M_AST(rd->argintregs[p], REG_SP, p * 8);
for (p = 0; p < FLT_ARG_CNT; p++)
M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
# if !defined(NDEBUG)
if (opt_verbosecall) {
for (p = 0; p < INT_ARG_CNT; p++)
- M_LLD(rd->argintregs[p], REG_SP, p * 8);
+ M_ALD(rd->argintregs[p], REG_SP, p * 8);
for (p = 0; p < FLT_ARG_CNT; p++)
M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
# endif
}
#endif
+ }
#if !defined(NDEBUG)
if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
emit_verbosecall_enter(jd);
#endif
- }
-
/* end of header generation */
/* create replacement points */
/* walk through all instructions */
len = bptr->icount;
- currentline = 0;
+/* currentline = 0; */
for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
if (iptr->line != currentline) {
case ICMD_LCONST: /* ... ==> ..., constant */
+#if SIZEOF_VOID_P == 8
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+#endif
LCONST(d, iptr->sx.val.l);
emit_store_dst(jd, iptr, d);
break;
case ICMD_LNEG: /* ..., value ==> ..., - value */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_LSUB(REG_ZERO, s1, d);
+#else
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
+ M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
+ M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
+ M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_I2L: /* ..., value ==> ..., value */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_INTMOVE(s1, d);
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_INTMOVE(s1, GET_LOW_REG(d));
+ M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_L2I: /* ..., value ==> ..., value */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_ISLL_IMM(s1, 0, d );
+ M_ISLL_IMM(s1, 0, d);
+#else
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_INTMOVE(GET_LOW_REG(s1), d);
+#endif
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
M_LSLL_IMM(s1, 56, d);
M_LSRA_IMM( d, 56, d);
+#else
+ M_ISLL_IMM(s1, 24, d);
+ M_ISRA_IMM( d, 24, d);
+#endif
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_CZEXT(s1, d);
+ M_AND_IMM(s1, 0xffff, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
M_LSLL_IMM(s1, 48, d);
M_LSRA_IMM( d, 48, d);
+#else
+ M_ISLL_IMM(s1, 16, d);
+ M_ISRA_IMM( d, 16, d);
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_LADD(s1, s2, d);
+#else
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_IADD(s1, s2, GET_HIGH_REG(d));
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
+ if (s1 == GET_LOW_REG(d)) {
+ M_MOV(s1, REG_ITMP3);
+ s1 = REG_ITMP3;
+ }
+ M_IADD(s1, s2, GET_LOW_REG(d));
+ M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
+ M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
/* sx.val.l = constant */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
LCONST(REG_ITMP2, iptr->sx.val.l);
M_LADD(s1, REG_ITMP2, d);
}
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+ M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
+ M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
+ }
+ else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+ M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
+ M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
+ M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+ }
+ else {
+ ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
+ M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
+ ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
+ M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+ }
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_LSUB(s1, s2, d);
+#else
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_ISUB(s1, s2, GET_HIGH_REG(d));
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
+ M_CMPULT(s1, s2, REG_ITMP3);
+ M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+ /* if s1 is equal to REG_ITMP3 we have to reload it, since
+ the CMPULT instruction destroyed it */
+ if (s1 == REG_ITMP3)
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_ISUB(s1, s2, GET_LOW_REG(d));
+
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
/* sx.val.l = constant */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
LCONST(REG_ITMP2, iptr->sx.val.l);
M_LSUB(s1, REG_ITMP2, d);
}
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+ M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
+ M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
+ M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+ }
+ else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
+ M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
+ M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
+ }
+ else {
+ ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
+ M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
+ ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
+ M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+ }
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_MFLO(d);
M_NOP;
M_NOP;
+#else
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_IMUL(s2, s1);
+ M_MFLO(REG_ITMP3);
+ M_NOP;
+ M_NOP;
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_IMULU(s2, s1);
+ M_MFHI(GET_HIGH_REG(d));
+ M_MFLO(GET_LOW_REG(d));
+ M_NOP;
+ M_NOP;
+ M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_IMUL(s1, s2);
+ M_MFLO(s2);
+ /* XXX do we need nops here? */
+#endif
emit_store_dst(jd, iptr, d);
break;
emit_store_dst(jd, iptr, d);
break;
- case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
+ case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
emit_arithmetic_check(cd, iptr, s2);
- M_LDIV(s1, s2);
- M_MFLO(d);
+ M_IDIV(s1, s2);
+ M_MFHI(d);
M_NOP;
M_NOP;
emit_store_dst(jd, iptr, d);
break;
- case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
+#if SIZEOF_VOID_P == 8
+
+ case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
emit_arithmetic_check(cd, iptr, s2);
- M_IDIV(s1, s2);
- M_MFHI(d);
+ M_LDIV(s1, s2);
+ M_MFLO(d);
M_NOP;
M_NOP;
emit_store_dst(jd, iptr, d);
emit_store_dst(jd, iptr, d);
break;
+#else /* SIZEOF_VOID_P == 8 */
+
+ case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
+ case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
+
+ bte = iptr->sx.s23.s3.bte;
+ md = bte->md;
+
+ s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
+ M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
+ emit_arithmetic_check(cd, iptr, REG_ITMP3);
+
+ s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
+ rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
+ M_LNGMOVE(s2, s3);
+
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
+ rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
+ M_LNGMOVE(s1, s3);
+
+ disp = dseg_add_functionptr(cd, bte->fp);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_JSR(REG_RA, REG_ITMP3);
+ M_NOP;
+
+ d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+ M_LNGMOVE(REG_RESULT_PACKED, d);
+ emit_store_dst(jd, iptr, d);
+ break;
+
+#endif /* SIZEOF_VOID_P == 8 */
+
case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
- case ICMD_LDIVPOW2: /* val.i = constant */
+ /* val.i = constant */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
M_LSRA_IMM(s1, 63, REG_ITMP2);
M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
M_LADD(s1, REG_ITMP2, REG_ITMP2);
M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
+#else
+ M_ISRA_IMM(s1, 31, REG_ITMP2);
+ M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
+ M_IADD(s1, REG_ITMP2, REG_ITMP2);
+ M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
- /* sx.val.i = constant */
+ /* val.i = constant */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
+#if SIZEOF_VOID_P == 8
+
+ case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
+ /* val.i = constant */
+
+ s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_LSRA_IMM(s1, 63, REG_ITMP2);
+ M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
+ M_LADD(s1, REG_ITMP2, REG_ITMP2);
+ M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
+ emit_store_dst(jd, iptr, d);
+ break;
+
case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
- /* sx.val.l = constant */
+ /* val.l = constant */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
+#endif /* SIZEOF_VOID_P == 8 */
+
case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_LSLL(s1, s2, d);
+#else
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ s2 = emit_load_s2(jd, iptr, REG_ITMP3);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+
+ M_ISLL(s2, 26, REG_ITMP1);
+ M_BGEZ(REG_ITMP1, 3);
+ M_NOP;
+
+ M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
+ M_BR(7);
+ M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
+
+#if 1
+ M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
+#endif
+ M_BEQZ(REG_ITMP1, 4);
+ M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
+
+ M_ISUB(s2, REG_ZERO, REG_ITMP3);
+ M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
+ M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+
+#if 0
+ M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
+#endif
+#endif
emit_store_dst(jd, iptr, d);
break;
+#if SIZEOF_VOID_P == 8
+
case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
/* sx.val.i = constant */
emit_store_dst(jd, iptr, d);
break;
+#endif /* SIZEOF_VOID_P == 8 */
+
case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
- case ICMD_LAND:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
+ if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
M_AND_IMM(s1, iptr->sx.val.i, d);
- } else {
+ else {
ICONST(REG_ITMP2, iptr->sx.val.i);
M_AND(s1, REG_ITMP2, d);
}
emit_store_dst(jd, iptr, d);
break;
+ case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
+
+#if SIZEOF_VOID_P == 8
+ s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
+ M_AND(s1, s2, d);
+#else
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_AND(s1, s2, GET_LOW_REG(d));
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+ M_AND(s1, s2, GET_HIGH_REG(d));
+#endif
+ emit_store_dst(jd, iptr, d);
+ break;
+
case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
/* sx.val.l = constant */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
LCONST(REG_ITMP2, iptr->sx.val.l);
M_AND(s1, REG_ITMP2, d);
}
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+ M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
+ }
+ else {
+ LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
+ M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
+ }
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
- case ICMD_LOR:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- M_OR(s1,s2, d);
+ M_OR(s1, s2, d);
emit_store_dst(jd, iptr, d);
break;
emit_store_dst(jd, iptr, d);
break;
+ case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
+
+#if SIZEOF_VOID_P == 8
+ s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_OR(s1, s2, d);
+#else
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_OR(s1, s2, GET_LOW_REG(d));
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+ M_OR(s1, s2, GET_HIGH_REG(d));
+#endif
+ emit_store_dst(jd, iptr, d);
+ break;
+
case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
/* sx.val.l = constant */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
LCONST(REG_ITMP2, iptr->sx.val.l);
M_OR(s1, REG_ITMP2, d);
}
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+ M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
+ }
+ else {
+ LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
+ M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
+ }
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
- case ICMD_LXOR:
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
emit_store_dst(jd, iptr, d);
break;
+ case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
+
+#if SIZEOF_VOID_P == 8
+ s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_XOR(s1, s2, d);
+#else
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ M_XOR(s1, s2, GET_LOW_REG(d));
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+ M_XOR(s1, s2, GET_HIGH_REG(d));
+#endif
+ emit_store_dst(jd, iptr, d);
+ break;
+
case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
/* sx.val.l = constant */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
LCONST(REG_ITMP2, iptr->sx.val.l);
M_XOR(s1, REG_ITMP2, d);
}
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+ M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
+ }
+ else {
+ LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
+ M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
+ }
+#endif
emit_store_dst(jd, iptr, d);
break;
case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_CMPLT(s1, s2, REG_ITMP3);
M_CMPLT(s2, s1, REG_ITMP1);
M_LSUB(REG_ITMP1, REG_ITMP3, d);
+#else
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_CMPLT(s1, s2, REG_ITMP3);
+ M_CMPLT(s2, s1, REG_ITMP1);
+ M_ISUB(REG_ITMP1, REG_ITMP3, d);
+ M_BNEZ(d, 4);
+ M_NOP;
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_CMPULT(s1, s2, REG_ITMP3);
+ M_CMPULT(s2, s1, REG_ITMP1);
+ M_ISUB(REG_ITMP1, REG_ITMP3, d);
+#endif
emit_store_dst(jd, iptr, d);
break;
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
M_FCMPULEF(s1, s2);
M_FBT(3);
- M_LADD_IMM(REG_ZERO, 1, d);
+ M_AADD_IMM(REG_ZERO, 1, d);
M_BR(4);
M_NOP;
M_FCMPEQF(s1, s2);
- M_LSUB_IMM(REG_ZERO, 1, d);
+ M_ASUB_IMM(REG_ZERO, 1, d);
M_CMOVT(REG_ZERO, d);
emit_store_dst(jd, iptr, d);
break;
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
M_FCMPULED(s1, s2);
M_FBT(3);
- M_LADD_IMM(REG_ZERO, 1, d);
+ M_AADD_IMM(REG_ZERO, 1, d);
M_BR(4);
M_NOP;
M_FCMPEQD(s1, s2);
- M_LSUB_IMM(REG_ZERO, 1, d);
+ M_ASUB_IMM(REG_ZERO, 1, d);
M_CMOVT(REG_ZERO, d);
emit_store_dst(jd, iptr, d);
break;
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
M_FCMPOLTF(s1, s2);
M_FBF(3);
- M_LSUB_IMM(REG_ZERO, 1, d);
+ M_ASUB_IMM(REG_ZERO, 1, d);
M_BR(4);
M_NOP;
M_FCMPEQF(s1, s2);
- M_LADD_IMM(REG_ZERO, 1, d);
+ M_AADD_IMM(REG_ZERO, 1, d);
M_CMOVT(REG_ZERO, d);
emit_store_dst(jd, iptr, d);
break;
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
M_FCMPOLTD(s1, s2);
M_FBF(3);
- M_LSUB_IMM(REG_ZERO, 1, d);
+ M_ASUB_IMM(REG_ZERO, 1, d);
M_BR(4);
M_NOP;
M_FCMPEQD(s1, s2);
- M_LADD_IMM(REG_ZERO, 1, d);
+ M_AADD_IMM(REG_ZERO, 1, d);
M_CMOVT(REG_ZERO, d);
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+#endif
emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+#else
+ s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
+#endif
M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
break;
emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
+#else
+ M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
+#endif
break;
case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
M_ILD_INTERN(d, REG_ITMP1, 0);
break;
case TYPE_LNG:
+#if SIZEOF_VOID_P == 8
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
+#endif
M_LLD_INTERN(d, REG_ITMP1, 0);
break;
case TYPE_ADR:
M_IST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP2);
+#else
+ s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
+#endif
M_LST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
M_ILD(d, s1, disp);
break;
case TYPE_LNG:
+#if SIZEOF_VOID_P == 8
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
M_LLD(d, s1, disp);
+#else
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
+ M_LLD_GETFIELD(d, s1, disp);
+#endif
break;
case TYPE_ADR:
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
disp = fi->offset;
}
+#if SIZEOF_VOID_P == 8
if (IS_INT_LNG_TYPE(fieldtype))
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
else
s2 = emit_load_s2(jd, iptr, REG_FTMP1);
+#else
+ if (IS_INT_LNG_TYPE(fieldtype)) {
+ if (IS_2_WORD_TYPE(fieldtype))
+ s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
+ else
+ s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+ }
+ else
+ s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+#endif
if (INSTRUCTION_IS_UNRESOLVED(iptr))
codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.i == 0) {
M_BLEZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
M_BNEZ(REG_ITMP1, 0);
- }
- else {
+ } else {
ICONST(REG_ITMP2, iptr->sx.val.i);
M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
M_BEQZ(REG_ITMP1, 0);
- }
}
+ }
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.i == 0) {
M_BNEZ(s1, 0);
- }
- else {
+ } else {
ICONST(REG_ITMP2, iptr->sx.val.i);
M_BNE(s1, REG_ITMP2, 0);
- }
+ }
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.i == 0) {
M_BGTZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
M_BEQZ(REG_ITMP1, 0);
- }
- else {
+ } else {
ICONST(REG_ITMP2, iptr->sx.val.i);
M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
M_BNEZ(REG_ITMP1, 0);
- }
}
+ }
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.i == 0) {
M_BGEZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
- }
- else {
+ } else {
ICONST(REG_ITMP2, iptr->sx.val.i);
M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
- }
- M_BEQZ(REG_ITMP1, 0);
}
+ M_BEQZ(REG_ITMP1, 0);
+ }
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_LEQ: /* ..., value ==> ... */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
M_BEQZ(s1, 0);
- }
- else {
+ } else {
LCONST(REG_ITMP2, iptr->sx.val.l);
M_BEQ(s1, REG_ITMP2, 0);
- }
+ }
+#else
+ if (iptr->sx.val.l == 0) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
+ }
+ else {
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+ M_XOR(s1, REG_ITMP2, REG_ITMP2);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
+ M_XOR(s1, REG_ITMP3, REG_ITMP3);
+ M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
+ }
+#endif
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_LLT: /* ..., value ==> ... */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
M_BLTZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
- }
- else {
+ } else {
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
- }
- M_BNEZ(REG_ITMP1, 0);
}
+ M_BNEZ(REG_ITMP1, 0);
+ }
+#else
+ if (iptr->sx.val.l == 0) {
+ /* if high word is less than zero, the whole long is too */
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ M_BLTZ(s1, 0);
+ }
+ else {
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+ M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_BNE(s1, REG_ITMP2, 5);
+ M_NOP;
+ ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+ M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ }
+#endif
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_LLE: /* ..., value ==> ... */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
M_BLEZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
M_BNEZ(REG_ITMP1, 0);
- }
- else {
+ } else {
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
M_BEQZ(REG_ITMP1, 0);
- }
}
+ }
+#else
+ if (iptr->sx.val.l == 0) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_BGTZ(GET_HIGH_REG(s1), 5);
+ M_NOP;
+ M_BLTZ(GET_HIGH_REG(s1), 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ M_BEQZ(GET_LOW_REG(s1), 0);
+ }
+ else {
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+ M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_BNE(s1, REG_ITMP2, 5);
+ M_NOP;
+ ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+ M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
+ }
+#endif
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_LNE: /* ..., value ==> ... */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
M_BNEZ(s1, 0);
- }
- else {
+ } else {
LCONST(REG_ITMP2, iptr->sx.val.l);
M_BNE(s1, REG_ITMP2, 0);
- }
+ }
+#else
+ if (iptr->sx.val.l == 0) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ }
+ else {
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+ M_XOR(s1, REG_ITMP2, REG_ITMP2);
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
+ M_XOR(s1, REG_ITMP3, REG_ITMP3);
+ M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ }
+#endif
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_LGT: /* ..., value ==> ... */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
M_BGTZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
M_BEQZ(REG_ITMP1, 0);
- }
- else {
+ } else {
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
M_BNEZ(REG_ITMP1, 0);
- }
}
+ }
+#else
+ if (iptr->sx.val.l == 0) {
+ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+ M_BGTZ(GET_HIGH_REG(s1), 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ M_BLTZ(GET_HIGH_REG(s1), 3);
+ M_NOP;
+ M_BNEZ(GET_LOW_REG(s1), 0);
+ }
+ else {
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+ M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_BNE(s1, REG_ITMP2, 5);
+ M_NOP;
+ ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+ M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ }
+#endif
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_LGE: /* ..., value ==> ... */
+#if SIZEOF_VOID_P == 8
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
M_BGEZ(s1, 0);
- }
- else {
+ } else {
if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
- }
- else {
+ } else {
LCONST(REG_ITMP2, iptr->sx.val.l);
M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
- }
- M_BEQZ(REG_ITMP1, 0);
}
+ M_BEQZ(REG_ITMP1, 0);
+ }
+#else
+ if (iptr->sx.val.l == 0) {
+ /* if high word is greater equal zero, the whole long is too */
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ M_BGEZ(s1, 0);
+ }
+ else {
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+ M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+ M_BNE(s1, REG_ITMP2, 5);
+ M_NOP;
+ ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+ M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
+ }
+#endif
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
- case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
- case ICMD_IF_ACMPEQ:
+ case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
+#if SIZEOF_VOID_P == 8
+ case ICMD_IF_LCMPEQ:
+#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_NOP;
break;
+#if SIZEOF_VOID_P == 4
+ case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
+ /* op1 = target JavaVM pc */
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_BNE(s1, s2, 3);
+ M_NOP;
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BEQ(s1, s2, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ break;
+#endif
+
case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
- case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
- case ICMD_IF_ACMPNE:
+ case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
+#if SIZEOF_VOID_P == 8
+ case ICMD_IF_LCMPNE:
+#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
M_NOP;
break;
+#if SIZEOF_VOID_P == 4
+ case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_BNE(s1, s2, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BNE(s1, s2, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ break;
+#endif
+
case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
+#if SIZEOF_VOID_P == 8
case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
+#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMPLT(s1, s2, REG_ITMP1);
- M_BNEZ(REG_ITMP1, 0);
+ M_CMPLT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ break;
+
+#if SIZEOF_VOID_P == 4
+ case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_CMPLT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ M_CMPGT(s1, s2, REG_ITMP3);
+ /* load low-bits before the branch, so we know the distance */
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BNEZ(REG_ITMP3, 4);
+ M_NOP;
+ M_CMPULT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
+#endif
case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
+#if SIZEOF_VOID_P == 8
case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
+#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMPGT(s1, s2, REG_ITMP1);
- M_BNEZ(REG_ITMP1, 0);
+ M_CMPGT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
+#if SIZEOF_VOID_P == 4
+ case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_CMPGT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ M_CMPLT(s1, s2, REG_ITMP3);
+ /* load low-bits before the branch, so we know the distance */
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BNEZ(REG_ITMP3, 4);
+ M_NOP;
+ M_CMPUGT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ break;
+#endif
+
case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
+#if SIZEOF_VOID_P == 8
case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
+#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMPGT(s1, s2, REG_ITMP1);
- M_BEQZ(REG_ITMP1, 0);
+ M_CMPGT(s1, s2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ break;
+
+#if SIZEOF_VOID_P == 4
+ case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_CMPLT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ M_CMPGT(s1, s2, REG_ITMP3);
+ /* load low-bits before the branch, so we know the distance */
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BNEZ(REG_ITMP3, 4);
+ M_NOP;
+ M_CMPUGT(s1, s2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
+#endif
case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
+#if SIZEOF_VOID_P == 8
case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
+#endif
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_CMPLT(s1, s2, REG_ITMP1);
- M_BEQZ(REG_ITMP1, 0);
+ M_CMPLT(s1, s2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
codegen_add_branch_ref(cd, iptr->dst.block);
M_NOP;
break;
+#if SIZEOF_VOID_P == 4
+ case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
+
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_CMPGT(s1, s2, REG_ITMP3);
+ M_BNEZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ M_CMPLT(s1, s2, REG_ITMP3);
+ /* load low-bits before the branch, so we know the distance */
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BNEZ(REG_ITMP3, 4);
+ M_NOP;
+ M_CMPULT(s1, s2, REG_ITMP3);
+ M_BEQZ(REG_ITMP3, 0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ M_NOP;
+ break;
+#endif
case ICMD_IRETURN: /* ..., retvalue ==> ... */
+#if SIZEOF_VOID_P == 8
case ICMD_LRETURN:
+#endif
REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
#endif /* ENABLE_VERIFIER */
goto nowperformreturn;
- case ICMD_FRETURN: /* ..., retvalue ==> ... */
+#if SIZEOF_VOID_P == 4
+ case ICMD_LRETURN: /* ..., retvalue ==> ... */
+ s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
+ M_LNGMOVE(s1, REG_RESULT_PACKED);
+ goto nowperformreturn;
+#endif
+
+ case ICMD_FRETURN: /* ..., retvalue ==> ... */
REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_FRESULT);
M_FLTMOVE(s1, REG_FRESULT);
switch (iptr->opc) {
case ICMD_IRETURN:
case ICMD_ARETURN:
+#if SIZEOF_VOID_P == 8
+ case ICMD_LRETURN:
+#endif
+ M_ALD(REG_A0, REG_SP, rd->memuse * 8);
+ M_JSR(REG_RA, REG_ITMP3);
+ M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
+ break;
+#if SIZEOF_VOID_P == 4
case ICMD_LRETURN:
M_ALD(REG_A0, REG_SP, rd->memuse * 8);
+ M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
M_JSR(REG_RA, REG_ITMP3);
- M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
+ M_NOP;
break;
+#endif
case ICMD_FRETURN:
case ICMD_DRETURN:
M_ALD(REG_A0, REG_SP, rd->memuse * 8);
switch (iptr->opc) {
case ICMD_IRETURN:
case ICMD_ARETURN:
+#if SIZEOF_VOID_P == 8
case ICMD_LRETURN:
- M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
+#endif
+ M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
break;
+#if SIZEOF_VOID_P == 4
+ case ICMD_LRETURN:
+ M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
+ break;
+#endif
case ICMD_FRETURN:
case ICMD_DRETURN:
M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
/* restore saved registers */
for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
- p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
+ p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
}
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
if (hi == 0) {
M_RET(REG_RA);
- M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
+ M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
} else {
M_LUI(REG_ITMP3,hi);
- M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
+ M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
M_RET(REG_RA);
- M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
+ M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
}
} else {
M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
M_BEQZ(REG_ITMP2, 0);
codegen_add_branch_ref(cd, table[0].block); /* default target */
- M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
+ M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot */
/* build jump table top down and use address of lowest entry */
continue;
if (IS_INT_LNG_TYPE(var->type)) {
+#if SIZEOF_VOID_P == 8
if (!md->params[s3].inmemory) {
s1 = rd->argintregs[md->params[s3].regoff];
d = emit_load(jd, iptr, var, s1);
d = emit_load(jd, iptr, var, REG_ITMP1);
M_LST(d, REG_SP, md->params[s3].regoff * 8);
}
+#else
+ if (!md->params[s3].inmemory) {
+ if (IS_2_WORD_TYPE(var->type)) {
+ s1 = md->params[s3].regoff;
+ s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ d = emit_load(jd, iptr, var, s1);
+ M_LNGMOVE(d, s1);
+ }
+ else {
+ s1 = rd->argintregs[md->params[s3].regoff];
+ d = emit_load(jd, iptr, var, s1);
+ M_INTMOVE(d, s1);
+ }
+ }
+ else {
+ if (IS_2_WORD_TYPE(var->type)) {
+ d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
+ M_LST(d, REG_SP, md->params[s3].regoff * 8);
+ }
+ else {
+ d = emit_load(jd, iptr, var, REG_ITMP1);
+ M_IST(d, REG_SP, md->params[s3].regoff * 8);
+ }
+ }
+#endif
}
else {
if (!md->params[s3].inmemory) {
+#if SIZEOF_VOID_P == 8
s1 = rd->argfltregs[md->params[s3].regoff];
d = emit_load(jd, iptr, var, s1);
if (IS_2_WORD_TYPE(var->type))
M_DMOV(d, s1);
else
M_FMOV(d, s1);
+#else
+ if ((s3 == 0) ||
+ ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
+ s1 = rd->argfltregs[md->params[s3].regoff];
+ d = emit_load(jd, iptr, var, s1);
+ if (IS_2_WORD_TYPE(var->type))
+ M_DBLMOVE(d, s1);
+ else
+ M_FLTMOVE(d, s1);
+ }
+ else {
+ if (IS_2_WORD_TYPE(var->type)) {
+ s1 = md->params[s3].regoff;
+ s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ d = emit_load(jd, iptr, var, REG_FTMP1);
+ M_MFC1(GET_LOW_REG(s2), d);
+ M_MFC1(GET_HIGH_REG(s2), d + 1);
+ M_NOP;
+ }
+ else {
+ s1 = rd->argintregs[md->params[s3].regoff];
+ d = emit_load(jd, iptr, var, s1);
+ M_MFC1(s1, d);
+ M_NOP;
+ }
+ }
+#endif
}
else {
d = emit_load(jd, iptr, var, REG_FTMP1);
if (d != TYPE_VOID) {
if (IS_INT_LNG_TYPE(d)) {
+#if SIZEOF_VOID_P == 8
s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
M_INTMOVE(REG_RESULT, s1);
+#else
+ if (IS_2_WORD_TYPE(d)) {
+ s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+ M_LNGMOVE(REG_RESULT_PACKED, s1);
+ }
+ else {
+ s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+ M_INTMOVE(REG_RESULT, s1);
+ }
+#endif
}
else {
s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
if (!(var->flags & PREALLOC)) {
s2 = emit_load(jd, iptr, var, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
M_LST(s2, REG_SP, s1 * 8);
+#else
+ M_IST(s2, REG_SP, (s1 + 2) * 8);
+#endif
}
}
/* a2 = pointer to dimensions = stack pointer */
- M_INTMOVE(REG_SP, REG_A2);
+#if SIZEOF_VOID_P == 8
+ M_MOV(REG_SP, REG_A2);
+#else
+ M_AADD_IMM(REG_SP, 4*4, REG_A2);
+#endif
disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
M_ALD(REG_ITMP3, REG_PV, disp);
sizeof(stackframeinfo) / SIZEOF_VOID_P +
sizeof(localref_table) / SIZEOF_VOID_P +
md->paramcount + /* for saving arguments over calls */
+#if SIZEOF_VOID_P == 4
+ 5 + /* additional save space (MIPS32) */
+#endif
1 + /* for saving return address */
nmd->memuse;
+ /* adjust stackframe size for 16-byte alignment */
+
+ if (cd->stackframesize & 1)
+ cd->stackframesize++;
+
/* create method header */
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
/* save integer and float argument registers */
+#if SIZEOF_VOID_P == 8
for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
- if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
- M_LST(rd->argintregs[i], REG_SP, j * 8);
+ if (IS_INT_LNG_TYPE(md->params[i].type)) {
+ M_AST(rd->argintregs[i], REG_SP, j * 8);
j++;
}
}
+#else
+ for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
+ if (IS_INT_LNG_TYPE(md->params[i].type)) {
+ if (!md->params[i].inmemory) {
+ s1 = md->params[i].regoff;
+ if (IS_2_WORD_TYPE(md->params[i].type)) {
+ s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ M_LST(s1, REG_SP, j * 8);
+ }
+ else {
+ M_IST(rd->argintregs[s1], REG_SP, j * 8);
+ }
+ j++;
+ }
+ }
+ }
+#endif
for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
- if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
- M_DST(rd->argfltregs[i], REG_SP, j * 8);
+ if (IS_FLT_DBL_TYPE(md->params[i].type)) {
+ if (IS_2_WORD_TYPE(md->params[i].type))
+ M_DST(rd->argfltregs[i], REG_SP, j * 8);
+ else
+ M_FST(rd->argfltregs[i], REG_SP, j * 8);
j++;
}
}
/* restore integer and float argument registers */
+#if SIZEOF_VOID_P == 8
for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
- if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
+ if (IS_INT_LNG_TYPE(md->params[i].type)) {
M_LLD(rd->argintregs[i], REG_SP, j * 8);
j++;
}
}
+#else
+ for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
+ if (IS_INT_LNG_TYPE(md->params[i].type)) {
+ if (!md->params[i].inmemory) {
+ s1 = md->params[i].regoff;
+ if (IS_2_WORD_TYPE(md->params[i].type)) {
+ s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ M_LLD(s1, REG_SP, j * 8);
+ }
+ else {
+ M_ILD(rd->argintregs[s1], REG_SP, j * 8);
+ }
+ j++;
+ }
+ }
+ }
+#endif
for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
- if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
- M_DLD(rd->argfltregs[i], REG_SP, j * 8);
+ if (IS_FLT_DBL_TYPE(md->params[i].type)) {
+ if (IS_2_WORD_TYPE(md->params[i].type))
+ M_DLD(rd->argfltregs[i], REG_SP, j * 8);
+ else
+ M_FLD(rd->argfltregs[i], REG_SP, j * 8);
j++;
}
}
/* copy or spill arguments to new locations */
for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
- t = md->paramtypes[i].type;
+ t = md->params[i].type;
if (IS_INT_LNG_TYPE(t)) {
if (!md->params[i].inmemory) {
- s1 = rd->argintregs[md->params[i].regoff];
+ s1 = md->params[i].regoff;
+#if SIZEOF_VOID_P == 8
+ s1 = rd->argintregs[s1];
+#else
+ if (IS_2_WORD_TYPE(t))
+ s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ else
+ s1 = rd->argintregs[s1];
+#endif
if (!nmd->params[j].inmemory) {
- s2 = rd->argintregs[nmd->params[j].regoff];
- M_INTMOVE(s1, s2);
- } else {
s2 = nmd->params[j].regoff;
- M_AST(s1, REG_SP, s2 * 8);
+#if SIZEOF_VOID_P == 8
+ s2 = rd->argintregs[s2];
+ M_INTMOVE(s1, s2);
+#else
+ if (IS_2_WORD_TYPE(t)) {
+ s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
+ rd->argintregs[GET_HIGH_REG(s2)]);
+ M_LNGMOVE(s1, s2);
+ }
+ else {
+ s2 = rd->argintregs[s2];
+ M_INTMOVE(s1, s2);
+ }
+#endif
}
+ else {
+ s2 = nmd->params[j].regoff;
- } else {
+#if SIZEOF_VOID_P == 8
+ M_LST(s1, REG_SP, s2 * 8);
+#else
+ if (IS_2_WORD_TYPE(t))
+ M_LST(s1, REG_SP, s2 * 4);
+ else
+ M_IST(s1, REG_SP, s2 * 4);
+#endif
+ }
+ }
+ else {
s1 = md->params[i].regoff + cd->stackframesize;
s2 = nmd->params[j].regoff;
- M_ALD(REG_ITMP1, REG_SP, s1 * 8);
- M_AST(REG_ITMP1, REG_SP, s2 * 8);
- }
- } else {
+#if SIZEOF_VOID_P == 8
+ M_LLD(REG_ITMP1, REG_SP, s1 * 8);
+ M_LST(REG_ITMP1, REG_SP, s2 * 8);
+#else
+ if (IS_2_WORD_TYPE(t)) {
+ M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
+ M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
+ }
+ else {
+ M_ILD(REG_ITMP1, REG_SP, s1 * 8);
+ M_IST(REG_ITMP1, REG_SP, s2 * 4);
+ }
+#endif
+ }
+ }
+ else {
if (!md->params[i].inmemory) {
- s1 = rd->argfltregs[md->params[i].regoff];
+ s1 = md->params[i].regoff;
+ s2 = nmd->params[j].regoff;
if (!nmd->params[j].inmemory) {
- s2 = rd->argfltregs[nmd->params[j].regoff];
+#if SIZEOF_VOID_P == 8
+ s1 = rd->argfltregs[s1];
+ s2 = rd->argfltregs[s2];
if (IS_2_WORD_TYPE(t))
M_DMOV(s1, s2);
else
M_FMOV(s1, s2);
+#else
+ /* On MIPS32 float arguments for native functions
+ can never be in float argument registers, since
+ the first argument is _always_ an integer
+ argument (JNIenv) */
+
+ if (IS_2_WORD_TYPE(t)) {
+ s1 = rd->argfltregs[s1];
+ s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
+ rd->argintregs[GET_HIGH_REG(s2)]);
+
+ /* double high/low order is endian
+ independent: even numbered holds low
+ 32-bits, odd numbered high 32-bits */
+
+ M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
+ M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
+ }
+ else {
+ s1 = rd->argfltregs[s1];
+ s2 = rd->argintregs[s2];
+ M_MFC1(s2, s1);
+ }
+#endif
+ }
+ else {
+#if SIZEOF_VOID_P == 8
+ s1 = rd->argfltregs[s1];
- } else {
- s2 = nmd->params[j].regoff;
if (IS_2_WORD_TYPE(t))
M_DST(s1, REG_SP, s2 * 8);
else
M_FST(s1, REG_SP, s2 * 8);
- }
+#else
+ /* s1 may have been originally in 2 int registers,
+ but was moved out by the native function
+ argument(s), just get low register */
- } else {
+ s1 = rd->argfltregs[GET_LOW_REG(s1)];
+
+ if (IS_2_WORD_TYPE(t))
+ M_DST(s1, REG_SP, s2 * 4);
+ else
+ M_FST(s1, REG_SP, s2 * 4);
+#endif
+ }
+ }
+ else {
s1 = md->params[i].regoff + cd->stackframesize;
s2 = nmd->params[j].regoff;
+
if (IS_2_WORD_TYPE(t)) {
M_DLD(REG_FTMP1, REG_SP, s1 * 8);
M_DST(REG_FTMP1, REG_SP, s2 * 8);
- } else {
+ }
+ else {
M_FLD(REG_FTMP1, REG_SP, s1 * 8);
M_FST(REG_FTMP1, REG_SP, s2 * 8);
}
/* save return value */
if (md->returntype.type != TYPE_VOID) {
+#if SIZEOF_VOID_P == 8
if (IS_INT_LNG_TYPE(md->returntype.type))
M_LST(REG_RESULT, REG_SP, 0 * 8);
else
M_DST(REG_FRESULT, REG_SP, 0 * 8);
+#else
+ if (IS_INT_LNG_TYPE(md->returntype.type)) {
+ M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
+ if (IS_2_WORD_TYPE(md->returntype.type))
+ M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
+ }
+ else
+ M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
+#endif
}
#if !defined(NDEBUG)
/* restore return value */
if (md->returntype.type != TYPE_VOID) {
+#if SIZEOF_VOID_P == 8
if (IS_INT_LNG_TYPE(md->returntype.type))
M_LLD(REG_RESULT, REG_SP, 0 * 8);
else
M_DLD(REG_FRESULT, REG_SP, 0 * 8);
+#else
+ if (IS_INT_LNG_TYPE(md->returntype.type)) {
+ M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
+ if (IS_2_WORD_TYPE(md->returntype.type))
+ M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
+ }
+ else
+ M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
+#endif
}
M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */