X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fmips%2Fcodegen.c;h=7fac7239123a0ac7950dab501895bae3951acce0;hb=8c6bb03b79a31fcdb02e2331a91a928d558c2845;hp=4bf2d0552a01e412c838f7393dc63171fe73086e;hpb=1cc5e8f6b04e16be6c2db2fb684af49b961eb7bc;p=cacao.git diff --git a/src/vm/jit/mips/codegen.c b/src/vm/jit/mips/codegen.c index 4bf2d0552..7fac72391 100644 --- a/src/vm/jit/mips/codegen.c +++ b/src/vm/jit/mips/codegen.c @@ -1,9 +1,7 @@ /* src/vm/jit/mips/codegen.c - machine code generator for MIPS - Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -37,35 +35,35 @@ #include "vm/jit/mips/arch.h" #include "vm/jit/mips/codegen.h" -#include "mm/memory.h" +#include "mm/memory.hpp" -#include "native/localref.h" -#include "native/native.h" +#include "native/localref.hpp" +#include "native/native.hpp" -#include "threads/lock-common.h" +#include "threads/lock.hpp" -#include "vm/builtin.h" -#include "vm/exceptions.h" -#include "vm/vm.h" +#include "vm/jit/builtin.hpp" +#include "vm/class.hpp" +#include "vm/exceptions.hpp" +#include "vm/options.h" +#include "vm/vm.hpp" #include "vm/jit/abi.h" #include "vm/jit/asmpart.h" -#include "vm/jit/codegen-common.h" +#include "vm/jit/codegen-common.hpp" #include "vm/jit/dseg.h" -#include "vm/jit/emit-common.h" -#include "vm/jit/jit.h" -#include "vm/jit/md.h" -#include "vm/jit/patcher-common.h" +#include "vm/jit/emit-common.hpp" +#include "vm/jit/jit.hpp" +#include "vm/jit/linenumbertable.hpp" +#include "vm/jit/patcher-common.hpp" #include "vm/jit/reg.h" -#include "vm/jit/replace.h" +#include "vm/jit/replace.hpp" +#include "vm/jit/trap.h" #if defined(ENABLE_LSRA) # include "vm/jit/allocator/lsra.h" #endif -#include "vmcore/class.h" -#include "vmcore/options.h" - /* codegen_emit **************************************************************** @@ -83,7 +81,6 @@ bool codegen_emit(jitdata *jd) varinfo *var; basicblock *bptr; instruction *iptr; - exception_entry *ex; u2 currentline; constant_classref *cr; unresolved_class *uc; @@ -130,7 +127,7 @@ bool codegen_emit(jitdata *jd) #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */ - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { # if SIZEOF_VOID_P == 8 cd->stackframesize++; # else @@ -150,19 +147,8 @@ bool codegen_emit(jitdata *jd) (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ -#if defined(ENABLE_THREADS) - /* IsSync contains the offset relative to the stack pointer for the - argument of monitor_exit used in the exception handler. Since the - offset could be zero and give a wrong meaning of the flag it is - offset by one. - */ - - if (checksync && (m->flags & ACC_SYNCHRONIZED)) - (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */ - else -#endif - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ - + code->synchronizedoffset = rd->memuse * 8; + /* REMOVEME: We still need it for exception handling in assembler. */ if (code_is_leafmethod(code)) @@ -172,18 +158,7 @@ bool codegen_emit(jitdata *jd) (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */ (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */ - dseg_addlinenumbertablesize(cd); - (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */ - - /* create exception table */ - for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) { - dseg_add_target(cd, ex->start); - dseg_add_target(cd, ex->end); - dseg_add_target(cd, ex->handler); - (void) dseg_add_unique_address(cd, ex->catchtype.any); - } - /* create stack frame (if necessary) */ if (cd->stackframesize) @@ -289,7 +264,7 @@ bool codegen_emit(jitdata *jd) /* call monitorenter function */ #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { /* stack offset for monitor argument */ s1 = rd->memuse; @@ -311,7 +286,7 @@ bool codegen_emit(jitdata *jd) /* get correct lock object */ if (m->flags & ACC_STATIC) { - disp = dseg_add_address(cd, &m->class->object.header); + disp = dseg_add_address(cd, &m->clazz->object.header); M_ALD(REG_A0, REG_PV, disp); disp = dseg_add_functionptr(cd, LOCK_monitor_enter); M_ALD(REG_ITMP3, REG_PV, disp); @@ -321,7 +296,7 @@ bool codegen_emit(jitdata *jd) M_BNEZ(REG_A0, 2); disp = dseg_add_functionptr(cd, LOCK_monitor_enter); M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */ - M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER); + M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException); } M_JSR(REG_RA, REG_ITMP3); @@ -414,7 +389,7 @@ bool codegen_emit(jitdata *jd) for (iptr = bptr->iinstr; len > 0; len--, iptr++) { if (iptr->line != currentline) { - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add(cd, iptr->line); currentline = iptr->line; } @@ -435,14 +410,14 @@ bool codegen_emit(jitdata *jd) case ICMD_INLINE_BODY: REPLACEMENT_POINT_INLINE_BODY(cd, iptr); - dseg_addlinenumber_inline_start(cd, iptr); - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add_inline_start(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_INLINE_END: - dseg_addlinenumber_inline_end(cd, iptr); - dseg_addlinenumber(cd, iptr->line); + linenumbertable_list_entry_add_inline_end(cd, iptr); + linenumbertable_list_entry_add(cd, iptr->line); break; case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */ @@ -1428,13 +1403,13 @@ bool codegen_emit(jitdata *jd) M_CMPLT(s1, s2, REG_ITMP3); M_CMPLT(s2, s1, REG_ITMP1); M_ISUB(REG_ITMP1, REG_ITMP3, d); - M_BNEZ(d, 4); - M_NOP; + emit_label_bnez(cd, BRANCH_LABEL_1, d); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); M_CMPULT(s1, s2, REG_ITMP3); M_CMPULT(s2, s1, REG_ITMP1); M_ISUB(REG_ITMP1, REG_ITMP3, d); + emit_label(cd, BRANCH_LABEL_1); #endif emit_store_dst(jd, iptr, d); break; @@ -2000,9 +1975,9 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, disp); + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2050,9 +2025,9 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, disp); + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2099,9 +2074,9 @@ bool codegen_emit(jitdata *jd) fieldtype = fi->type; disp = dseg_add_address(cd, fi->value); - if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) + if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) patcher_add_patch_ref(jd, PATCHER_initialize_class, - fi->class, disp); + fi->clazz, disp); } M_ALD(REG_ITMP1, REG_PV, disp); @@ -2455,12 +2430,12 @@ bool codegen_emit(jitdata *jd) ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPLT(s1, REG_ITMP2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); /* XXX */ - M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPULT(s2, REG_ITMP2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); } #endif break; @@ -2485,22 +2460,22 @@ bool codegen_emit(jitdata *jd) #else if (iptr->sx.val.l == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); - M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */ - M_NOP; + emit_label_bgtz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1)); emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1)); - emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1)); + emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1)); + emit_label(cd, BRANCH_LABEL_1); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPLT(s1, REG_ITMP2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); /* XXX */ - M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPUGT(s2, REG_ITMP2, REG_ITMP3); emit_beqz(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); } #endif break; @@ -2555,21 +2530,21 @@ bool codegen_emit(jitdata *jd) if (iptr->sx.val.l == 0) { s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED); emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1)); - M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */ - M_NOP; + emit_label_bltz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1)); emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1)); + emit_label(cd, BRANCH_LABEL_1); } else { s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPGT(s1, REG_ITMP2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); /* XXX */ - M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPUGT(s2, REG_ITMP2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); } #endif break; @@ -2601,12 +2576,12 @@ bool codegen_emit(jitdata *jd) ICONST(REG_ITMP2, iptr->sx.val.l >> 32); M_CMPGT(s1, REG_ITMP2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2); s2 = emit_load_s1_low(jd, iptr, REG_ITMP3); - M_BNE(s1, REG_ITMP2, 5); /* XXX */ - M_NOP; ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff); M_CMPULT(s2, REG_ITMP2, REG_ITMP3); emit_beqz(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); } #endif break; @@ -2628,11 +2603,11 @@ bool codegen_emit(jitdata *jd) s1 = emit_load_s1_high(jd, iptr, REG_ITMP1); s2 = emit_load_s2_high(jd, iptr, REG_ITMP2); - M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */ - M_NOP; + emit_label_bne(cd, BRANCH_LABEL_1, s1, s2); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); emit_beq(cd, iptr->dst.block, s1, s2); + emit_label(cd, BRANCH_LABEL_1); break; #endif @@ -2679,13 +2654,12 @@ bool codegen_emit(jitdata *jd) M_CMPLT(s1, s2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPGT(s1, s2, REG_ITMP3); - /* load low-bits before the branch, so we know the distance */ + emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); /* XXX */ - M_NOP; M_CMPULT(s1, s2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); break; #endif @@ -2708,13 +2682,12 @@ bool codegen_emit(jitdata *jd) M_CMPGT(s1, s2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPLT(s1, s2, REG_ITMP3); - /* load low-bits before the branch, so we know the distance */ + emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); /* XXX */ - M_NOP; M_CMPUGT(s1, s2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); break; #endif @@ -2737,13 +2710,12 @@ bool codegen_emit(jitdata *jd) M_CMPLT(s1, s2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPGT(s1, s2, REG_ITMP3); - /* load low-bits before the branch, so we know the distance */ + emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); /* XXX */ - M_NOP; M_CMPUGT(s1, s2, REG_ITMP3); emit_beqz(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); break; #endif @@ -2766,13 +2738,12 @@ bool codegen_emit(jitdata *jd) M_CMPGT(s1, s2, REG_ITMP3); emit_bnez(cd, iptr->dst.block, REG_ITMP3); M_CMPLT(s1, s2, REG_ITMP3); - /* load low-bits before the branch, so we know the distance */ + emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3); s1 = emit_load_s1_low(jd, iptr, REG_ITMP1); s2 = emit_load_s2_low(jd, iptr, REG_ITMP2); - M_BNEZ(REG_ITMP3, 4); /* XXX */ - M_NOP; M_CMPULT(s1, s2, REG_ITMP3); emit_beqz(cd, iptr->dst.block, REG_ITMP3); + emit_label(cd, BRANCH_LABEL_1); break; #endif @@ -2838,7 +2809,7 @@ nowperformreturn: #endif #if defined(ENABLE_THREADS) - if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + if (checksync && code_is_synchronized(code)) { disp = dseg_add_functionptr(cd, LOCK_monitor_exit); M_ALD(REG_ITMP3, REG_PV, disp); @@ -3193,9 +3164,9 @@ gen_method: } else { s1 = OFFSET(vftbl_t, interfacetable[0]) - - sizeof(methodptr*) * lm->class->index; + sizeof(methodptr*) * lm->clazz->index; - s2 = sizeof(methodptr) * (lm - lm->class->methods); + s2 = sizeof(methodptr) * (lm - lm->clazz->methods); } /* implicit null-pointer check */ @@ -3260,9 +3231,6 @@ gen_method: superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) - CODEGEN_CRITICAL_SECTION_NEW; - s1 = emit_load_s1(jd, iptr, REG_ITMP1); /* if class is not resolved, check which code to call */ @@ -3333,8 +3301,6 @@ gen_method: M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP3, REG_PV, disp); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); /* if (s1 != REG_ITMP1) { */ /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */ @@ -3349,8 +3315,6 @@ gen_method: M_ALD(REG_ITMP3, REG_PV, disp); M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - /* } */ M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3); emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1); @@ -3415,9 +3379,6 @@ gen_method: superindex = super->index; } - if ((super == NULL) || !(super->flags & ACC_INTERFACE)) - CODEGEN_CRITICAL_SECTION_NEW; - s1 = emit_load_s1(jd, iptr, REG_ITMP1); d = codegen_reg_of_dst(jd, iptr, REG_ITMP2); @@ -3495,14 +3456,10 @@ gen_method: M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl)); M_ALD(REG_ITMP2, REG_PV, disp); - CODEGEN_CRITICAL_SECTION_START; - M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval)); M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval)); - CODEGEN_CRITICAL_SECTION_END; - M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1); M_CMPULT(REG_ITMP2, REG_ITMP1, d); M_XOR_IMM(d, 1, d); @@ -3608,8 +3565,6 @@ gen_method: } /* if (bptr -> flags >= BBREACHED) */ } /* for basic block */ - dseg_createlinenumbertable(cd); - /* generate traps */ emit_patcher_traps(jd); @@ -3620,31 +3575,6 @@ gen_method: } -/* codegen_emit_stub_compiler ************************************************** - - Emits a stub routine which calls the compiler. - -*******************************************************************************/ - -void codegen_emit_stub_compiler(jitdata *jd) -{ - methodinfo *m; - codegendata *cd; - - /* get required compiler data */ - - m = jd->m; - cd = jd->cd; - - /* code for the stub */ - - M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */ - M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */ - M_JMP(REG_PV); - M_NOP; -} - - /* codegen_emit_stub_native **************************************************** Emits a stub routine which calls a native method. @@ -3659,8 +3589,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s methoddesc *md; s4 i, j; s4 t; - s4 s1, s2, disp; - s4 funcdisp; /* displacement of the function */ + int s1, s2; + int disp; /* get required compiler data */ @@ -3676,7 +3606,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s cd->stackframesize = 1 + /* return address */ - sizeof(stackframeinfo) / SIZEOF_VOID_P + + sizeof(stackframeinfo_t) / SIZEOF_VOID_P + sizeof(localref_table) / SIZEOF_VOID_P + md->paramcount + /* for saving arguments over calls */ #if SIZEOF_VOID_P == 4 @@ -3694,12 +3624,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */ (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */ - (void) dseg_add_unique_s4(cd, 0); /* IsSync */ (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */ (void) dseg_add_unique_s4(cd, 0); /* IntSave */ (void) dseg_add_unique_s4(cd, 0); /* FltSave */ - (void) dseg_addlinenumbertablesize(cd); - (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */ /* generate stub code */ @@ -3711,13 +3638,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s emit_verbosecall_enter(jd); #endif - /* get function address (this must happen before the stackframeinfo) */ - - funcdisp = dseg_add_functionptr(cd, f); - - if (f == NULL) - patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp); - /* save integer and float argument registers */ #if SIZEOF_VOID_P == 8 @@ -3946,13 +3866,14 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s /* put env into first argument register */ - disp = dseg_add_address(cd, _Jv_env); + disp = dseg_add_address(cd, VM_get_jnienv()); M_ALD(REG_A0, REG_PV, disp); } - /* do the native function call */ + /* Call the native function. */ - M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */ + disp = dseg_add_functionptr(cd, f); + M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */ M_JSR(REG_RA, REG_ITMP3); /* call native method */ M_NOP; /* delay slot */