Christian Ullrich
Edwin Steiner
- $Id: codegen.c 5162 2006-07-19 13:07:00Z tbfg $
+ $Id: codegen.c 5323 2006-09-05 16:45:24Z edwin $
*/
#endif
-void codegen_trace_args(jitdata *jd, s4 stackframesize, bool nativestub);
-
/* codegen *********************************************************************
Generates machine code.
/* space to save used callee saved registers */
savedregs_num += (INT_SAV_CNT - rd->savintreguse);
- savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
+ savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
stackframesize = rd->memuse + savedregs_num;
#if defined(ENABLE_THREADS)
/* space to save argument of monitor_enter and Return Values to survive */
/* monitor_exit. The stack position for the argument can not be shared */
- /* with place to save the return register on PPC, since both values */
+ /* with place to save the return register on PPC64, since both values */
/* reside in R3 */
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
/* reserve 2 slots for long/double return values for monitorexit */
-
- if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
- stackframesize += 3;
- else
- stackframesize += 2;
+ stackframesize += 2;
}
#endif
/* stackframesize = 0; */
(void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, stackframesize * 4); /* FrameSize */
+ (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
#if defined(ENABLE_THREADS)
/* IsSync contains the offset relative to the stack pointer for the
*/
if (checksync && (m->flags & ACC_SYNCHRONIZED))
- (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
+ (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
else
#endif
(void) dseg_adds4(cd, 0); /* IsSync */
}
if (stackframesize)
- M_STWU(REG_SP, REG_SP, -stackframesize * 4);
+ M_STDU(REG_SP, REG_SP, -stackframesize * 8);
/* save return address and used callee saved registers */
p = stackframesize;
for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
- p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
+ p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
}
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
- p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
+ p --; M_DST(rd->savfltregs[i], REG_SP, p * 8);
}
/* take arguments out of register or stack frame */
s2 = rd->argintregs[s1];
if (!md->params[p].inmemory) { /* register arguments */
if (!(var->flags & INMEMORY)) { /* reg arg -> register */
- if (IS_2_WORD_TYPE(t))
+ M_NOP;
+ if (IS_2_WORD_TYPE(t)) /* FIXME, only M_INTMOVE here */
M_LNGMOVE(s2, var->regoff);
else
M_INTMOVE(s2, var->regoff);
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
p = dseg_addaddress(cd, LOCK_monitor_enter);
M_ALD(REG_ITMP3, REG_PV, p);
+ M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
/* get or test the lock object */
codegen_add_nullpointerexception_ref(cd);
}
- M_AST(rd->argintregs[0], REG_SP, rd->memuse * 4);
+ M_AST(rd->argintregs[0], REG_SP, rd->memuse * 8);
M_JSR;
}
#endif
/* call trace function */
if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- codegen_trace_args(jd, stackframesize, false);
+ emit_verbosecall_enter(jd);
+
}
/* end of header generation */
src = bptr->instack;
len = bptr->icount;
currentline = 0;
-
+
for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
if (iptr->line != currentline) {
dseg_addlinenumber(cd, iptr->line);
MCODECHECK(64); /* an instruction usually needs < 64 words */
+ M_NOP; M_NOP; /* XXX */
switch (iptr->opc) {
case ICMD_NOP: /* ... ==> ... */
case ICMD_INLINE_START:
case ICMD_LCONST: /* ... ==> ..., constant */
/* op1 = 0, val.l = constant */
- d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
+ d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
LCONST(d, iptr->val.l);
emit_store(jd, iptr, iptr->dst, d);
break;
case ICMD_ACONST: /* ... ==> ..., constant */
/* op1 = 0, val.a = constant */
-
d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
disp = dseg_addaddress(cd, iptr->val.a);
/* load/store operations **********************************************/
case ICMD_ILOAD: /* ... ==> ..., content of local variable */
- case ICMD_ALOAD: /* op1 = local variable */
var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
emit_store(jd, iptr, iptr->dst, d);
break;
+ case ICMD_ALOAD: /* op1 = local variable */
case ICMD_LLOAD: /* ... ==> ..., content of local variable */
/* op1 = local variable */
disp = dseg_addaddress(cd, BUILTIN_canstore);
M_ALD(REG_ITMP3, REG_PV, disp);
+ M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(REG_ITMP3);
M_INTMOVE(s1, rd->argintregs[0]);
M_ALD(REG_ITMP1, REG_PV, disp);
switch (iptr->op1) {
case TYPE_INT:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_IST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_IST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_LNG:
- s2 = emit_load_s2(jd, iptr, src, PACK_REGS(REG_ITMP2, REG_ITMP3));
- M_LST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_LST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_ADR:
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- M_AST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
+ M_AST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_FLT:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_FST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_FST_INTERN(s1, REG_ITMP1, 0);
break;
case TYPE_DBL:
- s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
- M_DST_INTERN(s2, REG_ITMP1, 0);
+ s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
+ M_DST_INTERN(s1, REG_ITMP1, 0);
break;
}
break;
M_ILD(d, s1, disp);
break;
case TYPE_LNG:
- d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
- if (GET_HIGH_REG(d) == s1) {
- M_ILD(GET_LOW_REG(d), s1, disp + 4);
- M_ILD(GET_HIGH_REG(d), s1, disp);
- } else {
- M_ILD(GET_HIGH_REG(d), s1, disp);
- M_ILD(GET_LOW_REG(d), s1, disp + 4);
- }
+ d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
+ M_LLD(d, s1, disp);
break;
case TYPE_ADR:
d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
gen_nullptr_check(s1);
if (!IS_FLT_DBL_TYPE(iptr->op1)) {
- if (IS_2_WORD_TYPE(iptr->op1)) {
- s2 = emit_load_s2(jd, iptr, src, PACK_REGS(REG_ITMP2, REG_ITMP3));
- } else {
- s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
- }
+ s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
} else {
s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
}
M_IST(s2, s1, disp);
break;
case TYPE_LNG:
- M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
- M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
+ M_LST(s2, s1, disp);
break;
case TYPE_ADR:
M_AST(s2, s1, disp);
case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
- M_INTMOVE(s1, REG_ITMP1_XPTR);
+ M_LNGMOVE(s1, REG_ITMP1_XPTR);
#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
codegen_addreference(cd, (basicblock *) iptr->target);
break;
+ case ICMD_LRETURN: /* ..., retvalue ==> ... */
case ICMD_IRETURN: /* ..., retvalue ==> ... */
s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
- M_INTMOVE(s1, REG_RESULT);
+ M_LNGMOVE(s1, REG_RESULT);
goto nowperformreturn;
case ICMD_ARETURN: /* ..., retvalue ==> ... */
s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
- M_INTMOVE(s1, REG_RESULT);
+ M_LNGMOVE(s1, REG_RESULT);
#ifdef ENABLE_VERIFIER
if (iptr->val.a) {
M_NOP;
}
#endif /* ENABLE_VERIFIER */
- goto nowperformreturn;
-
- case ICMD_LRETURN: /* ..., retvalue ==> ... */
- /*s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_RESULT2, REG_RESULT)); FIXME*/
- /*M_LNGMOVE(s1, PACK_REGS(REG_RESULT2, REG_RESULT)); FIXME*/
goto nowperformreturn;
case ICMD_FRETURN: /* ..., retvalue ==> ... */
/* call trace function */
if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
- M_MFLR(REG_ZERO);
- M_LDA(REG_SP, REG_SP, -10 * 8);
- M_DST(REG_FRESULT, REG_SP, 48+0);
- M_IST(REG_RESULT, REG_SP, 48+8);
- M_AST(REG_ZERO, REG_SP, 48+12);
- /*M_IST(REG_RESULT2, REG_SP, 48+16); FIXME*/
-
- /* keep this order */
- switch (iptr->opc) {
- case ICMD_IRETURN:
- case ICMD_ARETURN:
-#if defined(__DARWIN__)
- M_MOV(REG_RESULT, rd->argintregs[2]);
- M_CLR(rd->argintregs[1]);
-#else
- M_MOV(REG_RESULT, rd->argintregs[3]);
- M_CLR(rd->argintregs[2]);
-#endif
- break;
-
- case ICMD_LRETURN:
-#if defined(__DARWIN__)
- /*M_MOV(REG_RESULT2, rd->argintregs[2]); FIXME */
- M_MOV(REG_RESULT, rd->argintregs[1]);
-#else
- /*M_MOV(REG_RESULT2, rd->argintregs[3]); FIXME*/
- M_MOV(REG_RESULT, rd->argintregs[2]);
-#endif
- break;
- }
-
- disp = dseg_addaddress(cd, m);
- M_ALD(rd->argintregs[0], REG_PV, disp);
-
- M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
- M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
- disp = dseg_addaddress(cd, builtin_displaymethodstop);
- M_ALD(REG_ITMP2, REG_PV, disp);
- M_MTCTR(REG_ITMP2);
- M_JSR;
-
- M_DLD(REG_FRESULT, REG_SP, 48+0);
- M_ILD(REG_RESULT, REG_SP, 48+8);
- M_ALD(REG_ZERO, REG_SP, 48+12);
- /*M_ILD(REG_RESULT2, REG_SP, 48+16); FIXME*/
- M_LDA(REG_SP, REG_SP, 10 * 8);
- M_MTLR(REG_ZERO);
+ emit_verbosecall_exit(jd);
}
#if defined(ENABLE_THREADS)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
disp = dseg_addaddress(cd, LOCK_monitor_exit);
M_ALD(REG_ITMP3, REG_PV, disp);
+ M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
M_MTCTR(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); FIXME*/
- /* fall through */
case ICMD_IRETURN:
case ICMD_ARETURN:
- M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
+ /* fall through */
+ M_LST(REG_RESULT , REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_FRETURN:
- M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_DRETURN:
- M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
}
- M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 4);
+ M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
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); FIXME*/
- /* fall through */
case ICMD_IRETURN:
case ICMD_ARETURN:
- M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
+ /* fall through */
+ M_LLD(REG_RESULT , REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_FRETURN:
- M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
case ICMD_DRETURN:
- M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
+ M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
break;
}
}
/* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
may have a displacement overflow. */
- M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
+ M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
M_MTLR(REG_ITMP1);
}
/* restore saved registers */
for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
- p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
+ p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
}
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
- p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
+ p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
}
/* deallocate stack */
if (stackframesize)
- M_LDA(REG_SP, REG_SP, stackframesize * 4);
+ M_LDA(REG_SP, REG_SP, stackframesize * 8);
M_RET;
ALIGNCODENOP;
if (IS_INT_LNG_TYPE(src->type)) {
if (!md->params[s3].inmemory) {
if (IS_2_WORD_TYPE(src->type)) {
- s1 = PACK_REGS(
- rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
- rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]);
+ s1 = rd->argintregs[md->params[s3].regoff]; /* removed PACKREGS */
d = emit_load_s1(jd, iptr, src, s1);
M_LNGMOVE(d, s1);
} else {
} else {
if (IS_2_WORD_TYPE(src->type)) {
- d = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP2, REG_ITMP1));
- M_LST(d, REG_SP, md->params[s3].regoff * 4);
+ d = emit_load_s1(jd, iptr, src, REG_ITMP1);
+ M_LST(d, REG_SP, md->params[s3].regoff * 8); /* XXX */
} else {
d = emit_load_s1(jd, iptr, src, REG_ITMP1);
- M_IST(d, REG_SP, md->params[s3].regoff * 4);
+ M_LST(d, REG_SP, md->params[s3].regoff * 8);
}
}
} else {
d = emit_load_s1(jd, iptr, src, REG_FTMP1);
if (IS_2_WORD_TYPE(src->type))
- M_DST(d, REG_SP, md->params[s3].regoff * 4);
+ M_DST(d, REG_SP, md->params[s3].regoff * 8);
else
- M_FST(d, REG_SP, md->params[s3].regoff * 4);
+ M_FST(d, REG_SP, md->params[s3].regoff * 8);
}
}
} /* end of for */
disp = dseg_addaddress(cd, bte->fp);
d = md->returntype.type;
- M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
- M_MTCTR(REG_PV);
+ M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function descriptor */
+ M_ALD(REG_ITMP1, REG_PV, 0); /* function entry point address */
+ M_ALD(REG_ITMP2, REG_PV, 8); /* TOC of callee */
+ M_MOV(REG_TOC, REG_ITMP2); /* load TOC for callee */
+ M_MTCTR(REG_ITMP1);
M_JSR;
+ /* TODO: restore TOC */
disp = (s4) (cd->mcodeptr - cd->mcodebase);
M_MFLR(REG_ITMP1);
M_LDA(REG_PV, REG_ITMP1, -disp);
if (jd->isleafmethod) {
M_MFLR(REG_ZERO);
- M_AST(REG_ZERO, REG_SP, stackframesize * 4 + LA_LR_OFFSET);
+ M_AST(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
}
M_MOV(REG_PV, rd->argintregs[0]);
M_MOV(REG_ZERO, rd->argintregs[2]);
else
M_ALD(rd->argintregs[2],
- REG_SP, stackframesize * 4 + LA_LR_OFFSET);
+ REG_SP, stackframesize * 8 + LA_LR_OFFSET);
M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
M_MOV(REG_ITMP1, rd->argintregs[4]);
- M_STWU(REG_SP, REG_SP, -(LA_SIZE + 6 * 4));
- M_AST(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 4);
+ M_STDU(REG_SP, REG_SP, -(LA_SIZE + 6 * 8));
+ M_AST(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8);
M_MTCTR(REG_ITMP3);
M_JSR;
M_MOV(REG_RESULT, REG_ITMP1_XPTR);
- M_ALD(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 4);
- M_IADD_IMM(REG_SP, LA_SIZE + 6 * 4, REG_SP);
+ M_ALD(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8);
+ M_LADD_IMM(REG_SP, LA_SIZE + 6 * 8, REG_SP);
if (jd->isleafmethod) {
/* XXX FIXME: REG_ZERO can cause problems here! */
- assert(stackframesize * 4 <= 32767);
+ assert(stackframesize * 8 <= 32767);
- M_ALD(REG_ZERO, REG_SP, stackframesize * 4 + LA_LR_OFFSET);
+ M_ALD(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
M_MTLR(REG_ZERO);
}
/* create stack frame - keep stack 16-byte aligned */
- M_AADD_IMM(REG_SP, -8 * 4, REG_SP);
+ M_AADD_IMM(REG_SP, -8 * 8, REG_SP);
/* calculate return address and move it onto the stack */
M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
- M_AST_INTERN(REG_ITMP3, REG_SP, 5 * 4);
+ M_AST_INTERN(REG_ITMP3, REG_SP, 5 * 8);
/* move pointer to java_objectheader onto stack */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 4 * 4);
+ M_AST_INTERN(REG_ITMP3, REG_SP, 4 * 8);
#else
/* do nothing */
#endif
disp = dseg_adds4(cd, mcode);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST_INTERN(REG_ITMP3, REG_SP, 3 * 4);
+ M_IST_INTERN(REG_ITMP3, REG_SP, 3 * 8);
/* move class/method/field reference onto stack */
disp = dseg_addaddress(cd, pref->ref);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 2 * 4);
+ M_AST_INTERN(REG_ITMP3, REG_SP, 2 * 8);
/* move data segment displacement onto stack */
disp = dseg_addaddress(cd, pref->disp);
- M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST_INTERN(REG_ITMP3, REG_SP, 1 * 4);
+ M_LLD(REG_ITMP3, REG_PV, disp);
+ M_IST_INTERN(REG_ITMP3, REG_SP, 1 * 8);
/* move patcher function pointer onto stack */
disp = dseg_addaddress(cd, pref->patcher);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 4);
+ M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 8);
disp = dseg_addaddress(cd, asm_patcher_wrapper);
M_ALD(REG_ITMP3, REG_PV, disp);
stackframesize =
sizeof(stackframeinfo) / SIZEOF_VOID_P +
sizeof(localref_table) / SIZEOF_VOID_P +
- 4 + /* 4 stackframeinfo arguments (darwin)*/
- nmd->paramcount * 2 + /* assume all arguments are doubles */
+ 4 + /* 4 stackframeinfo arguments (darwin)*/
+ nmd->paramcount +
nmd->memuse;
stackframesize = (stackframesize + 3) & ~3; /* keep stack 16-byte aligned */
/* create method header */
(void) dseg_addaddress(cd, code); /* CodeinfoPointer */
- (void) dseg_adds4(cd, stackframesize * 4); /* FrameSize */
+ (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
(void) dseg_adds4(cd, 0); /* IsSync */
(void) dseg_adds4(cd, 0); /* IsLeaf */
(void) dseg_adds4(cd, 0); /* IntSave */
M_MFLR(REG_ZERO);
M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
- M_STWU(REG_SP, REG_SP, -(stackframesize * 4));
+ M_STDU(REG_SP, REG_SP, -(stackframesize * 8));
- if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
- /* parent_argbase == stackframesize * 4 */
- codegen_trace_args(jd, stackframesize * 4 , true);
+ if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
+ emit_verbosecall_enter(jd);
+ }
/* get function address (this must happen before the stackframeinfo) */
if (IS_INT_LNG_TYPE(t)) {
if (!md->params[i].inmemory) {
s1 = md->params[i].regoff;
- if (IS_2_WORD_TYPE(t)) {
- M_IST(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
- j++;
- M_IST(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
- } else {
- M_IST(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
- }
+ M_LST(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
j++;
}
}
if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
if (!md->params[i].inmemory) {
s1 = md->params[i].regoff;
- M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
+ M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
j++;
}
}
/* create native stack info */
- M_AADD_IMM(REG_SP, stackframesize * 4, rd->argintregs[0]);
+ M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
M_MOV(REG_PV, rd->argintregs[1]);
- M_AADD_IMM(REG_SP, stackframesize * 4, rd->argintregs[2]);
- M_ALD(rd->argintregs[3], REG_SP, stackframesize * 4 + LA_LR_OFFSET);
+ M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
+ M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 + LA_LR_OFFSET);
disp = dseg_addaddress(cd, codegen_start_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
+ M_ALD(REG_ITMP1, REG_ITMP1, 0); /* FIXME what about TOC? */
M_MTCTR(REG_ITMP1);
M_JSR;
+ M_NOP;
+ M_NOP;
+ M_NOP;
+
/* restore integer and float argument registers */
j = 0;
if (IS_INT_LNG_TYPE(t)) {
if (!md->params[i].inmemory) {
s1 = md->params[i].regoff;
-
- if (IS_2_WORD_TYPE(t)) {
- M_ILD(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
- j++;
- M_ILD(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
- } else {
- M_ILD(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
- }
+ M_LLD(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
j++;
}
}
if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
if (!md->params[i].inmemory) {
s1 = md->params[i].regoff;
- M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
+ M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
j++;
}
}
if (IS_INT_LNG_TYPE(t)) {
if (!md->params[i].inmemory) {
- if (IS_2_WORD_TYPE(t))
- s1 = PACK_REGS(
- rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
- rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
- else
- s1 = rd->argintregs[md->params[i].regoff];
+ s1 = rd->argintregs[md->params[i].regoff];
if (!nmd->params[j].inmemory) {
- if (IS_2_WORD_TYPE(t)) {
- s2 = PACK_REGS(
- rd->argintregs[GET_LOW_REG(nmd->params[j].regoff)],
- rd->argintregs[GET_HIGH_REG(nmd->params[j].regoff)]);
- M_LNGMOVE(s1, s2);
- } else {
- s2 = rd->argintregs[nmd->params[j].regoff];
- M_INTMOVE(s1, s2);
- }
-
+ s2 = rd->argintregs[nmd->params[j].regoff];
+ M_INTMOVE(s1, s2);
} else {
s2 = nmd->params[j].regoff;
- if (IS_2_WORD_TYPE(t))
- M_LST(s1, REG_SP, s2 * 4);
- else
- M_IST(s1, REG_SP, s2 * 4);
+ M_LST(s1, REG_SP, s2 * 8);
}
} else {
s1 = md->params[i].regoff + stackframesize;
s2 = nmd->params[j].regoff;
- M_ILD(REG_ITMP1, REG_SP, s1 * 4);
- if (IS_2_WORD_TYPE(t))
- M_ILD(REG_ITMP2, REG_SP, s1 * 4 + 4);
-
- M_IST(REG_ITMP1, REG_SP, s2 * 4);
- if (IS_2_WORD_TYPE(t))
- M_IST(REG_ITMP2, REG_SP, s2 * 4 + 4);
+ M_LLD(REG_ITMP1, REG_SP, s1 * 8);
+ M_LST(REG_ITMP1, REG_SP, s2 * 8);
}
} else {
s2 = nmd->params[j].regoff;
if (IS_2_WORD_TYPE(t)) {
- M_DLD(REG_FTMP1, REG_SP, s1 * 4);
- M_DST(REG_FTMP1, REG_SP, s2 * 4);
+ M_DLD(REG_FTMP1, REG_SP, s1 * 8);
+ M_DST(REG_FTMP1, REG_SP, s2 * 8);
} else {
- M_FLD(REG_FTMP1, REG_SP, s1 * 4);
- M_FST(REG_FTMP1, REG_SP, s2 * 4);
+ M_FLD(REG_FTMP1, REG_SP, s1 * 8);
+ M_FST(REG_FTMP1, REG_SP, s2 * 8);
}
}
}
/* generate the actual native call */
M_ALD(REG_ITMP3, REG_PV, funcdisp);
+ M_ALD(REG_ITMP3, REG_ITMP3, 0); /* XXX what about TOC ? */
M_MTCTR(REG_ITMP3);
M_JSR;
+ M_NOP;
+ M_NOP;
+ M_NOP;
+
/* save return value */
if (md->returntype.type != TYPE_VOID) {
if (IS_INT_LNG_TYPE(md->returntype.type)) {
- if (IS_2_WORD_TYPE(md->returntype.type))
- /*M_IST(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4); // FIXME*/
- M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
+ M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
}
else {
if (IS_2_WORD_TYPE(md->returntype.type))
- M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
+ M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
else
- M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
+ M_FST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); /* FIXME, needed ?*/
}
}
/* print call trace */
if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
- /* just restore the value we need, don't care about the other */
-
- if (md->returntype.type != TYPE_VOID) {
- if (IS_INT_LNG_TYPE(md->returntype.type)) {
- if (IS_2_WORD_TYPE(md->returntype.type))
- /*M_ILD(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4); FIXME*/
- M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
- }
- else {
- if (IS_2_WORD_TYPE(md->returntype.type))
- M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
- else
- M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
- }
- }
-
- M_LDA(REG_SP, REG_SP, -(LA_SIZE + (1 + 2 + 2 + 1) * 4));
-
- /* keep this order */
- switch (md->returntype.type) {
- case TYPE_INT:
- case TYPE_ADR:
-#if defined(__DARWIN__)
- M_MOV(REG_RESULT, rd->argintregs[2]);
- M_CLR(rd->argintregs[1]);
-#else
- M_MOV(REG_RESULT, rd->argintregs[3]);
- M_CLR(rd->argintregs[2]);
-#endif
- break;
-
- case TYPE_LNG:
-#if defined(__DARWIN__)
- /*M_MOV(REG_RESULT2, rd->argintregs[2]);FIXME*/
- M_MOV(REG_RESULT, rd->argintregs[1]);
-#else
- /*M_MOV(REG_RESULT2, rd->argintregs[3]);FIXME*/
- M_MOV(REG_RESULT, rd->argintregs[2]);
-#endif
- break;
- }
-
- M_FLTMOVE(REG_FRESULT, rd->argfltregs[0]);
- M_FLTMOVE(REG_FRESULT, rd->argfltregs[1]);
- disp = dseg_addaddress(cd, m);
- M_ALD(rd->argintregs[0], REG_PV, disp);
-
- disp = dseg_addaddress(cd, builtin_displaymethodstop);
- M_ALD(REG_ITMP2, REG_PV, disp);
- M_MTCTR(REG_ITMP2);
- M_JSR;
-
- M_LDA(REG_SP, REG_SP, LA_SIZE + (1 + 2 + 2 + 1) * 4);
+ emit_verbosecall_exit(jd);
}
/* remove native stackframe info */
- M_AADD_IMM(REG_SP, stackframesize * 4, rd->argintregs[0]);
+ M_NOP;
+ M_NOP;
+ M_NOP;
+
+ M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
disp = dseg_addaddress(cd, codegen_finish_native_call);
M_ALD(REG_ITMP1, REG_PV, disp);
+ M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */
M_MTCTR(REG_ITMP1);
M_JSR;
M_MOV(REG_RESULT, REG_ITMP1_XPTR);
if (md->returntype.type != TYPE_VOID) {
if (IS_INT_LNG_TYPE(md->returntype.type)) {
- if (IS_2_WORD_TYPE(md->returntype.type))
- /*M_ILD(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);FIXME*/
- M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
+ M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
}
else {
if (IS_2_WORD_TYPE(md->returntype.type))
- M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
+ M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
else
- M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
+ M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
}
}
- M_ALD(REG_ITMP2_XPC, REG_SP, stackframesize * 4 + LA_LR_OFFSET);
+ M_ALD(REG_ITMP2_XPC, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
M_MTLR(REG_ITMP2_XPC);
- M_LDA(REG_SP, REG_SP, stackframesize * 4); /* remove stackframe */
+ M_LDA(REG_SP, REG_SP, stackframesize * 8); /* remove stackframe */
/* check for exception */
/* handle exception */
- M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
+ M_LADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
disp = dseg_addaddress(cd, asm_handle_nat_exception);
M_ALD(REG_ITMP3, REG_PV, disp);
/* create stack frame - keep stack 16-byte aligned */
- M_AADD_IMM(REG_SP, -8 * 4, REG_SP);
+ M_AADD_IMM(REG_SP, -8 * 8, REG_SP);
/* move return address onto stack */
M_MFLR(REG_ZERO);
- M_AST(REG_ZERO, REG_SP, 5 * 4);
+ M_AST(REG_ZERO, REG_SP, 5 * 8);
/* move pointer to java_objectheader onto stack */
disp = dseg_addaddress(cd, NULL); /* vftbl */
M_LDA(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, 4 * 4);
+ M_AST(REG_ITMP3, REG_SP, 4 * 8);
#else
/* do nothing */
#endif
disp = dseg_adds4(cd, mcode);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST(REG_ITMP3, REG_SP, 3 * 4);
+ M_IST(REG_ITMP3, REG_SP, 3 * 8);
/* move class/method/field reference onto stack */
disp = dseg_addaddress(cd, pref->ref);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, 2 * 4);
+ M_AST(REG_ITMP3, REG_SP, 2 * 8);
/* move data segment displacement onto stack */
- disp = dseg_addaddress(cd, pref->disp);
+ disp = dseg_adds4(cd, pref->disp);
M_ILD(REG_ITMP3, REG_PV, disp);
- M_IST(REG_ITMP3, REG_SP, 1 * 4);
+ M_IST(REG_ITMP3, REG_SP, 1 * 8);
/* move patcher function pointer onto stack */
disp = dseg_addaddress(cd, pref->patcher);
M_ALD(REG_ITMP3, REG_PV, disp);
- M_AST(REG_ITMP3, REG_SP, 0 * 4);
+ M_AST(REG_ITMP3, REG_SP, 0 * 8);
disp = dseg_addaddress(cd, asm_patcher_wrapper);
M_ALD(REG_ITMP3, REG_PV, disp);
}
-void codegen_trace_args(jitdata *jd, s4 stackframesize, bool nativestub)
-{
- methodinfo *m;
- codegendata *cd;
- registerdata *rd;
- s4 s1, p, t, d;
- int stack_off;
- int stack_size;
- methoddesc *md;
-
- /* get required compiler data */
-
- m = jd->m;
- cd = jd->cd;
- rd = jd->rd;
-
- md = m->parseddesc;
-
- if (!nativestub)
- M_MFLR(REG_ITMP3);
- /* Build up Stackframe for builtin_trace_args call (a multiple of 16) */
- /* For Darwin: */
- /* LA + TRACE_ARGS_NUM u8 args + methodinfo + LR */
- /* LA_SIZE(=6*4) + 8*8 + 4 + 4 + 0(Padding) */
- /* 6 * 4 + 8 * 8 + 2 * 4 = 12 * 8 = 6 * 16 */
- /* For Linux: */
- /* LA + (TRACE_ARGS_NUM - INT_ARG_CNT/2) u8 args + methodinfo */
- /* + INT_ARG_CNT * 4 ( save integer registers) + LR + 8 + 8 (Padding) */
- /* LA_SIZE(=2*4) + 4 * 8 + 4 + 8 * 4 + 4 + 8 */
- /* 2 * 4 + 4 * 8 + 10 * 4 + 1 * 8 + 8= 12 * 8 = 6 * 16 */
-
- /* in nativestubs no Place to save the LR (Link Register) would be needed */
- /* but since the stack frame has to be aligned the 4 Bytes would have to */
- /* be padded again */
-
-#if defined(__DARWIN__)
- stack_size = LA_SIZE + (TRACE_ARGS_NUM + 1) * 8;
-#else
- stack_size = 6 * 16;
-#endif
- M_LDA(REG_SP, REG_SP, -stack_size);
-
- /* Save LR */
- if (!nativestub)
- M_IST(REG_ITMP3, REG_SP, LA_SIZE + TRACE_ARGS_NUM * 8 + 1 * 4);
-
- M_CLR(REG_ITMP1); /* clear help register */
-
- /* save up to TRACE_ARGS_NUM arguments into the reserved stack space */
-#if defined(__DARWIN__)
- /* Copy Params starting from first to Stack */
- /* since TRACE_ARGS == INT_ARG_CNT all used integer argument regs */
- /* are saved */
- p = 0;
-#else
- /* Copy Params starting from fifth to Stack (INT_ARG_CNT/2) are in */
- /* integer argument regs */
- /* all integer argument registers have to be saved */
- for (p = 0; p < 8; p++) {
- d = rd->argintregs[p];
- /* save integer argument registers */
- M_IST(d, REG_SP, LA_SIZE + 4 * 8 + 4 + p * 4);
- }
- p = 4;
-#endif
- stack_off = LA_SIZE;
- for (; p < md->paramcount && p < TRACE_ARGS_NUM; p++, stack_off += 8) {
- t = md->paramtypes[p].type;
- if (IS_INT_LNG_TYPE(t)) {
- if (!md->params[p].inmemory) { /* Param in Arg Reg */
- if (IS_2_WORD_TYPE(t)) {
- M_IST(rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]
- , REG_SP, stack_off);
- M_IST(rd->argintregs[GET_LOW_REG(md->params[p].regoff)]
- , REG_SP, stack_off + 4);
- } else {
- M_IST(REG_ITMP1, REG_SP, stack_off);
- M_IST(rd->argintregs[md->params[p].regoff]
- , REG_SP, stack_off + 4);
- }
- } else { /* Param on Stack */
- s1 = (md->params[p].regoff + stackframesize) * 4
- + stack_size;
- if (IS_2_WORD_TYPE(t)) {
- M_ILD(REG_ITMP2, REG_SP, s1);
- M_IST(REG_ITMP2, REG_SP, stack_off);
- M_ILD(REG_ITMP2, REG_SP, s1 + 4);
- M_IST(REG_ITMP2, REG_SP, stack_off + 4);
- } else {
- M_IST(REG_ITMP1, REG_SP, stack_off);
- M_ILD(REG_ITMP2, REG_SP, s1);
- M_IST(REG_ITMP2, REG_SP, stack_off + 4);
- }
- }
- } else { /* IS_FLT_DBL_TYPE(t) */
- if (!md->params[p].inmemory) { /* in Arg Reg */
- s1 = rd->argfltregs[md->params[p].regoff];
- if (!IS_2_WORD_TYPE(t)) {
- M_IST(REG_ITMP1, REG_SP, stack_off);
- M_FST(s1, REG_SP, stack_off + 4);
- } else {
- M_DST(s1, REG_SP, stack_off);
- }
- } else { /* on Stack */
- /* this should not happen */
- }
- }
- }
-
- /* load first 4 (==INT_ARG_CNT/2) arguments into integer registers */
-#if defined(__DARWIN__)
- for (p = 0; p < 8; p++) {
- d = rd->argintregs[p];
- M_ILD(d, REG_SP, LA_SIZE + p * 4);
- }
-#else
- /* LINUX */
- /* Set integer and float argument registers vor trace_args call */
- /* offset to saved integer argument registers */
- stack_off = LA_SIZE + 4 * 8 + 4;
- for (p = 0; (p < 4) && (p < md->paramcount); p++) {
- t = md->paramtypes[p].type;
- if (IS_INT_LNG_TYPE(t)) {
- /* "stretch" int types */
- if (!IS_2_WORD_TYPE(t)) {
- M_CLR(rd->argintregs[2 * p]);
- M_ILD(rd->argintregs[2 * p + 1], REG_SP,stack_off);
- stack_off += 4;
- } else {
- M_ILD(rd->argintregs[2 * p + 1], REG_SP,stack_off + 4);
- M_ILD(rd->argintregs[2 * p], REG_SP,stack_off);
- stack_off += 8;
- }
- } else { /* Float/Dbl */
- if (!md->params[p].inmemory) { /* Param in Arg Reg */
- /* use reserved Place on Stack (sp + 5 * 16) to copy */
- /* float/double arg reg to int reg */
- s1 = rd->argfltregs[md->params[p].regoff];
- if (!IS_2_WORD_TYPE(t)) {
- M_FST(s1, REG_SP, 5 * 16);
- M_ILD(rd->argintregs[2 * p + 1], REG_SP, 5 * 16);
- M_CLR(rd->argintregs[2 * p]);
- } else {
- M_DST(s1, REG_SP, 5 * 16);
- M_ILD(rd->argintregs[2 * p + 1], REG_SP, 5 * 16 + 4);
- M_ILD(rd->argintregs[2 * p], REG_SP, 5 * 16);
- }
- }
- }
- }
-#endif
-
- /* put methodinfo pointer on Stackframe */
- p = dseg_addaddress(cd, m);
- M_ALD(REG_ITMP1, REG_PV, p);
-#if defined(__DARWIN__)
- M_AST(REG_ITMP1, REG_SP, LA_SIZE + TRACE_ARGS_NUM * 8);
-#else
- M_AST(REG_ITMP1, REG_SP, LA_SIZE + 4 * 8);
-#endif
- p = dseg_addaddress(cd, builtin_trace_args);
- M_ALD(REG_ITMP2, REG_PV, p);
- M_MTCTR(REG_ITMP2);
- M_JSR;
-
-#if defined(__DARWIN__)
- /* restore integer argument registers from the reserved stack space */
-
- stack_off = LA_SIZE;
- for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM;
- p++, stack_off += 8) {
- t = md->paramtypes[p].type;
-
- if (IS_INT_LNG_TYPE(t)) {
- if (!md->params[p].inmemory) {
- if (IS_2_WORD_TYPE(t)) {
- M_ILD(rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]
- , REG_SP, stack_off);
- M_ILD(rd->argintregs[GET_LOW_REG(md->params[p].regoff)]
- , REG_SP, stack_off + 4);
- } else {
- M_ILD(rd->argintregs[md->params[p].regoff]
- , REG_SP, stack_off + 4);
- }
- }
- }
- }
-#else
- /* LINUX */
- for (p = 0; p < 8; p++) {
- d = rd->argintregs[p];
- /* save integer argument registers */
- M_ILD(d, REG_SP, LA_SIZE + 4 * 8 + 4 + p * 4);
- }
-#endif
-
- if (!nativestub)
- M_ILD(REG_ITMP3, REG_SP, LA_SIZE + TRACE_ARGS_NUM * 8 + 1 * 4);
-
- M_LDA(REG_SP, REG_SP, stack_size);
-
- if (!nativestub)
- M_MTLR(REG_ITMP3);
-}
/*