X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fm68k%2Femit.c;h=f53e321908243d02abd547655ee457b1d68ca351;hb=b6fbb1958c8971b06e87ea3c37be0deaff131768;hp=b36a26b2ad9d9b7cb4f4ca0612839b735aab3334;hpb=207cd689f8776540388318f35a61d5707c58a607;p=cacao.git diff --git a/src/vm/jit/m68k/emit.c b/src/vm/jit/m68k/emit.c index b36a26b2a..f53e32190 100644 --- a/src/vm/jit/m68k/emit.c +++ b/src/vm/jit/m68k/emit.c @@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: arch.h 5330 2006-09-05 18:43:12Z edwin $ - */ @@ -35,35 +33,42 @@ #include "vm/jit/emit-common.h" #include "vm/exceptions.h" #include "vm/jit/asmpart.h" - #include "vm/builtin.h" + #include "mm/memory.h" +#include "threads/lock-common.h" + #include "codegen.h" +#include "md-os.h" -/* - * Loads an immededat operand into data register - */ +/* emit_mov_imm_reg ************************************************************************** + * + * Loads an immededat operand into an integer data register + * + ********************************************************************************************/ void emit_mov_imm_reg (codegendata *cd, s4 imm, s4 dreg) { - if ((imm & 0x000000FF) == imm) { + /* FIXME: -1 can be used as byte form 0xff, but this ifs cascade is plain wrong it seems */ + + if ( (imm & 0x0000007F) == imm) { /* use byte form */ *((s2*)cd->mcodeptr) = 0x7000 | (dreg << 9) | imm; /* MOVEQ.L */ cd->mcodeptr += 2; - } else if ((imm & 0xFFFF0000) != 0) { + } else if ((imm & 0x00007FFF) == imm) { + /* use word form */ + OPWORD( ((7<<6) | (dreg << 3) | 5), 7, 4); /* MVS.W */ + *((s2*)cd->mcodeptr) = (s2)imm; + cd->mcodeptr += 2; + } else { /* use long form */ OPWORD( ((2<<6) | (dreg << 3) | 0), 7, 4); *((s4*)cd->mcodeptr) = (s4)imm; cd->mcodeptr += 4; - } else { - /* use word form */ - OPWORD( ((3<<6) | (dreg << 3) | 0), 7, 4); - *((s2*)cd->mcodeptr) = (s2)imm; - cd->mcodeptr += 2; + } } - /* emit_copy ******************************************************************* Generates a register/memory to register/memory copy. @@ -159,23 +164,23 @@ inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d) case TYPE_DBL: #endif case TYPE_LNG: - M_LST(d, REG_SP, dst->vv.regoff * 4); + M_LST(d, REG_SP, dst->vv.regoff); break; #if defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #endif case TYPE_INT: - M_IST(d, REG_SP, dst->vv.regoff * 4); + M_IST(d, REG_SP, dst->vv.regoff); break; case TYPE_ADR: - M_AST(d, REG_SP, dst->vv.regoff * 4); + M_AST(d, REG_SP, dst->vv.regoff); break; #if !defined(ENABLE_SOFTFLOAT) case TYPE_DBL: - M_DST(d, REG_SP, dst->vv.regoff * 4); + M_DST(d, REG_SP, dst->vv.regoff); break; case TYPE_FLT: - M_FST(d, REG_SP, dst->vv.regoff * 4); + M_FST(d, REG_SP, dst->vv.regoff); break; #endif default: @@ -204,7 +209,7 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->vv.regoff * 4; + disp = src->vv.regoff; switch (src->type) { #if defined(ENABLE_SOFTFLOAT) @@ -301,8 +306,8 @@ void emit_patcher_stubs(jitdata *jd) cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */ - /* save REG_ITMP3 */ - M_IPUSH(REG_ITMP3); /* FIXME why, and restore where ? */ + /* save REG_ITMP3, restored in asm_patcher_wrapper */ + M_IPUSH(REG_ITMP3); /* move pointer to java_objectheader onto stack */ @@ -311,10 +316,9 @@ void emit_patcher_stubs(jitdata *jd) (void) dseg_add_unique_address(cd, lock_get_initial_lock_word()); disp = dseg_add_unique_address(cd, NULL); /* vftbl */ - assert(0); /* The next lines are wrong */ - M_MOV_IMM(0, REG_ITMP3); + M_IMOV_IMM32(0, REG_ITMP3); dseg_adddata(cd); - M_AADD_IMM(REG_ITMP3, disp); + M_IADD_IMM(disp, REG_ITMP3); M_IPUSH(REG_ITMP3); #else M_IPUSH_IMM(0); @@ -336,7 +340,11 @@ s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) s4 disp; s4 reg; +#if !defined(ENABLE_SOFTFLOAT) assert(src->type == TYPE_LNG); +#else + assert(src->type == TYPE_LNG || src->type == TYPE_DBL); +#endif /* get required compiler data */ cd = jd->cd; @@ -344,7 +352,7 @@ s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->vv.regoff * 4; + disp = src->vv.regoff; M_ILD(tempreg, REG_SP, disp + 4); reg = tempreg; } else { @@ -358,14 +366,17 @@ s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg) s4 disp; s4 reg; +#if !defined(ENABLE_SOFTFLOAT) assert(src->type == TYPE_LNG); - +#else + assert(src->type == TYPE_LNG || src->type == TYPE_DBL); +#endif /* get required compiler data */ cd = jd->cd; if (IS_INMEMORY(src->flags)) { COUNT_SPILLS; - disp = src->vv.regoff * 4; + disp = src->vv.regoff; M_ILD(tempreg, REG_SP, disp); reg = tempreg; } else { @@ -468,6 +479,74 @@ void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt) } } +/* emit_replacement_stubs ****************************************************** + + Generates the code for the replacement stubs. + +*******************************************************************************/ + +#if defined(ENABLE_REPLACEMENT) +void emit_replacement_stubs(jitdata *jd) +{ + codegendata *cd; + codeinfo *code; + rplpoint *rplp; + 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 */ + + if (rplp->flags & RPLPOINT_FLAG_NOTRAP) + continue; + + M_JSR_IMM(0); +#if 0 + /* 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); + + /* 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); + } + + assert(((cd->mcodeptr - cd->mcodebase) - outcode) == REPLACEMENT_STUB_SIZE); +#endif + } +} +#endif /* defined(ENABLE_REPLACEMENT) */ + + #if !defined(NDEBUG) /* @@ -495,21 +574,28 @@ void emit_verbosecall_enter(jitdata* jd) /* mark trace code */ M_NOP; - M_LINK(REG_FP, -16*4); - M_PUSHALL; + M_IPUSH(REG_D0); + M_IPUSH(REG_D1); + M_APUSH(REG_A0); + M_APUSH(REG_A1); +#if !defined(ENABLE_SOFTFLOAT) + M_AADD_IMM(-8*2, REG_SP); + M_FSTORE(REG_F0, REG_SP, 8); + M_FSTORE(REG_F1, REG_SP, 0); + + disp = 4*4 + 8*2 + 4; /* points to old argument stack initially */ +#else + disp = 4*4 + 4; +#endif /* builtin_verbosecall_enter takes all args as s8 type */ /* TRACE_ARGS_NUM is the number of args the builtin_verbosecall_enter expects */ M_IPUSH_IMM(m); - disp = 16*4 + 4 + 4; /* points to old argument stack initially */ /* travel up stack to the first argument of the function which needs to be copied */ for (i=0; (i < md->paramcount) && (i < TRACE_ARGS_NUM); i++) { - disp += 4; - if (IS_2_WORD_TYPE(md->paramtypes[i].type)) { - disp += 4; - } + disp += 8; } /* disp now points to the first arg which gets copied to the trace stack, relative to REG_SP! */ @@ -518,19 +604,11 @@ void emit_verbosecall_enter(jitdata* jd) /* traced function has such an argument */ t = md->paramtypes[i].type; - if (IS_2_WORD_TYPE(t)) { - /* copy from original argument stack */ - M_ILD(REG_ITMP1, REG_SP, disp); - M_IPUSH(REG_ITMP1); - M_ILD(REG_ITMP1, REG_SP, disp); - M_IPUSH(REG_ITMP1); - } else { - /* displacment is increased as 4 byte on original stack but 8 byte on trace stack */ - M_ILD(REG_ITMP1, REG_SP, disp); - M_IPUSH(REG_ITMP1); - M_IPUSH_IMM(0); - disp += 4; - } + /* copy from original argument stack */ + M_ILD(REG_ITMP1, REG_SP, disp); + M_ILD(REG_ITMP2, REG_SP, disp-4); + M_IPUSH(REG_ITMP2); + M_IPUSH(REG_ITMP1); } else { /* function has no arg here, push nothing and adapt displacement */ M_IPUSH_IMM(0); @@ -542,8 +620,17 @@ void emit_verbosecall_enter(jitdata* jd) /* pop arguments off stack */ M_AADD_IMM(TRACE_ARGS_NUM*8+4, REG_SP); - M_POPALL; - M_UNLK(REG_FP); +#if !defined(ENABLE_SOFTFLOAT) + M_FSTORE(REG_F1, REG_SP, 0); + M_FSTORE(REG_F0, REG_SP, 8); + M_AADD_IMM(8*2, REG_SP); +#endif + + M_APOP(REG_A1); + M_APOP(REG_A0); + M_IPOP(REG_D1); + M_IPOP(REG_D0); + M_NOP; } void emit_verbosecall_exit(jitdata* jd) @@ -567,36 +654,45 @@ void emit_verbosecall_exit(jitdata* jd) /* mark trace code */ M_NOP; - M_LINK(REG_FP, 0); + +#if !defined(ENABLE_SOFTFLOAT) + M_AADD_IMM(-8, REG_SP); + M_FSTORE(REG_D1, REG_SP, 0); +#endif M_IPUSH_IMM(m); /* push methodinfo */ - M_IPUSH_IMM(0); /* TODO push float result */ +#if !defined(ENABLE_SOFTFLOAT) + M_AADD_IMM(-3*4, REG_SP); + M_FST(REG_D0, REG_SP, 8); + M_DST(REG_D0, REG_SP, 0); +#else + M_IPUSH_IMM(0); - M_IPUSH_IMM(0); /* TODO push double result */ - M_IPUSH_IMM(0); /* TODO push double result */ + M_IPUSH_IMM(0); + M_IPUSH_IMM(0); +#endif M_IPUSH(GET_HIGH_REG(REG_RESULT_PACKED)) M_IPUSH(GET_LOW_REG(REG_RESULT_PACKED)) /* push long result */ - M_JSR_IMM(builtin_verbosecall_exit); /* poping result registers from stack */ M_IPOP(GET_LOW_REG(REG_RESULT_PACKED)) M_IPOP(GET_HIGH_REG(REG_RESULT_PACKED)) -#if 0 - /* that is wrong of course, overwrites registers and stuff */ - M_IPOP(0); /* TODO: pop double result */ - M_IPOP(0); /* TODO: pop double result */ +#if !defined(ENABLE_SOFTFLOAT) + M_DLD(REG_D0, REG_SP, 0) + M_FLD(REG_D0, REG_SP, 8) +#endif + M_AADD_IMM(3*4 + 4, REG_SP); - M_IPOP(0); /* TODO: pop float result */ -#else - M_AADD_IMM(3*4, REG_SP); +#if !defined(ENABLE_SOFTFLOAT) + M_FLOAD(REG_D1, REG_SP, 0) + M_AADD_IMM(8, REG_SP); #endif - M_AADD_IMM(4, REG_SP); /* remove rest of stack */ - M_UNLK(REG_FP); + M_NOP; } #endif @@ -621,7 +717,7 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r M_BLE(4); break; case BRANCH_UGT: - M_BHI(4); + M_BLS(4); break; default: vm_abort("emit_classcast_check: unknown condition %d", condition); @@ -639,11 +735,11 @@ void emit_classcast_check(codegendata *cd, instruction *iptr, s4 condition, s4 r 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_ICMP(REG_ITMP3, s2); - M_BLT(2); - /*M_ALD_INTERN(s2, REG_ZERO, EXCEPTION_LOAD_DISP_ARRAYINDEXOUTOFBOUNDS);*/ - M_ILLEGAL; /*FIXME */ + M_ILD(REG_ITMP3, s1, OFFSET(java_array_t, size)); + M_ICMP(s2, REG_ITMP3); + M_BHI(4); + M_TRAP_SETREGISTER(s2); + M_TRAP(EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS); } } @@ -655,12 +751,11 @@ void emit_arrayindexoutofbounds_check(codegendata *cd, instruction *iptr, s4 s1, void emit_nullpointer_check(codegendata *cd, instruction *iptr, s4 reg) { if (INSTRUCTION_MUST_CHECK(iptr)) { - /* did like to assert on TYPE_ADR, but not possible in here */ - /* so assert before each emit_nullpointer_check */ + /* XXX: this check is copied to call monitor_enter + * invocation at the beginning of codegen.c */ M_ATST(reg); M_BNE(2); - /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_LOAD_DISP_NULLPOINTER);*/ - M_ILLEGAL; + M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER); } } @@ -675,37 +770,22 @@ void emit_arithmetic_check(codegendata *cd, instruction *iptr, s4 reg) if (INSTRUCTION_MUST_CHECK(iptr)) { M_ITST(reg); M_BNE(2); - /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_ARITHMETIC);*/ - M_ILLEGAL; /* FIXME */ + M_TRAP(EXCEPTION_HARDWARE_ARITHMETIC); } } -/* emit_exception_check_areg ************************************************** - * - Emit an Exception check, tested register is address REG_RESULT - -*******************************************************************************/ -void emit_exception_check_areg(codegendata *cd, instruction *iptr) -{ - if (INSTRUCTION_MUST_CHECK(iptr)) { - M_ATST(REG_RESULT); - M_BNE(2); - /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);*/ - M_ILLEGAL; /*FIXME*/ - } -} /* emit_exception_check_ireg ************************************************** Emit an Exception check. Teste register is integer REG_RESULT *******************************************************************************/ -void emit_exception_check_ireg(codegendata *cd, instruction *iptr) +void emit_exception_check(codegendata *cd, instruction *iptr) { if (INSTRUCTION_MUST_CHECK(iptr)) { M_ITST(REG_RESULT); M_BNE(2); /*M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_EXCEPTION);*/ - M_ILLEGAL; /*FIXME*/ + M_TRAP(EXCEPTION_HARDWARE_EXCEPTION); } }