X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fi386%2Fcodegen.c;h=2eb99c0d4f7d2198239f5f0ab5f24ad128cda14b;hb=2ab77f5d50859fe9849586d1be0382fb61856b8f;hp=14340d7a4050151e87ba894f69327ed40f4934f8;hpb=7f461fba26d7241e160c580dbca9ba1c2656e572;p=cacao.git diff --git a/src/vm/jit/i386/codegen.c b/src/vm/jit/i386/codegen.c index 14340d7a4..2eb99c0d4 100644 --- a/src/vm/jit/i386/codegen.c +++ b/src/vm/jit/i386/codegen.c @@ -63,129 +63,36 @@ #include "vm/jit/parse.hpp" #include "vm/jit/patcher-common.hpp" #include "vm/jit/reg.h" -#include "vm/jit/replace.hpp" #include "vm/jit/stacktrace.hpp" #include "vm/jit/trap.hpp" -#if defined(ENABLE_SSA) -# include "vm/jit/optimizing/lsra.h" -# include "vm/jit/optimizing/ssa.h" -#elif defined(ENABLE_LSRA) -# include "vm/jit/allocator/lsra.h" -#endif - - -/* codegen_emit **************************************************************** - - Generates machine code. - -*******************************************************************************/ -bool codegen_emit(jitdata *jd) +/** + * Generates machine code for the method prolog. + */ +void codegen_emit_prolog(jitdata* jd) { - methodinfo *m; - codeinfo *code; - codegendata *cd; - registerdata *rd; - s4 len, s1, s2, s3, d, disp; - int align_off; /* offset for alignment compensation */ - varinfo *var, *var1; - basicblock *bptr; - instruction *iptr; - u2 currentline; - methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */ - builtintable_entry *bte; - methoddesc *md; - fieldinfo *fi; - unresolved_field *uf; - s4 fieldtype; - s4 varindex; -#if defined(ENABLE_SSA) - lsradata *ls; - bool last_cmd_was_goto; - - last_cmd_was_goto = false; - ls = jd->ls; -#endif - - /* get required compiler data */ - - m = jd->m; - code = jd->code; - cd = jd->cd; - rd = jd->rd; - - /* prevent compiler warnings */ - - s1 = 0; - s2 = 0; - d = 0; - currentline = 0; - lm = NULL; - bte = NULL; - - { - s4 i, p, t, l; - s4 savedregs_num = 0; - s4 stack_off = 0; - - /* space to save used callee saved registers */ - - savedregs_num += (INT_SAV_CNT - rd->savintreguse); - savedregs_num += (FLT_SAV_CNT - rd->savfltreguse); - - cd->stackframesize = rd->memuse + savedregs_num; + varinfo* var; + methoddesc* md; + int32_t s1, d; + int32_t p, t, l; + int32_t varindex; + int i; + int align_off; + + // Get required compiler data. + methodinfo* m = jd->m; + codegendata* cd = jd->cd; + registerdata* rd = jd->rd; - -#if defined(ENABLE_THREADS) - /* space to save argument of monitor_enter */ - - if (checksync && code_is_synchronized(code)) - cd->stackframesize++; -#endif - - /* create method header */ - - /* Keep stack of non-leaf functions 16-byte aligned. */ - - if (!code_is_leafmethod(code)) { - ALIGN_ODD(cd->stackframesize); - } + /* create stack frame (if necessary) */ align_off = cd->stackframesize ? 4 : 0; - (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4( - cd, cd->stackframesize * 8 + align_off); /* FrameSize */ - - code->synchronizedoffset = rd->memuse * 8; - - /* REMOVEME: We still need it for exception handling in assembler. */ - - if (code_is_leafmethod(code)) - (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */ - else - (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */ - - (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ - (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - -#if defined(ENABLE_PROFILING) - /* generate method profiling code */ - - if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { - /* count frequency */ - - M_MOV_IMM(code, REG_ITMP3); - M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency)); - } -#endif - - /* create stack frame (if necessary) */ - - if (cd->stackframesize) - /* align_off == 4 */ + if (cd->stackframesize) { + assert(align_off == 4); M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP); + } /* save return address and used callee saved registers */ @@ -201,9 +108,8 @@ bool codegen_emit(jitdata *jd) md = m->parseddesc; - stack_off = 0; - for (p = 0, l = 0; p < md->paramcount; p++) { - t = md->paramtypes[p].type; + for (p = 0, l = 0; p < md->paramcount; p++) { + t = md->paramtypes[p].type; varindex = jd->local_map[l * 5 + t]; #if defined(ENABLE_SSA) @@ -346,204 +252,76 @@ bool codegen_emit(jitdata *jd) } } } +} - /* call monitorenter function */ - -#if defined(ENABLE_THREADS) - if (checksync && code_is_synchronized(code)) { - s1 = rd->memuse; - - if (m->flags & ACC_STATIC) { - M_MOV_IMM(&m->clazz->object.header, REG_ITMP1); - } - else { - M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + 4 + align_off); - M_TEST(REG_ITMP1); - M_BNE(6); - M_ALD_MEM(REG_ITMP1, TRAP_NullPointerException); - } - - M_AST(REG_ITMP1, REG_SP, s1 * 8); - M_AST(REG_ITMP1, REG_SP, 0 * 4); - M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3); - M_CALL(REG_ITMP3); - } -#endif - -#if !defined(NDEBUG) - emit_verbosecall_enter(jd); -#endif - - } - -#if defined(ENABLE_SSA) - /* with SSA the Header is Basic Block 0 - insert phi Moves if necessary */ - if ( ls != NULL) - codegen_emit_phi_moves(jd, ls->basicblocks[0]); -#endif - - /* end of header generation */ - - /* create replacement points */ - - REPLACEMENT_POINTS_INIT(cd, jd); - - /* walk through all basic blocks */ - - for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) { - - bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase); - - if (bptr->flags >= BBREACHED) { - /* branch resolving */ - - codegen_resolve_branchrefs(cd, bptr); - - /* handle replacement points */ - - REPLACEMENT_POINT_BLOCK_START(cd, bptr); -#if defined(ENABLE_REPLACEMENT) - if (bptr->bitflags & BBFLAG_REPLACEMENT) { - if (cd->replacementpoint[-1].flags & RPLPOINT_FLAG_COUNTDOWN) { - MCODECHECK(32); - emit_trap_countdown(cd, &(m->hitcountdown)); - } - } -#endif +/** + * Generates machine code for the method epilog. + */ +void codegen_emit_epilog(jitdata* jd) +{ + methoddesc* md; + int32_t p; + int i; - /* copy interface registers to their destination */ + // Get required compiler data. + methodinfo* m = jd->m; + codegendata* cd = jd->cd; + registerdata* rd = jd->rd; - len = bptr->indepth; - MCODECHECK(512); + p = cd->stackframesize; + md = m->parseddesc; -#if defined(ENABLE_PROFILING) - /* generate basic block profiling code */ + /* restore saved registers */ - if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { - /* count frequency */ + for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { + p--; M_ALD(rd->savintregs[i], REG_SP, p * 8); + } - M_MOV_IMM(code->bbfrequency, REG_ITMP3); - M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4); + for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) { + p--; + emit_fldl_membase(cd, REG_SP, p * 8); + if (md->returntype.type == TYPE_FLT || md->returntype.type == TYPE_DBL) { + assert(0); +/* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */ + } else { + assert(0); +/* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */ } -#endif - -#if defined(ENABLE_LSRA) || defined(ENABLE_SSA) -# if defined(ENABLE_LSRA) && !defined(ENABLE_SSA) - if (opt_lsra) { -# endif -# if defined(ENABLE_SSA) - if (ls != NULL) { - last_cmd_was_goto = false; -# endif - if (len > 0) { - len--; - var = VAR(bptr->invars[len]); - if (bptr->type != BBTYPE_STD) { - if (!IS_2_WORD_TYPE(var->type)) { -#if !defined(ENABLE_SSA) - if (bptr->type == BBTYPE_EXH) { - d = codegen_reg_of_var(0, var, REG_ITMP1); - M_INTMOVE(REG_ITMP1, d); - emit_store(jd, NULL, var, d); - } -#endif - } - else { - log_text("copy interface registers(EXH, SBR): longs \ - have to be in memory (begin 1)"); - assert(0); - } - } - } - - } - else -#endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */ - { - while (len) { - len--; - var = VAR(bptr->invars[len]); - if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) { - if (!IS_2_WORD_TYPE(var->type)) { - if (bptr->type == BBTYPE_EXH) { - d = codegen_reg_of_var(0, var, REG_ITMP1); - M_INTMOVE(REG_ITMP1, d); - emit_store(jd, NULL, var, d); - } - } - else { - log_text("copy interface registers: longs have to be in \ - memory (begin 1)"); - assert(0); - } - - } - else { - assert((var->flags & INOUT)); - } - } /* while (len) */ - } /* */ - - /* walk through all instructions */ - - len = bptr->icount; - currentline = 0; - - for (iptr = bptr->iinstr; len > 0; len--, iptr++) { - if (iptr->line != currentline) { - linenumbertable_list_entry_add(cd, iptr->line); - currentline = iptr->line; - } - - MCODECHECK(1024); /* 1kB should be enough */ - - switch (iptr->opc) { - case ICMD_NOP: /* ... ==> ... */ - case ICMD_POP: /* ..., value ==> ... */ - case ICMD_POP2: /* ..., value, value ==> ... */ - break; - - case ICMD_INLINE_START: - - REPLACEMENT_POINT_INLINE_START(cd, iptr); - break; - - case ICMD_INLINE_BODY: + } - REPLACEMENT_POINT_INLINE_BODY(cd, iptr); - linenumbertable_list_entry_add_inline_start(cd, iptr); - linenumbertable_list_entry_add(cd, iptr->line); - break; + /* deallocate stack */ - case ICMD_INLINE_END: + if (cd->stackframesize) + M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP); - linenumbertable_list_entry_add_inline_end(cd, iptr); - linenumbertable_list_entry_add(cd, iptr->line); - break; + M_RET; +} - case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */ - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - emit_nullpointer_check(cd, iptr, s1); - break; +/** + * Generates machine code for one ICMD. + */ +void codegen_emit_instruction(jitdata* jd, instruction* iptr) +{ + varinfo* var; + varinfo* var1; + builtintable_entry* bte; + methodinfo* lm; // Local methodinfo for ICMD_INVOKE*. + unresolved_method* um; + fieldinfo* fi; + unresolved_field* uf; + int32_t fieldtype; + int32_t s1, s2, s3, d; + int32_t disp; + + // Get required compiler data. + codegendata* cd = jd->cd; + + switch (iptr->opc) { /* constant operations ************************************************/ - case ICMD_ICONST: /* ... ==> ..., constant */ - - d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - ICONST(d, iptr->sx.val.i); - emit_store_dst(jd, iptr, d); - break; - - case ICMD_LCONST: /* ... ==> ..., constant */ - - d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED); - LCONST(d, iptr->sx.val.l); - emit_store_dst(jd, iptr, d); - break; - case ICMD_FCONST: /* ... ==> ..., constant */ d = codegen_reg_of_dst(jd, iptr, REG_FTMP1); @@ -620,29 +398,6 @@ bool codegen_emit(jitdata *jd) break; - /* load/store/copy/move operations ************************************/ - - case ICMD_ILOAD: - case ICMD_ALOAD: - case ICMD_LLOAD: - case ICMD_FLOAD: - case ICMD_DLOAD: - case ICMD_ISTORE: - case ICMD_LSTORE: - case ICMD_FSTORE: - case ICMD_DSTORE: - case ICMD_COPY: - case ICMD_MOVE: - - emit_copy(jd, iptr); - break; - - case ICMD_ASTORE: - if (!(iptr->flags.bits & INS_FLAG_RETADDR)) - emit_copy(jd, iptr); - break; - - /* integer operations *************************************************/ case ICMD_INEG: /* ..., value ==> ..., - value */ @@ -988,7 +743,6 @@ bool codegen_emit(jitdata *jd) emit_arithmetic_check(cd, iptr, REG_ITMP3); bte = iptr->sx.s23.s3.bte; - md = bte->md; M_LST(s2, REG_SP, 2 * 4); @@ -1894,15 +1648,6 @@ bool codegen_emit(jitdata *jd) /* memory operations **************************************************/ - case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */ - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - /* implicit null-pointer check */ - M_ILD(d, s1, OFFSET(java_array_t, size)); - emit_store_dst(jd, iptr, d); - break; - case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */ s1 = emit_load_s1(jd, iptr, REG_ITMP1); @@ -2436,16 +2181,6 @@ bool codegen_emit(jitdata *jd) case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */ - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - M_INTMOVE(s1, REG_ITMP1_XPTR); - -#ifdef ENABLE_VERIFIER - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - patcher_add_patch_ref(jd, PATCHER_resolve_class, - iptr->sx.s23.s2.uc, 0); - } -#endif /* ENABLE_VERIFIER */ - M_CALL_IMM(0); /* passing exception pc */ M_POP(REG_ITMP2_XPC); @@ -2453,49 +2188,6 @@ bool codegen_emit(jitdata *jd) M_JMP(REG_ITMP3); break; - case ICMD_GOTO: /* ... ==> ... */ - case ICMD_RET: /* ... ==> ... */ - -#if defined(ENABLE_SSA) - if ( ls != NULL ) { - last_cmd_was_goto = true; - - /* In case of a Goto phimoves have to be inserted before the */ - /* jump */ - - codegen_emit_phi_moves(jd, bptr); - } -#endif - emit_br(cd, iptr->dst.block); - ALIGNCODENOP; - break; - - case ICMD_JSR: /* ... ==> ... */ - - emit_br(cd, iptr->sx.s23.s3.jsrtarget.block); - ALIGNCODENOP; - break; - - case ICMD_IFNULL: /* ..., value ==> ... */ - case ICMD_IFNONNULL: - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - M_TEST(s1); - emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE); - break; - - case ICMD_IFEQ: /* ..., value ==> ... */ - case ICMD_IFLT: - case ICMD_IFLE: - case ICMD_IFNE: - case ICMD_IFGT: - case ICMD_IFGE: - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - M_CMP_IMM(iptr->sx.val.i, s1); - emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE); - break; - case ICMD_IF_LEQ: /* ..., value ==> ... */ s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); @@ -2586,28 +2278,6 @@ bool codegen_emit(jitdata *jd) } break; - case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */ - case ICMD_IF_ICMPNE: - case ICMD_IF_ICMPLT: - case ICMD_IF_ICMPGT: - case ICMD_IF_ICMPGE: - case ICMD_IF_ICMPLE: - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - s2 = emit_load_s2(jd, iptr, REG_ITMP2); - M_CMP(s2, s1); - emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE); - break; - - case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */ - case ICMD_IF_ACMPNE: - - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - s2 = emit_load_s2(jd, iptr, REG_ITMP2); - M_CMP(s2, s1); - emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE); - break; - case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */ s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); @@ -2688,134 +2358,6 @@ bool codegen_emit(jitdata *jd) emit_buge(cd, iptr->dst.block); break; - - case ICMD_IRETURN: /* ..., retvalue ==> ... */ - - REPLACEMENT_POINT_RETURN(cd, iptr); - s1 = emit_load_s1(jd, iptr, REG_RESULT); - M_INTMOVE(s1, REG_RESULT); - goto nowperformreturn; - - case ICMD_LRETURN: /* ..., retvalue ==> ... */ - - REPLACEMENT_POINT_RETURN(cd, iptr); - s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED); - M_LNGMOVE(s1, REG_RESULT_PACKED); - goto nowperformreturn; - - case ICMD_ARETURN: /* ..., retvalue ==> ... */ - - REPLACEMENT_POINT_RETURN(cd, iptr); - s1 = emit_load_s1(jd, iptr, REG_RESULT); - M_INTMOVE(s1, REG_RESULT); - -#ifdef ENABLE_VERIFIER - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - patcher_add_patch_ref(jd, PATCHER_resolve_class, - iptr->sx.s23.s2.uc, 0); - } -#endif /* ENABLE_VERIFIER */ - goto nowperformreturn; - - case ICMD_FRETURN: /* ..., retvalue ==> ... */ - case ICMD_DRETURN: - - REPLACEMENT_POINT_RETURN(cd, iptr); - s1 = emit_load_s1(jd, iptr, REG_FRESULT); - goto nowperformreturn; - - case ICMD_RETURN: /* ... ==> ... */ - - REPLACEMENT_POINT_RETURN(cd, iptr); - -nowperformreturn: - { - s4 i, p; - - p = cd->stackframesize; - -#if !defined(NDEBUG) - emit_verbosecall_exit(jd); -#endif - -#if defined(ENABLE_THREADS) - if (checksync && code_is_synchronized(code)) { - M_ALD(REG_ITMP2, REG_SP, rd->memuse * 8); - - /* we need to save the proper return value */ - switch (iptr->opc) { - case ICMD_IRETURN: - case ICMD_ARETURN: - M_IST(REG_RESULT, REG_SP, rd->memuse * 8); - break; - - case ICMD_LRETURN: - M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8); - break; - - case ICMD_FRETURN: - emit_fstps_membase(cd, REG_SP, rd->memuse * 8); - break; - - case ICMD_DRETURN: - emit_fstpl_membase(cd, REG_SP, rd->memuse * 8); - break; - } - - M_AST(REG_ITMP2, REG_SP, 0); - M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3); - M_CALL(REG_ITMP3); - - /* and now restore the proper return value */ - switch (iptr->opc) { - case ICMD_IRETURN: - case ICMD_ARETURN: - M_ILD(REG_RESULT, REG_SP, rd->memuse * 8); - break; - - case ICMD_LRETURN: - M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8); - break; - - case ICMD_FRETURN: - emit_flds_membase(cd, REG_SP, rd->memuse * 8); - break; - - case ICMD_DRETURN: - emit_fldl_membase(cd, REG_SP, rd->memuse * 8); - break; - } - } -#endif - - /* restore saved registers */ - - for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) { - p--; M_ALD(rd->savintregs[i], REG_SP, p * 8); - } - - for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) { - p--; - emit_fldl_membase(cd, REG_SP, p * 8); - if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) { - assert(0); -/* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */ - } else { - assert(0); -/* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */ - } - } - - /* deallocate stack */ - - if (cd->stackframesize) - M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP); - - M_RET; - } - break; - - case ICMD_TABLESWITCH: /* ..., index ==> ... */ { s4 i, l; @@ -2858,243 +2400,95 @@ nowperformreturn: } break; - - case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */ - { - s4 i; - lookup_target_t *lookup; - - lookup = iptr->dst.lookup; - - i = iptr->sx.s23.s2.lookupcount; - - MCODECHECK((i<<2)+8); - s1 = emit_load_s1(jd, iptr, REG_ITMP1); - - while (--i >= 0) { - M_CMP_IMM(lookup->value, s1); - emit_beq(cd, lookup->target.block); - lookup++; - } - - emit_br(cd, iptr->sx.s23.s3.lookupdefault.block); - ALIGNCODENOP; + case ICMD_BUILTIN: + bte = iptr->sx.s23.s3.bte; + if (bte->stub == NULL) { + M_MOV_IMM(bte->fp, REG_ITMP1); } - break; - - case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */ - - REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr); + else { + M_MOV_IMM(bte->stub, REG_ITMP1); + } + M_CALL(REG_ITMP1); - bte = iptr->sx.s23.s3.bte; - md = bte->md; - -#if defined(ENABLE_ESCAPE_REASON) - if (bte->fp == BUILTIN_escape_reason_new) { - void set_escape_reasons(void *); - M_ASUB_IMM(8, REG_SP); - M_MOV_IMM(iptr->escape_reasons, REG_ITMP1); - M_AST(EDX, REG_SP, 4); - M_AST(REG_ITMP1, REG_SP, 0); - M_MOV_IMM(set_escape_reasons, REG_ITMP1); - M_CALL(REG_ITMP1); - M_ALD(EDX, REG_SP, 4); - M_AADD_IMM(8, REG_SP); +#if defined(ENABLE_ESCAPE_CHECK) + if (bte->opcode == ICMD_NEW || bte->opcode == ICMD_NEWARRAY) { + /*emit_escape_annotate_object(cd, m);*/ } #endif + break; - goto gen_method; - - case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */ + case ICMD_INVOKESPECIAL: + M_ALD(REG_ITMP1, REG_SP, 0 * 8); + emit_nullpointer_check(cd, iptr, REG_ITMP1); + /* fall through */ - case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */ - case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */ - case ICMD_INVOKEINTERFACE: + case ICMD_INVOKESTATIC: + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + um = iptr->sx.s23.s3.um; - REPLACEMENT_POINT_INVOKE(cd, iptr); + patcher_add_patch_ref(jd, PATCHER_invokestatic_special, + um, 0); - if (INSTRUCTION_IS_UNRESOLVED(iptr)) { - md = iptr->sx.s23.s3.um->methodref->parseddesc.md; - lm = NULL; + disp = 0; } else { lm = iptr->sx.s23.s3.fmiref->p.method; - md = lm->parseddesc; + disp = (ptrint) lm->stubroutine; } -gen_method: - s3 = md->paramcount; - - MCODECHECK((s3 << 1) + 64); - - /* copy arguments to registers or stack location */ - - for (s3 = s3 - 1; s3 >= 0; s3--) { - var = VAR(iptr->sx.s23.s2.args[s3]); - - /* Already Preallocated (ARGVAR) ? */ - if (var->flags & PREALLOC) - continue; - if (IS_INT_LNG_TYPE(var->type)) { - if (!md->params[s3].inmemory) { - log_text("No integer argument registers available!"); - assert(0); - - } else { - if (IS_2_WORD_TYPE(var->type)) { - d = emit_load(jd, iptr, var, REG_ITMP12_PACKED); - M_LST(d, REG_SP, md->params[s3].regoff); - } else { - d = emit_load(jd, iptr, var, REG_ITMP1); - M_IST(d, REG_SP, md->params[s3].regoff); - } - } - - } else { - if (!md->params[s3].inmemory) { - s1 = md->params[s3].regoff; - d = emit_load(jd, iptr, var, s1); - M_FLTMOVE(d, s1); - - } else { - d = emit_load(jd, iptr, var, REG_FTMP1); - if (IS_2_WORD_TYPE(var->type)) - M_DST(d, REG_SP, md->params[s3].regoff); - else - M_FST(d, REG_SP, md->params[s3].regoff); - } - } - } /* end of for */ - - switch (iptr->opc) { - case ICMD_BUILTIN: - d = md->returntype.type; - - if (bte->stub == NULL) { - M_MOV_IMM(bte->fp, REG_ITMP1); - } - else { - M_MOV_IMM(bte->stub, REG_ITMP1); - } - M_CALL(REG_ITMP1); - -#if defined(ENABLE_ESCAPE_CHECK) - if (bte->opcode == ICMD_NEW || bte->opcode == ICMD_NEWARRAY) { - /*emit_escape_annotate_object(cd, m);*/ - } -#endif - break; - - case ICMD_INVOKESPECIAL: - M_ALD(REG_ITMP1, REG_SP, 0 * 8); - emit_nullpointer_check(cd, iptr, REG_ITMP1); - /* fall through */ - - case ICMD_INVOKESTATIC: - if (lm == NULL) { - unresolved_method *um = iptr->sx.s23.s3.um; - - patcher_add_patch_ref(jd, PATCHER_invokestatic_special, - um, 0); - - disp = 0; - d = md->returntype.type; - } - else { - disp = (ptrint) lm->stubroutine; - d = lm->parseddesc->returntype.type; - } - - M_MOV_IMM2(disp, REG_ITMP2); - M_CALL(REG_ITMP2); - break; - - case ICMD_INVOKEVIRTUAL: - M_ALD(REG_ITMP1, REG_SP, 0 * 8); - emit_nullpointer_check(cd, iptr, s1); - - if (lm == NULL) { - unresolved_method *um = iptr->sx.s23.s3.um; - - patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); + M_MOV_IMM2(disp, REG_ITMP2); + M_CALL(REG_ITMP2); + break; - s1 = 0; - d = md->returntype.type; - } - else { - s1 = OFFSET(vftbl_t, table[0]) + - sizeof(methodptr) * lm->vftblindex; - d = md->returntype.type; - } + case ICMD_INVOKEVIRTUAL: + M_ALD(REG_ITMP1, REG_SP, 0 * 8); + emit_nullpointer_check(cd, iptr, s1); - M_ALD(REG_METHODPTR, REG_ITMP1, - OFFSET(java_object_t, vftbl)); - M_ALD32(REG_ITMP3, REG_METHODPTR, s1); - M_CALL(REG_ITMP3); - break; + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + um = iptr->sx.s23.s3.um; - case ICMD_INVOKEINTERFACE: - M_ALD(REG_ITMP1, REG_SP, 0 * 8); - emit_nullpointer_check(cd, iptr, s1); + patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0); - if (lm == NULL) { - unresolved_method *um = iptr->sx.s23.s3.um; + s1 = 0; + } + else { + lm = iptr->sx.s23.s3.fmiref->p.method; + s1 = OFFSET(vftbl_t, table[0]) + + sizeof(methodptr) * lm->vftblindex; + } - patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0); + M_ALD(REG_METHODPTR, REG_ITMP1, + OFFSET(java_object_t, vftbl)); + M_ALD32(REG_ITMP3, REG_METHODPTR, s1); + M_CALL(REG_ITMP3); + break; - s1 = 0; - s2 = 0; - d = md->returntype.type; - } - else { - s1 = OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr) * lm->clazz->index; + case ICMD_INVOKEINTERFACE: + M_ALD(REG_ITMP1, REG_SP, 0 * 8); + emit_nullpointer_check(cd, iptr, s1); - s2 = sizeof(methodptr) * (lm - lm->clazz->methods); + if (INSTRUCTION_IS_UNRESOLVED(iptr)) { + um = iptr->sx.s23.s3.um; - d = md->returntype.type; - } + patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0); - M_ALD(REG_METHODPTR, REG_ITMP1, - OFFSET(java_object_t, vftbl)); - M_ALD32(REG_METHODPTR, REG_METHODPTR, s1); - M_ALD32(REG_ITMP3, REG_METHODPTR, s2); - M_CALL(REG_ITMP3); - break; + s1 = 0; + s2 = 0; } + else { + lm = iptr->sx.s23.s3.fmiref->p.method; + s1 = OFFSET(vftbl_t, interfacetable[0]) - + sizeof(methodptr) * lm->clazz->index; - /* store size of call code in replacement point */ - - REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr); - REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr); - - /* d contains return type */ - - if (d != TYPE_VOID) { -#if defined(ENABLE_SSA) - if ((ls == NULL) /* || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) */ || - (ls->lifetime[iptr->dst.varindex].type != UNUSED)) - /* a "living" stackslot */ -#endif - { - if (IS_INT_LNG_TYPE(d)) { - if (IS_2_WORD_TYPE(d)) { - s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED); - M_LNGMOVE(REG_RESULT_PACKED, s1); - } - else { - s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT); - M_INTMOVE(REG_RESULT, s1); - } - } - else { - s1 = codegen_reg_of_dst(jd, iptr, REG_NULL); - } - emit_store_dst(jd, iptr, s1); - } + s2 = sizeof(methodptr) * (lm - lm->clazz->methods); } - break; + M_ALD(REG_METHODPTR, REG_ITMP1, + OFFSET(java_object_t, vftbl)); + M_ALD32(REG_METHODPTR, REG_METHODPTR, s1); + M_ALD32(REG_ITMP3, REG_METHODPTR, s2); + M_CALL(REG_ITMP3); + break; case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */ @@ -3491,59 +2885,9 @@ gen_method: emit_store_dst(jd, iptr, s1); break; -#if defined(ENABLE_SSA) - case ICMD_GETEXCEPTION: - d = codegen_reg_of_dst(jd, iptr, REG_ITMP1); - M_INTMOVE(REG_ITMP1, d); - emit_store_dst(jd, iptr, d); - break; -#endif default: - exceptions_throw_internalerror("Unknown ICMD %d during code generation", - iptr->opc); - return false; + vm_abort("Unknown ICMD %d during code generation", iptr->opc); } /* switch */ - - } /* for instruction */ - - MCODECHECK(64); - -#if defined(ENABLE_LSRA) && !defined(ENABLE_SSA) - if (!opt_lsra) -#endif -#if defined(ENABLE_SSA) - if ( ls != NULL ) { - - /* by edge splitting, in Blocks with phi moves there can only */ - /* be a goto as last command, no other Jump/Branch Command */ - - if (!last_cmd_was_goto) - codegen_emit_phi_moves(jd, bptr); - } - -#endif - - /* At the end of a basic block we may have to append some nops, - because the patcher stub calling code might be longer than the - actual instruction. So codepatching does not change the - following block unintentionally. */ - - if (cd->mcodeptr < cd->lastmcodeptr) { - while (cd->mcodeptr < cd->lastmcodeptr) { - M_NOP; - } - } - - } /* if (bptr -> flags >= BBREACHED) */ - } /* for basic block */ - - /* generate stubs */ - - emit_patcher_traps(jd); - - /* everything's ok */ - - return true; } @@ -3588,7 +2932,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s /* create method header */ (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ - (void) dseg_add_unique_s4(cd, cd->stackframesize * 8 + 4); /* FrameSize */ + (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */ (void) dseg_add_unique_s4(cd, 0); /* IntSave */ (void) dseg_add_unique_s4(cd, 0); /* FltSave */