/* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
J. Wenninger, Institut f. Computersprachen - TU Wien
Authors: Andreas Krall
Reinhard Grafl
Alexander Jordan
-
- Changes: Edwin Steiner
+ Edwin Steiner
$Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
*/
#define REG_PV REG_PV_CALLEE
+bool fits_13(s4 disp)
+{
+ /* printf("fits disp %d?\n", disp); */
+
+ return (disp >= -4096) && (disp <= 4095);
+}
/* codegen *********************************************************************
methoddesc *md;
fieldinfo *fi;
unresolved_field *uf;
- rplpoint *replacementpoint;
s4 fieldtype;
s4 varindex;
#if 0 /* no leaf optimization yet */
savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
#endif
- savedregs_num = 16; /* register-window save area */
+ savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
/* space to save used callee saved registers */
cd->stackframesize++;
#endif
+ /* keep stack 16-byte aligned (ABI requirement) */
+
+ if (cd->stackframesize & 1)
+ cd->stackframesize++;
+
/* create method header */
(void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
md = m->parseddesc;
/* when storing locals, use this as base */
- localbase = USESTACK;
+ localbase = JITSTACK;
/* since the register allocator does not know about the shifting window
* arg regs need to be copied via the stack
localbase += INT_ARG_CNT * 8;
+ /* XXX could use the param slots on the stack for this! */
for (p = 0; p < INT_ARG_CNT; p++)
- M_STX(REG_WINDOW_TRANSPOSE(rd->argintregs[p]), REG_SP, USESTACK + (p * 8));
+ M_STX(REG_WINDOW_TRANSPOSE(rd->argintregs[p]), REG_SP, JITSTACK + (p * 8));
}
/*s2 = REG_WINDOW_TRANSPOSE(s2);*/
if (!(var->flags & INMEMORY)) { /* reg arg -> register */
/*M_INTMOVE(s2, var->vv.regoff);*/
- M_LDX(var->vv.regoff, REG_SP, USESTACK + (s1 * 8));
+ M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 8));
} else { /* reg arg -> spilled */
/*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
- M_LDX(REG_ITMP1, REG_SP, USESTACK + (s1 * 8));
+ M_LDX(REG_ITMP1, REG_SP, JITSTACK + (s1 * 8));
M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
}
} else { /* stack arguments */
if (!(var->flags & INMEMORY)) { /* stack arg -> register */
- M_LDX(var->vv.regoff, REG_FP, (WINSAVE_CNT + s1) * 8);
+ M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
} else { /* stack arg -> spilled */
- assert(0); /* XXX winsave area in between */
- var->vv.regoff = cd->stackframesize + s1;
+ /* add the callers window save registers */
+ var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
}
}
} else { /* stack arguments */
if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
- M_DLD(var->vv.regoff, REG_FP, (WINSAVE_CNT + s1) * 8);
+ M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
} else { /* stack-arg -> spilled */
- assert(0); /* XXX winsave area in between */
- var->vv.regoff = cd->stackframesize + s1;
+ var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
}
}
}
/* end of header generation */
- replacementpoint = jd->code->rplpoints;
+ /* create replacement points */
+
+ REPLACEMENT_POINTS_INIT(cd, jd);
/* walk through all basic blocks */
MCODECHECK(64+len);
#if defined(ENABLE_LSRA)
+#error XXX LSRA not tested yet
if (opt_lsra) {
while (len) {
len--;
var = VAR(bptr->invars[len]);
if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
d = codegen_reg_of_var(0, var, REG_ITMP1);
- M_INTMOVE(REG_ITMP1, d);
+ M_INTMOVE(REG_ITMP2_XPTR, d);
emit_store(jd, NULL, var, d);
}
else {
case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- emit_nullpointer_check(cd, s1);
+ emit_nullpointer_check(cd, iptr, s1);
break;
/* constant operations ************************************************/
break;
case ICMD_INT2CHAR: /* ..., value ==> ..., value */
- case ICMD_INT2SHORT:
+
+ s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+ M_SLLX_IMM(s1, 48, d);
+ M_SRLX_IMM( d, 48, d);
+ emit_store_dst(jd, iptr, d);
+ break;
+
+ case ICMD_INT2SHORT: /* ..., value ==> ..., value */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
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);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, iptr, s2);
M_ISEXT(s1, s1);
/* XXX trim s2 like s1 ? */
M_DIVX(s1, s2, d);
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);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, iptr, s2);
M_DIVX(s1, s2, d);
emit_store_dst(jd, iptr, d);
break;
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);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, iptr, s2);
M_ISEXT(s1, s1);
/* XXX trim s2 like s1 ? */
M_DIVX(s1, s2, d);
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);
- gen_div_check(s2);
+ emit_arithmetic_check(cd, iptr, s2);
M_DIVX(s1, s2, d);
M_MULX(s2, d, d);
M_SUB(s1, d, d);
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
M_FCMP(s1,s2);
- M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
- M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
- M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
+ M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
+ M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+ M_CMOVFGT_IMM(1, d); /* 1 if greater */
emit_store_dst(jd, iptr, d);
break;
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
M_DCMP(s1,s2);
- M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
- M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
- M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
+ M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
+ M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+ M_CMOVFGT_IMM(1, d); /* 1 if greater */
emit_store_dst(jd, iptr, d);
break;
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
M_FCMP(s1,s2);
- M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
- M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
- M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
+ M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
+ M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+ M_CMOVFLT_IMM(-1, d); /* -1 if less */
emit_store_dst(jd, iptr, d);
break;
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
M_DCMP(s1,s2);
- M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
- M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
- M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
+ M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
+ M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+ M_CMOVFLT_IMM(-1, d); /* -1 if less */
emit_store_dst(jd, iptr, d);
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
M_ILD(d, s1, OFFSET(java_arrayheader, size));
emit_store_dst(jd, iptr, d);
break;
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);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP3);
- M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+ M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
emit_store_dst(jd, iptr, d);
break;
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);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP3);
M_AADD(s2, REG_ITMP3, REG_ITMP3);
M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
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);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP3);
M_AADD(s2, REG_ITMP3, REG_ITMP3);
- M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+ M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
emit_store_dst(jd, iptr, d);
break;
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);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 2, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
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);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 2, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
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);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
M_AADD(REG_ITMP3, s1, REG_ITMP3);
M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP1);
M_AADD(s2, REG_ITMP1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
s3 = emit_load_s3(jd, iptr, REG_FTMP1);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
M_MOV(s1, rd->argintregs[0]);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP1);
M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
break;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_AADD(s2, s1, REG_ITMP1);
M_AADD(s2, REG_ITMP1, REG_ITMP1);
M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 2, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, 3, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- if (INSTRUCTION_MUST_CHECK(iptr)) {
- gen_nullptr_check(s1);
- gen_bound_check;
- }
+ emit_array_checks(cd, iptr, s1, s2);
M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
M_AADD(REG_ITMP2, s1, REG_ITMP1);
M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
case ICMD_GETFIELD: /* ... ==> ..., value */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
uf = iptr->sx.s23.s3.uf;
/* following NOP) */
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
- gen_nullptr_check(s1);
+ emit_nullpointer_check(cd, iptr, s1);
if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
unresolved_field *uf = iptr->sx.s23.s3.uf;
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
- M_BLTZ(s1, 0);
+ M_BGTZ(s1, 0);
} else {
if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
M_CMP_IMM(s1, iptr->sx.val.l);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
if (iptr->sx.val.l == 0) {
- M_BLEZ(s1, 0);
- }
+ M_BGEZ(s1, 0);
+ }
else {
if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
M_CMP_IMM(s1, iptr->sx.val.l);
- }
+ }
else {
ICONST(REG_ITMP2, iptr->sx.val.l);
M_CMP(s1, REG_ITMP2);
/* range check */
if (i <= 4095) {
- M_CMP_IMM(REG_ITMP1, i);
+ M_CMP_IMM(REG_ITMP1, i - 1);
}
else {
- ICONST(REG_ITMP2, i);
+ ICONST(REG_ITMP2, i - 1);
M_CMP(REG_ITMP1, REG_ITMP2);
}
- M_XBULT(0);
+ M_XBUGT(0);
codegen_add_branch_ref(cd, table[0].block); /* default target */
M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
}
else {
d = emit_load(jd, iptr, var, REG_ITMP1);
- M_STX(d, REG_SP, md->params[s3].regoff * 8);
+ M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
}
}
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, JITSTACK + md->params[s3].regoff * 8);
else
- M_FST(d, REG_SP, md->params[s3].regoff * 8);
+ M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
}
}
}
M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
s1 = REG_PV_CALLER;
- /* c call, allocate parameter array */
- M_LDA(REG_SP, REG_SP, -(ABI_PARAMARRAY_SLOTS) * 8);
+ /* XXX jit-c-call */
break;
break;
case ICMD_INVOKEVIRTUAL:
- gen_nullptr_check(REG_OUT0);
+ emit_nullpointer_check(cd, iptr, REG_OUT0);
if (lm == NULL) {
codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
break;
case ICMD_INVOKEINTERFACE:
- gen_nullptr_check(rd->argintregs[0]);
+ emit_nullpointer_check(cd, iptr, REG_OUT0);
if (lm == NULL) {
codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
/* REG_RA holds the value of the jmp instruction, therefore +8 */
M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
- if (iptr->opc == ICMD_BUILTIN) {
- /* remove param slots */
- M_LDA(REG_SP, REG_SP, (ABI_PARAMARRAY_SLOTS) * 8);
- }
-
/* actually only used for ICMD_BUILTIN */
M_ALD(rd->argintregs[1], REG_PV, disp);
disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_LDA(REG_SP, -6*8, REG_SP); /* PARAMARRAY SLOTS */
+ /* XXX jit-c-call */
M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
M_NOP;
- M_LDA(REG_SP, 6*8, REG_SP);
s1 = emit_load_s1(jd, iptr, REG_ITMP1);
M_BEQZ(REG_RESULT_CALLER, 0);
case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
- /* val.a: (classinfo*) superclass */
-
/* superclass is an interface:
*
* return (sub != NULL) &&
default:
- *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+ exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+ iptr->opc);
return false;
} /* switch */
#if !defined(WITH_STATIC_CLASSPATH)
if (f == NULL) {
- codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
-
- if (opt_showdisassemble) {
- M_NOP; M_NOP;
- }
+ codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
}
#endif
for (i = 0, j = 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);
+ M_DST(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
j++;
}
}
for (i = 0, j = 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);
+ M_DLD(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
j++;
}
}
M_INTMOVE(s1, s2);
} else {
s2 = nmd->params[j].regoff;
- M_AST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+ M_AST(s1, REG_SP, CSTACK + s2 * 8);
}
} else {
s1 = md->params[i].regoff + cd->stackframesize;
s2 = nmd->params[j].regoff;
- M_ALD(REG_ITMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
- M_AST(REG_ITMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+ M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
+ M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
}
} else {
} else {
s2 = nmd->params[j].regoff;
if (IS_2_WORD_TYPE(t))
- M_DST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+ M_DST(s1, REG_SP, CSTACK + (s2 * 8));
else
- M_FST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+ M_FST(s1, REG_SP, CSTACK + (s2 * 8));
}
} 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, USESTACK_PARAMS + s1 * 8);
- M_DST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+ M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
+ M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
} else {
- M_FLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
- M_FST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+ M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
+ M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
}
}
}
if (IS_INT_LNG_TYPE(md->returntype.type))
M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
else
- M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+ M_DST(REG_FRESULT, REG_SP, CSTACK);
}
/* Note: native functions return float values in %f0 (see ABI) */
/* But for the trace function we need to put a flt result into %f1 */
if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
if (!IS_2_WORD_TYPE(md->returntype.type))
- M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+ M_FLD(REG_FRESULT, REG_SP, CSTACK);
emit_verbosecall_exit(jd);
}
#endif
if (md->returntype.type != TYPE_VOID) {
if (IS_FLT_DBL_TYPE(md->returntype.type)) {
if (IS_2_WORD_TYPE(md->returntype.type))
- M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+ M_DLD(REG_FRESULT, REG_SP, CSTACK);
else
- M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+ M_FLD(REG_FRESULT, REG_SP, CSTACK);
}
}