* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / alpha / codegen.c
index b39fba8cbc62dfd88fd0a58275439f4ba3d6419f..bb5f050f82ced2be5400d5c93ba7bafe8b08e500 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
 
-   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.
 
 
 #include "mm/memory.h"
 
-#include "native/jni.h"
-#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/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/loader.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/linenumbertable.h"
-#include "vm/jit/parse.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/parse.hpp"
+#include "vm/jit/patcher-common.hpp"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
-
-#if defined(ENABLE_LSRA)
+#include "vm/jit/replace.hpp"
+#include "vm/jit/stacktrace.hpp"
+#include "vm/jit/trap.h"
+
+#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
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -246,12 +246,12 @@ bool codegen_emit(jitdata *jd)
                /* decide which monitor enter function to call */
 
                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);
                }
                else {
                        M_BNEZ(REG_A0, 1);
-                       M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
+                       M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
                }
 
                M_AST(REG_A0, REG_SP, s1 * 8);
@@ -1115,17 +1115,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_FADD(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_FADDS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_FADDS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_FADDS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_FADDS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1135,17 +1131,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_DADD(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_DADDS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_DADDS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_DADDS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_DADDS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1155,17 +1147,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_FSUB(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_FSUBS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_FSUBS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_FSUBS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_FSUBS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1175,17 +1163,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_DSUB(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_DSUBS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_DSUBS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_DSUBS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_DSUBS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1195,17 +1179,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_FMUL(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_FMULS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_FMULS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_FMULS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_FMULS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1215,17 +1195,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_DMUL(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_DMULS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_DMULS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_DMULS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_DMULS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1235,17 +1211,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_FDIV(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_FDIVS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_FDIVS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_FDIVS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_FDIVS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1255,17 +1227,13 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_DDIV(s1, s2, d);
+                       if (d == s1 || d == s2) {
+                               M_DDIVS(s1, s2, REG_FTMP3);
+                               M_TRAPB;
+                               M_FMOV(REG_FTMP3, d);
                        } else {
-                               if (d == s1 || d == s2) {
-                                       M_DDIVS(s1, s2, REG_FTMP3);
-                                       M_TRAPB;
-                                       M_FMOV(REG_FTMP3, d);
-                               } else {
-                                       M_DDIVS(s1, s2, d);
-                                       M_TRAPB;
-                               }
+                               M_DDIVS(s1, s2, d);
+                               M_TRAPB;
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1274,7 +1242,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_L2F:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_LST(s1, REG_PV, disp);
                        M_DLD(d, REG_PV, disp);
                        M_CVTLF(d, d);
@@ -1285,7 +1253,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_L2D:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_LST(s1, REG_PV, disp);
                        M_DLD(d, REG_PV, disp);
                        M_CVTLD(d, d);
@@ -1296,7 +1264,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_D2I:
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_CVTDL_C(s1, REG_FTMP2);
                        M_CVTLI(REG_FTMP2, REG_FTMP3);
                        M_DST(REG_FTMP3, REG_PV, disp);
@@ -1308,7 +1276,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_D2L:
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_unique_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
                        M_CVTDL_C(s1, REG_FTMP2);
                        M_DST(REG_FTMP2, REG_PV, disp);
                        M_LLD(d, REG_PV, disp);
@@ -1328,12 +1296,8 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       if (opt_noieee) {
-                               M_CVTDF(s1, d);
-                       } else {
-                               M_CVTDFS(s1, d);
-                               M_TRAPB;
-                       }
+                       M_CVTDFS(s1, d);
+                       M_TRAPB;
                        emit_store_dst(jd, iptr, d);
                        break;
                
@@ -1342,25 +1306,15 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       if (opt_noieee) {
-                               M_LSUB_IMM(REG_ZERO, 1, d);
-                               M_FCMPEQ(s1, s2, REG_FTMP3);
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instructions */
-                               M_CLR   (d);
-                               M_FCMPLT(s2, s1, REG_FTMP3);
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
-                               M_LADD_IMM(REG_ZERO, 1, d);
-                       } else {
-                               M_LSUB_IMM(REG_ZERO, 1, d);
-                               M_FCMPEQS(s1, s2, REG_FTMP3);
-                               M_TRAPB;
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instructions */
-                               M_CLR   (d);
-                               M_FCMPLTS(s2, s1, REG_FTMP3);
-                               M_TRAPB;
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
-                               M_LADD_IMM(REG_ZERO, 1, d);
-                       }
+                       M_LSUB_IMM(REG_ZERO, 1, d);
+                       M_FCMPEQS(s1, s2, REG_FTMP3);
+                       M_TRAPB;
+                       M_FBEQZ (REG_FTMP3, 1);        /* jump over next instructions */
+                       M_CLR   (d);
+                       M_FCMPLTS(s2, s1, REG_FTMP3);
+                       M_TRAPB;
+                       M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
+                       M_LADD_IMM(REG_ZERO, 1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
                        
@@ -1369,25 +1323,15 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       if (opt_noieee) {
-                               M_LADD_IMM(REG_ZERO, 1, d);
-                               M_FCMPEQ(s1, s2, REG_FTMP3);
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
-                               M_CLR   (d);
-                               M_FCMPLT(s1, s2, REG_FTMP3);
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
-                               M_LSUB_IMM(REG_ZERO, 1, d);
-                       } else {
-                               M_LADD_IMM(REG_ZERO, 1, d);
-                               M_FCMPEQS(s1, s2, REG_FTMP3);
-                               M_TRAPB;
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
-                               M_CLR   (d);
-                               M_FCMPLTS(s1, s2, REG_FTMP3);
-                               M_TRAPB;
-                               M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
-                               M_LSUB_IMM(REG_ZERO, 1, d);
-                       }
+                       M_LADD_IMM(REG_ZERO, 1, d);
+                       M_FCMPEQS(s1, s2, REG_FTMP3);
+                       M_TRAPB;
+                       M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
+                       M_CLR   (d);
+                       M_FCMPLTS(s1, s2, REG_FTMP3);
+                       M_TRAPB;
+                       M_FBEQZ (REG_FTMP3, 1);        /* jump over next instruction  */
+                       M_LSUB_IMM(REG_ZERO, 1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1783,8 +1727,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                  0);
                        }
 
@@ -1828,8 +1772,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                  0);
                        }
 
@@ -1874,8 +1818,8 @@ bool codegen_emit(jitdata *jd)
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
                                                                                  0);
                        }
                        
@@ -2653,9 +2597,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 */
@@ -2707,9 +2651,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 */
@@ -2781,8 +2722,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)); */
@@ -2798,8 +2737,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_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
                                        emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
@@ -2867,9 +2804,6 @@ gen_method:
                                supervftbl = super->vftbl;
                        }
 
-                       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);
 
@@ -2952,14 +2886,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_CMPULE(REG_ITMP1, REG_ITMP2, d);
 
@@ -3068,10 +2998,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        codeinfo    *code;
        codegendata *cd;
        methoddesc  *md;
-       s4           i, j;                 /* count variables                    */
-       s4           t;
-       s4           s1, s2, disp;
-       s4           funcdisp;             /* displacement of the function       */
+       int          i, j;
+       int          t;
+       int          s1, s2;
+       int          disp;
 
        /* get required compiler data */
 
@@ -3106,13 +3036,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
        M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
 
-       /* 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);
-
 #if defined(ENABLE_GC_CACAO)
        /* Save callee saved integer registers in stackframeinfo (GC may
           need to recover them during a collection). */
@@ -3241,13 +3164,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_PV, REG_PV, funcdisp);
+       disp = dseg_add_functionptr(cd, f);
+       M_ALD(REG_PV, REG_PV, disp);
        M_JSR(REG_RA, REG_PV);              /* call native method                 */
        disp = (s4) (cd->mcodeptr - cd->mcodebase);
        M_LDA(REG_PV, REG_RA, -disp);       /* recompute pv from ra               */
@@ -3325,10 +3249,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
        M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
        M_JMP(REG_ZERO, REG_ITMP3);         /* jump to asm exception handler      */
-       
-       /* generate patcher stubs */
-
-       emit_patcher_traps(jd);
 }