X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fcodegen-common.cpp;h=81c3c75c8894580314da9387624ef9c7796fe74b;hb=97408c9748640b078f801500620baec571dc6baa;hp=f05b6d951a932feeae117d1f29a6feaa8e5b5cad;hpb=981c77f13ccb6b5b78c26b49489e09c91dff5f00;p=cacao.git diff --git a/src/vm/jit/codegen-common.cpp b/src/vm/jit/codegen-common.cpp index f05b6d951..81c3c75c8 100644 --- a/src/vm/jit/codegen-common.cpp +++ b/src/vm/jit/codegen-common.cpp @@ -1,6 +1,6 @@ /* src/vm/jit/codegen-common.cpp - architecture independent code generator stuff - Copyright (C) 1996-2005, 2006, 2007, 2008, 2009 + Copyright (C) 1996-2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO Copyright (C) 2009 Theobroma Systems Ltd. @@ -989,6 +989,21 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum) return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum); } +/** + * Fix up register locations in the case where control is transferred to an + * exception handler block via normal control flow (no exception). + */ +static void fixup_exc_handler_interface(jitdata *jd, basicblock *bptr) +{ + // Exception handlers have exactly 1 in-slot + assert(bptr->indepth == 1); + varinfo *var = VAR(bptr->invars[0]); + int32_t d = codegen_reg_of_var(0, var, REG_ITMP1_XPTR); + emit_load(jd, NULL, var, d); + // Copy the interface variable to ITMP1 (XPTR) because that's where + // the handler expects it. + emit_imove(jd->cd, d, REG_ITMP1_XPTR); +} /** * Generates machine code. @@ -996,7 +1011,7 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum) bool codegen_emit(jitdata *jd) { varinfo* var; - builtintable_entry* bte; + builtintable_entry* bte = 0; methoddesc* md; int32_t s1, s2, /*s3,*/ d; int32_t fieldtype; @@ -1507,16 +1522,22 @@ bool codegen_emit(jitdata *jd) #if defined(__I386__) // Generate architecture specific instructions. codegen_emit_instruction(jd, iptr); + break; #else + { + fieldinfo* fi; + patchref_t* pr; if (INSTRUCTION_IS_UNRESOLVED(iptr)) { unresolved_field* uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, 0); - patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + + fi = NULL; /* Silence compiler warning */ } else { - fieldinfo* fi = iptr->sx.s23.s3.fmiref->p.field; + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); @@ -1525,8 +1546,14 @@ bool codegen_emit(jitdata *jd) patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0); PROFILE_CYCLE_START; } + + pr = NULL; /* Silence compiler warning */ } +#if defined(USES_PATCHABLE_MEMORY_BARRIER) + codegen_emit_patchable_barrier(iptr, cd, pr, fi); +#endif + // XXX X86_64: Here We had this: /* This approach is much faster than moving the field address inline into a register. */ @@ -1539,13 +1566,20 @@ bool codegen_emit(jitdata *jd) M_ALD(d, REG_ITMP1, 0); break; case TYPE_INT: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); M_ILD(d, REG_ITMP1, 0); break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif d = codegen_reg_of_dst(jd, iptr, REG_LTMP23); M_LLD(d, REG_ITMP1, 0); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); M_FLD(d, REG_ITMP1, 0); @@ -1554,26 +1588,38 @@ bool codegen_emit(jitdata *jd) d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); M_DLD(d, REG_ITMP1, 0); break; +#endif + default: + // Silence compiler warning. + d = 0; } emit_store_dst(jd, iptr, d); -#endif break; + } +#endif case ICMD_PUTSTATIC: /* ..., value ==> ... */ #if defined(__I386__) // Generate architecture specific instructions. codegen_emit_instruction(jd, iptr); + break; #else + { + fieldinfo* fi; + patchref_t* pr; + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { unresolved_field* uf = iptr->sx.s23.s3.uf; fieldtype = uf->fieldref->parseddesc.fd->type; disp = dseg_add_unique_address(cd, 0); - patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp); + + fi = NULL; /* Silence compiler warning */ } else { - fieldinfo* fi = iptr->sx.s23.s3.fmiref->p.field; + fi = iptr->sx.s23.s3.fmiref->p.field; fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); @@ -1582,6 +1628,8 @@ bool codegen_emit(jitdata *jd) patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0); PROFILE_CYCLE_START; } + + pr = NULL; /* Silence compiler warning */ } // XXX X86_64: Here We had this: @@ -1596,13 +1644,20 @@ bool codegen_emit(jitdata *jd) M_AST(s1, REG_ITMP1, 0); break; case TYPE_INT: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif s1 = emit_load_s1(jd, iptr, REG_ITMP2); M_IST(s1, REG_ITMP1, 0); break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif s1 = emit_load_s1(jd, iptr, REG_LTMP23); M_LST(s1, REG_ITMP1, 0); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: s1 = emit_load_s1(jd, iptr, REG_FTMP2); M_FST(s1, REG_ITMP1, 0); @@ -1611,9 +1666,14 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1(jd, iptr, REG_FTMP2); M_DST(s1, REG_ITMP1, 0); break; +#endif } +#if defined(USES_PATCHABLE_MEMORY_BARRIER) + codegen_emit_patchable_barrier(iptr, cd, pr, fi); #endif break; + } +#endif /* branch operations **********************************************/ @@ -1650,12 +1710,15 @@ bool codegen_emit(jitdata *jd) codegen_emit_phi_moves(jd, bptr); } #endif + if (iptr->dst.block->type == BBTYPE_EXH) + fixup_exc_handler_interface(jd, iptr->dst.block); emit_br(cd, iptr->dst.block); ALIGNCODENOP; break; case ICMD_JSR: /* ... ==> ... */ + assert(iptr->sx.s23.s3.jsrtarget.block->type != BBTYPE_EXH); emit_br(cd, iptr->sx.s23.s3.jsrtarget.block); ALIGNCODENOP; break; @@ -1663,6 +1726,7 @@ bool codegen_emit(jitdata *jd) case ICMD_IFNULL: /* ..., value ==> ... */ case ICMD_IFNONNULL: + assert(iptr->dst.block->type != BBTYPE_EXH); s1 = emit_load_s1(jd, iptr, REG_ITMP1); #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE); @@ -1685,6 +1749,8 @@ bool codegen_emit(jitdata *jd) // register directly. Reason is, that register content is // not 32-bit clean. Fix this! + assert(iptr->dst.block->type != BBTYPE_EXH); + #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER if (iptr->sx.val.i == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP1); @@ -1709,6 +1775,8 @@ bool codegen_emit(jitdata *jd) case ICMD_IF_LGT: case ICMD_IF_LLE: + assert(iptr->dst.block->type != BBTYPE_EXH); + // Generate architecture specific instructions. codegen_emit_instruction(jd, iptr); break; @@ -1716,6 +1784,8 @@ bool codegen_emit(jitdata *jd) case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */ case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */ + assert(iptr->dst.block->type != BBTYPE_EXH); + s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS @@ -1748,6 +1818,8 @@ bool codegen_emit(jitdata *jd) case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */ case ICMD_IF_ICMPNE: /* op1 = target JavaVM pc */ + assert(iptr->dst.block->type != BBTYPE_EXH); + #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); @@ -1769,6 +1841,8 @@ bool codegen_emit(jitdata *jd) case ICMD_IF_ICMPLE: case ICMD_IF_ICMPGE: + assert(iptr->dst.block->type != BBTYPE_EXH); + s1 = emit_load_s1(jd, iptr, REG_ITMP1); s2 = emit_load_s2(jd, iptr, REG_ITMP2); #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER @@ -1794,6 +1868,8 @@ bool codegen_emit(jitdata *jd) case ICMD_IF_LCMPLE: case ICMD_IF_LCMPGE: + assert(iptr->dst.block->type != BBTYPE_EXH); + // Generate architecture specific instructions. codegen_emit_instruction(jd, iptr); break; @@ -1822,6 +1898,9 @@ bool codegen_emit(jitdata *jd) goto nowperformreturn; case ICMD_IRETURN: /* ..., retvalue ==> ... */ +#if defined(ENABLE_SOFTFLOAT) + case ICMD_FRETURN: +#endif REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_RESULT); @@ -1830,6 +1909,9 @@ bool codegen_emit(jitdata *jd) goto nowperformreturn; case ICMD_LRETURN: /* ..., retvalue ==> ... */ +#if defined(ENABLE_SOFTFLOAT) + case ICMD_DRETURN: +#endif REPLACEMENT_POINT_RETURN(cd, iptr); s1 = emit_load_s1(jd, iptr, REG_LRESULT); @@ -1837,6 +1919,7 @@ bool codegen_emit(jitdata *jd) emit_lmove(cd, s1, REG_LRESULT); goto nowperformreturn; +#if !defined(ENABLE_SOFTFLOAT) case ICMD_FRETURN: /* ..., retvalue ==> ... */ REPLACEMENT_POINT_RETURN(cd, iptr); @@ -1858,6 +1941,7 @@ bool codegen_emit(jitdata *jd) M_CAST_D2L(s1, REG_LRESULT); #endif goto nowperformreturn; +#endif nowperformreturn: #if !defined(NDEBUG) @@ -1962,35 +2046,45 @@ gen_method: continue; if (!md->params[i].inmemory) { - assert(ARG_CNT > 0); - s1 = emit_load(jd, iptr, var, d); - switch (var->type) { case TYPE_ADR: case TYPE_INT: - assert(INT_ARG_CNT > 0); +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif + s1 = emit_load(jd, iptr, var, d); emit_imove(cd, s1, d); break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif + s1 = emit_load(jd, iptr, var, d); emit_lmove(cd, s1, d); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) + s1 = emit_load(jd, iptr, var, d); emit_fmove(cd, s1, d); #else + s1 = emit_load(jd, iptr, var, REG_FTMP1); M_CAST_F2I(s1, d); #endif break; case TYPE_DBL: #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) + s1 = emit_load(jd, iptr, var, d); emit_dmove(cd, s1, d); #else + s1 = emit_load(jd, iptr, var, REG_FTMP1); M_CAST_D2L(s1, d); #endif break; +#endif } } else { @@ -2005,6 +2099,9 @@ gen_method: break; case TYPE_INT: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif #if SIZEOF_VOID_P == 4 s1 = emit_load(jd, iptr, var, REG_ITMP1); M_IST(s1, REG_SP, d); @@ -2014,12 +2111,16 @@ gen_method: #endif case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif s1 = emit_load(jd, iptr, var, REG_LTMP12); // XXX Sparc64: Here this actually was: // M_STX(s1, REG_SP, JITSTACK + d); M_LST(s1, REG_SP, d); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #if SIZEOF_VOID_P == 4 s1 = emit_load(jd, iptr, var, REG_FTMP1); @@ -2035,6 +2136,7 @@ gen_method: // M_DST(s1, REG_SP, JITSTACK + d); M_DST(s1, REG_SP, d); break; +#endif } } } @@ -2064,6 +2166,9 @@ gen_method: switch (md->returntype.type) { case TYPE_INT: case TYPE_ADR: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_FLT: +#endif s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT); // XXX Sparc64: This should actually be REG_RESULT_CALLER, fix this! emit_imove(cd, REG_RESULT, s1); @@ -2071,12 +2176,16 @@ gen_method: break; case TYPE_LNG: +#if defined(ENABLE_SOFTFLOAT) + case TYPE_DBL: +#endif s1 = codegen_reg_of_dst(jd, iptr, REG_LRESULT); // XXX Sparc64: This should actually be REG_RESULT_CALLER, fix this! emit_lmove(cd, REG_LRESULT, s1); emit_store_dst(jd, iptr, s1); break; +#if !defined(ENABLE_SOFTFLOAT) case TYPE_FLT: #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS) s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT); @@ -2098,6 +2207,7 @@ gen_method: #endif emit_store_dst(jd, iptr, s1); break; +#endif case TYPE_VOID: break; @@ -2195,6 +2305,9 @@ gen_method: } #endif + if (bptr->next && bptr->next->type == BBTYPE_EXH) + fixup_exc_handler_interface(jd, bptr->next); + } // for all basic blocks // Generate traps.