#include "vm/exceptions.h"
#include "vm/global.h"
+#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
/* 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, JITSTACK + (p * 8));
+ M_STX(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[p]), REG_SP, JITSTACK + (p * 8));
}
continue;
var = VAR(varindex);
-
- s1 = md->params[p].regoff;
- if (IS_INT_LNG_TYPE(t)) { /* integer args */
+ s1 = md->params[p].regoff;
+
+ if (IS_INT_LNG_TYPE(t)) { /* integer args */
+
if (!md->params[p].inmemory) { /* register arguments */
/*s2 = rd->argintregs[s1];*/
/*s2 = REG_WINDOW_TRANSPOSE(s2);*/
+
+ /* need the argument index here, not the register number */
+ s1 = md->params[p].regoff - abi_registers_integer_argument[0];
+
if (!(var->flags & INMEMORY)) { /* reg arg -> register */
- /*M_INTMOVE(s2, var->vv.regoff);*/
+ /*M_INTMOVE(s2, var->vv.regoff);*/
M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 8));
} else { /* reg arg -> spilled */
} else { /* floating args */
if (!md->params[p].inmemory) { /* register arguments */
- s2 = rd->argfltregs[s1];
if (!(var->flags & INMEMORY)) { /* reg arg -> register */
- M_FLTMOVE(s2, var->vv.regoff);
+ M_FLTMOVE(s1, var->vv.regoff);
} else { /* reg arg -> spilled */
- M_DST(s2, REG_SP, localbase + (var->vv.regoff) * 8);
+ M_DST(s1, REG_SP, localbase + (var->vv.regoff) * 8);
}
} else { /* stack arguments */
emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
s3 = emit_load_s3(jd, iptr, REG_ITMP3);
- M_MOV(s1, rd->argintregs[0]);
- M_MOV(s3, rd->argintregs[1]);
+ M_MOV(s1, REG_OUT0);
+ M_MOV(s3, REG_OUT1);
disp = dseg_add_functionptr(cd, BUILTIN_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
for (s3 = s3 - 1; s3 >= 0; s3--) {
var = VAR(iptr->sx.s23.s2.args[s3]);
- if (var->flags & PREALLOC)
- continue;
-
if (IS_FLT_DBL_TYPE(var->type)) {
if (!md->params[s3].inmemory) {
- s1 = md->params[s3].regoff; /*native flt args use regoff directly*/
+ s1 = s3; /*native flt args use argument index directly*/
d = emit_load(jd, iptr, var, REG_FTMP1);
M_DMOV(d, s1 + 16);
for (s3 = s3 - 1; s3 >= 0; s3--) {
var = VAR(iptr->sx.s23.s2.args[s3]);
+ d = md->params[s3].regoff;
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);
+ s1 = emit_load(jd, iptr, var, d);
+ M_INTMOVE(s1, d);
}
else {
- d = emit_load(jd, iptr, var, REG_ITMP1);
- M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
+ s1 = emit_load(jd, iptr, var, REG_ITMP1);
+ M_STX(s1, REG_SP, JITSTACK + d * 8);
}
}
else {
continue;
if (!md->params[s3].inmemory) {
- s1 = rd->argfltregs[md->params[s3].regoff];
- d = emit_load(jd, iptr, var, s1);
+ s1 = emit_load(jd, iptr, var, d);
if (IS_2_WORD_TYPE(var->type))
- M_DMOV(d, s1);
+ M_DMOV(s1, d);
else
- M_FMOV(d, s1);
+ M_FMOV(s1, d);
}
else {
- d = emit_load(jd, iptr, var, REG_FTMP1);
+ s1 = emit_load(jd, iptr, var, REG_FTMP1);
if (IS_2_WORD_TYPE(var->type))
- M_DST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
+ M_DST(s1, REG_SP, JITSTACK + d * 8);
else
- M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
+ M_FST(s1, REG_SP, JITSTACK + d * 8);
}
}
}
else {
/* array type cast-check */
- s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
- M_INTMOVE(s1, rd->argintregs[0]);
+ s1 = emit_load_s1(jd, iptr, REG_OUT0);
+ M_INTMOVE(s1, REG_OUT0);
disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
else
disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
- M_ALD(rd->argintregs[1], REG_PV, disp);
+ M_ALD(REG_OUT1, REG_PV, disp);
disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
M_ALD(REG_ITMP3, REG_PV, disp);
/* XXX jit-c-call */
methodinfo *m;
codeinfo *code;
codegendata *cd;
- registerdata *rd;
methoddesc *md;
s4 nativeparams;
s4 i, j; /* count variables */
m = jd->m;
code = jd->code;
cd = jd->cd;
- rd = jd->rd;
/* initialize variables */
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, CSTACK + (j * 8));
+ M_DST(abi_registers_float_argument[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, CSTACK + (j * 8));
+ M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
j++;
}
}
if (IS_INT_LNG_TYPE(t)) {
if (!md->params[i].inmemory) {
- s1 = rd->argintregs[md->params[i].regoff];
+ s1 = md->params[i].regoff;
/* s1 refers to the old window, transpose */
s1 = REG_WINDOW_TRANSPOSE(s1);
}
} else {
+ /*assert(false);*/
s1 = md->params[i].regoff + cd->stackframesize;
s2 = nmd->params[j].regoff - 6;
M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
} else {
if (!md->params[i].inmemory) {
- s1 = rd->argfltregs[md->params[i].regoff];
+ s1 = md->params[i].regoff;
if (!nmd->params[j].inmemory) {
/* no mapping to regs needed, native flt args use regoff */
}
} else {
+ /*assert(false);*/
s1 = md->params[i].regoff + cd->stackframesize;
s2 = nmd->params[j].regoff - 6;
if (IS_2_WORD_TYPE(t)) {
#include "vm/exceptions.h"
#include "vm/stringlocal.h" /* XXX for gen_resolvebranch */
+#include "vm/jit/abi.h"
#include "vm/jit/abi-asm.h"
#include "vm/jit/asmpart.h"
#include "vm/builtin.h"
/* get required compiler data */
cd = jd->cd;
- rd = jd->rd;
/* get source and destination variables */
/* save float argument registers */
for (i = 0; i < FLT_ARG_CNT; i++)
- M_DST(rd->argfltregs[i], REG_SP, JITSTACK + (1 + i) * 8);
+ M_DST(abi_registers_float_argument[i], REG_SP, JITSTACK + (1 + i) * 8);
/* save temporary registers for leaf methods */
/* XXX no leaf optimization yet
if (IS_INT_LNG_TYPE(t)) {
if (i < INT_ARG_CNT) {
- M_INTMOVE(REG_WINDOW_TRANSPOSE(rd->argintregs[i]), rd->argintregs[i]);
+ M_INTMOVE(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]),
+ abi_registers_integer_argument[i]);
}
else {
assert(i == 5);
}
}
else {
- assert(i < 4); /* XXX only 4 float reg args right now! */
+ assert(i < 5); /* XXX 5 float reg args right now! */
if (IS_2_WORD_TYPE(t)) {
- M_DST(rd->argfltregs[i], REG_SP, JITSTACK);
- M_LDX(rd->argintregs[i], REG_SP, JITSTACK);
+ M_DST(abi_registers_float_argument[i], REG_SP, JITSTACK);
+ M_LDX(abi_registers_integer_argument[i], REG_SP, JITSTACK);
}
else {
- M_FST(rd->argfltregs[i], REG_SP, JITSTACK);
- M_ILD(rd->argintregs[i], REG_SP, JITSTACK);
+ M_FST(abi_registers_float_argument[i], REG_SP, JITSTACK);
+ M_ILD(abi_registers_integer_argument[i], REG_SP, JITSTACK);
}
}
}
/* restore float argument registers */
for (i = 0; i < FLT_ARG_CNT; i++)
- M_DLD(rd->argfltregs[i], REG_SP, JITSTACK + (1 + i) * 8);
+ M_DLD(abi_registers_float_argument[i], REG_SP, JITSTACK + (1 + i) * 8);
/* restore temporary registers for leaf methods */
/* XXX no leaf optimization yet
M_DST(REG_FRESULT, REG_SP, JITSTACK);
- M_MOV(REG_RESULT_CALLEE, rd->argintregs[0]);
+ M_MOV(REG_RESULT_CALLEE, REG_OUT0);
M_DMOV(REG_FRESULT, 1); /* logical dreg 1 => f2 */
M_FMOV(REG_FRESULT, 2); /* logical freg 2 => f5 */
disp = dseg_add_functionptr(cd, m);
- M_ALD(rd->argintregs[3], REG_PV_CALLEE, disp);
+ M_ALD(REG_OUT3, REG_PV_CALLEE, disp);
disp = dseg_add_functionptr(cd, builtin_verbosecall_exit);
M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
/* i0/v0 i1 i2 i3 i4 pv/i5 fp/i6 ra/i7 */
REG_RET, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_RES, REG_RES, REG_RES,
REG_END
-
-
};
const char *abi_registers_integer_name[] = {
"i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
};
+const s4 abi_registers_integer_argument[] = {
+ 8, /* o0 */
+ 9, /* o1 */
+ 10, /* o2 */
+ 11, /* o3 */
+ 12, /* o4 */
+};
+
+const s4 abi_registers_integer_saved[] = {
+ 16, /* l0 */
+ 17, /* l1 */
+ 18, /* l2 */
+ 19, /* l3 */
+ 20, /* l4 */
+ 21, /* l5 */
+ 22, /* l6 */
+ 23, /* l7 */
+ 25, /* i1 */
+ 26, /* i2 */
+ 27, /* i3 */
+ 28, /* i4 */
+};
+
+const s4 abi_registers_integer_temporary[] = {
+};
+
+
s4 nregdescfloat[] = {
REG_RET, REG_RES, REG_RES, REG_RES, REG_TMP, REG_TMP, REG_TMP, REG_TMP,
REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP,
};
+const s4 abi_registers_float_argument[] = {
+ 8, /* f16 */
+ 9, /* f18 */
+ 10, /* f20 */
+ 11, /* f22 */
+ 12, /* f24 */
+};
+
+const s4 abi_registers_float_saved[] = {
+};
+
+const s4 abi_registers_float_temporary[] = {
+ 4, /* f8 */
+ 5, /* f10 */
+ 6, /* f12 */
+ 7, /* f14 */
+ 13, /* f26 */
+ 14, /* f28 */
+ 15, /* f30 */
+};
+
s4 nat_argintregs[] = {
REG_OUT0, REG_OUT1, REG_OUT2, REG_OUT3, REG_OUT4, REG_OUT5
};
case TYPE_LNG:
if (i < INT_ARG_CNT) {
pd->inmemory = false;
- pd->regoff = reguse;
+ pd->regoff = abi_registers_integer_argument[reguse];
reguse++;
md->argintreguse = reguse;
-
- } else {
+ }
+ else {
pd->inmemory = true;
pd->regoff = stacksize;
stacksize++;
}
break;
+
case TYPE_FLT:
case TYPE_DBL:
if (i < FLT_ARG_CNT) {
pd->inmemory = false;
- pd->regoff = reguse;
+ pd->regoff = abi_registers_float_argument[reguse];
reguse++;
md->argfltreguse = reguse;
- } else {
+ }
+ else {
pd->inmemory = true;
pd->regoff = stacksize;
stacksize++;