* Removed all Id tags.
[cacao.git] / src / vm / jit / x86_64 / codegen.c
index 1b28041c8005d1e0fb5e318e64e970ee685d04f5..de2ceaed1f96ddeeeee41eb17cfb0b33a074e51f 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: codegen.c 7692 2007-04-12 14:47:24Z twisti $
-
 */
 
 
 #include "vm/jit/x86_64/emit.h"
 
 #include "mm/memory.h"
+
 #include "native/jni.h"
+#include "native/localref.h"
 #include "native/native.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#endif
+#include "threads/lock-common.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
@@ -54,6 +52,7 @@
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
+#include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/dseg.h"
@@ -230,45 +229,35 @@ bool codegen_emit(jitdata *jd)
                s1 = md->params[p].regoff;
 
                if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
-                       s2 = rd->argintregs[s1];
                        if (!md->params[p].inmemory) {           /* register arguments    */
-                               if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
-                                       M_INTMOVE(s2, var->vv.regoff);
-
-                               } else {                             /* reg arg -> spilled    */
-                                   M_LST(s2, REG_SP, var->vv.regoff * 8);
-                               }
-
-                       } else {                                 /* stack arguments       */
-                               if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
+                               if (!IS_INMEMORY(var->flags))
+                                       M_INTMOVE(s1, var->vv.regoff);
+                               else
+                                   M_LST(s1, REG_SP, var->vv.regoff);
+                       }
+                       else {                                 /* stack arguments       */
+                               if (!IS_INMEMORY(var->flags))
                                        /* + 8 for return address */
-                                       M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
-
-                               } else {                             /* stack arg -> spilled  */
-                                       var->vv.regoff = cd->stackframesize + s1 + 1;
-                               }
+                                       M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
+                               else
+                                       var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
                        }
-
-               else {                                     /* floating args         */
+               }
+               else {                                     /* floating args         */
                        if (!md->params[p].inmemory) {           /* register arguments    */
-                               s2 = rd->argfltregs[s1];
-                               if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
-                                       M_FLTMOVE(s2, var->vv.regoff);
-
-                               } else {                                         /* reg arg -> spilled    */
-                                       M_DST(s2, REG_SP, var->vv.regoff * 8);
-                               }
-
-                       } else {                                 /* stack arguments       */
-                               if (!IS_INMEMORY(var->flags)) {      /* stack-arg -> register */
-                                       M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
-
-                               } else {
-                                       var->vv.regoff = cd->stackframesize + s1 + 1;
-                               }
+                               if (!IS_INMEMORY(var->flags))
+                                       M_FLTMOVE(s1, var->vv.regoff);
+                               else
+                                       M_DST(s1, REG_SP, var->vv.regoff);
+                       }
+                       else {                                 /* stack arguments       */
+                               if (!IS_INMEMORY(var->flags))
+                                       M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
+                               else
+                                       var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
                        }
                }
-       }  /* end for */
+       }
 
        /* save monitorenter argument */
 
@@ -282,10 +271,10 @@ bool codegen_emit(jitdata *jd)
                        M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
 
                        for (p = 0; p < INT_ARG_CNT; p++)
-                               M_LST(rd->argintregs[p], REG_SP, p * 8);
+                               M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
 
                        for (p = 0; p < FLT_ARG_CNT; p++)
-                               M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
+                               M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
 
                        s1 += INT_ARG_CNT + FLT_ARG_CNT;
                }
@@ -307,10 +296,10 @@ bool codegen_emit(jitdata *jd)
 
                if (opt_verbosecall) {
                        for (p = 0; p < INT_ARG_CNT; p++)
-                               M_LLD(rd->argintregs[p], REG_SP, p * 8);
+                               M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
 
                        for (p = 0; p < FLT_ARG_CNT; p++)
-                               M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
+                               M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
 
                        M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
                }
@@ -519,12 +508,12 @@ bool codegen_emit(jitdata *jd)
                case ICMD_COPY:
                case ICMD_MOVE:
                        
-                       emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
+                       emit_copy(jd, iptr);
                        break;
 
                case ICMD_ASTORE:
                        if (!(iptr->flags.bits & INS_FLAG_RETADDR))
-                               emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
+                               emit_copy(jd, iptr);
                        break;
 
                /* integer operations *************************************************/
@@ -1510,7 +1499,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
-                       M_ILD(d, s1, OFFSET(java_arrayheader, size));
+                       M_ILD(d, s1, OFFSET(java_array_t, size));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1521,7 +1510,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
+                       emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1532,7 +1521,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
+                       emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
                        emit_store_dst(jd, iptr, d);
                        break;                  
 
@@ -1543,7 +1532,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
+                       emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1554,7 +1543,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
+                       emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1565,7 +1554,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
+                       emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1576,7 +1565,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
+                       emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1587,7 +1576,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
+                       emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1598,7 +1587,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
+                       emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1610,7 +1599,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
+                       emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
                        break;
 
                case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1620,7 +1609,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
+                       emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
                        break;
 
                case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1630,7 +1619,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
+                       emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
                        break;
 
                case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1640,7 +1629,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
+                       emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
                        break;
 
                case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1650,7 +1639,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
+                       emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
                        break;
 
                case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1660,7 +1649,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP3);
-                       emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
+                       emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
                        break;
 
                case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1670,7 +1659,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP3);
-                       emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
+                       emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
                        break;
 
                case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1690,7 +1679,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
+                       emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
                        break;
 
 
@@ -1700,7 +1689,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
+                       emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
                        break;
 
                case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1709,7 +1698,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
+                       emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
                        break;
 
                case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1718,7 +1707,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
+                       emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
                        break;
 
                case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
@@ -1727,7 +1716,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
+                       emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
                        break;
 
                case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
@@ -1738,11 +1727,11 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
 
                        if (IS_IMM32(iptr->sx.s23.s3.constval)) {
-                               emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
+                               emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
                        }
                        else {
-                               emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
-                               emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
+                               emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
+                               emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
                        }
                        break;
 
@@ -1752,7 +1741,7 @@ bool codegen_emit(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
-                       emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
+                       emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
                        break;
 
 
@@ -1778,7 +1767,7 @@ bool codegen_emit(jitdata *jd)
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp      = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
                                disp      = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
@@ -1842,7 +1831,7 @@ bool codegen_emit(jitdata *jd)
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp      = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
                                disp      = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
@@ -1907,7 +1896,7 @@ bool codegen_emit(jitdata *jd)
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp      = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
                                disp      = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
 
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
@@ -2388,35 +2377,35 @@ gen_method:
 
                        for (s3 = s3 - 1; s3 >= 0; s3--) {
                                var = VAR(iptr->sx.s23.s2.args[s3]);
+                               d   = md->params[s3].regoff;
+
+                               /* already preallocated (ARGVAR)? */
 
-                               /* Already Preallocated (ARGVAR) ? */
                                if (var->flags & PREALLOC)
                                        continue;
 
                                if (IS_INT_LNG_TYPE(var->type)) {
                                        if (!md->params[s3].inmemory) {
-                                               s1 = rd->argintregs[md->params[s3].regoff];
-                                               d = emit_load(jd, iptr, var, s1);
-                                               M_INTMOVE(d, s1);
+                                               s1 = emit_load(jd, iptr, var, d);
+                                               M_INTMOVE(s1, d);
                                        }
                                        else {
-                                               d = emit_load(jd, iptr, var, REG_ITMP1);
-                                               M_LST(d, REG_SP, md->params[s3].regoff * 8);
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP1);
+                                               M_LST(s1, REG_SP, d);
                                        }
                                }
                                else {
                                        if (!md->params[s3].inmemory) {
-                                               s1 = rd->argfltregs[md->params[s3].regoff];
-                                               d = emit_load(jd, iptr, var, s1);
-                                               M_FLTMOVE(d, s1);
+                                               s1 = emit_load(jd, iptr, var, d);
+                                               M_FLTMOVE(s1, d);
                                        }
                                        else {
-                                               d = emit_load(jd, iptr, var, REG_FTMP1);
+                                               s1 = emit_load(jd, iptr, var, REG_FTMP1);
 
                                                if (IS_2_WORD_TYPE(var->type))
-                                                       M_DST(d, REG_SP, md->params[s3].regoff * 8);
+                                                       M_DST(s1, REG_SP, d);
                                                else
-                                                       M_FST(d, REG_SP, md->params[s3].regoff * 8);
+                                                       M_FST(s1, REG_SP, d);
                                        }
                                }
                        }
@@ -2476,7 +2465,7 @@ gen_method:
                                }
 
                                /* implicit null-pointer check */
-                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
                                M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
                                M_CALL(REG_ITMP3);
                                break;
@@ -2496,7 +2485,7 @@ gen_method:
                                }
 
                                /* implicit null-pointer check */
-                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
                                M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
                                M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
                                M_CALL(REG_ITMP3);
@@ -2554,9 +2543,9 @@ gen_method:
                                        supervftbl = super->vftbl;
                                }
 
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                               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 */
@@ -2581,7 +2570,7 @@ gen_method:
                                                emit_label_beq(cd, BRANCH_LABEL_3);
                                        }
 
-                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
 
                                        if (super == NULL) {
                                                codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
@@ -2617,7 +2606,7 @@ gen_method:
                                                emit_label_beq(cd, BRANCH_LABEL_5);
                                        }
 
-                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
 
                                        if (super == NULL) {
                                                codegen_add_patch_ref(cd, PATCHER_checkcast_class,
@@ -2626,9 +2615,9 @@ gen_method:
                                        }
 
                                        M_MOV_IMM(supervftbl, REG_ITMP3);
-#if defined(ENABLE_THREADS)
-                                       codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+                                       CODEGEN_CRITICAL_SECTION_START;
+
                                        M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
 
                                        /*                                      if (s1 != REG_ITMP1) { */
@@ -2650,9 +2639,9 @@ gen_method:
                                        M_MOV_IMM(supervftbl, REG_ITMP3);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
                                        /*                                      } */
-#if defined(ENABLE_THREADS)
-                                       codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+                                       CODEGEN_CRITICAL_SECTION_END;
+
                                        M_ICMP(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
 
@@ -2705,16 +2694,15 @@ gen_method:
                                super      = NULL;
                                superindex = 0;
                                supervftbl = NULL;
-
-                       else {
+                       }
+                       else {
                                super      = iptr->sx.s23.s3.c.cls;
                                superindex = super->index;
                                supervftbl = super->vftbl;
                        }
 
-#if defined(ENABLE_THREADS)
-            codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                       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);
@@ -2748,7 +2736,7 @@ gen_method:
                                        emit_label_beq(cd, BRANCH_LABEL_3);
                                }
 
-                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
 
                                if (super == NULL) {
                                        codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
@@ -2785,7 +2773,7 @@ gen_method:
                                        emit_label_beq(cd, BRANCH_LABEL_5);
                                }
 
-                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
 
                                if (super == NULL) {
                                        codegen_add_patch_ref(cd, PATCHER_instanceof_class,
@@ -2794,17 +2782,13 @@ gen_method:
 
                                M_MOV_IMM(supervftbl, REG_ITMP2);
 
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                               CODEGEN_CRITICAL_SECTION_START;
 
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
 
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                               CODEGEN_CRITICAL_SECTION_END;
 
                                M_ISUB(REG_ITMP2, REG_ITMP1);
                                M_CLR(d); /* may be REG_ITMP2 */
@@ -2902,7 +2886,6 @@ gen_method:
        /* generate stubs */
 
        emit_patcher_stubs(jd);
-       REPLACEMENT_EMIT_STUBS(jd);
 
        /* everything's ok */
 
@@ -2942,22 +2925,20 @@ void codegen_emit_stub_compiler(jitdata *jd)
 
 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 {
-       methodinfo   *m;
-       codeinfo     *code;
-       codegendata  *cd;
-       registerdata *rd;
-       methoddesc   *md;
-       s4            nativeparams;
-       s4            i, j;                 /* count variables                    */
-       s4            t;
-       s4            s1, s2;
+       methodinfo  *m;
+       codeinfo    *code;
+       codegendata *cd;
+       methoddesc  *md;
+       s4           nativeparams;
+       s4           i, j;
+       s4           t;
+       s4           s1, s2;
 
        /* get required compiler data */
 
        m    = jd->m;
        code = jd->code;
        cd   = jd->cd;
-       rd   = jd->rd;
 
        /* initialize variables */
 
@@ -2969,7 +2950,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        cd->stackframesize =
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
-               INT_ARG_CNT + FLT_ARG_CNT +
+               md->paramcount +
                1 +                       /* functionptr, TODO: store in data segment */
                nmd->memuse;
 
@@ -3015,23 +2996,27 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        M_MOV_IMM(f, REG_ITMP3);
 
-
        /* save integer and float argument registers */
 
-       for (i = 0, j = 0; i < md->paramcount; i++) {
+       for (i = 0; i < md->paramcount; i++) {
                if (!md->params[i].inmemory) {
                        s1 = md->params[i].regoff;
 
-                       if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
-                               M_LST(rd->argintregs[s1], REG_SP, j * 8);
-                       else
-                               M_DST(rd->argfltregs[s1], REG_SP, j * 8);
-
-                       j++;
+                       switch (md->paramtypes[i].type) {
+                       case TYPE_INT:
+                       case TYPE_LNG:
+                       case TYPE_ADR:
+                               M_LST(s1, REG_SP, i * 8);
+                               break;
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               M_DST(s1, REG_SP, i * 8);
+                               break;
+                       }
                }
        }
 
-       M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
+       M_AST(REG_ITMP3, REG_SP, md->paramcount * 8);
 
        /* create dynamic stack info */
 
@@ -3044,61 +3029,61 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* restore integer and float argument registers */
 
-       for (i = 0, j = 0; i < md->paramcount; i++) {
+       for (i = 0; i < md->paramcount; i++) {
                if (!md->params[i].inmemory) {
                        s1 = md->params[i].regoff;
 
-                       if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
-                               M_LLD(rd->argintregs[s1], REG_SP, j * 8);
-                       else
-                               M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
-
-                       j++;
+                       switch (md->paramtypes[i].type) {
+                       case TYPE_INT:
+                       case TYPE_LNG:
+                       case TYPE_ADR:
+                               M_LLD(s1, REG_SP, i * 8);
+                               break;
+                       case TYPE_FLT:
+                       case TYPE_DBL:
+                               M_DLD(s1, REG_SP, i * 8);
+                               break;
+                       }
                }
        }
 
-       M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
-
+       M_ALD(REG_ITMP3, REG_SP, md->paramcount * 8);
 
        /* copy or spill arguments to new locations */
 
        for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
-               t = md->paramtypes[i].type;
+               t  = md->paramtypes[i].type;
+               s2 = nmd->params[j].regoff;
 
                if (IS_INT_LNG_TYPE(t)) {
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argintregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
 
-                               if (!nmd->params[j].inmemory) {
-                                       s2 = rd->argintregs[nmd->params[j].regoff];
+                               if (!nmd->params[j].inmemory)
                                        M_INTMOVE(s1, s2);
-
-                               } else {
-                                       s2 = nmd->params[j].regoff;
-                                       M_LST(s1, REG_SP, s2 * 8);
-                               }
-
-                       } else {
-                               s1 = md->params[i].regoff + cd->stackframesize + 1;   /* + 1 (RA) */
-                               s2 = nmd->params[j].regoff;
-                               M_LLD(REG_ITMP1, REG_SP, s1 * 8);
-                               M_LST(REG_ITMP1, REG_SP, s2 * 8);
+                               else
+                                       M_LST(s1, REG_SP, s2);
                        }
-
-               } else {
-                       /* We only copy spilled float arguments, as the float argument    */
-                       /* registers keep unchanged.                                      */
+                       else {
+                               s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
+                               M_LLD(REG_ITMP1, REG_SP, s1);
+                               M_LST(REG_ITMP1, REG_SP, s2);
+                       }
+               }
+               else {
+                       /* We only copy spilled float arguments, as the float
+                          argument registers keep unchanged. */
 
                        if (md->params[i].inmemory) {
-                               s1 = md->params[i].regoff + cd->stackframesize + 1;   /* + 1 (RA) */
-                               s2 = nmd->params[j].regoff;
+                               s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
 
                                if (IS_2_WORD_TYPE(t)) {
-                                       M_DLD(REG_FTMP1, REG_SP, s1 * 8);
-                                       M_DST(REG_FTMP1, REG_SP, s2 * 8);
-                               } else {
-                                       M_FLD(REG_FTMP1, REG_SP, s1 * 8);
-                                       M_FST(REG_FTMP1, REG_SP, s2 * 8);
+                                       M_DLD(REG_FTMP1, REG_SP, s1);
+                                       M_DST(REG_FTMP1, REG_SP, s2);
+                               }
+                               else {
+                                       M_FLD(REG_FTMP1, REG_SP, s1);
+                                       M_FST(REG_FTMP1, REG_SP, s2);
                                }
                        }
                }
@@ -3119,11 +3104,18 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* save return value */
 
-       if (md->returntype.type != TYPE_VOID) {
-               if (IS_INT_LNG_TYPE(md->returntype.type))
-                       M_LST(REG_RESULT, REG_SP, 0 * 8);
-               else
-                       M_DST(REG_FRESULT, REG_SP, 0 * 8);
+       switch (md->returntype.type) {
+       case TYPE_INT:
+       case TYPE_LNG:
+       case TYPE_ADR:
+               M_LST(REG_RESULT, REG_SP, 0 * 8);
+               break;
+       case TYPE_FLT:
+       case TYPE_DBL:
+               M_DST(REG_FRESULT, REG_SP, 0 * 8);
+               break;
+       case TYPE_VOID:
+               break;
        }
 
 #if !defined(NDEBUG)
@@ -3140,11 +3132,18 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* restore return value */
 
-       if (md->returntype.type != TYPE_VOID) {
-               if (IS_INT_LNG_TYPE(md->returntype.type))
-                       M_LLD(REG_RESULT, REG_SP, 0 * 8);
-               else
-                       M_DLD(REG_FRESULT, REG_SP, 0 * 8);
+       switch (md->returntype.type) {
+       case TYPE_INT:
+       case TYPE_LNG:
+       case TYPE_ADR:
+               M_LLD(REG_RESULT, REG_SP, 0 * 8);
+               break;
+       case TYPE_FLT:
+       case TYPE_DBL:
+               M_DLD(REG_FRESULT, REG_SP, 0 * 8);
+               break;
+       case TYPE_VOID:
+               break;
        }
 
        /* remove stackframe */