* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / powerpc / codegen.c
index d164016bea0218f011434c8bf377a4eb217c2964..dcfc0482e276bfe38417c7cbebd7ecc8ca58ab41 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
 
-   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/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/stringlocal.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/abi-asm.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/md.h"
+#include "vm/jit/emit-common.hpp"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/linenumbertable.hpp"
 #include "vm/jit/methodheader.h"
-#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#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"
+#include "vm/jit/replace.hpp"
+#include "vm/jit/stacktrace.hpp"
+#include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen *********************************************************************
 
@@ -88,7 +84,6 @@ bool codegen_emit(jitdata *jd)
        codegendata        *cd;
        registerdata       *rd;
        s4                  len, s1, s2, s3, d, disp;
-       ptrint              a;
        varinfo            *var;
        basicblock         *bptr;
        instruction        *iptr;
@@ -100,7 +95,8 @@ bool codegen_emit(jitdata *jd)
        fieldinfo          *fi;
        unresolved_field   *uf;
        s4                  fieldtype;
-       s4                 varindex;
+       s4                  varindex;
+       int                 i;
 
        /* get required compiler data */
 
@@ -308,13 +304,13 @@ bool codegen_emit(jitdata *jd)
                /* get or test the 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);
                }
                else {
                        M_TST(REG_A0);
                        M_BNE(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);
@@ -479,16 +475,16 @@ bool codegen_emit(jitdata *jd)
                case ICMD_FCONST:     /* ...  ==> ..., constant                       */
 
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       a = dseg_add_float(cd, iptr->sx.val.f);
-                       M_FLD(d, REG_PV, a);
+                       disp = dseg_add_float(cd, iptr->sx.val.f);
+                       M_FLD(d, REG_PV, disp);
                        emit_store_dst(jd, iptr, d);
                        break;
                        
                case ICMD_DCONST:     /* ...  ==> ..., constant                       */
 
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       a = dseg_add_double(cd, iptr->sx.val.d);
-                       M_DLD(d, REG_PV, a);
+                       disp = dseg_add_double(cd, iptr->sx.val.d);
+                       M_DLD(d, REG_PV, disp);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -773,7 +769,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
 
                        /* XXX TODO: only do this if arithmetic check is really done! */
-                       M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
+                       M_IOR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
                        /* XXX could be optimized */
                        emit_arithmetic_check(cd, iptr, REG_ITMP3);
 
@@ -829,7 +825,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND_IMM(s2, 0x1f, REG_ITMP3);
+                       M_IAND_IMM(s2, 0x1f, REG_ITMP3);
                        M_SLL(s1, REG_ITMP3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -848,7 +844,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND_IMM(s2, 0x1f, REG_ITMP3);
+                       M_IAND_IMM(s2, 0x1f, REG_ITMP3);
                        M_SRA(s1, REG_ITMP3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -867,7 +863,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND_IMM(s2, 0x1f, REG_ITMP2);
+                       M_IAND_IMM(s2, 0x1f, REG_ITMP2);
                        M_SRL(s1, REG_ITMP2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -890,7 +886,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_AND(s1, s2, d);
+                       M_IAND(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -900,7 +896,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
-                               M_AND_IMM(s1, iptr->sx.val.i, d);
+                               M_IAND_IMM(s1, iptr->sx.val.i, d);
                        /*
                        else if (iptr->sx.val.i == 0xffffff) {
                                M_RLWINM(s1, 0, 8, 31, d);
@@ -908,7 +904,7 @@ bool codegen_emit(jitdata *jd)
                        */
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.i);
-                               M_AND(s1, REG_ITMP3, d);
+                               M_IAND(s1, REG_ITMP3, d);
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -918,10 +914,10 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
-                       M_AND(s1, s2, GET_LOW_REG(d));
+                       M_IAND(s1, s2, GET_LOW_REG(d));
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
-                       M_AND(s1, s2, GET_HIGH_REG(d));
+                       M_IAND(s1, s2, GET_HIGH_REG(d));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -932,18 +928,18 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_AND_IMM(s1, s3, GET_LOW_REG(d));
+                               M_IAND_IMM(s1, s3, GET_LOW_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);
-                               M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
+                               M_IAND(s1, REG_ITMP3, GET_LOW_REG(d));
                        }
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s3 = iptr->sx.val.l >> 32;
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_AND_IMM(s1, s3, GET_HIGH_REG(d));
+                               M_IAND_IMM(s1, s3, GET_HIGH_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
-                               M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
+                               M_IAND(s1, REG_ITMP3, GET_HIGH_REG(d));
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -958,7 +954,7 @@ bool codegen_emit(jitdata *jd)
                        M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
                        if (iptr->sx.val.i >= 32768) {
                                M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
-                               M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
+                               M_IOR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
                                M_IADD(s1, REG_ITMP2, REG_ITMP2);
                        }
                        else {
@@ -979,7 +975,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_OR(s1, s2, d);
+                       M_IOR(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -989,10 +985,10 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
-                               M_OR_IMM(s1, iptr->sx.val.i, d);
+                               M_IOR_IMM(s1, iptr->sx.val.i, d);
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.i);
-                               M_OR(s1, REG_ITMP3, d);
+                               M_IOR(s1, REG_ITMP3, d);
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1002,10 +998,10 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
-                       M_OR(s1, s2, GET_LOW_REG(d));
+                       M_IOR(s1, s2, GET_LOW_REG(d));
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
-                       M_OR(s1, s2, GET_HIGH_REG(d));
+                       M_IOR(s1, s2, GET_HIGH_REG(d));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1016,18 +1012,18 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_OR_IMM(s1, s3, GET_LOW_REG(d));
+                               M_IOR_IMM(s1, s3, GET_LOW_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);
-                               M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
+                               M_IOR(s1, REG_ITMP3, GET_LOW_REG(d));
                        }
                        s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
                        s3 = iptr->sx.val.l >> 32;
                        if ((s3 >= 0) && (s3 <= 65535))
-                               M_OR_IMM(s1, s3, GET_HIGH_REG(d));
+                               M_IOR_IMM(s1, s3, GET_HIGH_REG(d));
                        else {
                                ICONST(REG_ITMP3, s3);                 /* don't use REG_ITMP2 */
-                               M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
+                               M_IOR(s1, REG_ITMP3, GET_HIGH_REG(d));
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1501,9 +1497,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);
@@ -1547,9 +1543,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);
@@ -1753,19 +1749,19 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
                        if (iptr->sx.val.l == 0) {
-                               M_OR_TST(s1, s2, REG_ITMP3);
+                               M_IOR_TST(s1, s2, REG_ITMP3);
                        }
                        else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
                                M_XOR_IMM(s2, 0, REG_ITMP2);
                                M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
                                M_XOR(s1, REG_ITMP3, REG_ITMP1);
                                ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
                                M_XOR(s2, REG_ITMP3, REG_ITMP2);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        emit_beq(cd, iptr->dst.block);
                        break;
@@ -1804,7 +1800,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
 /*                     if (iptr->sx.val.l == 0) { */
-/*                             M_OR(s1, s2, REG_ITMP3); */
+/*                             M_IOR(s1, s2, REG_ITMP3); */
 /*                             M_CMPI(REG_ITMP3, 0); */
 
 /*                     } else  */
@@ -1831,19 +1827,19 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
                        if (iptr->sx.val.l == 0) {
-                               M_OR_TST(s1, s2, REG_ITMP3);
+                               M_IOR_TST(s1, s2, REG_ITMP3);
                        }
                        else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
                                M_XOR_IMM(s2, 0, REG_ITMP2);
                                M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        else {
                                ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
                                M_XOR(s1, REG_ITMP3, REG_ITMP1);
                                ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
                                M_XOR(s2, REG_ITMP3, REG_ITMP2);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
+                               M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
                        }
                        emit_bne(cd, iptr->dst.block);
                        break;
@@ -1853,7 +1849,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
 /*                     if (iptr->sx.val.l == 0) { */
-/*                             M_OR(s1, s2, REG_ITMP3); */
+/*                             M_IOR(s1, s2, REG_ITMP3); */
 /*                             M_CMPI(REG_ITMP3, 0); */
 
 /*                     } else  */
@@ -2238,50 +2234,58 @@ nowperformreturn:
                        }
 
 gen_method:
-                       s3 = md->paramcount;
+                       i = md->paramcount;
 
-                       MCODECHECK((s3 << 1) + 64);
+                       MCODECHECK((i << 1) + 64);
 
-                       /* copy arguments to registers or stack location */
+                       /* Copy arguments to registers or stack location. */
 
-                       for (s3 = s3 - 1; s3 >= 0; s3--) {
-                               var = VAR(iptr->sx.s23.s2.args[s3]);
-                               d   = md->params[s3].regoff;
+                       for (i = i - 1; i >= 0; i--) {
+                               var = VAR(iptr->sx.s23.s2.args[i]);
+                               d   = md->params[i].regoff;
+
+                               /* Already pre-allocated? */
 
-                               /* Already Preallocated? */
                                if (var->flags & PREALLOC)
                                        continue;
 
-                               if (IS_INT_LNG_TYPE(var->type)) {
-                                       if (!md->params[s3].inmemory) {
-                                               if (IS_2_WORD_TYPE(var->type)) {
-                                                       s1 = emit_load(jd, iptr, var, d);
-                                                       M_LNGMOVE(s1, d);
-                                               }
-                                               else {
-                                                       s1 = emit_load(jd, iptr, var, d);
-                                                       M_INTMOVE(s1, d);
-                                               }
-                                       }
-                                       else {
-                                               if (IS_2_WORD_TYPE(var->type)) {
-                                                       s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
-                                                       M_LST(s1, REG_SP, d);
-                                               }
-                                               else {
-                                                       s1 = emit_load(jd, iptr, var, REG_ITMP1);
-                                                       M_IST(s1, REG_SP, d);
-                                               }
+                               if (!md->params[i].inmemory) {
+                                       s1 = emit_load(jd, iptr, var, d);
+
+                                       switch (var->type) {
+                                       case TYPE_INT:
+                                       case TYPE_ADR:
+                                               M_INTMOVE(s1, d);
+                                               break;
+
+                                       case TYPE_LNG:
+                                               M_LNGMOVE(s1, d);
+                                               break;
+
+                                       case TYPE_FLT:
+                                       case TYPE_DBL:
+                                               M_FLTMOVE(s1, d);
+                                               break;
                                        }
                                }
                                else {
-                                       if (!md->params[s3].inmemory) {
-                                               s1 = emit_load(jd, iptr, var, d);
-                                               M_FLTMOVE(s1, d);
-                                       }
-                                       else {
+                                       switch (var->type) {
+                                       case TYPE_INT:
+                                       case TYPE_ADR:
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP1);
+                                               M_IST(s1, REG_SP, d);
+                                               break;
+
+                                       case TYPE_LNG:
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
+                                               M_LST(s1, REG_SP, d);
+                                               break;
+
+                                       case TYPE_FLT:
+                                       case TYPE_DBL:
                                                s1 = emit_load(jd, iptr, var, REG_FTMP1);
                                                M_DST(s1, REG_SP, d);
+                                               break;
                                        }
                                }
                        }
@@ -2366,9 +2370,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 */
@@ -2387,26 +2391,31 @@ gen_method:
                                break;
                        }
 
-                       /* store return value */
+                       /* Store return value. */
 
-                       d = md->returntype.type;
+                       switch (md->returntype.type) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+                               M_INTMOVE(REG_RESULT, s1);
+                               emit_store_dst(jd, iptr, s1);
+                               break;
 
-                       if (d != TYPE_VOID) {
-                               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_FRESULT);
-                                       M_FLTMOVE(REG_FRESULT, s1);
-                               }
+                       case TYPE_LNG:
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                               M_LNGMOVE(REG_RESULT_PACKED, s1);
+                               emit_store_dst(jd, iptr, s1);
+                               break;
+
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
+                               M_FLTMOVE(REG_FRESULT, s1);
                                emit_store_dst(jd, iptr, s1);
+                               break;
+
+                       case TYPE_VOID:
+                               break;
                        }
                        break;
 
@@ -2428,9 +2437,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 */
@@ -2447,7 +2453,7 @@ gen_method:
                                                                                disp);
 
                                        M_ILD(REG_ITMP2, REG_PV, disp);
-                                       M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
+                                       M_IAND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
                                        emit_label_beq(cd, BRANCH_LABEL_2);
                                }
 
@@ -2503,16 +2509,12 @@ gen_method:
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
 
-                                       CODEGEN_CRITICAL_SECTION_START;
-
                                        M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        M_ALD(REG_ITMP2, REG_PV, disp);
                                        if (s1 != REG_ITMP1) {
                                                M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                                               CODEGEN_CRITICAL_SECTION_END;
-
                                                M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
                                        }
                                        else {
@@ -2520,8 +2522,6 @@ gen_method:
                                                M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
                                                M_ALD(REG_ITMP2, REG_PV, disp);
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-
-                                               CODEGEN_CRITICAL_SECTION_END;
                                        }
                                        M_CMPU(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
@@ -2583,9 +2583,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);
@@ -2608,7 +2605,7 @@ gen_method:
                                                                        iptr->sx.s23.s3.c.ref, disp);
 
                                M_ILD(REG_ITMP3, REG_PV, disp);
-                               M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
+                               M_IAND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
                                emit_label_beq(cd, BRANCH_LABEL_2);
                        }
 
@@ -2664,14 +2661,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_CMPU(REG_ITMP1, REG_ITMP2);
                                M_CLR(d);
@@ -2792,7 +2785,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        s4           s1, s2;
        int          disp;
 
-       /* get required compiler data */
+       /* Sanity check. */
+
+       assert(f != NULL);
+
+       /* Get required compiler data. */
 
        m    = jd->m;
        code = jd->code;
@@ -2904,51 +2901,58 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
                t = md->paramtypes[i].type;
 
-               if (IS_INT_LNG_TYPE(t)) {
-                       if (!md->params[i].inmemory) {
-                               s1 = md->params[i].regoff;
-                               s2 = nmd->params[j].regoff;
+               if (!md->params[i].inmemory) {
+                       s1 = md->params[i].regoff;
+                       s2 = nmd->params[j].regoff;
 
-                               if (!nmd->params[j].inmemory) {
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_LNGMOVE(s1, s2);
-                                       else
-                                               M_INTMOVE(s1, s2);
-                               }
-                               else {
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_LST(s1, REG_SP, s2);
-                                       else
-                                               M_IST(s1, REG_SP, s2);
-                               }
-                       }
-                       else {
-                               s1 = md->params[i].regoff + cd->stackframesize * 8;
-                               s2 = nmd->params[j].regoff;
+                       switch (t) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               if (!nmd->params[j].inmemory)
+                                       M_INTMOVE(s1, s2);
+                               else
+                                       M_IST(s1, REG_SP, s2);
+                               break;
 
-                               M_ILD(REG_ITMP1, REG_SP, s1);
-                               if (IS_2_WORD_TYPE(t))
-                                       M_ILD(REG_ITMP2, REG_SP, s1 + 4);
+                       case TYPE_LNG:
+                               if (!nmd->params[j].inmemory)
+                                       M_LNGMOVE(s1, s2);
+                               else
+                                       M_LST(s1, REG_SP, s2);
+                               break;
 
-                               M_IST(REG_ITMP1, REG_SP, s2);
-                               if (IS_2_WORD_TYPE(t))
-                                       M_IST(REG_ITMP2, REG_SP, s2 + 4);
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               /* We only copy spilled float arguments, as the float
+                                  argument registers keep unchanged. */
+                               break;
                        }
                }
                else {
-                       /* We only copy spilled float arguments, as the float
-                          argument registers keep unchanged. */
+                       s1 = md->params[i].regoff + cd->stackframesize * 8;
+                       s2 = nmd->params[j].regoff;
 
-                       if (md->params[i].inmemory) {
-                               s1 = md->params[i].regoff + cd->stackframesize * 8;
-                               s2 = nmd->params[j].regoff;
+                       switch (t) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               M_ILD(REG_ITMP1, REG_SP, s1);
+                               M_IST(REG_ITMP1, REG_SP, s2);
+                               break;
 
+                       case TYPE_LNG:
+                               M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
+                               M_LST(REG_ITMP12_PACKED, REG_SP, s2);
+                               break;
+
+                       case TYPE_FLT:
                                M_DLD(REG_FTMP1, REG_SP, s1);
+                               M_FST(REG_FTMP1, REG_SP, s2);
+                               break;
 
-                               if (IS_2_WORD_TYPE(t))
-                                       M_DST(REG_FTMP1, REG_SP, s2);
-                               else
-                                       M_FST(REG_FTMP1, REG_SP, s2);
+                       case TYPE_DBL:
+                               M_DLD(REG_FTMP1, REG_SP, s1);
+                               M_DST(REG_FTMP1, REG_SP, s2);
+                               break;
                        }
                }
        }
@@ -2963,7 +2967,7 @@ 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);
        }