* src/vm/jit/md.h: Removed.
[cacao.git] / src / vm / jit / arm / codegen.c
index f87c1b0db1fd373682b2f038d7f93bcc557fa19b..9ff1c63e5b45695a6572322c66fdee4c947b3870 100644 (file)
@@ -55,7 +55,7 @@
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
-#include "vm/jit/md.h"
+#include "vm/jit/linenumbertable.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
@@ -87,7 +87,6 @@ bool codegen_emit(jitdata *jd)
        varinfo        *var;
        basicblock     *bptr;
        instruction    *iptr;
-       exception_entry *ex;
 
        s4              spilledregs_num;
        s4              savedregs_num;
@@ -120,7 +119,8 @@ bool codegen_emit(jitdata *jd)
        
        /* space to save used callee saved registers */
 
-       savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the LR */
+       savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the LR */
+
        savedregs_num += (INT_SAV_CNT - rd->savintreguse);
        /*savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);*/
        assert((FLT_SAV_CNT - rd->savfltreguse) == 0);
@@ -128,7 +128,7 @@ bool codegen_emit(jitdata *jd)
        spilledregs_num = rd->memuse;
 
 #if defined(ENABLE_THREADS)        /* space to save argument of monitor_enter */
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+       if (checksync && code_is_synchronized(code))
                spilledregs_num++;
 #endif
 
@@ -146,39 +146,23 @@ bool codegen_emit(jitdata *jd)
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
        (void) dseg_add_unique_s4(cd, cd->stackframesize);     /* FrameSize       */
 
-#if defined(ENABLE_THREADS)
-       /* IsSync contains the offset relative to the stack pointer for the
-          argument of monitor_exit used in the exception handler. Since the
-          offset could be zero and give a wrong meaning of the flag it is
-          offset by one.
-       */
-
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_add_unique_s4(cd, rd->memuse * 8 + 4);/* IsSync         */
+       code->synchronizedoffset = rd->memuse * 8;
+
+       /* REMOVEME: We still need it for exception handling in assembler. */
+
+       if (code_is_leafmethod(code))
+               (void) dseg_add_unique_s4(cd, 1);
        else
-#endif
-               (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
+               (void) dseg_add_unique_s4(cd, 0);
 
-       (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
        (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
        (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
-       (void) dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
-
-       /* create exception table */
-
-       for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
-               dseg_add_target(cd, ex->start);
-               dseg_add_target(cd, ex->end);
-               dseg_add_target(cd, ex->handler);
-               (void) dseg_add_unique_address(cd, ex->catchtype.any);
-       }
 
        /* save return address and used callee saved registers */
 
        savedregs_bitmask = 0;
 
-       if (!jd->isleafmethod)
+       if (!code_is_leafmethod(code))
                savedregs_bitmask = (1<<REG_LR);
 
        for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--)
@@ -250,7 +234,10 @@ bool codegen_emit(jitdata *jd)
                else {
                        if (!md->params[i].inmemory) {
                                if (!(var->flags & INMEMORY)) {
-                                       M_CAST_INT_TO_FLT_TYPED(t, s1, var->vv.regoff);
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_CAST_L2D(s1, var->vv.regoff);
+                                       else
+                                               M_CAST_I2F(s1, var->vv.regoff);
                                }
                                else {
                                        if (IS_2_WORD_TYPE(t))
@@ -278,7 +265,7 @@ bool codegen_emit(jitdata *jd)
 #if defined(ENABLE_THREADS)
        /* call monitorenter function */
 
-       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+       if (checksync && code_is_synchronized(code)) {
                /* stack offset for monitor argument */
 
                s1 = rd->memuse * 8;
@@ -390,18 +377,21 @@ bool codegen_emit(jitdata *jd)
 
                        /* add line number */
                        if (iptr->line != currentline) {
-                               dseg_addlinenumber(cd, iptr->line);
+                               linenumbertable_list_entry_add(cd, iptr->line);
                                currentline = iptr->line;
                        }
 
                        MCODECHECK(64);   /* an instruction usually needs < 64 words      */
 
-                       /* the big switch */
-                       switch (iptr->opc) {
-               case ICMD_NOP:        /* ... ==> ...                                  */
+               /* the big switch */
+               switch (iptr->opc) {
+
+               case ICMD_NOP:        /* ...  ==> ...                                 */
+               case ICMD_POP:        /* ..., value  ==> ...                          */
+               case ICMD_POP2:       /* ..., value, value  ==> ...                   */
                        break;
 
-       /* constant operations ************************************************/
+               /* constant operations ************************************************/
 
                case ICMD_ICONST:     /* ...  ==> ..., constant                       */
 
@@ -419,9 +409,6 @@ bool codegen_emit(jitdata *jd)
                                patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
                                                    iptr->sx.val.c.ref, disp);
 
-                               if (opt_showdisassemble)
-                                       M_NOP;
-
                                M_DSEG_LOAD(d, disp);
                        }
                        else {
@@ -482,19 +469,11 @@ bool codegen_emit(jitdata *jd)
                        break;
 
                case ICMD_ASTORE:
+
                        if (!(iptr->flags.bits & INS_FLAG_RETADDR))
                                emit_copy(jd, iptr);
                        break;
 
-               /* pop operations *****************************************************/
-
-               /* attention: double and longs are only one entry in CACAO ICMDs      */
-
-               case ICMD_POP:        /* ..., value  ==> ...                          */
-               case ICMD_POP2:       /* ..., value, value  ==> ...                   */
-
-                       break;
-
 
                /* integer operations *************************************************/
 
@@ -922,7 +901,7 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       M_MNFS(d, s1);
+                       M_FNEG(s1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -931,7 +910,7 @@ 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_FTMP1);
-                       M_ADFS(d, s1, s2);
+                       M_FADD(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -940,7 +919,7 @@ 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_FTMP1);
-                       M_SUFS(d, s1, s2);
+                       M_FSUB(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -949,7 +928,7 @@ 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_FTMP1);
-                       M_MUFS(d, s1, s2);
+                       M_FMUL(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -957,13 +936,14 @@ 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_FTMP1);
-                       M_DVFS(d, s1, s2);
+                       M_FDIV(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
                /* ATTENTION: Jave does not want IEEE behaviour in FREM, do
                   not use this */
 
+#if 0
                case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
@@ -972,12 +952,13 @@ bool codegen_emit(jitdata *jd)
                        M_RMFS(d, s1, s2);
                        emit_store_dst(jd, iptr, d);
                        break;
+#endif
 
                case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       M_MNFD(d, s1);
+                       M_DNEG(s1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -986,7 +967,7 @@ 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_FTMP1);
-                       M_ADFD(d, s1, s2);
+                       M_DADD(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -995,7 +976,7 @@ 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_FTMP1);
-                       M_SUFD(d, s1, s2);
+                       M_DSUB(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1004,7 +985,7 @@ 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_FTMP1);
-                       M_MUFD(d, s1, s2);
+                       M_DMUL(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1013,13 +994,14 @@ 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_FTMP1);
-                       M_DVFD(d, s1, s2);
+                       M_DDIV(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
                /* ATTENTION: Jave does not want IEEE behaviour in DREM, do
                   not use this */
 
+#if 0
                case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
@@ -1028,12 +1010,13 @@ bool codegen_emit(jitdata *jd)
                        M_RMFD(d, s1, s2);
                        emit_store_dst(jd, iptr, d);
                        break;
+#endif
 
                case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       M_FLTS(d, s1);
+                       M_CVTIF(s1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1041,7 +1024,7 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                       M_FLTD(d, s1);
+                       M_CVTID(s1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1050,10 +1033,12 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        /* this uses round towards zero, as Java likes it */
-                       M_FIX(d, s1);
+                       M_CVTFI(s1, d);
+#if !defined(__VFP_FP__)
                        /* this checks for NaN; to return zero as Java likes it */
-                       M_CMF(s1, 0x8);
+                       M_FCMP(s1, 0x8);
                        M_MOVVS_IMM(0, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1062,10 +1047,12 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        /* this uses round towards zero, as Java likes it */
-                       M_FIX(d, s1);
+                       M_CVTDI(s1, d);
+#if !defined(__VFP_FP__)
                        /* this checks for NaN; to return zero as Java likes it */
-                       M_CMF(s1, 0x8);
+                       M_DCMP(s1, 0x8);
                        M_MOVVS_IMM(0, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1073,7 +1060,7 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
-                       M_MVFS(d,s1);
+                       M_CVTDF(s1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1081,7 +1068,7 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
-                       M_MVFD(d,s1);
+                       M_CVTFD(s1, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1090,8 +1077,11 @@ 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_ITMP1);
-                       M_CMF(s2, s1);
+                       M_FCMP(s2, s1);
                        M_MOV_IMM(d, 0);
+#if defined(__VFP_FP__)
+                       M_FMSTAT; /* on VFP we need to transfer the flags */
+#endif
                        M_SUBGT_IMM(d, d, 1);
                        M_ADDLT_IMM(d, d, 1);
                        emit_store_dst(jd, iptr, d);
@@ -1102,8 +1092,11 @@ 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_ITMP1);
-                       M_CMF(s2, s1);
+                       M_DCMP(s2, s1);
                        M_MOV_IMM(d, 0);
+#if defined(__VFP_FP__)
+                       M_FMSTAT; /* on VFP we need to transfer the flags */
+#endif
                        M_SUBGT_IMM(d, d, 1);
                        M_ADDLT_IMM(d, d, 1);
                        emit_store_dst(jd, iptr, d);
@@ -1114,8 +1107,11 @@ 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_ITMP1);
-                       M_CMF(s1, s2);
+                       M_FCMP(s1, s2);
                        M_MOV_IMM(d, 0);
+#if defined(__VFP_FP__)
+                       M_FMSTAT; /* on VFP we need to transfer the flags */
+#endif
                        M_SUBLT_IMM(d, d, 1);
                        M_ADDGT_IMM(d, d, 1);
                        emit_store_dst(jd, iptr, d);
@@ -1126,8 +1122,11 @@ 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_ITMP1);
-                       M_CMF(s1, s2);
+                       M_DCMP(s1, s2);
                        M_MOV_IMM(d, 0);
+#if defined(__VFP_FP__)
+                       M_FMSTAT; /* on VFP we need to transfer the flags */
+#endif
                        M_SUBLT_IMM(d, d, 1);
                        M_ADDGT_IMM(d, d, 1);
                        emit_store_dst(jd, iptr, d);
@@ -1354,7 +1353,7 @@ bool codegen_emit(jitdata *jd)
                        M_INTMOVE(s3, REG_A1);
 
                        /* call builtin function */
-                       disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+                       disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
                        M_DSEG_BRANCH(disp);
 
                        /* recompute pv */
@@ -1362,7 +1361,7 @@ bool codegen_emit(jitdata *jd)
                        M_RECOMPUTE_PV(s1);
 
                        /* check resturn value of builtin */
-                       emit_exception_check(cd, iptr);
+                       emit_arraystore_check(cd, iptr);
 
                        /* finally store address into array */
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -1380,9 +1379,6 @@ bool codegen_emit(jitdata *jd)
                                disp      = dseg_add_unique_address(cd, NULL);
 
                                patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
@@ -1392,9 +1388,6 @@ bool codegen_emit(jitdata *jd)
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
                                                            fi->class, 0);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                        }
 
@@ -1439,9 +1432,6 @@ bool codegen_emit(jitdata *jd)
                                disp      = dseg_add_unique_address(cd, NULL);
 
                                patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
@@ -1451,9 +1441,6 @@ bool codegen_emit(jitdata *jd)
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
                                                            fi->class, 0);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                        }
 
@@ -1517,9 +1504,6 @@ bool codegen_emit(jitdata *jd)
                                uf = iptr->sx.s23.s3.uf;
 
                                patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
 
                        switch (fieldtype) {
@@ -1605,9 +1589,6 @@ bool codegen_emit(jitdata *jd)
                                uf = iptr->sx.s23.s3.uf;
 
                                patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
 
                        switch (fieldtype) {
@@ -1647,9 +1628,6 @@ bool codegen_emit(jitdata *jd)
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                patcher_add_patch_ref(jd, PATCHER_resolve_class,
                                                                        iptr->sx.s23.s2.uc, 0);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
                        disp = dseg_add_functionptr(cd, asm_handle_exception);
                        M_DSEG_LOAD(REG_ITMP3, disp);
@@ -2069,7 +2047,7 @@ bool codegen_emit(jitdata *jd)
 #if !defined(ENABLE_SOFTFLOAT)
                        REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
-                       M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT);
+                       M_CAST_F2I(s1, REG_RESULT);
                        goto ICMD_RETURN_do;
 #endif
 
@@ -2085,7 +2063,7 @@ bool codegen_emit(jitdata *jd)
 #if !defined(ENABLE_SOFTFLOAT)
                        REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
-                       M_CAST_FLT_TO_INT_TYPED(VAROP(iptr->s1)->type, s1, REG_RESULT_PACKED);
+                       M_CAST_D2L(s1, REG_RESULT_PACKED);
                        goto ICMD_RETURN_do;
 #endif
 
@@ -2104,9 +2082,6 @@ bool codegen_emit(jitdata *jd)
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                patcher_add_patch_ref(jd, PATCHER_resolve_class,
                                                                        iptr->sx.s23.s2.uc, 0);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
                        goto ICMD_RETURN_do;
 
@@ -2123,7 +2098,7 @@ bool codegen_emit(jitdata *jd)
 #if defined(ENABLE_THREADS)
                        /* call monitorexit function */
 
-                       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+                       if (checksync && code_is_synchronized(code)) {
                                /* stack offset for monitor argument */
 
                                s1 = rd->memuse * 8;
@@ -2169,7 +2144,7 @@ bool codegen_emit(jitdata *jd)
                        /* restore callee saved registers + do return */
 
                        if (savedregs_bitmask) {
-                               if (!jd->isleafmethod) {
+                               if (!code_is_leafmethod(code)) {
                                        savedregs_bitmask &= ~(1<<REG_LR);
                                        savedregs_bitmask |= (1<<REG_PC);
                                }
@@ -2178,7 +2153,7 @@ bool codegen_emit(jitdata *jd)
 
                        /* if LR was not on stack, we need to return manually */
 
-                       if (jd->isleafmethod)
+                       if (code_is_leafmethod(code))
                                M_MOV(REG_PC, REG_LR);
                        break;
 
@@ -2247,7 +2222,10 @@ bool codegen_emit(jitdata *jd)
                                else {
                                        if (!md->params[s3].inmemory) {
                                                s1 = emit_load(jd, iptr, var, REG_FTMP1);
-                                               M_CAST_FLT_TO_INT_TYPED(var->type, s1, d);
+                                               if (IS_2_WORD_TYPE(var->type))
+                                                       M_CAST_D2L(s1, d);
+                                               else
+                                                       M_CAST_F2I(s1, d);
                                        }
                                        else {
                                                s1 = emit_load(jd, iptr, var, REG_FTMP1);
@@ -2277,8 +2255,6 @@ bool codegen_emit(jitdata *jd)
                                M_MOV(REG_PC, REG_PV);
                                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
                                M_RECOMPUTE_PV(s1);
-
-                               emit_exception_check(cd, iptr);
                                break;
 
                        case ICMD_INVOKESPECIAL:
@@ -2291,9 +2267,6 @@ bool codegen_emit(jitdata *jd)
 
                                        patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
                                                                                um, disp);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                                else
                                        disp = dseg_add_address(cd, lm->stubroutine);
@@ -2312,9 +2285,6 @@ bool codegen_emit(jitdata *jd)
                                if (lm == NULL) {
                                        patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
 
-                                       if (opt_showdisassemble)
-                                               M_NOP;
-
                                        s1 = 0;
                                }
                                else
@@ -2338,9 +2308,6 @@ bool codegen_emit(jitdata *jd)
                                if (lm == NULL) {
                                        patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
 
-                                       if (opt_showdisassemble)
-                                               M_NOP;
-
                                        s1 = 0;
                                        s2 = 0;
                                }
@@ -2409,7 +2376,10 @@ bool codegen_emit(jitdata *jd)
 #if !defined(ENABLE_SOFTFLOAT)
                                } else {
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
-                                       M_CAST_INT_TO_FLT_TYPED(VAROP(iptr->dst)->type, REG_RESULT_TYPED(VAROP(iptr->dst)->type), s1);
+                                       if (IS_2_WORD_TYPE(d))
+                                               M_CAST_L2D(REG_RESULT_PACKED, s1);
+                                       else
+                                               M_CAST_I2F(REG_RESULT, s1);
                                }
 #endif /* !defined(ENABLE_SOFTFLOAT) */
 
@@ -2449,9 +2419,6 @@ bool codegen_emit(jitdata *jd)
                                patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
                                                    iptr->sx.s23.s3.c.ref, disp);
 
-                               if (opt_showdisassemble)
-                                       M_NOP;
-
                                M_DSEG_LOAD(REG_ITMP2, disp);
                                disp = dseg_add_s4(cd, ACC_INTERFACE);
                                M_DSEG_LOAD(REG_ITMP3, disp);
@@ -2468,9 +2435,6 @@ bool codegen_emit(jitdata *jd)
                                if (super == NULL) {
                                        patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index,
                                                            iptr->sx.s23.s3.c.ref, disp);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                                else {
                                        M_TST(s1, s1);
@@ -2535,9 +2499,6 @@ bool codegen_emit(jitdata *jd)
                                        patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
                                                            iptr->sx.s23.s3.c.ref,
                                                                                disp);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                                else {
                                        disp = dseg_add_address(cd, super->vftbl);
@@ -2585,9 +2546,6 @@ bool codegen_emit(jitdata *jd)
                                        patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
                                                                                iptr->sx.s23.s3.c.ref,
                                                                                disp);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                                else
                                        disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
@@ -2649,9 +2607,6 @@ bool codegen_emit(jitdata *jd)
                                patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
                                                    iptr->sx.s23.s3.c.ref, disp);
 
-                               if (opt_showdisassemble)
-                                       M_NOP;
-
                                M_DSEG_LOAD(REG_ITMP2, disp);
                                disp = dseg_add_s4(cd, ACC_INTERFACE);
                                M_DSEG_LOAD(REG_ITMP3, disp);
@@ -2673,9 +2628,6 @@ bool codegen_emit(jitdata *jd)
 
                                        patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_index,
                                                            iptr->sx.s23.s3.c.ref, disp);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                                else {
                                        M_EOR(d, d, d);
@@ -2745,9 +2697,6 @@ bool codegen_emit(jitdata *jd)
 
                                        patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
                                                            iptr->sx.s23.s3.c.ref, disp);
-
-                                       if (opt_showdisassemble)
-                                               M_NOP;
                                }
                                else {
                                        disp = dseg_add_address(cd, super->vftbl);
@@ -2819,9 +2768,6 @@ bool codegen_emit(jitdata *jd)
 
                                patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
                                                                        iptr->sx.s23.s3.c.ref, disp);
-
-                               if (opt_showdisassemble)
-                                       M_NOP;
                        }
                        else
                                disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
@@ -2871,9 +2817,6 @@ bool codegen_emit(jitdata *jd)
 
        } /* for all basic blocks */
 
-       dseg_createlinenumbertable(cd);
-
-
        /* generate traps */
 
        emit_patcher_traps(jd);
@@ -2907,159 +2850,22 @@ void codegen_emit_stub_compiler(jitdata *jd)
 }
 
 
-/* codegen_emit_stub_builtin ***************************************************
-
-   Emits a stub routine which calls a builtin function.
-
-*******************************************************************************/
-
-void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
-{
-       codeinfo    *code;
-       codegendata *cd;
-       methoddesc  *md;
-       s4           i;
-       s4           disp;
-       s4           s1;
-
-       /* get required compiler data */
-
-       code = jd->code;
-       cd   = jd->cd;
-
-       /* set some variables */
-
-       md = bte->md;
-
-       /* calculate stack frame size */
-
-       cd->stackframesize =
-               SIZEOF_VOID_P +                                    /* return address  */
-               sizeof(stackframeinfo);                            /* stackframeinfo  */
-
-       /* align stack to 8-byte */
-
-       cd->stackframesize = (cd->stackframesize + 4) & ~4;
-
-       /* create method header */
-
-       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize);     /* FrameSize       */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
-       (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
-       (void) dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
-
-       /* generate stub code */
-
-       M_SUB_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - 1);
-       M_STMFD(1<<REG_LR, REG_SP);
-
-#if defined(ENABLE_GC_CACAO)
-       /* Save callee saved integer registers in stackframeinfo (GC may
-          need to recover them during a collection). */
-
-       disp = cd->stackframesize - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
-
-       for (i = 0; i < INT_SAV_CNT; i++)
-               M_STR_INTERN(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
-#endif
-
-       /* Save integer and float argument registers (these are 4
-          registers, stack is 8-byte aligned). */
-
-       M_STMFD(BITMASK_ARGS, REG_SP);
-
-       /* create builtin stackframe info */
-
-       assert(IS_IMM(4*4 + cd->stackframesize));
-       M_ADD_IMM(REG_A0, REG_SP, 4*4 + cd->stackframesize);
-       M_MOV(REG_A1, REG_PV);
-       M_ADD_IMM(REG_A2, REG_SP, 4*4 + cd->stackframesize);
-       M_LDR_INTERN(REG_A3, REG_SP, 4*4);
-       disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
-       M_DSEG_BRANCH(disp);
-
-       s1 = (s4) (cd->mcodeptr - cd->mcodebase);
-       M_RECOMPUTE_PV(s1);
-
-       /* Restore integer and float argument registers (these are 4
-          registers, stack is 8-byte aligned). */
-
-       M_LDMFD(BITMASK_ARGS, REG_SP);
-
-       /* builtins are allowed to have 4 arguments max */
-
-       assert(md->paramcount <= 4);
-       for (i = 0; i < md->paramcount; i++) {
-               assert(!IS_2_WORD_TYPE(md->paramtypes[i].type));
-       }
-
-       /* call the builtin function */
-
-       disp = dseg_add_functionptr(cd, bte->fp);
-       M_DSEG_BRANCH(disp);
-
-       /* recompute pv */
-
-       s1 = (s4) (cd->mcodeptr - cd->mcodebase);
-       M_RECOMPUTE_PV(s1);
-
-       /* save return value */
-
-       assert(!IS_FLT_DBL_TYPE(md->returntype.type));
-       M_STMFD(BITMASK_RESULT, REG_SP);
-
-       /* remove builtin stackframe info */
-
-       M_ADD_IMM(REG_A0, REG_SP, 2*4 + cd->stackframesize);
-       disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
-       M_DSEG_BRANCH(disp);
-       /*s1 = (s4) (cd->mcodeptr - cd->mcodebase);
-       M_RECOMPUTE_PV(s1);*/
-
-       /* restore return value */
-
-       M_LDMFD(BITMASK_RESULT, REG_SP);
-
-#if defined(ENABLE_GC_CACAO)
-       /* Restore callee saved integer registers from stackframeinfo (GC
-          might have modified them during a collection). */
-        
-       disp = cd->stackframesize - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
-
-       for (i = 0; i < INT_SAV_CNT; i++)
-               M_LDR_INTERN(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
-#endif
-
-       /* remove stackframe and return */
-
-       M_LDMFD(1<<REG_LR, REG_SP);
-       M_ADD_IMM_EXT_MUL4(REG_SP, REG_SP, cd->stackframesize / 4 - 1);
-       M_MOV(REG_PC, REG_LR);
-}
-
-
 /* codegen_emit_stub_native ****************************************************
 
    Emits a stub routine which calls a native method.
 
 *******************************************************************************/
 
-void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
+void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
 {
        methodinfo  *m;
        codeinfo    *code;
        codegendata *cd;
-       s4           nativeparams;
        methoddesc  *md;
        s4           i, j;
        s4           t;
-       s4           disp, funcdisp, s1, s2;
+       int          s1, s2;
+       int          disp;
 
        /* get required compiler data */
 
@@ -3070,13 +2876,12 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* initialize variables */
 
        md = m->parseddesc;
-       nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
 
        /* calculate stackframe size */
 
        cd->stackframesize =
                4 +                                                /* return address  */
-               sizeof(stackframeinfo) +                           /* stackframeinfo  */
+               sizeof(stackframeinfo_t) +                         /* stackframeinfo  */
                sizeof(localref_table) +                           /* localref_table  */
                nmd->memuse * 4;                                   /* stack arguments */
 
@@ -3088,12 +2893,9 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
        (void) dseg_add_unique_s4(cd, cd->stackframesize);     /* FrameSize       */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
        (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
-       (void) dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
 
        /* generate stub code */
 
@@ -3105,25 +2907,12 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                emit_verbosecall_enter(jd);
 #endif
 
-       /* get function address (this must happen before the stackframeinfo) */
-
-       funcdisp = dseg_add_functionptr(cd, f);
-
-#if !defined(WITH_STATIC_CLASSPATH)
-       if (f == NULL) {
-               patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
-
-               if (opt_showdisassemble)
-                       M_NOP;
-       }
-#endif
-
 #if defined(ENABLE_GC_CACAO)
        /* Save callee saved integer registers in stackframeinfo (GC may
           need to recover them during a collection). */
 
-       disp = cd->stackframesize - SIZEOF_VOID_P - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
+       disp = cd->stackframesize - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
+               OFFSET(stackframeinfo_t, intregs);
 
        for (i = 0; i < INT_SAV_CNT; i++)
                M_STR_INTERN(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
@@ -3137,11 +2926,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        /* create native stackframe info */
 
-       assert(IS_IMM(4*4 + cd->stackframesize));
-       M_ADD_IMM(REG_A0, REG_SP, 4*4 + cd->stackframesize - SIZEOF_VOID_P);
+       M_ADD_IMM(REG_A0, REG_SP, 4*4);
        M_MOV(REG_A1, REG_PV);
-       M_ADD_IMM(REG_A2, REG_SP, 4*4 + cd->stackframesize);
-       M_LDR_INTERN(REG_A3, REG_SP, 4*4 + cd->stackframesize - SIZEOF_VOID_P);
        disp = dseg_add_functionptr(cd, codegen_start_native_call);
        M_DSEG_BRANCH(disp);
 
@@ -3150,6 +2936,11 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        s1 = (s4) (cd->mcodeptr - cd->mcodebase);
        M_RECOMPUTE_PV(s1);
 
+       /* remember class argument */
+
+       if (m->flags & ACC_STATIC)
+               M_MOV(REG_ITMP3, REG_RESULT);
+
        /* Restore integer and float argument registers (these are 4
           registers, stack is 8-byte aligned). */
 
@@ -3159,7 +2950,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* copy or spill arguments to new locations */
        /* ATTENTION: the ARM has only integer argument registers! */
 
-       for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
+       for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
                t = md->paramtypes[i].type;
 
                if (!md->params[i].inmemory) {
@@ -3202,21 +2993,24 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
                }
        }
 
-       /* put class into second argument register */
+       /* Handle native Java methods. */
 
-       if (m->flags & ACC_STATIC) {
-               disp = dseg_add_address(cd, m->class);
-               M_DSEG_LOAD(REG_A1, disp);
-       }
+       if (m->flags & ACC_NATIVE) {
+               /* put class into second argument register */
 
-       /* put env into first argument register */
+               if (m->flags & ACC_STATIC)
+                       M_MOV(REG_A1, REG_ITMP3);
 
-       disp = dseg_add_address(cd, _Jv_env);
-       M_DSEG_LOAD(REG_A0, disp);
+               /* put env into first argument register */
+
+               disp = dseg_add_address(cd, _Jv_env);
+               M_DSEG_LOAD(REG_A0, disp);
+       }
 
-       /* do the native function call */
+       /* Call the native function. */
 
-       M_DSEG_BRANCH(funcdisp);
+       disp = dseg_add_functionptr(cd, f);
+       M_DSEG_BRANCH(disp);
 
        /* recompute pv */
        /* TODO: this is only needed because of the tracer ... do we
@@ -3254,7 +3048,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 
        M_STMFD(BITMASK_RESULT, REG_SP);
 
-       M_ADD_IMM(REG_A0, REG_SP, 2*4 + cd->stackframesize - SIZEOF_VOID_P);
+       M_ADD_IMM(REG_A0, REG_SP, 2*4);
+       M_MOV(REG_A1, REG_PV);
        disp = dseg_add_functionptr(cd, codegen_finish_native_call);
        M_DSEG_BRANCH(disp);
        s1 = (s4) (cd->mcodeptr - cd->mcodebase);
@@ -3267,8 +3062,8 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        /* restore callee saved int registers from stackframeinfo (GC might have  */
        /* modified them during a collection).                                    */
 
-       disp = cd->stackframesize - SIZEOF_VOID_P - sizeof(stackframeinfo) +
-               OFFSET(stackframeinfo, intregs);
+       disp = cd->stackframesize - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
+               OFFSET(stackframeinfo_t, intregs);
 
        for (i = 0; i < INT_SAV_CNT; i++)
                M_LDR_INTERN(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
@@ -3291,10 +3086,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
        disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
        M_DSEG_LOAD(REG_ITMP3, disp);       /* load asm exception handler address */
        M_MOV(REG_PC, REG_ITMP3);           /* jump to asm exception handler      */
-
-       /* generate patcher stubs */
-
-       emit_patcher_traps(jd);
 }