Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: emit.c 7766 2007-04-19 13:24:48Z michi $
-
*/
#include "mm/memory.h"
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "threads/lock-common.h"
#include "vm/builtin.h"
#include "vm/exceptions.h"
+#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
if (IS_INMEMORY(src->flags)) {
COUNT_SPILLS;
- disp = src->vv.regoff * 4;
+ disp = src->vv.regoff;
switch (src->type) {
case TYPE_INT:
if (IS_INMEMORY(src->flags)) {
COUNT_SPILLS;
- disp = src->vv.regoff * 4;
+ disp = src->vv.regoff;
M_ILD(tempreg, REG_SP, disp);
if (IS_INMEMORY(src->flags)) {
COUNT_SPILLS;
- disp = src->vv.regoff * 4;
+ disp = src->vv.regoff;
M_ILD(tempreg, REG_SP, disp + 4);
if (IS_INMEMORY(dst->flags)) {
COUNT_SPILLS;
- disp = dst->vv.regoff * 4;
+ disp = dst->vv.regoff;
switch (dst->type) {
case TYPE_INT:
if (IS_INMEMORY(dst->flags)) {
COUNT_SPILLS;
- M_IST(GET_LOW_REG(d), REG_SP, dst->vv.regoff * 4);
+ M_IST(GET_LOW_REG(d), REG_SP, dst->vv.regoff);
}
}
if (IS_INMEMORY(dst->flags)) {
COUNT_SPILLS;
- M_IST(GET_HIGH_REG(d), REG_SP, dst->vv.regoff * 4 + 4);
+ M_IST(GET_HIGH_REG(d), REG_SP, dst->vv.regoff + 4);
}
}
void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, s4 s2)
{
if (INSTRUCTION_MUST_CHECK(iptr)) {
- M_ILD(REG_ITMP3, s1, OFFSET(java_arrayheader, size));
+ M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size));
M_CMP(REG_ITMP3, s2);
M_BB(6);
M_ALD_MEM(s2, EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS);
}
-/* emit_replacement_stubs ******************************************************
+/* emit_trap *******************************************************************
- Generates the code for the replacement stubs.
+ Emit a trap instruction and return the original machine code.
*******************************************************************************/
-#if defined(ENABLE_REPLACEMENT)
-void emit_replacement_stubs(jitdata *jd)
+uint32_t emit_trap(codegendata *cd)
{
- codegendata *cd;
- codeinfo *code;
- rplpoint *rplp;
- s4 disp;
- s4 i;
- s4 branchmpc;
- s4 outcode;
-
- /* get required compiler data */
-
- cd = jd->cd;
- code = jd->code;
-
- rplp = code->rplpoints;
-
- /* store beginning of replacement stubs */
-
- code->replacementstubs = (u1*) (cd->mcodeptr - cd->mcodebase);
-
- for (i = 0; i < code->rplpointcount; ++i, ++rplp) {
- /* do not generate stubs for non-trappable points */
+ uint32_t mcode;
- if (rplp->flags & RPLPOINT_FLAG_NOTRAP)
- continue;
+ /* Get machine code which is patched back in later. The
+ trap is 1 instruction word long. */
- /* check code segment size */
-
- MCODECHECK(512);
-
- /* note start of stub code */
-
- outcode = (s4) (cd->mcodeptr - cd->mcodebase);
-
- /* push address of `rplpoint` struct */
-
- M_PUSH_IMM(rplp);
+ mcode = *((uint32_t *) cd->mcodeptr);
- /* jump to replacement function */
-
- M_PUSH_IMM(asm_replacement_out);
- M_RET;
-
- /* add jump reference for COUNTDOWN points */
-
- if (rplp->flags & RPLPOINT_FLAG_COUNTDOWN) {
-
- branchmpc = (s4)rplp->pc + (7 + 6);
-
- md_codegen_patch_branch(cd, branchmpc, (s4) outcode);
- }
+ M_NOP;
- assert(((cd->mcodeptr - cd->mcodebase) - outcode) == REPLACEMENT_STUB_SIZE);
- }
+ return mcode;
}
-#endif /* defined(ENABLE_REPLACEMENT) */
-
+
/* emit_verbosecall_enter ******************************************************
codegendata *cd;
registerdata *rd;
methoddesc *md;
- s4 disp;
- s4 i, t;
+ int32_t disp;
+ int i;
+ int d;
if (!JITDATA_HAS_FLAG_VERBOSECALL(jd))
return;
/* methodinfo* + arguments + return address */
- disp = TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4 +
- cd->stackframesize * 4 + 4;
+ disp = (TRACE_ARGS_NUM + 1 + TMP_CNT) * 8 + cd->stackframesize * 8 + 4;
- M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4, REG_SP);
+ M_ASUB_IMM((TRACE_ARGS_NUM + 1 + TMP_CNT) * 8, REG_SP);
/* save temporary registers for leaf methods */
for (i = 0; i < INT_TMP_CNT; i++)
- M_IST(rd->tmpintregs[i], REG_SP, TRACE_ARGS_NUM * 8 + 4 + i * 4);
+ M_IST(rd->tmpintregs[i], REG_SP, (TRACE_ARGS_NUM + 1 + i) * 8);
- for (i = 0; i < md->paramcount && i < TRACE_ARGS_NUM; i++) {
- t = md->paramtypes[i].type;
+ /* save argument registers */
- if (IS_INT_LNG_TYPE(t)) {
- if (IS_2_WORD_TYPE(t)) {
- M_LLD(REG_ITMP12_PACKED, REG_SP, disp);
- M_LST(REG_ITMP12_PACKED, REG_SP, i * 8);
- }
- else if (IS_ADR_TYPE(t)) {
- M_ALD(REG_ITMP1, REG_SP, disp);
- M_AST(REG_ITMP1, REG_SP, i * 8);
- M_IST_IMM(0, REG_SP, i * 8 + 4);
- }
- else {
- M_ILD(EAX, REG_SP, disp);
- emit_cltd(cd);
- M_LST(EAX_EDX_PACKED, REG_SP, i * 8);
- }
- }
- else {
- if (IS_2_WORD_TYPE(t)) {
- M_DLD(REG_NULL, REG_SP, disp);
- M_DST(REG_NULL, REG_SP, i * 8);
- }
- else {
- M_FLD(REG_NULL, REG_SP, disp);
- M_FST(REG_NULL, REG_SP, i * 8);
- M_IST_IMM(0, REG_SP, i * 8 + 4);
- }
+ for (i = 0; i < md->paramcount; i++) {
+ d = i * 8;
+
+ switch (md->paramtypes[i].type) {
+ case TYPE_INT:
+ M_ILD(EAX, REG_SP, disp);
+ emit_cltd(cd);
+ M_LST(EAX_EDX_PACKED, REG_SP, d);
+ break;
+ case TYPE_LNG:
+ M_LLD(REG_ITMP12_PACKED, REG_SP, disp);
+ M_LST(REG_ITMP12_PACKED, REG_SP, d);
+ break;
+ case TYPE_ADR:
+ M_ALD(REG_ITMP1, REG_SP, disp);
+ M_AST(REG_ITMP1, REG_SP, d);
+ M_IST_IMM(0, REG_SP, d + 4); /* high-bits are zero */
+ break;
+ case TYPE_FLT:
+ M_FLD(REG_NULL, REG_SP, disp);
+ M_FST(REG_NULL, REG_SP, d);
+ M_IST_IMM(0, REG_SP, d + 4); /* high-bits are zero */
+ break;
+ case TYPE_DBL:
+ M_DLD(REG_NULL, REG_SP, disp);
+ M_DST(REG_NULL, REG_SP, d);
+ break;
}
- disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
+ disp += 8;
}
-
+
M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
M_MOV_IMM(builtin_verbosecall_enter, REG_ITMP1);
/* restore temporary registers for leaf methods */
for (i = 0; i < INT_TMP_CNT; i++)
- M_ILD(rd->tmpintregs[i], REG_SP, TRACE_ARGS_NUM * 8 + 4 + i * 4);
+ M_ILD(rd->tmpintregs[i], REG_SP, (TRACE_ARGS_NUM + 1 + i) * 8);
- M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4 + INT_TMP_CNT * 4, REG_SP);
+ M_AADD_IMM((TRACE_ARGS_NUM + 1 + TMP_CNT) * 8, REG_SP);
/* mark trace code */