* jit/dseg.c: Likewise.
* jit/s390/md-abi.h: Continued work on s390 port.
* jit/s390/emit.c: Likewise.
* jit/s390/md.c: Likewise.
* jit/s390/codegen.c: Likewise.
* jit/s390/codegen.h: Likewise.
* jit/s390/md-asm.h: Likewise.
* jit/s390/asmpart.S: Likewise.
* jit/s390/md-abi.c: Likewise.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen-common.h 7246 2007-01-29 18:49:05Z twisti $
+ $Id: codegen-common.h 7283 2007-02-04 19:41:14Z pm $
*/
jumpref *jumpreferences; /* list of jumptable target addresses */
-#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
+#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP) || defined(__S390__)
dataref *datareferences; /* list of data segment references */
#endif
Joseph Wenninger
Edwin Steiner
- $Id: dseg.c 7246 2007-01-29 18:49:05Z twisti $
+ $Id: dseg.c 7283 2007-02-04 19:41:14Z pm $
*/
*******************************************************************************/
-#if defined(__I386__) || defined(__X86_64__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
+#if defined(__I386__) || defined(__X86_64__) || defined(__S390__) || defined(__XDSPCORE__) || defined(ENABLE_INTRP)
void dseg_adddata(codegendata *cd)
{
dataref *dr;
Changes: Edwin Steiner
- $Id: asmpart.S 7219 2007-01-16 22:18:57Z pm $
+ $Id: asmpart.S 7283 2007-02-04 19:41:14Z pm $
*/
/* call L_asm_call_jit_compiler like JIT code would do */
- l itmp3, 12(s3) /* load address of target from memory */
+ l itmp3, 0(mptr) /* load address of target from memory */
basr %r14, itmp3 /* jump to target */
/* todo will s4 survive the call? */
j L_register_copy
-/* .... */
-
-#if 0
-
- .align 8
-
- .quad 0 /* catch type all */
- .quad 0 /* handler pc */
- .quad 0 /* end pc */
- .quad 0 /* start pc */
- .long 1 /* extable size */
- .long 0 /* ALIGNMENT PADDING */
- .quad 0 /* line number table start */
- .quad 0 /* line number table size */
- .long 0 /* ALIGNMENT PADDING */
- .long 0 /* fltsave */
- .long 0 /* intsave */
- .long 0 /* isleaf */
- .long 0 /* IsSync */
- .long 0 /* frame size */
- .quad 0 /* codeinfo pointer */
-
-asm_vm_call_method:
-asm_vm_call_method_int:
-asm_vm_call_method_long:
-asm_vm_call_method_float:
-asm_vm_call_method_double:
-
- stm %r6,%r15,24(sp) /* save callers regiters */
-
- ahi sp, -12 /* allocate space on stack for local variables */
-
- st a0, 0(sp) /* store method info */
- st a1, 4(sp) /* store arg count */
- st a2, 8(sp) /* store args */
-
-
-# define r_methodinfo itmp1
-# define r_vmargscount itmp2
-# define r_vmargs s0
-
-# define r_arg_ctr s1
-# define r_arg_ptr s2
-
-# define r_int_ctr s3
-# define r_float_ctr s4
-# define r_int_extra_ctr itmp3
-
- /* save arguments */
-
- lr r_methodinfo,a0 /* move method pointer for compiler */
- lr r_vmargscount,a1
- lr r_vmargs,a2
-
- ltr a1,a1 /* maybe we have no args... */
- je L_copy_done
-
- lr r_arg_ctr,r_vmargscount /* arg count */
- lr r_arg_ptr,r_vmargs /* pointer to arg block */
-
- ahi r_arg_ptr,-sizevmarg /* initialize pointer (smaller code) */
- ahi r_arg_ctr,1 /* initialize argument count */
-
- lhi r_int_ctr,0 /* initialize integer argument counter*/
- lhi r_float_ctr,0 /* initialize float argument counter */
- lhi r_int_extra_ctr,0
-
-L_register_copy:
- ahi r_arg_ptr,sizevmarg /* goto next argument block */
- ahi r_arg_ctr,-1 /* argument count - 1 */
- je L_register_copy_done
-
- tm offvmargtype(r_arg_ptr),0x02 /* is this a float/double type? */
- jne L_register_handle_float /* yes, handle it */
-
- cli offvmargtype(r_arg_ptr),0x01
- je L_register_handle_long
-
-L_register_handle_int:
-
- chi r_int_ctr,INT_ARG_CNT /* are we out of integer argument */
- je L_register_copy /* register? yes, next loop */
-
- ahi r_int_ctr,1
-
- chi r_int_ctr,1
- je L_handle_a0
- chi r_int_ctr,2
- je L_handle_a1
- chi r_int_ctr,3
- je L_handle_a2
- chi r_int_ctr,4
- je L_handle_a3
- chi r_int_ctr,5
- je L_handle_a4
-
-L_register_handle_long:
-
- chi r_int_ctr,INT_ARG_CNT-1 /* only one integer register left ? */
- je L_register_handle_long_last_reg
-
- chi r_int_ctr,INT_ARG_CNT /* no registers left */
- je L_register_copy
-
- ahi r_int_ctr,2
- ahi r_int_extra_ctr,1
-
- chi r_int_ctr,2
- je L_handle_al0
- chi r_int_ctr,3
- je L_handle_al1
- chi r_int_ctr,4
- je L_handle_al2
- chi r_int_ctr,5
- je L_handle_al3
-
-L_register_handle_long_last_reg:
- ahi r_int_ctr,1 /* skip the integer register */
- ahi r_int_extra_ctr,1
- j L_register_copy
-
-L_register_handle_float:
- chi r_float_ctr,FLT_ARG_CNT /* are we out of float argument */
- je L_register_copy /* register? yes, next loop */
-
- ahi r_float_ctr,1
-
- chi r_int_ctr,1
- je L_handle_af0
- chi r_int_ctr,2
- je L_handle_af1
-
-L_register_copy_done:
-
- lr r_arg_ctr, r_vmargscount
- sr r_arg_ctr, r_int_ctr
- ar r_arg_ctr, r_int_extra_ctr
- sr r_arg_ctr, r_float_ctr
- jle L_copy_done
-
- /* now allocate the parameter area on the stack
- * the register save area will be allocated later
- */
-
-# define r_arg_stack_ptr r_arg_ptr
-
- sll r_arg_ctr, 3 /* 8 bytes per parameter on stack */
- sr sp,r_arg_ctr /* allocate stack space for parameters */
- lr r_arg_stack_ptr,sp /* points now to arguments on stack */
-
- ahi r_vmargs,-sizevmarg /* initialize pointer (smaller code) */
- ahi r_vmargscount,1 /* initialize argument count */
-
-L_stack_copy_loop:
- ahi r_vmargs,sizevmarg /* goto next argument block */
- ahi r_vmargscount,-1 /* argument count - 1 */
- jz L_copy_done /* no test needed after dec */
-
- tm offvmargtype(r_vmargs),0x02 /* is this a float/double type? */
- jne L_stack_handle_float /* yes, handle it */
-
- cli offvmargtype(r_vmargs),0x01
- je L_stack_handle_long
-
-L_stack_handle_int:
-
- ahi r_int_ctr,-1 /* arguments assigned to registers */
- jhe L_stack_copy_loop
- j L_stack_copy
-
-L_stack_handle_long:
-
- ahi r_int_ctr,-2
- jhe L_stack_copy_loop
- j L_stack_copy
-
-L_stack_handle_float:
- ahi r_float_ctr,-1 /* arguments assigned to registers */
- jhe L_stack_copy_loop
-
-L_stack_copy:
- mvc 0(8,r_arg_stack_ptr),offvmargdata(r_vmargs) /* copy s8 argument onto stack */
-
- ahi r_arg_stack_ptr,8 /* increase sp to next argument */
- j L_stack_copy_loop
-
-L_copy_done:
-#if 0
- /* itmp1 still contains method pointer*/
- lea L_asm_call_jit_compiler(%rip),mptr
- mov sp,itmp3 /* calculate the old stack pointer */
- add bp,itmp3
- mov mptr,6*8(itmp3) /* store mptr on stack */
- lea (6*8-256)(itmp3),mptr /* We subtract 256 to force the next */
- /* move instruction to have a 32-bit */
- /* offset. */
-
- mov (0*8+256)(mptr),itmp3 /* method call as in Java */
- call *itmp3 /* call JIT compiler */
-
- add bp,sp /* remove argument stack frame if any */
-#endif
-
- /* itmp1 still contains method pointer*/
-
- bras %r14, L_asm_call_jit_compiler
- ar sp,r_arg_ctr /* r_arg_ctr in callee saved regiter */
-
-L_asm_vm_call_method_return:
-
- ahi sp, 12 /* free stack space */
- lm %r6,%r15,24(sp) /* restore registers */
- br %r14 /* branch to return address */
-
-#if 0
-asm_vm_call_method_exception_handler:
- mov xptr,a0 /* pass exception pointer */
- call builtin_throw_exception@PLT
- jmp L_asm_vm_call_method_return
-#endif
-
-L_handle_a0:
- l a0,offvmargdata(r_arg_ptr)
- j L_register_copy
-L_handle_a1:
- l a1,offvmargdata(r_arg_ptr)
- j L_register_copy
-L_handle_a2:
- l a2,offvmargdata(r_arg_ptr)
- j L_register_copy
-L_handle_a3:
- l a3,offvmargdata(r_arg_ptr)
- j L_register_copy
-L_handle_a4:
- l a4,offvmargdata(r_arg_ptr)
- j L_register_copy
-
-L_handle_al0:
- l a0,offvmargdata(r_arg_ptr)
- l a1,offvmargdata+4(r_arg_ptr)
- j L_register_copy
-L_handle_al1:
- l a1,offvmargdata(r_arg_ptr)
- l a2,offvmargdata+4(r_arg_ptr)
- j L_register_copy
-L_handle_al2:
- l a2,offvmargdata(r_arg_ptr)
- l a3,offvmargdata+4(r_arg_ptr)
- j L_register_copy
-L_handle_al3:
- l a3,offvmargdata(r_arg_ptr)
- l a4,offvmargdata+4(r_arg_ptr)
- j L_register_copy
-
-L_handle_af0:
- ld fa0,offvmargdata(r_arg_ptr)
- j L_register_copy
-L_handle_af1:
- ld fa1,offvmargdata(r_arg_ptr)
- j L_register_copy
-
-#endif
-
/****************** function asm_call_jit_compiler *****************************
* *
* invokes the compiler for untranslated JavaVM methods. *
l itmp3, 0(itmp3)
basr %r14, itmp3
- lm %r2,%r5,96(sp) /* restore volatile int arg regs */
- ld %f0,96+16(sp) /* store volatile float arg regs */
- ld %f2,96+24(sp) /* store volatile float arg regs */
- ld %r14,96+32(sp) /* restore return address */
+ lr pv, v0 /* save return value */
+
+ lm %r2,%r5,96(sp) /* restore volatile int arg regs */
+ ld %f0,96+16(sp) /* restore volatile float arg regs */
+ ld %f2,96+24(sp) /* restore volatile float arg regs */
+ ld %r14,96+32(sp) /* restore return address */
#if 0
ltr v0,v0
je L_asm_call_jit_compiler_exception
#endif
- b 0(v0) /* call the method, it will return to the caller */
+ br pv /* call the method, it will return to the caller */
L_asm_call_jit_compiler_exception:
Christian Ullrich
Edwin Steiner
- $Id: codegen.c 7219 2007-01-16 22:18:57Z pm $
+ $Id: codegen.c 7283 2007-02-04 19:41:14Z pm $
*/
fieldinfo *fi;
unresolved_field *uf;
s4 fieldtype;
+#if 0
rplpoint *replacementpoint;
+#endif
s4 varindex;
/* get required compiler data */
s4 i, p, t, l;
s4 savedregs_num;
- savedregs_num = 0;
+ savedregs_num = 1; /* space to save RA */
/* space to save used callee saved registers */
savedregs_num += (INT_SAV_CNT - rd->savintreguse);
- savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
+ savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
cd->stackframesize = rd->memuse + savedregs_num;
+ /* CAUTION:
+ * As REG_ITMP3 == REG_RA, do not touch REG_ITMP3, until it has been saved.
+ */
+
#if defined(ENABLE_THREADS)
/* space to save argument of monitor_enter */
-
+ OOPS(); /* see powerpc */
+#if 0
if (checksync && (m->flags & ACC_SYNCHRONIZED))
cd->stackframesize++;
+#endif
#endif
/* Keep stack of non-leaf functions 16-byte aligned for calls into
movaps). */
if (!jd->isleafmethod || opt_verbosecall)
- cd->stackframesize |= 0x1;
+ /* TODO really 16 bytes ? */
+ cd->stackframesize = (cd->stackframesize + 3) & ~3;
/* create method header */
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
- (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
+ (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
#if defined(ENABLE_THREADS)
/* IsSync contains the offset relative to the stack pointer for the
*/
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
+ (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync */
else
#endif
(void) dseg_add_unique_s4(cd, 0); /* IsSync */
if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
/* count frequency */
- M_MOV_IMM(code, REG_ITMP3);
- M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
+ M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
+ M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
+ M_IADD_IMM(1, REG_ITMP2);
+ M_IST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
- PROFILE_CYCLE_START;
+/* PROFILE_CYCLE_START; */
}
/* create stack frame (if necessary) */
if (cd->stackframesize)
- M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
+ M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
- /* save used callee saved registers */
+ /* save used callee saved registers and return address */
p = cd->stackframesize;
+ p--; M_AST(REG_RA, REG_SP, p * 4);
for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
- p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
+ p--; M_LST(rd->savintregs[i], REG_SP, p * 4);
}
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
- p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
+ p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
}
/* take arguments out of register or stack frame */
for (p = 0, l = 0; p < md->paramcount; p++) {
t = md->paramtypes[p].type;
-
- varindex = jd->local_map[l * 5 + t];
+ varindex = jd->local_map[l * 5 + t];
l++;
if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
if (varindex == UNUSED)
continue;
- var = VAR(varindex);
-
- s1 = md->params[p].regoff;
+ var = VAR(varindex);
+ s1 = md->params[p].regoff;
if (IS_INT_LNG_TYPE(t)) { /* integer args */
- s2 = rd->argintregs[s1];
+ if (IS_2_WORD_TYPE(t))
+ s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+ rd->argintregs[GET_HIGH_REG(s1)]);
+ else
+ s2 = rd->argintregs[s1];
if (!md->params[p].inmemory) { /* register arguments */
if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
- M_INTMOVE(s2, var->vv.regoff);
+ if (IS_2_WORD_TYPE(t))
+ M_LNGMOVE(s2, var->vv.regoff);
+ else
+ M_INTMOVE(s2, var->vv.regoff);
} else { /* reg arg -> spilled */
- M_LST(s2, REG_SP, var->vv.regoff * 8);
- }
+ if (IS_2_WORD_TYPE(t))
+ M_LST(s2, REG_SP, var->vv.regoff * 4);
+ else
+ M_IST(s2, REG_SP, var->vv.regoff * 4);
+ }
} else { /* stack arguments */
if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
- /* + 8 for return address */
- M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
+ if (IS_2_WORD_TYPE(t))
+ M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+ else
+ M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
} else { /* stack arg -> spilled */
- var->vv.regoff = cd->stackframesize + s1 + 1;
+ M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
+ M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
+ if (IS_2_WORD_TYPE(t)) {
+ M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
+ M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
+ }
}
}
if (!md->params[p].inmemory) { /* register arguments */
s2 = rd->argfltregs[s1];
if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
- M_FLTMOVE(s2, var->vv.regoff);
+ M_FLTMOVE(s2, var->vv.regoff);
} else { /* reg arg -> spilled */
- M_DST(s2, REG_SP, var->vv.regoff * 8);
+ if (IS_2_WORD_TYPE(t))
+ M_DST(s2, REG_SP, var->vv.regoff * 4);
+ else
+ M_FST(s2, REG_SP, var->vv.regoff * 4);
}
} else { /* stack arguments */
if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
- M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
+ if (IS_2_WORD_TYPE(t))
+ M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
- } else {
- var->vv.regoff = cd->stackframesize + s1 + 1;
+ else
+ M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
+
+ } else { /* stack-arg -> spilled */
+ if (IS_2_WORD_TYPE(t)) {
+ M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
+ M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
+ var->vv.regoff = cd->stackframesize + s1;
+
+ } else {
+ M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
+ M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
+ }
}
}
}
- } /* end for */
+ } /* end for */
/* save monitorenter argument */
}
/* end of header generation */
-
+#if 0
replacementpoint = jd->code->rplpoints;
+#endif
/* walk through all basic blocks */
break;
case ICMD_ACONST: /* ... ==> ..., constant */
- OOPS();
-#if 0
d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
cr = iptr->sx.val.c.ref;
+ disp = dseg_add_unique_address(cd, NULL);
/* PROFILE_CYCLE_STOP; */
- codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
+ codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
/* PROFILE_CYCLE_START; */
- M_MOV_IMM(NULL, d);
-
+ M_ALD(d, REG_PV, disp);
} else {
- if (iptr->sx.val.anyptr == 0)
+ if (iptr->sx.val.anyptr == 0) {
M_CLR(d);
- else
- M_MOV_IMM(iptr->sx.val.anyptr, d);
+ } else {
+ disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
+ M_ALD(d, REG_PV, disp);
+ }
}
emit_store_dst(jd, iptr, d);
-#endif
break;
case ICMD_DSTORE:
case ICMD_COPY:
case ICMD_MOVE:
- OOPS();
-#if 0
emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
-#endif
break;
case ICMD_ASTORE:
- OOPS();
-#if 0
if (!(iptr->flags.bits & INS_FLAG_RETADDR))
emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
-#endif
break;
/* integer operations *************************************************/
break;
case ICMD_IFNULL: /* ..., value ==> ... */
- OOPS();
-#if 0
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TEST(s1);
M_BEQ(0);
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
break;
case ICMD_IFNONNULL: /* ..., value ==> ... */
OOPS();
-#if 0
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_TEST(s1);
M_BNE(0);
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
break;
case ICMD_IFEQ: /* ..., value ==> ... */
break;
case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
- OOPS();
-#if 0
+ case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_ICMP(s2, s1);
+ M_CMP(s1, s2);
M_BEQ(0);
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
break;
case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
- case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_LCMP(s2, s1);
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_CMP(s1, s2);
+ /* load low-bits before the branch, so we know the distance */
+ /* TODO do the loads modify the condition code?
+ * lr, l, la, lhi dont
+ */
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BNE(SZ_BRC + SZ_CR + SZ_BRC);
+ M_CMP(s1, s2);
M_BEQ(0);
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
break;
case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
- OOPS();
-#if 0
- s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- M_LCMP(s2, s1);
+ s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+ M_CMP(s1, s2);
+ M_BLT(0);
+ codegen_add_branch_ref(cd, iptr->dst.block);
+ /* load low-bits before the branch, so we know the distance */
+ /* TODO: the loads should not touch the condition code. */
+ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+ s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+ M_BGT(SZ_BRC + SZ_CR + SZ_BRC);
+ M_CMP(s1, s2);
M_BLE(0);
codegen_add_branch_ref(cd, iptr->dst.block);
-#endif
break;
case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
break;
case ICMD_IRETURN: /* ..., retvalue ==> ... */
- case ICMD_LRETURN:
- OOPS();
-#if 0
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
-#endif
goto nowperformreturn;
case ICMD_ARETURN: /* ..., retvalue ==> ... */
- OOPS();
-#if 0
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_RESULT);
M_INTMOVE(s1, REG_RESULT);
#ifdef ENABLE_VERIFIER
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
- uc = iptr->sx.s23.s2.uc;
+ unresolved_class *uc = iptr->sx.s23.s2.uc;
- PROFILE_CYCLE_STOP;
-
- codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
-
- PROFILE_CYCLE_START;
+ codegen_addpatchref(cd, PATCHER_athrow_areturn, uc, 0);
}
#endif /* ENABLE_VERIFIER */
-#endif
+ goto nowperformreturn;
+
+ case ICMD_LRETURN: /* ..., retvalue ==> ... */
+
+ REPLACEMENT_POINT_RETURN(cd, iptr);
+ s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
+ M_LNGMOVE(s1, REG_RESULT_PACKED);
goto nowperformreturn;
case ICMD_FRETURN: /* ..., retvalue ==> ... */
case ICMD_DRETURN:
- OOPS();
-#if 0
+ REPLACEMENT_POINT_RETURN(cd, iptr);
s1 = emit_load_s1(jd, iptr, REG_FRESULT);
M_FLTMOVE(s1, REG_FRESULT);
-#endif
goto nowperformreturn;
case ICMD_RETURN: /* ... ==> ... */
+ REPLACEMENT_POINT_RETURN(cd, iptr);
+
nowperformreturn:
- OOPS();
-#if 0
{
s4 i, p;
+
+ p = cd->stackframesize;
- p = cd->stackframesize;
+ /* call trace function */
-#if !defined(NDEBUG)
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- emit_verbosecall_exit(jd);
-#endif /* !defined(NDEBUG) */
+ emit_verbosecall_exit(jd);
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
- M_ALD(REG_A0, REG_SP, rd->memuse * 8);
-
+ disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
+ M_ALD(REG_ITMP3, REG_PV, disp);
+ M_CALL(REG_ITMP3);
+
/* we need to save the proper return value */
+
switch (iptr->opc) {
+ case ICMD_LRETURN:
+ M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
+ /* fall through */
case ICMD_IRETURN:
case ICMD_ARETURN:
- case ICMD_LRETURN:
- M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
+ M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
break;
case ICMD_FRETURN:
+ M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ break;
case ICMD_DRETURN:
- M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
+ M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
break;
}
- M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
- M_CALL(REG_ITMP1);
+ M_ALD(REG_A0, REG_SP, rd->memuse * 4);
+ M_JSR;
/* and now restore the proper return value */
+
switch (iptr->opc) {
+ case ICMD_LRETURN:
+ M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
+ /* fall through */
case ICMD_IRETURN:
case ICMD_ARETURN:
- case ICMD_LRETURN:
- M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
+ M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
break;
case ICMD_FRETURN:
+ M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ break;
case ICMD_DRETURN:
- M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
+ M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
break;
}
}
#endif
- /* restore saved registers */
+ /* restore return address */
+
+ M_ALD(REG_RA, REG_SP, p * 4);
+
+ /* 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_ILD(rd->savintregs[i], REG_SP, p * 4);
}
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
- p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
+ p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
}
- /* deallocate stack */
+ /* deallocate stack */
if (cd->stackframesize)
- M_AADD_IMM(cd->stackframesize * 8, REG_SP);
-
- /* generate method profiling code */
-
- PROFILE_CYCLE_STOP;
+ M_AADD_IMM(cd->stackframesize * 4, REG_SP);
M_RET;
+ ALIGNCODENOP;
}
-#endif
break;
-
case ICMD_TABLESWITCH: /* ..., index ==> ... */
OOPS();
#if 0
case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
- OOPS();
-#if 0
bte = iptr->sx.s23.s3.bte;
md = bte->md;
-#endif
goto gen_method;
case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
case ICMD_INVOKEINTERFACE:
- OOPS();
-#if 0
+
+ REPLACEMENT_POINT_INVOKE(cd, iptr);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
lm = NULL;
um = NULL;
md = lm->parseddesc;
}
-#endif
+
gen_method:
-#if 0
s3 = md->paramcount;
- MCODECHECK((20 * s3) + 128);
+ MCODECHECK((s3 << 1) + 64);
/* copy arguments to registers or stack location */
for (s3 = s3 - 1; s3 >= 0; s3--) {
var = VAR(iptr->sx.s23.s2.args[s3]);
- /* Already Preallocated (ARGVAR) ? */
+ /* Already Preallocated? */
if (var->flags & PREALLOC)
continue;
if (IS_INT_LNG_TYPE(var->type)) {
if (!md->params[s3].inmemory) {
- s1 = rd->argintregs[md->params[s3].regoff];
- d = emit_load(jd, iptr, var, s1);
- M_INTMOVE(d, s1);
+ if (IS_2_WORD_TYPE(var->type)) {
+ s1 = PACK_REGS(
+ rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
+ rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]
+ );
+ 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 {
- d = emit_load(jd, iptr, var, REG_ITMP1);
- M_LST(d, REG_SP, md->params[s3].regoff * 8);
+ 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 * 4);
+ }
+ else {
+ d = emit_load(jd, iptr, var, REG_ITMP1);
+ M_IST(d, REG_SP, md->params[s3].regoff * 4);
+ }
}
}
else {
}
else {
d = emit_load(jd, iptr, var, REG_FTMP1);
-
if (IS_2_WORD_TYPE(var->type))
- M_DST(d, REG_SP, md->params[s3].regoff * 8);
+ M_DST(d, REG_SP, md->params[s3].regoff * 4);
else
- M_FST(d, REG_SP, md->params[s3].regoff * 8);
+ M_FST(d, REG_SP, md->params[s3].regoff * 4);
}
}
}
- /* generate method profiling code */
-
- PROFILE_CYCLE_STOP;
-
switch (iptr->opc) {
case ICMD_BUILTIN:
- M_MOV_IMM(bte->fp, REG_ITMP1);
- M_CALL(REG_ITMP1);
+ disp = dseg_add_functionptr(cd, bte->fp);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- M_TEST(REG_RESULT);
- M_BEQ(0);
- codegen_add_fillinstacktrace_ref(cd);
- }
+ N_LHI(REG_ITMP1, disp);
+ N_L(REG_PV, 0, REG_ITMP1, REG_PV);
break;
case ICMD_INVOKESPECIAL:
- M_TEST(REG_A0);
- M_BEQ(0);
- codegen_add_nullpointerexception_ref(cd);
-
+ emit_nullpointer_check(cd, iptr, REG_A0);
+ M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr */
/* fall through */
case ICMD_INVOKESTATIC:
if (lm == NULL) {
- disp = dseg_add_unique_address(cd, NULL);
- disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
-
- /* must be calculated before codegen_add_patch_ref */
-
- if (opt_shownops)
- disp -= PATCHER_CALL_SIZE;
-
- codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
- um, disp);
-
-/* a = 0; */
- }
- else {
- disp = dseg_add_functionptr(cd, lm->stubroutine);
- disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
+ disp = dseg_add_unique_address(cd, um);
-/* a = (ptrint) lm->stubroutine; */
+ codegen_addpatchref(cd, PATCHER_invokestatic_special,
+ um, disp);
}
+ else
+ disp = dseg_add_address(cd, lm->stubroutine);
-/* M_MOV_IMM(a, REG_ITMP2); */
- M_ALD(REG_ITMP2, RIP, disp);
- M_CALL(REG_ITMP2);
+ N_LHI(REG_ITMP1, disp);
+ N_L(REG_PV, 0, REG_ITMP1, REG_PV);
break;
case ICMD_INVOKEVIRTUAL:
- gen_nullptr_check(REG_A0);
+ emit_nullpointer_check(cd, iptr, REG_A0);
if (lm == NULL) {
- codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
+ codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
s1 = 0;
}
- else
+ else {
s1 = OFFSET(vftbl_t, table[0]) +
sizeof(methodptr) * lm->vftblindex;
+ }
- M_ALD(REG_METHODPTR, REG_A0,
- OFFSET(java_objectheader, vftbl));
- M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
- M_CALL(REG_ITMP3);
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_PV, REG_METHODPTR, s1);
break;
case ICMD_INVOKEINTERFACE:
- gen_nullptr_check(REG_A0);
+ emit_nullpointer_check(cd, iptr, REG_A0);
if (lm == NULL) {
- codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
+ codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
s1 = 0;
s2 = 0;
}
else {
s1 = OFFSET(vftbl_t, interfacetable[0]) -
- sizeof(methodptr) * lm->class->index;
+ sizeof(methodptr*) * lm->class->index;
s2 = sizeof(methodptr) * (lm - lm->class->methods);
}
- M_ALD(REG_METHODPTR, REG_A0,
- OFFSET(java_objectheader, vftbl));
- M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
- M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
- M_CALL(REG_ITMP3);
+ M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+ M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
+ M_ALD(REG_PV, REG_METHODPTR, s2);
break;
}
- /* generate method profiling code */
+ /* generate the actual call */
- PROFILE_CYCLE_START;
+ M_CALL(REG_PV);
+ REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
+ N_BASR(REG_ITMP1, RN);
+ disp = (s4) (cd->mcodeptr - cd->mcodebase);
+ M_LDA(REG_PV, REG_ITMP1, -disp);
+
+ /* actually only used for ICMD_BUILTIN */
+
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TEST(REG_RESULT);
+ M_BEQ(0);
+ codegen_add_fillinstacktrace_ref(cd);
+ }
/* store return value */
if (d != TYPE_VOID) {
if (IS_INT_LNG_TYPE(d)) {
- s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
- M_INTMOVE(REG_RESULT, s1);
+ 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);
+ }
}
else {
s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
}
emit_store_dst(jd, iptr, s1);
}
-#endif
+
break;
break;
default:
- *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+ exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
return false;
} /* switch */
/* don't touch ITMP3 as it cointains the return address */
- N_L2(REG_ITMP1, -2 * 4, REG_PV); /* methodinfo */
+ M_ILD(REG_ITMP1, REG_PV, -2 * 4); /* methodinfo */
/* TODO where is methodpointer loaded into itmp2? is it already inside? */
- N_L2(REG_PV, -3 * 4, REG_PV); /* compiler pointer */
+ M_ILD(REG_PV, REG_PV, -3 * 4); /* compiler pointer */
N_BR(REG_PV);
#if defined(ENABLE_STATISTICS)
/* save return address */
- N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, 0, REG_SP)
+ N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, RN, REG_SP);
#if 0
#if !defined(NDEBUG)
#endif
disp = dseg_add_functionptr(cd, f);
- N_L2(REG_ITMP3, disp, REG_PV);
+ M_ILD(REG_ITMP1, REG_PV, disp);
j = 96 + (nmd->memuse * 4);
if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
if (IS_2_WORD_TYPE(t)) {
/* todo store multiple */
- N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, 0, REG_SP);
- N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, 0, REG_SP);
+ N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
+ N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
} else {
- N_ST(rd->argintregs[s1], j, 0, REG_SP);
+ N_ST(rd->argintregs[s1], j, RN, REG_SP);
}
} else {
if (IS_2_WORD_TYPE(t)) {
- N_STD(rd->argfltregs[s1], j, 0, REG_SP);
+ N_STD(rd->argfltregs[s1], j, RN, REG_SP);
} else {
- N_STE(rd->argfltregs[s1], j, 0, REG_SP);
+ N_STE(rd->argfltregs[s1], j, RN, REG_SP);
}
}
}
}
- N_ST(REG_ITMP3, j, 0, REG_SP);
+ N_ST(REG_ITMP1, j, RN, REG_SP);
/* create dynamic stack info */
- N_LAE(REG_A0, (cd->stackframesize - 1) * 4, 0, REG_SP); /* datasp */
- N_LR(REG_A1, REG_PV) /* pv */
- N_LAE(REG_A2, cd->stackframesize * 4, 0, REG_SP); /* old SP */
- N_L(REG_A3, (cd->stackframesize - 1) * 4, 0, REG_SP); /* return address */
+ N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
+ N_LR(REG_A1, REG_PV); /* pv */
+ N_LAE(REG_A2, cd->stackframesize * 4, RN, REG_SP); /* old SP */
+ N_L(REG_A3, (cd->stackframesize - 1) * 4, RN, REG_SP); /* return address */
disp = dseg_add_functionptr(cd, codegen_start_native_call);
- N_L2(REG_ITMP1, disp, REG_PV);
+ M_ILD(REG_ITMP1, REG_PV, disp);
M_CALL(REG_ITMP1); /* call */
if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
if (IS_2_WORD_TYPE(t)) {
/* todo load multiple ! */
- N_L(rd->argintregs[GET_HIGH_REG(s1)], j, 0, REG_SP);
- N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, 0, REG_SP);
+ N_L(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
+ N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
} else {
- N_L(rd->argintregs[s1], j, 0, REG_SP);
+ N_L(rd->argintregs[s1], j, RN, REG_SP);
}
} else {
if (IS_2_WORD_TYPE(t)) {
- N_LD(rd->argfltregs[s1], j, 0, REG_SP);
+ N_LD(rd->argfltregs[s1], j, RN, REG_SP);
} else {
- N_LE(rd->argfltregs[s1], j, 0, REG_SP);
+ N_LE(rd->argfltregs[s1], j, RN, REG_SP);
}
}
}
}
- N_L(REG_ITMP3, j, 0, REG_SP);
+ N_L(REG_ITMP1, j, RN, REG_SP);
/* copy or spill arguments to new locations */
if (IS_2_WORD_TYPE(t)) {
N_LM(GET_LOW_REG(s1), GET_HIGH_REG(s1), 96 + (s2 * 4), REG_SP);
} else {
- N_L(s1, 96 + (s2 * 4), 0, REG_SP);
+ N_L(s1, 96 + (s2 * 4), RN, REG_SP);
}
}
if (m->flags & ACC_STATIC) {
disp = dseg_add_address(cd, m->class);
- N_L2(REG_A1, disp, REG_PV);
+ M_ILD(REG_A1, REG_PV, disp);
}
/* put env into first argument register */
disp = dseg_add_address(cd, _Jv_env);
- N_L2(REG_A0, disp, REG_PV);
+ M_ILD(REG_A0, REG_PV, disp);
/* do the native function call */
- M_CALL(REG_ITMP3); /* call */
+ M_CALL(REG_ITMP1); /* call */
/* save return value */
if (IS_2_WORD_TYPE(t)) {
N_STM(REG_RESULT, REG_RESULT2, 96, REG_SP);
} else {
- N_ST(REG_RESULT, 96, 0, REG_SP);
+ N_ST(REG_RESULT, 96, RN, REG_SP);
}
} else {
if (IS_2_WORD_TYPE(t)) {
- N_STD(REG_FRESULT, 96, 0, REG_SP);
+ N_STD(REG_FRESULT, 96, RN, REG_SP);
} else {
- N_STE(REG_FRESULT, 96, 0, REG_SP);
+ N_STE(REG_FRESULT, 96, RN, REG_SP);
}
}
}
/* remove native stackframe info */
- N_LAE(REG_A0, cd->stackframesize * 4, 0, REG_SP);
+ N_LAE(REG_A0, cd->stackframesize * 4, RN, REG_SP);
disp = dseg_add_functionptr(cd, codegen_finish_native_call);
- N_L2(REG_ITMP1, disp, REG_PV);
+ M_ILD(REG_ITMP1, REG_PV, disp);
M_CALL(REG_ITMP1);
N_LR(REG_ITMP3, REG_RESULT);
if (IS_2_WORD_TYPE(t)) {
N_LM(REG_RESULT, REG_RESULT2, 96, REG_SP);
} else {
- N_L(REG_RESULT, 96, 0, REG_SP);
+ N_L(REG_RESULT, 96, RN, REG_SP);
}
} else {
if (IS_2_WORD_TYPE(t)) {
- N_LD(REG_FRESULT, 96, 0, REG_SP);
+ N_LD(REG_FRESULT, 96, RN, REG_SP);
} else {
- N_LE(REG_FRESULT, 96, 0, REG_SP);
+ N_LE(REG_FRESULT, 96, RN, REG_SP);
}
}
}
N_LTR(REG_ITMP3, REG_ITMP3);
N_BRC(DD_NE, SZ_BRC + SZ_BC);
- N_BC(DD_ANY, 0, 0, REG_SP); /* return */
+ N_BC(DD_ANY, 0, RN, REG_SP); /* return */
/* handle exception */
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.h 7219 2007-01-16 22:18:57Z pm $
+ $Id: codegen.h 7283 2007-02-04 19:41:14Z pm $
*/
}
-/* M_INTMOVE:
- generates an integer-move from register a to b.
- if a and b are the same int-register, no code will be generated.
-*/
-
-#define M_INTMOVE(reg,dreg) \
- do { \
- if ((reg) != (dreg)) { \
- M_MOV(reg, dreg); \
- } \
- } while (0)
-
-
-/* M_FLTMOVE:
- generates a floating-point-move from register a to b.
- if a and b are the same float-register, no code will be generated
-*/
-
-#define M_FLTMOVE(reg,dreg) \
- do { \
- if ((reg) != (dreg)) { \
- M_FMOV(reg, dreg); \
- } \
- } while (0)
-
#define ICONST(r,c) \
do { \
M_MOV_IMM((c), (d)); \
} while (0)
+/* branch defines *************************************************************/
+
+#define BRANCH_NOPS \
+ do { \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ } while (0)
+
/* some patcher defines *******************************************************/
/* S390 specific code */
+/* Argument checks for debug mode */
+
+/* Some instructions with register arguments treat %r0 as "value not given".
+ * To prevent bugs, in debug mode we use a special value RN (reg none) with
+ * the meaning "value not given".
+ * In debug mode, the instructions assert that %r0 was not given as argument.
+ */
+
+#if 1
+# include <stdlib.h>
+ /* register none */
+# define RN 16
+ /* Optional register.
+ * Check that value given is %r1 - %r15 or RN
+ */
+# define _WITH_LINE(f, ...) f(__FILE__, __LINE__, __VA_ARGS__)
+ static inline int _OR_IMPL(const char *file, int line, int r) {
+ if(!(
+ ((0 < r) && (r < 16)) ||
+ (r == RN)
+ )) {
+ fprintf(stdout, "%d is not a valid register at %s:%d.\n", r, file, line);
+ abort();
+ }
+ return ((r == RN) ? 0 : r);
+ }
+# define _OR(r) _WITH_LINE(_OR_IMPL, r)
+
+# define _SMIN(b) (-(1 << (bits - 1)))
+# define _SMAX(b) ((1 << (b - 1)) - 1)
+# define _UMIN(b) 0
+# define _UMAX(b) ((1 << b) - 1)
+
+ static inline int _UBITS_IMPL(const char *file, int line, int i, int bits) {
+ if (!((_UMIN(bits) <= i) && (i <= _UMAX(bits)))) {
+ fprintf(stdout, "%d (0x%X) is not an unsigned %d bit integer at %s:%d.\n", i, i, bits, file, line);
+ abort();
+ }
+ return i;
+ }
+# define _UBITS(i, bits) _WITH_LINE(_UBITS_IMPL, i, bits)
+ static inline int _SBITS_IMPL(const char *file, int line, int i, int bits) {
+ if(!((_SMIN(bits) <= i) && (i <= _SMAX(bits)))) {
+ fprintf(stdout, "%d (0x%X) is not an signed %d bit integer at %s:%d.\n", i, i, bits, file, line);
+ abort();
+ }
+ return i;
+ }
+# define _SBITS(i, bits) _WITH_LINE(_SBITS_IMPL, i, bits)
+ static inline int _BITS_IMPL(const char *file, int line, int i, int bits) {
+ if (!(
+ ((_UMIN(bits) <= i) && (i <= _UMAX(bits))) ||
+ ((_SMIN(bits) <= i) && (i <= _SMAX(bits)))
+ )) {
+ fprintf(stdout, "%d (0x%X) is not an %d bit integer at %s:%d.\n", i, i, bits, file, line);
+ abort();
+ }
+ return i;
+ }
+# define _BITS(i, bits) _WITH_LINE(_BITS_IMPL, i, bits)
+#else
+# define RN 0
+# define _OR(x) (x)
+# define _BITS(x, b) (x)
+# define _UBITS(x, b) (x)
+# define _SBITS(x, b) (x)
+#endif
+
+/* Register */
+#define _R(x) _UBITS((x), 4)
+/* Displacement */
+#define _D(x) _UBITS((x), 12)
+/* 4 bit Immediate */
+#define _I4(x) _BITS((x), 4)
+#define _UI4(x) _UBITS((x), 4)
+#define _SI4(x) _SBITS((x), 4)
+/* 8 bit Immediate */
+#define _I8(x) _BITS((x), 8)
+#define _UI8(x) _UBITS((x), 8)
+#define _SI8(x) _SBITS((x), 8)
+/* 12 bit Immediate */
+#define _I12(x) _BITS((x), 12)
+#define _UI12(x) _UBITS((x), 12)
+#define _SI12(x) _SBITS((x), 12)
+/* 16 bit Immediate */
+#define _I16(x) _BITS((x), 16)
+#define _UI16(x) _UBITS((x), 16)
+#define _SI16(x) _SBITS((x), 16)
+/* Opcode */
+#define _OP(x) _UBITS((x), 8)
+/* Second part of opcode */
+#define _OP4(x) _UBITS((x), 4)
+/* Extended opcode */
+#define _OP16(x) _UBITS((x), 16)
+
/* Instruction formats */
#define _CODE(t, code) \
do { \
*((t *) cd->mcodeptr) = (code); \
cd->mcodeptr += sizeof(t); \
- } while (0);
+ } while (0)
#define _CODE2(code) _CODE(u2, code)
#define _CODE4(code) _CODE(u4, code)
do { if ((val) < 0) { neg ; } else { pos ; } } while (0)
#define N_RR(op, r1, r2) \
- _CODE2( (op << 8) | (r1 << 4) | (r2) )
+ _CODE2( (_OP(op) << 8) | (_R(r1) << 4) | _R(r2) )
#define SZ_RR 2
#define N_RR2(op, i) \
- _CODE2( (op << 8) | (i) )
+ _CODE2( (_OP(op) << 8) | _I8(i) )
#define N_RX(op, r1, d2, x2, b2) \
- _CODE4( ((op) << 24) | ((r1) << 20) | ((x2) << 16) | ((b2) << 12) | ((d2) << 0) )
+ _CODE4( (_OP(op) << 24) | (_R(r1) << 20) | (_OR(x2) << 16) | (_OR(b2) << 12) | (_D(d2) << 0) )
#define SZ_RX 4
#define N_RI(op1, op2, r1, i2) \
- _CODE4( ((op1) << 24) | ((r1) << 20) | ((op2) << 16) | ((u2) i2) )
+ _CODE4( (_OP(op1) << 24) | (_R(r1) << 20) | (_OP4(op2) << 16) | (u2)_I16(i2) )
#define SZ_RI 4
#define N_SI(op, d1, b1, i2) \
- _CODE4( ((op) << 24) | ((i2) << 16) | ((b1) << 12) | (d1) )
+ _CODE4( (_OP(op) << 24) | (_OR(i2) << 16) | (_OR(b1) << 12) | _D(d1) )
#define SZ_SI 4
#define N_SS(op, d1, l, b1, d2, b2) \
- _CODE4( ((op) << 24) | ((l) << 16) | ((b1) << 12) | (d1) ) \
- _CODE2( ((b2) << 12) | (d2) )
+ do { \
+ _CODE4( (_OP(op) << 24) | (_I8(l) << 16) | (_OR(b1) << 12) | _D(d1) ); \
+ _CODE2( (_OR(b2) << 12) | _D(d2) ); \
+ } while (0)
#define SZ_SS 6
#define N_SS2(op, d1, l1, b1, d2, l2, b2) \
- N_SS(op, d1, ((l1) << 4) | (l2), b1, d2, l2)
+ N_SS(op, d1, (_I4(l1) << 4) | _I4(l2), b1, d2, l2)
#define N_RS(op, r1, r3, d2, b2) \
- _CODE4( ((op) << 24) | ((r1) << 20) | ((r3) << 16) | ((b2) << 12) | (d2) )
+ _CODE4( (_OP(op) << 24) | (_R(r1) << 20) | (_R(r3) << 16) | (_OR(b2) << 12) | _D(d2) )
#define SZ_RS 4
#define N_RSI(op, r1, r2, i2) \
- _CODE4( ((op) << 24) | ((r1) << 20) | ((r3) << 16) | ((u2)i2) )
+ _CODE4( ((op) << 24) | (_R(r1) << 20) | (_R(r3) << 16) | (u2)_16(i2) )
#define SZ_RSI 4
#define N_RRE(op, r1, r2) \
- _CODE4( ((op) << 16) | ((r1) << 4) | (r2) )
+ _CODE4( (_OP16(op) << 16) | (_R(r1) << 4) | _R(r2) )
#define SZ_RRE 4
#define N_S2(d2, b2) \
- _CODE4( ((op) << 16) | ((b2) << 12) | (d2) )
+ _CODE4( (_OP16(op) << 16) | (_OR(b2) << 12) | _D(d2) )
#define SZ_S2 4
#define N_E(op) \
- _CODE2( (op) )
+ _CODE2( _OP16(op) )
#define SZ_E 2
#define N_N(r1, d2, x2, b2) N_RX(0x54, r1, d2, x2, b2)
#define N_NI(d1, b1, i2) N_SI(0x94, d1, b1, i2)
#define N_NC(d1, l, b1, d2, b2) N_NC(0xD4, l, b1, d1, b2, d2)
-#define N_BALR(r1, r2) N_RR(0x05, r1, r2)
+#define N_BALR(r1, r2) N_RR(0x05, r1, _OR(r2))
#define N_BAL(r1, d2, x2, b2) N_RX(0x45, r1, d2, x2, b2)
-#define N_BASR(r1, r2) N_RR(0x0D, r1, r2)
+#define N_BASR(r1, r2) N_RR(0x0D, r1, _OR(r2))
#define N_BAS(r1, d2, x2, b2) N_RX(0x4D, r1, d2, x2, b2)
-#define N_BASSM(r1, r2) N_RR(0x0C, r1, r2)
-#define N_BSM(r1, r2) N_RR(0x0B, r1, r2)
-#define N_BCR(m1, r2) N_RR(0x07, m1, r2)
+#define N_BASSM(r1, r2) N_RR(0x0C, r1, _OR(r2))
+#define N_BSM(r1, r2) N_RR(0x0B, r1, _OR(r2))
+#define N_BCR(m1, r2) N_RR(0x07, m1, _OR(r2))
# define SZ_BCR SZ_RR
# define N_BR(r2) N_BCR(DD_ANY, r2)
# define SZ_BR SZ_BCR
#define N_BC(m1, d2, x2, b2) N_RS(0x47, m1, d2, x2, b2)
# define SZ_BC SZ_RS
-#define N_BCTR(r1, r2) N_RR(0x06, r1, r2)
+#define N_BCTR(r1, r2) N_RR(0x06, r1, _OR(r2))
#define N_BCT(r1, d2, x2, b2) N_RX(0x46, r1, d2, x2, b2)
#define N_BHX(r1, r2, d2, b2) N_RS(0xB6, r1, r3, d2, b2)
#define N_BXLE(r1, r3, d2, b2) N_RS(0xB7, r1, r3, d2, b2)
#define N_BRXH(r1, r3, i2) N_RSI(0x84, r1, r3, (i2) / 2)
#define N_BRXLE(r1, r3, i2) N_RSI(0x85, r1, r2, (i2) / 2)
#define N_CKSM(r1, r2) N_RRE(0xB241, r1, r2)
-#define N_CR(r1, r2), N_RR(0x19, r1, r2)
+#define N_CR(r1, r2) N_RR(0x19, r1, r2)
+# define SZ_CR SZ_RR
#define N_C(r1, d2, x2, b2) N_RX(0x59, r1, d2, x2, b2)
#define N_CFC(d2, b2) N_S2(0xB21A, d2, b2)
#define N_CS(r1, r3, d2, b2) N_RS(0xBA, r1, r3, d2, b2)
#define N_LR(r1, r2) N_RR(0x18, r1, r2)
#define N_L(r1, d2, x2, b2) N_RX(0x58, r1, d2, x2, b2)
# define SZ_L SZ_RX
-# define N_L2(r1, d2, b2) \
- do { N_LHI(r1, d2); N_L(r1, 0, r1, b2); } while (0)
#define N_LAM(r1, r3, d2, b2) N_RS(0x9A, r1, r3, d2, b2)
#define N_LA(r1, d2, x2, b2) N_RX(0x41, r1, d2, x2, b2)
-# define N_LA2(r1, d2, b2) \
- do { N_LHI(r1, d2); N_LA(r1, 0, r1, b2); } while (0)
#define N_LAE(r1, d2, x2, b2) N_RX(0x51, r1, d2, x2, b2)
#define N_LTR(r1, r2) N_RR(0x12, r1, r2)
#define N_LCR(r1, r2) N_RR(0x13, r1, r2)
#define M_CALL(r2) N_BASR(R14, r2)
-#define M_ALD(r, b, d) _IFNEG(d, N_L2(r, d, b), N_L(r, d, 0, b))
-#define M_ILD(r, b, d) _IFNEG(d, N_LA2(r, d, b), N_LA(r, d, 0, b))
-#define M_FLD(r, b, d) _IFNEG(d, assert(0), N_LE(r, d, 0, b))
-#define M_DLD(r, b, d) _IFNEG(d, assert(0), N_LD(r, d, 0, b))
-/* TODO 3 instead of 4 instrs for d < 0 ! */
-#define M_LLD(r, b, d) \
- do { M_ILD(GET_HIGH_REG(r), b, d); M_ILD(GET_LOW_REG(r), b, d + 4); } while(0)
+#define M_ILD(r, b, d) _IFNEG( \
+ d, \
+ N_LHI(r, d); N_L(r, 0, r, b), \
+ N_L(r, d, RN, b) \
+)
+
+#define M_ALD(r, b, d) M_ILD(r, b, d)
+
+#define M_LDA(r, b, d) _IFNEG( \
+ d, \
+ N_LHI(r, d); N_LA(r, 0, r, b), \
+ N_LA(r, d, RN, b) \
+)
+
+#define M_FLD(r, b, d) _IFNEG(d, assert(0), N_LE(r, d, RN, b))
+#define M_DLD(r, b, d) _IFNEG(d, assert(0), N_LD(r, d, RN, b))
+
+#define M_LLD(r, b, d) _IFNEG( \
+ d, \
+ N_LHI(GET_LOW_REG(r), d); \
+ N_L(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
+ N_L(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
+ N_L(GET_HIGH_REG(r), 0, RN, b); N_L(GET_LOW_REG(r), 4, RN, b) \
+)
+
+#define M_MOV(a, b) N_LR(a, b)
+#define M_FMOV(a, b) N_LDR(a, b)
+#define M_DST(r, b, d) _IFNEG(d, assert(0), N_STD(r, d, RN, b))
+#define M_FST(r, b, d) _IFNEG(d, assert(0), N_STE(r, d, RN, b))
+#define M_IST(r, b, d) _IFNEG( \
+ d, \
+ N_LHI(r, d); N_S(r, 0, r, b), \
+ N_S(r, d, RN, b) \
+)
+#define M_AST(r, b, d) M_IST(r, b, d)
+#define M_LST(r, b, d) _IFNEG( \
+ d, \
+ N_LHI(GET_LOW_REG(r), d); \
+ N_S(GET_HIGH_REG(r), 0, GET_LOW_REG(r), b); \
+ N_S(GET_LOW_REG(r), 4, GET_LOW_REG(r), b), \
+ N_S(GET_HIGH_REG(r), 0, RN, b); N_S(GET_LOW_REG(r), 4, RN, b) \
+)
+#define M_TEST(r) N_LTR(r, r)
+#define M_BEQ(off) N_BRC(DD_E, off)
+#define M_BNE(off) N_BRC(DD_NE, off)
+#define M_BLE(off) N_BRC(DD_LE, off)
+#define M_BGT(off) N_BRC(DD_H, off)
+#define M_BLT(off) N_BRC(DD_L, off)
+
+#define M_CMP(r1, r2) N_CR(r1, r2)
+#define M_CLR(r) N_LHI(r, 0)
+#define M_AADD_IMM(val, reg) N_LA(reg, val, RN, reg)
+#define M_IADD_IMM(val, reg) N_AHI(reg, val)
+#define M_ASUB_IMM(val, reg) N_AHI(reg, -(val))
+#define M_RET N_BCR(DD_ANY, R14)
+
+/* M_INTMOVE:
+ generates an integer-move from register a to b.
+ if a and b are the same int-register, no code will be generated.
+*/
+
+#define M_INTMOVE(reg,dreg) \
+ do { \
+ if ((reg) != (dreg)) { \
+ M_MOV(reg, dreg); \
+ } \
+ } while (0)
+
+#define M_LNGMOVE(a, b) \
+ do { \
+ if (GET_HIGH_REG(a) == GET_LOW_REG(b)) { \
+ assert((GET_LOW_REG(a) != GET_HIGH_REG(b))); \
+ M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+ M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+ } else { \
+ M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+ M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+ } \
+ } while (0)
+
+/* M_FLTMOVE:
+ generates a floating-point-move from register a to b.
+ if a and b are the same float-register, no code will be generated
+*/
+
+#define M_FLTMOVE(reg,dreg) \
+ do { \
+ if ((reg) != (dreg)) { \
+ M_FMOV(reg, dreg); \
+ } \
+ } while (0)
+
+
/* ----------------------------------------------- */
-#define M_MOV(a,b) emit_mov_reg_reg(cd, (a), (b))
-#define M_MOV_IMM(a,b) emit_mov_imm_reg(cd, (u8) (a), (b))
+#define _DEPR(x) \
+ do { \
+ fprintf(stdout, \
+ "Using old x86_64 instruction %s at %s (%s:%d), fix this.\n", \
+ #x, __FUNCTION__, __FILE__, __LINE__); \
+ } while (0)
+
+#define M_MOV_IMM(a,b) _DEPR( M_MOV_IMM(a,b) )
+
+#define M_IMOV(a,b) _DEPR( M_IMOV(a,b) )
+#define M_IMOV_IMM(a,b) _DEPR( M_IMOV_IMM(a,b) )
-#define M_IMOV(a,b) emit_movl_reg_reg(cd, (a), (b))
-#define M_IMOV_IMM(a,b) emit_movl_imm_reg(cd, (u4) (a), (b))
-#define M_FMOV(a,b) emit_movq_reg_reg(cd, (a), (b))
+#define M_ILD32(a,b,disp) _DEPR( M_ILD32(a,b,disp) )
+#define M_LLD32(a,b,disp) _DEPR( M_LLD32(a,b,disp) )
-#define M__ILD(a,b,disp) emit_movl_membase_reg(cd, (b), (disp), (a))
-#define M__LLD(a,b,disp) emit_mov_membase_reg(cd, (b), (disp), (a))
-#define M_ILD32(a,b,disp) emit_movl_membase32_reg(cd, (b), (disp), (a))
-#define M_LLD32(a,b,disp) emit_mov_membase32_reg(cd, (b), (disp), (a))
+#define M_IST_IMM(a,b,disp) _DEPR( M_IST_IMM(a,b,disp) )
+#define M_LST_IMM32(a,b,disp) _DEPR( M_LST_IMM32(a,b,disp) )
-#define M_IST(a,b,disp) emit_movl_reg_membase(cd, (a), (b), (disp))
-#define M_LST(a,b,disp) emit_mov_reg_membase(cd, (a), (b), (disp))
+#define M_IST32(a,b,disp) _DEPR( M_IST32(a,b,disp) )
+#define M_LST32(a,b,disp) _DEPR( M_LST32(a,b,disp) )
-#define M_IST_IMM(a,b,disp) emit_movl_imm_membase(cd, (a), (b), (disp))
-#define M_LST_IMM32(a,b,disp) emit_mov_imm_membase(cd, (a), (b), (disp))
+#define M_IST32_IMM(a,b,disp) _DEPR( M_IST32_IMM(a,b,disp) )
+#define M_LST32_IMM32(a,b,disp) _DEPR( M_LST32_IMM32(a,b,disp) )
-#define M_IST32(a,b,disp) emit_movl_reg_membase32(cd, (a), (b), (disp))
-#define M_LST32(a,b,disp) emit_mov_reg_membase32(cd, (a), (b), (disp))
+#define M_IADD(a,b) _DEPR( M_IADD(a,b) )
+#define M_ISUB(a,b) _DEPR( M_ISUB(a,b) )
+#define M_IMUL(a,b) _DEPR( M_IMUL(a,b) )
-#define M_IST32_IMM(a,b,disp) emit_movl_imm_membase32(cd, (a), (b), (disp))
-#define M_LST32_IMM32(a,b,disp) emit_mov_imm_membase32(cd, (a), (b), (disp))
+#define M_ISUB_IMM(a,b) _DEPR( M_ISUB_IMM(a,b) )
+#define M_IMUL_IMM(a,b,c) _DEPR( M_IMUL_IMM(a,b,c) )
-#define M_IADD(a,b) emit_alul_reg_reg(cd, ALU_ADD, (a), (b))
-#define M_ISUB(a,b) emit_alul_reg_reg(cd, ALU_SUB, (a), (b))
-#define M_IMUL(a,b) emit_imull_reg_reg(cd, (a), (b))
+#define M_LADD(a,b) _DEPR( M_LADD(a,b) )
+#define M_LSUB(a,b) _DEPR( M_LSUB(a,b) )
+#define M_LMUL(a,b) _DEPR( M_LMUL(a,b) )
-#define M_IADD_IMM(a,b) emit_alul_imm_reg(cd, ALU_ADD, (a), (b))
-#define M_ISUB_IMM(a,b) emit_alul_imm_reg(cd, ALU_SUB, (a), (b))
-#define M_IMUL_IMM(a,b,c) emit_imull_imm_reg_reg(cd, (b), (a), (c))
+#define M_LADD_IMM(a,b) _DEPR( M_LADD_IMM(a,b) )
+#define M_LSUB_IMM(a,b) _DEPR( M_LSUB_IMM(a,b) )
+#define M_LMUL_IMM(a,b,c) _DEPR( M_LMUL_IMM(a,b,c) )
-#define M_LADD(a,b) emit_alu_reg_reg(cd, ALU_ADD, (a), (b))
-#define M_LSUB(a,b) emit_alu_reg_reg(cd, ALU_SUB, (a), (b))
-#define M_LMUL(a,b) emit_imul_reg_reg(cd, (a), (b))
+#define M_IINC(a) _DEPR( M_IINC(a) )
+#define M_IDEC(a) _DEPR( M_IDEC(a) )
-#define M_LADD_IMM(a,b) emit_alu_imm_reg(cd, ALU_ADD, (a), (b))
-#define M_LSUB_IMM(a,b) emit_alu_imm_reg(cd, ALU_SUB, (a), (b))
-#define M_LMUL_IMM(a,b,c) emit_imul_imm_reg_reg(cd, (b), (a), (c))
+#define M_ALD32(a,b,disp) _DEPR( M_ALD32(a,b,disp) )
-#define M_IINC(a) emit_incl_reg(cd, (a))
-#define M_IDEC(a) emit_decl_reg(cd, (a))
+#define M_AST_IMM32(a,b,c) _DEPR( M_AST_IMM32(a,b,c) )
-#define M__ALD(a,b,disp) M_LLD(a,b,disp)
-#define M_ALD32(a,b,disp) M_LLD32(a,b,disp)
+#define M_AADD(a,b) _DEPR( M_AADD(a,b) )
-#define M_AST(a,b,c) M_LST(a,b,c)
-#define M_AST_IMM32(a,b,c) M_LST_IMM32(a,b,c)
+#define M_LADD_IMM32(a,b) _DEPR( M_LADD_IMM32(a,b) )
+#define M_AADD_IMM32(a,b) _DEPR( M_AADD_IMM32(a,b) )
+#define M_LSUB_IMM32(a,b) _DEPR( M_LSUB_IMM32(a,b) )
-#define M_AADD(a,b) M_LADD(a,b)
-#define M_AADD_IMM(a,b) M_LADD_IMM(a,b)
-#define M_ASUB_IMM(a,b) M_LSUB_IMM(a,b)
+#define M_ILEA(a,b,c) _DEPR( M_ILEA(a,b,c) )
+#define M_LLEA(a,b,c) _DEPR( M_LLEA(a,b,c) )
+#define M_ALEA(a,b,c) _DEPR( M_ALEA(a,b,c) )
-#define M_LADD_IMM32(a,b) emit_alu_imm32_reg(cd, ALU_ADD, (a), (b))
-#define M_AADD_IMM32(a,b) M_LADD_IMM32(a,b)
-#define M_LSUB_IMM32(a,b) emit_alu_imm32_reg(cd, ALU_SUB, (a), (b))
+#define M_INEG(a) _DEPR( M_INEG(a) )
+#define M_LNEG(a) _DEPR( M_LNEG(a) )
-#define M_ILEA(a,b,c) emit_leal_membase_reg(cd, (a), (b), (c))
-#define M_LLEA(a,b,c) emit_lea_membase_reg(cd, (a), (b), (c))
-#define M_ALEA(a,b,c) M_LLEA(a,b,c)
+#define M_IAND(a,b) _DEPR( M_IAND(a,b) )
+#define M_IOR(a,b) _DEPR( M_IOR(a,b) )
+#define M_IXOR(a,b) _DEPR( M_IXOR(a,b) )
-#define M_INEG(a) emit_negl_reg(cd, (a))
-#define M_LNEG(a) emit_neg_reg(cd, (a))
+#define M_IAND_IMM(a,b) _DEPR( M_IAND_IMM(a,b) )
+#define M_IOR_IMM(a,b) _DEPR( M_IOR_IMM(a,b) )
+#define M_IXOR_IMM(a,b) _DEPR( M_IXOR_IMM(a,b) )
-#define M_IAND(a,b) emit_alul_reg_reg(cd, ALU_AND, (a), (b))
-#define M_IOR(a,b) emit_alul_reg_reg(cd, ALU_OR, (a), (b))
-#define M_IXOR(a,b) emit_alul_reg_reg(cd, ALU_XOR, (a), (b))
+#define M_LAND(a,b) _DEPR( M_LAND(a,b) )
+#define M_LOR(a,b) _DEPR( M_LOR(a,b) )
+#define M_LXOR(a,b) _DEPR( M_LXOR(a,b) )
-#define M_IAND_IMM(a,b) emit_alul_imm_reg(cd, ALU_AND, (a), (b))
-#define M_IOR_IMM(a,b) emit_alul_imm_reg(cd, ALU_OR, (a), (b))
-#define M_IXOR_IMM(a,b) emit_alul_imm_reg(cd, ALU_XOR, (a), (b))
+#define M_LAND_IMM(a,b) _DEPR( M_LAND_IMM(a,b) )
+#define M_LOR_IMM(a,b) _DEPR( M_LOR_IMM(a,b) )
+#define M_LXOR_IMM(a,b) _DEPR( M_LXOR_IMM(a,b) )
-#define M_LAND(a,b) emit_alu_reg_reg(cd, ALU_AND, (a), (b))
-#define M_LOR(a,b) emit_alu_reg_reg(cd, ALU_OR, (a), (b))
-#define M_LXOR(a,b) emit_alu_reg_reg(cd, ALU_XOR, (a), (b))
+#define M_SSEXT(a,b) _DEPR( M_SSEXT(a,b) )
+#define M_ISEXT(a,b) _DEPR( M_ISEXT(a,b) )
-#define M_LAND_IMM(a,b) emit_alu_imm_reg(cd, ALU_AND, (a), (b))
-#define M_LOR_IMM(a,b) emit_alu_imm_reg(cd, ALU_OR, (a), (b))
-#define M_LXOR_IMM(a,b) emit_alu_imm_reg(cd, ALU_XOR, (a), (b))
+#define M_CZEXT(a,b) _DEPR( M_CZEXT(a,b) )
-#define M_BSEXT(a,b) emit_movsbq_reg_reg(cd, (a), (b))
-#define M_SSEXT(a,b) emit_movswq_reg_reg(cd, (a), (b))
-#define M_ISEXT(a,b) emit_movslq_reg_reg(cd, (a), (b))
+#define M_ISLL_IMM(a,b) _DEPR( M_ISLL_IMM(a,b) )
+#define M_ISRA_IMM(a,b) _DEPR( M_ISRA_IMM(a,b) )
+#define M_ISRL_IMM(a,b) _DEPR( M_ISRL_IMM(a,b) )
-#define M_CZEXT(a,b) emit_movzwq_reg_reg(cd, (a), (b))
+#define M_LSLL_IMM(a,b) _DEPR( M_LSLL_IMM(a,b) )
+#define M_LSRA_IMM(a,b) _DEPR( M_LSRA_IMM(a,b) )
+#define M_LSRL_IMM(a,b) _DEPR( M_LSRL_IMM(a,b) )
-#define M_ISLL_IMM(a,b) emit_shiftl_imm_reg(cd, SHIFT_SHL, (a), (b))
-#define M_ISRA_IMM(a,b) emit_shiftl_imm_reg(cd, SHIFT_SAR, (a), (b))
-#define M_ISRL_IMM(a,b) emit_shiftl_imm_reg(cd, SHIFT_SHR, (a), (b))
+#define M_LCMP(a,b) _DEPR( M_LCMP(a,b) )
+#define M_LCMP_IMM(a,b) _DEPR( M_LCMP_IMM(a,b) )
+#define M_LCMP_IMM_MEMBASE(a,b,c) _DEPR( M_LCMP_IMM_MEMBASE(a,b,c) )
+#define M_LCMP_MEMBASE(a,b,c) _DEPR( M_LCMP_MEMBASE(a,b,c) )
-#define M_LSLL_IMM(a,b) emit_shift_imm_reg(cd, SHIFT_SHL, (a), (b))
-#define M_LSRA_IMM(a,b) emit_shift_imm_reg(cd, SHIFT_SAR, (a), (b))
-#define M_LSRL_IMM(a,b) emit_shift_imm_reg(cd, SHIFT_SHR, (a), (b))
+#define M_ICMP(a,b) _DEPR( M_ICMP(a,b) )
+#define M_ICMP_IMM(a,b) _DEPR( M_ICMP_IMM(a,b) )
+#define M_ICMP_IMM_MEMBASE(a,b,c) _DEPR( M_ICMP_IMM_MEMBASE(a,b,c) )
+#define M_ICMP_MEMBASE(a,b,c) _DEPR( M_ICMP_MEMBASE(a,b,c) )
-#define M_TEST(a) emit_test_reg_reg(cd, (a), (a))
-#define M_ITEST(a) emit_testl_reg_reg(cd, (a), (a))
+#define M_BGE(disp) _DEPR( M_BGE(disp) )
+#define M_BAE(disp) _DEPR( M_BAE(disp) )
+#define M_BA(disp) _DEPR( M_BA(disp) )
-#define M_LCMP(a,b) emit_alu_reg_reg(cd, ALU_CMP, (a), (b))
-#define M_LCMP_IMM(a,b) emit_alu_imm_reg(cd, ALU_CMP, (a), (b))
-#define M_LCMP_IMM_MEMBASE(a,b,c) emit_alu_imm_membase(cd, ALU_CMP, (a), (b), (c))
-#define M_LCMP_MEMBASE(a,b,c) emit_alu_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_CMOVEQ(a,b) _DEPR( M_CMOVEQ(a,b) )
+#define M_CMOVNE(a,b) _DEPR( M_CMOVNE(a,b) )
+#define M_CMOVLT(a,b) _DEPR( M_CMOVLT(a,b) )
+#define M_CMOVLE(a,b) _DEPR( M_CMOVLE(a,b) )
+#define M_CMOVGE(a,b) _DEPR( M_CMOVGE(a,b) )
+#define M_CMOVGT(a,b) _DEPR( M_CMOVGT(a,b) )
-#define M_ICMP(a,b) emit_alul_reg_reg(cd, ALU_CMP, (a), (b))
-#define M_ICMP_IMM(a,b) emit_alul_imm_reg(cd, ALU_CMP, (a), (b))
-#define M_ICMP_IMM_MEMBASE(a,b,c) emit_alul_imm_membase(cd, ALU_CMP, (a), (b), (c))
-#define M_ICMP_MEMBASE(a,b,c) emit_alul_membase_reg(cd, ALU_CMP, (a), (b), (c))
+#define M_CMOVEQ_MEMBASE(a,b,c) _DEPR( M_CMOVEQ_MEMBASE(a,b,c) )
+#define M_CMOVNE_MEMBASE(a,b,c) _DEPR( M_CMOVNE_MEMBASE(a,b,c) )
+#define M_CMOVLT_MEMBASE(a,b,c) _DEPR( M_CMOVLT_MEMBASE(a,b,c) )
+#define M_CMOVLE_MEMBASE(a,b,c) _DEPR( M_CMOVLE_MEMBASE(a,b,c) )
+#define M_CMOVGE_MEMBASE(a,b,c) _DEPR( M_CMOVGE_MEMBASE(a,b,c) )
+#define M_CMOVGT_MEMBASE(a,b,c) _DEPR( M_CMOVGT_MEMBASE(a,b,c) )
-#define M_BEQ(disp) emit_jcc(cd, CC_E, (disp))
-#define M_BNE(disp) emit_jcc(cd, CC_NE, (disp))
-#define M_BLT(disp) emit_jcc(cd, CC_L, (disp))
-#define M_BLE(disp) emit_jcc(cd, CC_LE, (disp))
-#define M_BGE(disp) emit_jcc(cd, CC_GE, (disp))
-#define M_BGT(disp) emit_jcc(cd, CC_G, (disp))
-#define M_BAE(disp) emit_jcc(cd, CC_AE, (disp))
-#define M_BA(disp) emit_jcc(cd, CC_A, (disp))
+#define M_CMOVB(a,b) _DEPR( M_CMOVB(a,b) )
+#define M_CMOVA(a,b) _DEPR( M_CMOVA(a,b) )
+#define M_CMOVP(a,b) _DEPR( M_CMOVP(a,b) )
-#define M_CMOVEQ(a,b) emit_cmovcc_reg_reg(cd, CC_E, (a), (b))
-#define M_CMOVNE(a,b) emit_cmovcc_reg_reg(cd, CC_NE, (a), (b))
-#define M_CMOVLT(a,b) emit_cmovcc_reg_reg(cd, CC_L, (a), (b))
-#define M_CMOVLE(a,b) emit_cmovcc_reg_reg(cd, CC_LE, (a), (b))
-#define M_CMOVGE(a,b) emit_cmovcc_reg_reg(cd, CC_GE, (a), (b))
-#define M_CMOVGT(a,b) emit_cmovcc_reg_reg(cd, CC_G, (a), (b))
+#define M_PUSH(a) _DEPR( M_PUSH(a) )
+#define M_PUSH_IMM(a) _DEPR( M_PUSH_IMM(a) )
+#define M_POP(a) _DEPR( M_POP(a) )
-#define M_CMOVEQ_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_E, (a), (b))
-#define M_CMOVNE_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_NE, (a), (b))
-#define M_CMOVLT_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_L, (a), (b))
-#define M_CMOVLE_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_LE, (a), (b))
-#define M_CMOVGE_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_GE, (a), (b))
-#define M_CMOVGT_MEMBASE(a,b,c) emit_cmovcc_reg_membase(cd, CC_G, (a), (b))
+#define M_JMP(a) _DEPR( M_JMP(a) )
+#define M_JMP_IMM(a) _DEPR( M_JMP_IMM(a) )
+#define M_CALL_IMM(a) _DEPR( M_CALL_IMM(a) )
-#define M_CMOVB(a,b) emit_cmovcc_reg_reg(cd, CC_B, (a), (b))
-#define M_CMOVA(a,b) emit_cmovcc_reg_reg(cd, CC_A, (a), (b))
-#define M_CMOVP(a,b) emit_cmovcc_reg_reg(cd, CC_P, (a), (b))
+#define M_NOP _DEPR( M_NOP )
-#define M_PUSH(a) emit_push_reg(cd, (a))
-#define M_PUSH_IMM(a) emit_push_imm(cd, (a))
-#define M_POP(a) emit_pop_reg(cd, (a))
-#define M_JMP(a) emit_jmp_reg(cd, (a))
-#define M_JMP_IMM(a) emit_jmp_imm(cd, (a))
-#define M__CALL(a) emit_call_reg(cd, (a))
-#define M_CALL_IMM(a) emit_call_imm(cd, (a))
-#define M_RET emit_ret(cd)
-
-#define M_NOP emit_nop(cd)
-
-#define M_CLR(a) M_LXOR(a,a)
-#define M__FLD(a,b,disp) emit_movss_membase_reg(cd, (b), (disp), (a))
-#define M__DLD(a,b,disp) emit_movsd_membase_reg(cd, (b), (disp), (a))
-
-#define M_FLD32(a,b,disp) emit_movss_membase32_reg(cd, (b), (disp), (a))
-#define M_DLD32(a,b,disp) emit_movsd_membase32_reg(cd, (b), (disp), (a))
-
-#define M_FST(a,b,disp) emit_movss_reg_membase(cd, (a), (b), (disp))
-#define M_DST(a,b,disp) emit_movsd_reg_membase(cd, (a), (b), (disp))
-
-#define M_FST32(a,b,disp) emit_movss_reg_membase32(cd, (a), (b), (disp))
-#define M_DST32(a,b,disp) emit_movsd_reg_membase32(cd, (a), (b), (disp))
+#define M_FLD32(a,b,disp) _DEPR( M_FLD32(a,b,disp) )
+#define M_DLD32(a,b,disp) _DEPR( M_DLD32(a,b,disp) )
-#define M_FADD(a,b) emit_addss_reg_reg(cd, (a), (b))
-#define M_DADD(a,b) emit_addsd_reg_reg(cd, (a), (b))
-#define M_FSUB(a,b) emit_subss_reg_reg(cd, (a), (b))
-#define M_DSUB(a,b) emit_subsd_reg_reg(cd, (a), (b))
-#define M_FMUL(a,b) emit_mulss_reg_reg(cd, (a), (b))
-#define M_DMUL(a,b) emit_mulsd_reg_reg(cd, (a), (b))
-#define M_FDIV(a,b) emit_divss_reg_reg(cd, (a), (b))
-#define M_DDIV(a,b) emit_divsd_reg_reg(cd, (a), (b))
-
-#define M_CVTIF(a,b) emit_cvtsi2ss_reg_reg(cd, (a), (b))
-#define M_CVTID(a,b) emit_cvtsi2sd_reg_reg(cd, (a), (b))
-#define M_CVTLF(a,b) emit_cvtsi2ssq_reg_reg(cd, (a), (b))
-#define M_CVTLD(a,b) emit_cvtsi2sdq_reg_reg(cd, (a), (b))
-#define M_CVTFI(a,b) emit_cvttss2si_reg_reg(cd, (a), (b))
-#define M_CVTDI(a,b) emit_cvttsd2si_reg_reg(cd, (a), (b))
-#define M_CVTFL(a,b) emit_cvttss2siq_reg_reg(cd, (a), (b))
-#define M_CVTDL(a,b) emit_cvttsd2siq_reg_reg(cd, (a), (b))
-
-#define M_CVTFD(a,b) emit_cvtss2sd_reg_reg(cd, (a), (b))
-#define M_CVTDF(a,b) emit_cvtsd2ss_reg_reg(cd, (a), (b))
+
+#define M_FST32(a,b,disp) _DEPR( M_FST32(a,b,disp) )
+#define M_DST32(a,b,disp) _DEPR( M_DST32(a,b,disp) )
+
+#define M_FADD(a,b) _DEPR( M_FADD(a,b) )
+#define M_DADD(a,b) _DEPR( M_DADD(a,b) )
+#define M_FSUB(a,b) _DEPR( M_FSUB(a,b) )
+#define M_DSUB(a,b) _DEPR( M_DSUB(a,b) )
+#define M_FMUL(a,b) _DEPR( M_FMUL(a,b) )
+#define M_DMUL(a,b) _DEPR( M_DMUL(a,b) )
+#define M_FDIV(a,b) _DEPR( M_FDIV(a,b) )
+#define M_DDIV(a,b) _DEPR( M_DDIV(a,b) )
+
+#define M_CVTIF(a,b) _DEPR( M_CVTIF(a,b) )
+#define M_CVTID(a,b) _DEPR( M_CVTID(a,b) )
+#define M_CVTLF(a,b) _DEPR( M_CVTLF(a,b) )
+#define M_CVTLD(a,b) _DEPR( M_CVTLD(a,b) )
+#define M_CVTFI(a,b) _DEPR( M_CVTFI(a,b) )
+#define M_CVTDI(a,b) _DEPR( M_CVTDI(a,b) )
+#define M_CVTFL(a,b) _DEPR( M_CVTFL(a,b) )
+#define M_CVTDL(a,b) _DEPR( M_CVTDL(a,b) )
+
+#define M_CVTFD(a,b) _DEPR( M_CVTFD(a,b) )
+#define M_CVTDF(a,b) _DEPR( M_CVTDF(a,b) )
/* system instructions ********************************************************/
-#define M_RDTSC emit_rdtsc(cd)
+#define M_RDTSC _DEPR( M_RDTSC )
-#define M_IINC_MEMBASE(a,b) emit_incl_membase(cd, (a), (b))
+#define M_IINC_MEMBASE(a,b) _DEPR( M_IINC_MEMBASE(a,b) )
-#define M_IADD_MEMBASE(a,b,c) emit_alul_reg_membase(cd, ALU_ADD, (a), (b), (c))
-#define M_IADC_MEMBASE(a,b,c) emit_alul_reg_membase(cd, ALU_ADC, (a), (b), (c))
-#define M_ISUB_MEMBASE(a,b,c) emit_alul_reg_membase(cd, ALU_SUB, (a), (b), (c))
-#define M_ISBB_MEMBASE(a,b,c) emit_alul_reg_membase(cd, ALU_SBB, (a), (b), (c))
+#define M_IADD_MEMBASE(a,b,c) _DEPR( M_IADD_MEMBASE(a,b,c) )
+#define M_IADC_MEMBASE(a,b,c) _DEPR( M_IADC_MEMBASE(a,b,c) )
+#define M_ISUB_MEMBASE(a,b,c) _DEPR( M_ISUB_MEMBASE(a,b,c) )
+#define M_ISBB_MEMBASE(a,b,c) _DEPR( M_ISBB_MEMBASE(a,b,c) )
-#define PROFILE_CYCLE_START
-#define __PROFILE_CYCLE_START \
- do { \
- if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \
- M_PUSH(RAX); \
- M_PUSH(RDX); \
- \
- M_MOV_IMM(code, REG_ITMP3); \
- M_RDTSC; \
- M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); \
- M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); \
- \
- M_POP(RDX); \
- M_POP(RAX); \
- } \
- } while (0)
+#define PROFILE_CYCLE_START _DEPR( PROFILE_CYCLE_START )
+#define __PROFILE_CYCLE_START _DEPR( __PROFILE_CYCLE_START )
-#define PROFILE_CYCLE_STOP
-#define __PROFILE_CYCLE_STOP \
- do { \
- if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \
- M_PUSH(RAX); \
- M_PUSH(RDX); \
- \
- M_MOV_IMM(code, REG_ITMP3); \
- M_RDTSC; \
- M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); \
- M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); \
- \
- M_POP(RDX); \
- M_POP(RAX); \
- } \
- } while (0)
+#define PROFILE_CYCLE_STOP _DEPR( PROFILE_CYCLE_STOP )
+#define __PROFILE_CYCLE_STOP _DEPR( __PROFILE_CYCLE_STOP )
/* function gen_resolvebranch **************************************************
Authors: Christian Thalinger
- $Id: emit.c 7219 2007-01-16 22:18:57Z pm $
+ $Id: emit.c 7283 2007-02-04 19:41:14Z pm $
*/
+#include <assert.h>
+
#include "config.h"
#include "vm/types.h"
*******************************************************************************/
-inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
+__PORTED__ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
{
- codegendata *cd;
- s4 disp;
-#if 0
- s4 s;
- u2 opcode;
-#endif
+ codegendata *cd;
/* get required compiler data */
cd = jd->cd;
-#if 0
- /* do we have to generate a conditional move? */
-
- if ((iptr != NULL) && (iptr->opc & ICMD_CONDITION_MASK)) {
- /* the passed register d is actually the source register */
-
- s = d;
-
- /* Only pass the opcode to codegen_reg_of_var to get the real
- destination register. */
-
- opcode = iptr->opc & ICMD_OPCODE_MASK;
-
- /* get the real destination register */
-
- d = codegen_reg_of_var(rd, opcode, dst, REG_ITMP1);
-
- /* and emit the conditional move */
-
- emit_cmovxx(cd, iptr, s, d);
- }
-#endif
-
if (IS_INMEMORY(dst->flags)) {
COUNT_SPILLS;
- disp = dst->vv.regoff * 8;
-
if (IS_FLT_DBL_TYPE(dst->type)) {
if (IS_2_WORD_TYPE(dst->type))
- M_DST(d, REG_SP, disp);
+ M_DST(d, REG_SP, dst->vv.regoff * 4);
else
- M_FST(d, REG_SP, disp);
+ M_FST(d, REG_SP, dst->vv.regoff * 4);
+ }
+ else {
+ if (IS_2_WORD_TYPE(dst->type))
+ M_LST(d, REG_SP, dst->vv.regoff * 4);
+ else
+ M_IST(d, REG_SP, dst->vv.regoff * 4);
}
- else
- M_LST(d, REG_SP, disp);
}
}
*******************************************************************************/
-void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
+__PORTED__ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
{
codegendata *cd;
s4 s1, d;
void emit_replacement_stubs(jitdata *jd)
{
+#if 0
codegendata *cd;
codeinfo *code;
rplpoint *rplp;
M_MOV_IMM(asm_replacement_out, REG_ITMP3);
M_JMP(REG_ITMP3);
}
+#endif
}
*(cd->mcodeptr++) = 0x31;
}
+/* emit_load_high **************************************************************
+
+ Emits a possible load of the high 32-bits of an operand.
+
+*******************************************************************************/
+
+s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+ codegendata *cd;
+ s4 disp;
+ s4 reg;
+
+ assert(src->type == TYPE_LNG);
+
+ /* get required compiler data */
+
+ cd = jd->cd;
+
+ if (IS_INMEMORY(src->flags)) {
+ COUNT_SPILLS;
+
+ disp = src->vv.regoff * 4;
+
+ M_ILD(tempreg, REG_SP, disp);
+
+ reg = tempreg;
+ }
+ else
+ reg = GET_HIGH_REG(src->vv.regoff);
+
+ return reg;
+}
+
+/* emit_load_low ***************************************************************
+
+ Emits a possible load of the low 32-bits of an operand.
+
+*******************************************************************************/
+
+s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+ codegendata *cd;
+ s4 disp;
+ s4 reg;
+
+ assert(src->type == TYPE_LNG);
+
+ /* get required compiler data */
+
+ cd = jd->cd;
+
+ if (IS_INMEMORY(src->flags)) {
+ COUNT_SPILLS;
+
+ disp = src->vv.regoff * 4;
+
+ M_ILD(tempreg, REG_SP, disp + 4);
+
+ reg = tempreg;
+ }
+ else
+ reg = GET_LOW_REG(src->vv.regoff);
+
+ return reg;
+}
+
+/* emit_nullpointer_check ******************************************************
+
+ Emit a NullPointerException check.
+
+*******************************************************************************/
+
+__PORTED__ void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg)
+{
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_TEST(reg);
+ M_BEQ(0);
+ codegen_add_nullpointerexception_ref(cd);
+ }
+}
+
+/* emit_arrayindexoutofbounds_check ********************************************
+
+ Emit a ArrayIndexOutOfBoundsException check.
+
+*******************************************************************************/
+
+void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
+{
+#if 0
+ if (INSTRUCTION_MUST_CHECK(iptr)) {
+ M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+ M_ICMP(REG_ITMP3, s2);
+ M_BAE(0);
+ codegen_add_arrayindexoutofboundsexception_ref(cd, s2);
+ }
+#endif
+}
+
/*
* These are local overrides for various environment variables in Emacs.
Changes:
- $Id: md-abi.c 7219 2007-01-16 22:18:57Z pm $
+ $Id: md-abi.c 7283 2007-02-04 19:41:14Z pm $
*/
/* register descripton array **************************************************/
s4 nregdescint[] = {
-#if 0
- REG_RET, REG_ARG, REG_ARG, REG_TMP, REG_RES, REG_SAV, REG_ARG, REG_ARG,
- REG_ARG, REG_ARG, REG_RES, REG_RES, REG_SAV, REG_SAV, REG_SAV, REG_SAV,
-#endif
- REG_TMP, REG_TMP, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_SAV,
- REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_TMP, REG_RES,
+ /* r0, itmp1, a0, a1, a2, a3, a4, s0, */
+ REG_TMP, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_SAV,
+ /* s1, s2, s3, s4, itmp2, pv, ra/itmp3, sp */
+ REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_RES, REG_RES, REG_RES,
REG_END
};
s4 nregdescfloat[] = {
-#if 0
- REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG,
- REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
-#endif
REG_ARG, REG_TMP, REG_ARG, REG_TMP, REG_SAV, REG_TMP, REG_SAV, REG_TMP,
REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
REG_END
Changes:
- $Id: md-abi.h 7219 2007-01-16 22:18:57Z pm $
+ $Id: md-abi.h 7283 2007-02-04 19:41:14Z pm $
*/
#define REG_RESULT R2 /* to deliver method results */
#define REG_RESULT2 R3
-#define REG_ITMP1 R0 /* temporary register */
-#define REG_ITMP2 R1 /* temporary register and method pointer */
-#define REG_ITMP3 R14 /* temporary register */
+#define REG_ITMP1 R1 /* temporary register */
+#define REG_ITMP2 R12 /* temporary register and method pointer */
+#define REG_ITMP3 R14 /* temporary register */
#define REG_ITMP12_PACKED PACK_REGS(REG_ITMP2, REG_ITMP1)
#define REG_ITMP23_PACKED PACK_REGS(REG_ITMP3, REG_ITMP2)
#define REG_ITMP2_XPC REG_ITMP2/* exception pc = temporary register 2 */
#define REG_SP R15 /* stack pointer */
+#define REG_RA R14 /* same as itmp3 */
#define REG_PV R13
#define INT_REG_CNT 16 /* number of integer registers */
-#define INT_SAV_CNT 6 /* number of integer callee saved registers */
+#define INT_SAV_CNT 5 /* number of integer callee saved registers */
#define INT_ARG_CNT 5 /* number of integer argument registers */
-#define INT_TMP_CNT 3 /* number of integer temporary registers */
-#define INT_RES_CNT 2 /* number of integer reserved registers */
+#define INT_TMP_CNT 1 /* number of integer temporary registers */
+#define INT_RES_CNT 5 /* number of integer reserved registers */
#define FLT_REG_CNT 16 /* number of float registers */
#define FLT_SAV_CNT 2 /* number of float callee saved registers */
Changes:
- $Id: md-asm.h 7219 2007-01-16 22:18:57Z pm $
+ $Id: md-asm.h 7283 2007-02-04 19:41:14Z pm $
*/
#define a4 %r6
#define sp %r15
-#define itmp1 %r0
-#define itmp2 %r1
+#define itmp1 %r1
+#define itmp2 %r12
#define itmp3 %r14
#define v0 %r2
#define pv %r13
#define s2 %r9
#define s3 %r10
#define s4 %r11
-#define s5 %r12
#define fa0 %f0
#define fa1 %f2
Changes: Edwin Steiner
- $Id: md.c 7219 2007-01-16 22:18:57Z pm $
+ $Id: md.c 7283 2007-02-04 19:41:14Z pm $
*/
#include "vm/jit/disass.h" /* XXX debug */
#endif
+#include <assert.h>
+#define OOPS() assert(0);
/* md_init *********************************************************************
void md_codegen_patch_branch(codegendata *cd, s4 branchmpc, s4 targetmpc)
{
+
s4 *mcodeptr;
s4 disp; /* branch displacement */
/* Calculate the branch displacement. */
disp = targetmpc - branchmpc;
+ disp += 4; /* size of branch */
+ disp /= 2; /* specified in halfwords */
- /* I don't think we have to check for branch-displacement
- overflow. +/-2GB should be enough. */
+ /* TODO check for overflow */
/* patch the branch instruction before the mcodeptr */
- mcodeptr[-1] = disp;
+ mcodeptr[-1] |= (disp & 0xFFFF);
}
{
u1 *ra;
- /* on x86_64 the return address is above the current stack frame */
+ /* on S390 the return address is located on the top of the stackframe */
+ /* TODO is this true? hope so, copyed from alpha */
- ra = *((u1 **) (sp + framesize));
+ ra = *((u1 **) (sp + framesize - SIZEOF_VOID_P));
return ra;
}
INVOKESTATIC/SPECIAL:
- 4d 8b 15 e2 fe ff ff mov -286(%rip),%r10
- 49 ff d2 rex64Z callq *%r10
+0x7748d7b2: a7 18 ff d4 lhi %r1,-44
+(load dseg offset)
+0x7748d7b6: 58 d1 d0 00 l %r13,0(%r1,%r13)
+(load pv)
+0x7748d7ba: 0d ed basr %r14,%r13
+(jump to pv)
INVOKEVIRTUAL:
- 4c 8b 17 mov (%rdi),%r10
- 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
- 48 ff d3 rex64 callq *%rax
+0x7748d82a: 58 c0 20 00 l %r12,0(%r2)
+(load mptr)
+0x7748d82e: 58 d0 c0 00 l %r13,0(%r12)
+(load pv from mptr)
+0x7748d832: 0d ed basr %r14,%r13
+(jump to pv)
+
INVOKEINTERFACE:
- 4c 8b 17 mov (%rdi),%r10
- 4d 8b 92 00 00 00 00 mov 0x0(%r10),%r10
- 49 8b 82 00 00 00 00 mov 0x0(%r10),%rax
- 48 ff d3 rex64 callq *%r11
+last 2 instructions the same as in invokevirtual
*******************************************************************************/
u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr)
{
- u1 mcode;
+ u1 base;
s4 offset;
u1 *pa; /* patch address */
- /* go back to the actual call instruction (3-bytes) */
+ /* go back to the load before the call instruction */
- ra = ra - 3;
+ ra = ra - 2 /* sizeof bcr */ - 4 /* sizeof l */;
- /* get the last byte of the call */
+ /* get the base register of the load */
- mcode = ra[2];
+ base = ra[2] >> 4;
/* check for the different calls */
- if (mcode == 0xd2) {
+ if (base == 0xd) { /* pv relative */
/* INVOKESTATIC/SPECIAL */
- /* Get the offset from the instruction (the offset address is
- 4-bytes before the call instruction). */
+ /* the offset is in the load before the load */
- offset = *((s4 *) (ra - 4));
+ offset = *((s2 *) (ra - 2));
- /* add the offset to the return address (IP-relative addressing) */
+ /* add the offset to the procedure vector */
- pa = ra + offset;
+ pa = sfi->pv + offset;
}
- else if (mcode == 0xd3) {
+ else if (base == 0xc) { /* mptr relative */
/* INVOKEVIRTUAL/INTERFACE */
- /* Get the offset from the instruction (the offset address is
- 4-bytes before the call instruction). */
-
- offset = *((s4 *) (ra - 4));
-
- /* add the offset to the method pointer */
+ offset = *((u2 *)(ra + 2)) & 0xFFF;
+ /* add offset to method pointer */
+
pa = mptr + offset;
}
else {
/* catch any problems */
-
- assert(0);
+ assert(0);
}
return pa;
Patch the given replacement point.
*******************************************************************************/
-
+#if 0
void md_patch_replacement_point(rplpoint *rp)
{
u8 mcode;
/* XXX if required asm_cacheflush(rp->pc,8); */
}
-
+#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