Merged revisions 7766-7796 via svnmerge from
[cacao.git] / src / vm / jit / sparc64 / codegen.c
index 45e00f5bc4a854367fcb81599c817962bea817d6..5504b550c0a6759d2586fc91bd041bdfe20f0995 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-            Reinhard Grafl
-            Alexander Jordan
-            Edwin Steiner
-
    $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
 
 */
@@ -36,9 +29,8 @@
 
 #include "config.h"
 
-#include <stdio.h>
 #include <assert.h>
-
+#include <stdio.h>
 
 #include "vm/types.h"
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/stringlocal.h"
+
+#include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
+#include "vm/jit/sparc64/emit.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
+#include "vm/jit/replace.h"
+#include "vm/jit/stacktrace.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+
+
+#define BUILTIN_FLOAT_ARGS 1
 
 /* XXX use something like this for window control ? 
  * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
  */
 #define REG_PV REG_PV_CALLEE
 
+bool fits_13(s4 disp)
+{
+       /*
+       if ((disp < -4096) || (disp > 4095))
+               printf("disp %d\n", disp);
+       */
+
+       return (disp >= -4096) && (disp <= 4095);
+}
 
-/* codegen *********************************************************************
+s4 get_lopart_disp(disp)
+{
+       s4 lodisp;
+       
+       if (disp > 0)
+               lodisp = setlo_part(disp);
+       else {
+               if (setlo_part(disp) == 0)
+                       lodisp = 0;
+               else
+                       lodisp = setlo_part(disp) | 0x1c00;
+       }
+               
+       return lodisp;
+}
+       
+
+/* codegen_emit ****************************************************************
 
    Generates machine code.
 
 *******************************************************************************/
 
-bool codegen(jitdata *jd)
+bool codegen_emit(jitdata *jd)
 {
        methodinfo         *m;
        codeinfo           *code;
@@ -97,7 +122,6 @@ bool codegen(jitdata *jd)
        methoddesc         *md;
        fieldinfo          *fi;
        unresolved_field   *uf;
-       rplpoint           *replacementpoint;
        s4                  fieldtype;
        s4                  varindex;
 
@@ -122,7 +146,7 @@ bool codegen(jitdata *jd)
 #if 0 /* no leaf optimization yet */
        savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
 #endif
-       savedregs_num = 16;                          /* register-window save area */ 
+       savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */ 
 
 
        /* space to save used callee saved registers */
@@ -137,6 +161,11 @@ bool codegen(jitdata *jd)
                cd->stackframesize++;
 #endif
 
+       /* keep stack 16-byte aligned (ABI requirement) */
+
+       if (cd->stackframesize & 1)
+               cd->stackframesize++;
+
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
@@ -196,7 +225,7 @@ bool codegen(jitdata *jd)
        md = m->parseddesc;
 
        /* when storing locals, use this as base */
-       localbase = USESTACK;
+       localbase = JITSTACK;
        
        /* since the register allocator does not know about the shifting window
         * arg regs need to be copied via the stack
@@ -207,8 +236,9 @@ bool codegen(jitdata *jd)
                
                localbase += INT_ARG_CNT * 8;
                
+               /* XXX could use the param slots on the stack for this! */
                for (p = 0; p < INT_ARG_CNT; p++)
-                       M_STX(REG_WINDOW_TRANSPOSE(rd->argintregs[p]), REG_SP, USESTACK + (p * 8));
+                       M_STX(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[p]), REG_SP, JITSTACK + (p * 8));
        }
        
 
@@ -225,49 +255,52 @@ bool codegen(jitdata *jd)
                        continue;
 
                var = VAR(varindex);
-
-               s1 = md->params[p].regoff;
-               if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
+               s1 = md->params[p].regoff;
+               
+               if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */                        
+                       
                        if (!md->params[p].inmemory) {           /* register arguments    */
                                /*s2 = rd->argintregs[s1];*/
                                /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
+                               
+                               /* need the argument index (p) here, not the register number */
+                               
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       /*M_INTMOVE(s2, var->vv.regoff);*/
-                                       M_LDX(var->vv.regoff, REG_SP, USESTACK + (s1 * 8));
+                                       /*M_INTMOVE(s2, var->vv.regoff);*/                                      
+                                       M_LDX(var->vv.regoff, REG_SP, JITSTACK + (p * 8));
 
                                } else {                             /* reg arg -> spilled    */
                                        /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
                                        
-                                       M_LDX(REG_ITMP1, REG_SP, USESTACK + (s1 * 8));
+                                       M_LDX(REG_ITMP1, REG_SP, JITSTACK + (p * 8));
                                        M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
                                }
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
-                                       M_LDX(var->vv.regoff, REG_FP, USESTACK + (s1 * 8));
+                                       M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
 
                                } else {                             /* stack arg -> spilled  */
                                        /* add the callers window save registers */
-                                       var->vv.regoff = cd->stackframesize + WINSAVE_CNT + s1;
+                                       var->vv.regoff = cd->stackframesize + s1;
                                }
                        }
                
                } else {                                     /* floating args         */
                        if (!md->params[p].inmemory) {           /* register arguments    */
-                               s2 = rd->argfltregs[s1];
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       M_FLTMOVE(s2, var->vv.regoff);
+                                       M_FLTMOVE(s1, var->vv.regoff);
 
                                } else {                                         /* reg arg -> spilled    */
-                                       M_DST(s2, REG_SP, localbase + (var->vv.regoff) * 8);
+                                       M_DST(s1, REG_SP, localbase + (var->vv.regoff) * 8);
                                }
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
-                                       M_DLD(var->vv.regoff, REG_FP, USESTACK + (s1 * 8));
+                                       M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
 
                                } else {                             /* stack-arg -> spilled  */
-                                       var->vv.regoff = cd->stackframesize + WINSAVE_CNT + s1;
+                                       var->vv.regoff = cd->stackframesize + s1;
                                }
                        }
                }
@@ -288,7 +321,9 @@ bool codegen(jitdata *jd)
        
        /* end of header generation */ 
        
-       replacementpoint = jd->code->rplpoints;
+       /* create replacement points */
+
+       REPLACEMENT_POINTS_INIT(cd, jd);
 
        /* walk through all basic blocks */
 
@@ -318,6 +353,7 @@ bool codegen(jitdata *jd)
                MCODECHECK(64+len);
                
 #if defined(ENABLE_LSRA)
+#error XXX LSRA not tested yet
                if (opt_lsra) {
                while (len) {
                        len--;
@@ -339,7 +375,7 @@ bool codegen(jitdata *jd)
                        var = VAR(bptr->invars[len]);
                        if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
                                d = codegen_reg_of_var(0, var, REG_ITMP1);
-                               M_INTMOVE(REG_ITMP1, d);
+                               M_INTMOVE(REG_ITMP2_XPTR, d);
                                emit_store(jd, NULL, var, d);
                        }
                        else {
@@ -373,7 +409,7 @@ bool codegen(jitdata *jd)
                case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       emit_nullpointer_check(cd, s1);
+                       emit_nullpointer_check(cd, iptr, s1);
                        break;
        
                /* constant operations ************************************************/
@@ -437,23 +473,23 @@ bool codegen(jitdata *jd)
                /* load/store/copy/move operations ************************************/
 
                case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
+               case ICMD_LLOAD:
+               case ICMD_ALOAD:
+               case ICMD_FLOAD:
+               case ICMD_DLOAD:
                case ICMD_ISTORE:     /* ..., value  ==> ...                          */
-               case ICMD_LSTORE:     /* ..., value  ==> ...                          */
-               case ICMD_FSTORE:     /* ..., value  ==> ...                          */
-               case ICMD_DSTORE:     /* ..., value  ==> ...                          */
+               case ICMD_LSTORE:
+               case ICMD_FSTORE:
+               case ICMD_DSTORE:
                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;
 
 
@@ -503,7 +539,15 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
-               case ICMD_INT2SHORT:
+               
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_SLLX_IMM(s1, 48, d);
+                       M_SRLX_IMM( d, 48, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+                       
+               case ICMD_INT2SHORT:   /* ..., value  ==> ..., value                   */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -632,7 +676,7 @@ bool codegen(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);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, iptr, s2);
                        M_ISEXT(s1, s1);
                        /* XXX trim s2 like s1 ? */
                        M_DIVX(s1, s2, d);
@@ -644,7 +688,7 @@ bool codegen(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);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, iptr, s2);
                        M_DIVX(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -654,12 +698,12 @@ bool codegen(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_ITMP3);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, iptr, s2);
                        M_ISEXT(s1, s1);
                        /* XXX trim s2 like s1 ? */
-                       M_DIVX(s1, s2, d);
-                       M_MULX(s2, d, d);
-                       M_SUB(s1, d, d);
+                       M_DIVX(s1, s2, REG_ITMP3);
+                       M_MULX(s2, REG_ITMP3, REG_ITMP3);
+                       M_SUB(s1, REG_ITMP3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -668,10 +712,10 @@ bool codegen(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_ITMP3);
-                       gen_div_check(s2);
-                       M_DIVX(s1, s2, d);
-                       M_MULX(s2, d, d);
-                       M_SUB(s1, d, d);
+                       emit_arithmetic_check(cd, iptr, s2);
+                       M_DIVX(s1, s2, REG_ITMP3);
+                       M_MULX(s2, REG_ITMP3, REG_ITMP3);
+                       M_SUB(s1, REG_ITMP3, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -688,7 +732,15 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
-               case ICMD_LSHL:
+
+                       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_SLL(s1, s2, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+                       
+               case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -698,7 +750,16 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
-               case ICMD_LSHLCONST:  /* val.i = constant                             */
+                                     /* val.i = constant                             */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_SLL_IMM(s1, iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+                       
+               case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
+                                     /* val.i = constant                             */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -802,26 +863,27 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
+               case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant           */
                                      /* sx.val.i = constant                             */
+                                     /* constant is actually constant - 1               */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
                        if (s1 == d) {
                                M_MOV(s1, REG_ITMP1);
                                s1 = REG_ITMP1;
                        }
-                       if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
+                       M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
+                       if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
                                M_AND_IMM(s1, iptr->sx.val.i, d);
-                               M_BGEZ(s1, 4);
+                               M_BGEZ(s1, 5);
                                M_NOP;
                                M_SUB(REG_ZERO, s1, d);
                                M_AND_IMM(d, iptr->sx.val.i, d);
                        } else {
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_AND(s1, REG_ITMP2, d);
-                               M_BGEZ(s1, 4);
+                               M_BGEZ(s1, 5);
                                M_NOP;
                                M_SUB(REG_ZERO, s1, d);
                                M_AND(d, REG_ITMP2, d);
@@ -1054,7 +1116,7 @@ bool codegen(jitdata *jd)
                case ICMD_I2F:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
                        M_IST (s1, REG_PV_CALLEE, disp);
                        M_FLD (d, REG_PV_CALLEE, disp);
                        M_CVTIF (d, d); /* rd gets translated to double target register */
@@ -1064,17 +1126,43 @@ bool codegen(jitdata *jd)
                case ICMD_I2D:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_float(cd, 0.0);
-                       M_IST (s1, REG_PV_CALLEE, disp);
-                       M_FLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
+                       disp = dseg_add_unique_float(cd, 0.0);
+                       M_IST(s1, REG_PV_CALLEE, disp);
+                       M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
                        M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
                        emit_store_dst(jd, iptr, d);
                        break;
+                       
+               case ICMD_L2F:
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       disp = dseg_add_unique_double(cd, 0.0);
+                       M_STX(s1, REG_PV_CALLEE, disp);
+                       M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
+                       M_CVTLF(REG_FTMP3, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+                       
+               case ICMD_L2D:
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       disp = dseg_add_unique_double(cd, 0.0);
+                       M_STX(s1, REG_PV_CALLEE, disp);
+                       M_DLD(d, REG_PV_CALLEE, disp);
+                       M_CVTLD(d, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
 
                case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_FCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTFI(s1, REG_FTMP2);
                        M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
                        M_ILD(d, REG_PV, disp);
@@ -1085,7 +1173,13 @@ bool codegen(jitdata *jd)
                case ICMD_D2I:       /* ..., value  ==> ..., (int) value             */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_DCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTDI(s1, REG_FTMP2);
                        M_FST(REG_FTMP2, REG_PV, disp);
                        M_ILD(d, REG_PV, disp);
@@ -1095,7 +1189,13 @@ bool codegen(jitdata *jd)
                case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_FCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
                        M_DST(REG_FTMP2, REG_PV, disp);
                        M_LDX(d, REG_PV, disp);
@@ -1105,7 +1205,13 @@ bool codegen(jitdata *jd)
                case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_DCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
                        M_DST(REG_FTMP2, REG_PV, disp);
                        M_LDX(d, REG_PV, disp);
@@ -1135,9 +1241,9 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        M_FCMP(s1,s2);
-                       M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
-                       M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
-                       M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
+                       M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
+                       M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+                       M_CMOVFGT_IMM(1, d); /* 1 if greater */
                        emit_store_dst(jd, iptr, d);
                        break;
                        
@@ -1147,9 +1253,9 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        M_DCMP(s1,s2);
-                       M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
-                       M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
-                       M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
+                       M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
+                       M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+                       M_CMOVFGT_IMM(1, d); /* 1 if greater */
                        emit_store_dst(jd, iptr, d);
                        break;
                        
@@ -1159,9 +1265,9 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);    
                        M_FCMP(s1,s2);
-                       M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
-                       M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
-                       M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
+                       M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
+                       M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+                       M_CMOVFLT_IMM(-1, d); /* -1 if less */
                        emit_store_dst(jd, iptr, d);
                        break;
                        
@@ -1171,9 +1277,9 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);    
                        M_DCMP(s1,s2);
-                       M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
-                       M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
-                       M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
+                       M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
+                       M_CMOVFEQ_IMM(0, d); /* 0 if equal */
+                       M_CMOVFLT_IMM(-1, d); /* -1 if less */
                        emit_store_dst(jd, iptr, d);
                        break;
                        
@@ -1184,7 +1290,7 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, iptr, s1);
                        M_ILD(d, s1, OFFSET(java_arrayheader, size));
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1194,12 +1300,10 @@ bool codegen(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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
-                       M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+                       M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1208,10 +1312,8 @@ bool codegen(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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
                        M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
@@ -1223,13 +1325,11 @@ bool codegen(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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
-                       M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+                       M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1238,10 +1338,8 @@ bool codegen(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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
                        M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
@@ -1253,10 +1351,8 @@ bool codegen(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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
                        M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
@@ -1268,10 +1364,8 @@ bool codegen(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_FTMP1);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
                        M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
@@ -1283,10 +1377,8 @@ bool codegen(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_FTMP1);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
                        M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
@@ -1298,10 +1390,8 @@ bool codegen(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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
                        M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
@@ -1313,10 +1403,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
@@ -1327,10 +1415,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
@@ -1341,10 +1427,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
@@ -1355,10 +1439,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
@@ -1369,10 +1451,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
@@ -1383,10 +1463,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
@@ -1398,28 +1476,24 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
 
-                       M_MOV(s1, rd->argintregs[0]);
-                       M_MOV(s3, rd->argintregs[1]);
+                       M_MOV(s1, REG_OUT0);
+                       M_MOV(s3, REG_OUT1);
                        disp = dseg_add_functionptr(cd, BUILTIN_canstore);
                        M_ALD(REG_ITMP3, REG_PV, disp);
                        M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
                        M_NOP;
-
-                       M_BEQZ(REG_RESULT_CALLER, 0);
-                       codegen_add_arraystoreexception_ref(cd);
-                       M_NOP;
+                       emit_exception_check(cd, iptr);
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       /* implicit null-pointer check */
                        M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
                        break;
 
@@ -1428,10 +1502,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
                        break;
@@ -1441,10 +1513,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
                        M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
@@ -1454,10 +1524,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
@@ -1467,10 +1535,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
@@ -1480,10 +1546,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
@@ -1624,7 +1688,7 @@ bool codegen(jitdata *jd)
                case ICMD_GETFIELD:   /* ...  ==> ..., value                          */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, iptr, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf = iptr->sx.s23.s3.uf;
@@ -1671,7 +1735,7 @@ bool codegen(jitdata *jd)
                case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, iptr, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf = iptr->sx.s23.s3.uf;
@@ -1720,7 +1784,7 @@ bool codegen(jitdata *jd)
                                          /* following NOP)                           */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       gen_nullptr_check(s1);
+                       emit_nullpointer_check(cd, iptr, s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                unresolved_field *uf = iptr->sx.s23.s3.uf;
@@ -1775,7 +1839,7 @@ bool codegen(jitdata *jd)
 
 #ifdef ENABLE_VERIFIER
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               uc = iptr->sx.s23.s2.uc;
+                               unresolved_class *uc = iptr->sx.s23.s2.uc;
 
                                codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
                        }
@@ -1793,158 +1857,115 @@ bool codegen(jitdata *jd)
                case ICMD_GOTO:         /* ... ==> ...                                */
                case ICMD_RET:          /* ... ==> ...                                */
 
-                       M_BR(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_br(cd, iptr->dst.block);
                        ALIGNCODENOP;
                        break;
 
                case ICMD_JSR:          /* ... ==> ...                                */
 
-                       M_BR(0);
-                       codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
-                       M_NOP;
+                       emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
                        ALIGNCODENOP;
                        break;
 
                case ICMD_IFNULL:       /* ..., value ==> ...                         */
+               case ICMD_IFNONNULL:
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       M_BEQZ(s1, 0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
-                       break;
-
-               case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       M_BNEZ(s1, 0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
                        break;
+                       
+               /* Note: int compares must not branch on the register directly.       */
+               /* Reason is, that register content is not 32-bit clean.              */
 
                case ICMD_IFEQ:         /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.i == 0) {
-                               M_BEQZ(s1, 0);
-                       } else {
-                               if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
-                                       }
-                               else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                                       M_CMP(s1, REG_ITMP2);
-                                       }
-                               M_BEQ(0);
-                               }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       
+                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
+                               M_CMP_IMM(s1, iptr->sx.val.i);
+                       }
+                       else {
+                               ICONST(REG_ITMP2, iptr->sx.val.i);
+                               M_CMP(s1, REG_ITMP2);
+                       }
+                       emit_beq(cd, iptr->dst.block);
                        break;
 
                case ICMD_IFLT:         /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.i == 0) {
-                               M_BLTZ(s1, 0);
-                       } else {
-                               if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
-                               } else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                                       M_CMP(s1, REG_ITMP2);
-                               }
-                               M_BLT(0);
+                       
+                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
+                               M_CMP_IMM(s1, iptr->sx.val.i);
+                       } 
+                       else {
+                               ICONST(REG_ITMP2, iptr->sx.val.i);
+                               M_CMP(s1, REG_ITMP2);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_blt(cd, iptr->dst.block);
                        break;
 
                case ICMD_IFLE:         /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.i == 0) {
-                               M_BLEZ(s1, 0);
-                               }
+
+                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
+                               M_CMP_IMM(s1, iptr->sx.val.i);
+                       }
                        else {
-                               if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
-                                       }
-                               else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                                       M_CMP(s1, REG_ITMP2);
-                               }
-                               M_BLE(0);
+                               ICONST(REG_ITMP2, iptr->sx.val.i);
+                               M_CMP(s1, REG_ITMP2);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_ble(cd, iptr->dst.block);
                        break;
 
                case ICMD_IFNE:         /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.i == 0) {
-                               M_BNEZ(s1, 0);
-                               }
+               
+                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
+                               M_CMP_IMM(s1, iptr->sx.val.i);
+                       }
                        else {
-                               if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
-                               }
-                               else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                                       M_CMP(s1, REG_ITMP2);
-                               }
-                               M_BNE(0);
+                               ICONST(REG_ITMP2, iptr->sx.val.i);
+                               M_CMP(s1, REG_ITMP2);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bne(cd, iptr->dst.block);
                        break;
                                                
                case ICMD_IFGT:         /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.i == 0) {
-                               M_BGTZ(s1, 0);
+               
+                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
+                               M_CMP_IMM(s1, iptr->sx.val.i);
                        } 
                        else {
-                               if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
-                               } else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                                       M_CMP(s1, REG_ITMP2);
-                               }
-                               M_BGT(0);
+                               ICONST(REG_ITMP2, iptr->sx.val.i);
+                               M_CMP(s1, REG_ITMP2);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bgt(cd, iptr->dst.block);          
                        break;
 
                case ICMD_IFGE:         /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.i == 0) {
-                               M_BGEZ(s1, 0);
-                               }
+
+                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
+                               M_CMP_IMM(s1, iptr->sx.val.i);
+                       }
                        else {
-                               if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
-                                       }
-                               else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                                       M_CMP(s1, REG_ITMP2);
-                               }
-                               M_BGE(0);
+                               ICONST(REG_ITMP2, iptr->sx.val.i);
+                               M_CMP(s1, REG_ITMP2);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bge(cd, iptr->dst.block);
                        break;
                        
                case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.l == 0) {
-                               M_BEQZ(s1, 0);
-                       }
+                       if (iptr->sx.val.l == 0)
+                               emit_beqz(cd, iptr->dst.block, s1);
                        else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
                                        M_CMP_IMM(s1, iptr->sx.val.l);
@@ -1953,108 +1974,93 @@ bool codegen(jitdata *jd)
                                        LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_XBEQ(0);
+                               emit_beq_xcc(cd, iptr->dst.block);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
                        break;
                        
                case ICMD_IF_LLT:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.l == 0) {
-                               M_BLTZ(s1, 0);
-                       } 
+                       if (iptr->sx.val.l == 0)
+                               emit_bltz(cd, iptr->dst.block, s1);
                        else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
                                        M_CMP_IMM(s1, iptr->sx.val.l);
                                } 
                                else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.l);
+                                       LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_XBLT(0);
+                               emit_blt_xcc(cd, iptr->dst.block);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
                        break;
 
                case ICMD_IF_LLE:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.l == 0) {
-                               M_BLEZ(s1, 0);
-                               }
+                       if (iptr->sx.val.l == 0)
+                               emit_blez(cd, iptr->dst.block, s1);
                        else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
                                        M_CMP_IMM(s1, iptr->sx.val.l);
-                                       }
+                               }
                                else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.l);
+                                       LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_XBLE(0);
+                               emit_ble_xcc(cd, iptr->dst.block);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
                        break;
                        
                case ICMD_IF_LNE:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.l == 0) {
-                               M_BNEZ(s1, 0);
-                               }
+                       if (iptr->sx.val.l == 0)
+                               emit_bnez(cd, iptr->dst.block, s1);
                        else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
-                                       M_CMP_IMM(s1, iptr->sx.val.i);
+                                       M_CMP_IMM(s1, iptr->sx.val.l);
                                }
                                else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.l);
+                                       LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_XBNE(0);
+                               emit_bne_xcc(cd, iptr->dst.block);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
                        break;
                                                
                case ICMD_IF_LGT:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.l == 0) {
-                               M_BLTZ(s1, 0);
-                       else {
+                       if (iptr->sx.val.l == 0)
+                               emit_bgtz(cd, iptr->dst.block, s1);
+                       else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
                                        M_CMP_IMM(s1, iptr->sx.val.l);
-                               } else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.l);
+                               } 
+                               else {
+                                       LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_XBGT(0);
+                               emit_bgt_xcc(cd, iptr->dst.block);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
                        break;
 
                case ICMD_IF_LGE:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       if (iptr->sx.val.l == 0) {
-                               M_BLEZ(s1, 0);
-                               }
+                       if (iptr->sx.val.l == 0)
+                               emit_bgez(cd, iptr->dst.block, s1);
                        else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
                                        M_CMP_IMM(s1, iptr->sx.val.l);
-                                       }
+                               }
                                else {
-                                       ICONST(REG_ITMP2, iptr->sx.val.l);
+                                       LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_XBGE(0);
+                               emit_bge_xcc(cd, iptr->dst.block);
                        }
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
                        break;                  
                        
 
@@ -2064,9 +2070,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_XBEQ(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_beq_xcc(cd, iptr->dst.block);
                        break;
 
                case ICMD_IF_ICMPEQ:    /* 32-bit compare                             */
@@ -2074,9 +2078,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BEQ(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_beq(cd, iptr->dst.block);
                        break;
 
                case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
@@ -2085,9 +2087,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_XBNE(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bne_xcc(cd, iptr->dst.block);
                        break;
                        
                case ICMD_IF_ICMPNE:    /* 32-bit compare                             */
@@ -2095,9 +2095,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BNE(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bne(cd, iptr->dst.block);
                        break;
 
                case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
@@ -2105,9 +2103,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_XBLT(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_blt_xcc(cd, iptr->dst.block);
                        break;
                        
                case ICMD_IF_ICMPLT:    /* 32-bit compare                             */
@@ -2115,9 +2111,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BLT(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_blt(cd, iptr->dst.block);
                        break;
 
                case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
@@ -2125,9 +2119,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_XBGT(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bgt_xcc(cd, iptr->dst.block);
                        break;
                        
                case ICMD_IF_ICMPGT:    /* 32-bit compare                             */
@@ -2135,9 +2127,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BGT(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bgt(cd, iptr->dst.block);
                        break;
 
                case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
@@ -2145,9 +2135,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BLE(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_ble_xcc(cd, iptr->dst.block);
                        break;
                        
                case ICMD_IF_ICMPLE:    /* 32-bit compare                             */
@@ -2155,9 +2143,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BLE(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_ble(cd, iptr->dst.block);
                        break;                  
        
 
@@ -2166,9 +2152,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BGE(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bge_xcc(cd, iptr->dst.block);
                        break;
                        
                case ICMD_IF_ICMPGE:    /* 32-bit compare                             */
@@ -2176,9 +2160,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       M_BGE(0);
-                       codegen_add_branch_ref(cd, iptr->dst.block);
-                       M_NOP;
+                       emit_bge(cd, iptr->dst.block);
                        break;
 
 
@@ -2196,12 +2178,9 @@ bool codegen(jitdata *jd)
 
 #ifdef ENABLE_VERIFIER
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
-                                                                       iptr->sx.s23.s2.uc, 0);
+                               unresolved_class *uc = iptr->sx.s23.s2.uc;
 
-                               if (opt_showdisassemble) {
-                                       M_NOP; M_NOP;
-                               }
+                               codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
                        }
 #endif /* ENABLE_VERIFIER */
                        goto nowperformreturn;
@@ -2210,7 +2189,7 @@ bool codegen(jitdata *jd)
                case ICMD_DRETURN:
 
                        s1 = emit_load_s1(jd, iptr, REG_FRESULT);
-                       M_FLTMOVE(s1, REG_FRESULT);
+                       M_DBLMOVE(s1, REG_FRESULT);
                        goto nowperformreturn;
 
                case ICMD_RETURN:       /* ...  ==> ...                               */
@@ -2287,15 +2266,13 @@ nowperformreturn:
                        /* range check */
                                        
                        if (i <= 4095) {
-                               M_CMP_IMM(REG_ITMP1, i);
+                               M_CMP_IMM(REG_ITMP1, i - 1);
                        }
                        else {
-                               ICONST(REG_ITMP2, i);
+                               ICONST(REG_ITMP2, i - 1);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                        }               
-                       M_XBULT(0);
-                       codegen_add_branch_ref(cd, table[0].block); /* default target */
-                       M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
+                       emit_bugt(cd, table[0].block); /* default target */
 
                        /* build jump table top down and use address of lowest entry */
 
@@ -2309,6 +2286,7 @@ nowperformreturn:
 
                        /* length of dataseg after last dseg_addtarget is used by load */
 
+                       M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
                        M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
                        M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
                        M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
@@ -2335,15 +2313,11 @@ nowperformreturn:
                                        ICONST(REG_ITMP2, lookup->value);
                                        M_CMP(s1, REG_ITMP2);
                                }
-                               M_BEQ(0);
-                               codegen_add_branch_ref(cd, lookup->target.block); 
-                               M_NOP;
+                               emit_beq(cd, lookup->target.block);
                                ++lookup;
                        }
 
-                       M_BR(0);
-                       codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
-                       M_NOP;
+                       emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
                        ALIGNCODENOP;
                        break;
                        }
@@ -2354,8 +2328,50 @@ nowperformreturn:
                        bte = iptr->sx.s23.s3.bte;
                        md = bte->md;
                        
-                       /* XXX: proper builtin calling and float args are so not implemented */
-                       assert(md->paramcount <= 5 && md->argfltreguse < 1);
+                       /* XXX: builtin calling with stack arguments not implemented */
+                       assert(md->paramcount <= 5 && md->argfltreguse <= 16);
+                       
+                       s3 = md->paramcount;
+
+                       MCODECHECK((s3 << 1) + 64);
+
+#ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
+
+                       /* copy float arguments according to ABI convention */
+
+                       int num_fltregargs = 0;
+                       int fltregarg_inswap[16];
+
+                       for (s3 = s3 - 1; s3 >= 0; s3--) {
+                               var = VAR(iptr->sx.s23.s2.args[s3]);
+
+                               if (IS_FLT_DBL_TYPE(var->type)) {
+                                       if (!md->params[s3].inmemory) {
+                                               s1 = s3; /*native flt args use argument index directly*/
+                                               d = emit_load(jd, iptr, var, REG_FTMP1);
+                                               
+                                               M_DMOV(d, s1 + 16);
+                                               fltregarg_inswap[num_fltregargs] = s1;
+                                               num_fltregargs++;
+                                               /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
+                                       }
+                                       else {
+                                               assert(0);
+                                       }
+                               }
+                       }
+                       
+                       int i;
+                       /* move swapped float args to target regs */
+                       for (i = 0; i < num_fltregargs; i++) {
+                               s1 = fltregarg_inswap[i];
+                               M_DMOV(s1 + 16, s1);
+                               /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
+                       }
+                       
+#else
+                       assert(md->argfltreguse == 0);
+#endif
                        
                        goto gen_method;
 
@@ -2385,36 +2401,40 @@ gen_method:
 
                        for (s3 = s3 - 1; s3 >= 0; s3--) {
                                var = VAR(iptr->sx.s23.s2.args[s3]);
+                               d  = md->params[s3].regoff;
 
                                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_STX(d, REG_SP, USESTACK + md->params[s3].regoff * 8);
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP1);
+                                               M_STX(s1, REG_SP, JITSTACK + d * 8);
                                        }
                                }
                                else {
+#ifdef BUILTIN_FLOAT_ARGS
+                                       if (iptr->opc == ICMD_BUILTIN)
+                                               continue;
+#endif
+                                               
                                        if (!md->params[s3].inmemory) {
-                                               s1 = rd->argfltregs[md->params[s3].regoff];
-                                               d = emit_load(jd, iptr, var, s1);
+                                               s1 = emit_load(jd, iptr, var, d);
                                                if (IS_2_WORD_TYPE(var->type))
-                                                       M_DMOV(d, s1);
+                                                       M_DMOV(s1, d);
                                                else
-                                                       M_FMOV(d, s1);
+                                                       M_FMOV(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, USESTACK + md->params[s3].regoff * 8);
+                                                       M_DST(s1, REG_SP, JITSTACK + d * 8);
                                                else
-                                                       M_FST(d, REG_SP, USESTACK + md->params[s3].regoff * 8);
+                                                       M_FST(s1, REG_SP, JITSTACK + d * 8);
                                        }
                                }
                        }
@@ -2424,18 +2444,26 @@ gen_method:
                                disp = dseg_add_functionptr(cd, bte->fp);
 
                                M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
-                               s1 = REG_PV_CALLER;
-
-                               /* c call, allocate parameter array */
-                               M_LDA(REG_SP, REG_SP, -(ABI_PARAMARRAY_SLOTS) * 8);
 
+                               /* XXX jit-c-call */
+                               /* generate the actual call */
+    
+                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                           M_NOP;
+                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
+                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
+
+                               emit_exception_check(cd, iptr);
+                               if (md->returntype.type == TYPE_FLT) {
+                                       /* special handling for float return value in %f0 */
+                                       M_FMOV_INTERN(0,1);
+                               }
                                break;
 
                        case ICMD_INVOKESPECIAL:
-                               M_BEQZ(REG_OUT0, 0);
-                               codegen_add_nullpointerexception_ref(cd);
-                               M_NOP;
-                               /* fall through */
+                               emit_nullpointer_check(cd, iptr, REG_OUT0);
+                               /* fall-through */
 
                        case ICMD_INVOKESTATIC:
                                if (lm == NULL) {
@@ -2448,11 +2476,18 @@ gen_method:
                                        disp = dseg_add_address(cd, lm->stubroutine);
 
                                M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
-                               s1 = REG_PV_CALLER;
+                               
+                               /* generate the actual call */
+    
+                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                           M_NOP;
+                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
+                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
                                break;
 
                        case ICMD_INVOKEVIRTUAL:
-                               gen_nullptr_check(REG_OUT0);
+                               emit_nullpointer_check(cd, iptr, REG_OUT0);
 
                                if (lm == NULL) {
                                        codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
@@ -2463,14 +2498,21 @@ gen_method:
                                        s1 = OFFSET(vftbl_t, table[0]) +
                                                sizeof(methodptr) * lm->vftblindex;
 
-                               M_ALD(REG_METHODPTR, REG_OUT0,
-                                         OFFSET(java_objectheader, vftbl));
+                               /* implicit null-pointer check */
+                               M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
                                M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
-                               s1 = REG_PV_CALLER;
+                               
+                               /* generate the actual call */
+    
+                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                           M_NOP;
+                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
+                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
                                break;
 
                        case ICMD_INVOKEINTERFACE:
-                               gen_nullptr_check(rd->argintregs[0]);
+                               emit_nullpointer_check(cd, iptr, REG_OUT0);
 
                                if (lm == NULL) {
                                        codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
@@ -2485,34 +2527,19 @@ gen_method:
                                        s2 = sizeof(methodptr) * (lm - lm->class->methods);
                                }
 
-                               M_ALD(REG_METHODPTR, REG_OUT0,
-                                         OFFSET(java_objectheader, vftbl));
+                               /* implicit null-pointer check */
+                               M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
                                M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
                                M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
-                               s1 = REG_PV_CALLER;
-                               break;
-                       }
 
-                       /* generate the actual call */
-
-                       M_JMP(REG_RA_CALLER, s1, REG_ZERO);
-                       M_NOP;
-                       disp = (s4) (cd->mcodeptr - cd->mcodebase);
-                       /* REG_RA holds the value of the jmp instruction, therefore +8 */
-                       M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
-
-                       if (iptr->opc == ICMD_BUILTIN) {
-                               /* remove param slots */
-                               M_LDA(REG_SP, REG_SP, (ABI_PARAMARRAY_SLOTS) * 8);
-                       }
-
-
-                       /* actually only used for ICMD_BUILTIN */
-
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               M_BEQZ(REG_RESULT_CALLER, 0);
-                               codegen_add_fillinstacktrace_ref(cd);
-                               M_NOP;
+                           /* generate the actual call */
+    
+                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                           M_NOP;
+                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
+                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
+                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
+                               break;
                        }
 
                        /* store return value */
@@ -2572,23 +2599,10 @@ gen_method:
 
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
-                               /* calculate interface checkcast code size */
-
-                               s2 = 8;
-                               if (super == NULL)
-                                       s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
-
-                               /* calculate class checkcast code size */
-
-                               s3 = 10;
-                               if (super == NULL)
-                                       s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
-
                                /* if class is not resolved, check which code to call */
 
                                if (super == NULL) {
-                                       M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3 + 1);
-                                       M_NOP;
+                                       emit_label_beqz(cd, BRANCH_LABEL_1, s1);
 
                                        cr   = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
@@ -2598,8 +2612,7 @@ gen_method:
 
                                        M_ILD(REG_ITMP2, REG_PV, disp);
                                        M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
-                                       M_BEQZ(REG_ITMP2, s2 + 2 + 2);
-                                       M_NOP;
+                                       emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
                                }
 
                                /* interface checkcast code */
@@ -2612,37 +2625,32 @@ gen_method:
                                                                                          cr, 0);
                                        }
                                        else {
-                                               M_BEQZ(s1, s2 + 2);
-                                               M_NOP;
+                                               emit_label_beqz(cd, BRANCH_LABEL_3, s1);
                                        }
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
                                        M_ILD(REG_ITMP3, REG_ITMP2,
                                                        OFFSET(vftbl_t, interfacetablelength));
                                        M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
-                                       M_BLEZ(REG_ITMP3, 0);
-                                       codegen_add_classcastexception_ref(cd, s1);
-                                       M_NOP;
+                                       emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
+
                                        M_ALD(REG_ITMP3, REG_ITMP2,
                                                  OFFSET(vftbl_t, interfacetable[0]) -
                                                  superindex * sizeof(methodptr*));
-                                       M_BEQZ(REG_ITMP3, 0);
-                                       codegen_add_classcastexception_ref(cd, s1);
-                                       M_NOP;
+                                       emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
 
-                                       if (super == NULL) {
-                                   /* on sparc we always add 2 to the size of the code we want  */
-                                   /* branch over. (1 for branch delay nop, 1 since the base is */
-                                   /* the address of the branch instruction */
-                                               M_BR(s3 + 2);
-                                               M_NOP;
-                                       }
+                                       if (super == NULL)
+                                               emit_label_br(cd, BRANCH_LABEL_4);
+                                       else
+                                               emit_label(cd, BRANCH_LABEL_3);
                                }
 
                                /* class checkcast code */
 
                                if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
                                        if (super == NULL) {
+                                               emit_label(cd, BRANCH_LABEL_2);
+
                                                cr   = iptr->sx.s23.s3.c.ref;
                                                disp = dseg_add_unique_address(cd, NULL);
 
@@ -2653,8 +2661,7 @@ gen_method:
                                        else {
                                                disp = dseg_add_address(cd, super->vftbl);
 
-                                               M_BEQZ(s1, s3 + 2);
-                                               M_NOP;
+                                               emit_label_beqz(cd, BRANCH_LABEL_5, s1);
                                        }
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
@@ -2672,9 +2679,15 @@ gen_method:
 #endif
                                        /*                              } */
                                        M_CMP(REG_ITMP3, REG_ITMP2);
-                                       M_BULT(0);                         /* branch if ITMP3 < ITMP2 */ 
-                                       codegen_add_classcastexception_ref(cd, s1);
-                                       M_NOP;
+                                       emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
+
+                                       if (super != NULL)
+                                               emit_label(cd, BRANCH_LABEL_5);
+                               }
+
+                               if (super == NULL) {
+                                       emit_label(cd, BRANCH_LABEL_1);
+                                       emit_label(cd, BRANCH_LABEL_4);
                                }
 
                                d = codegen_reg_of_dst(jd, iptr, s1);
@@ -2682,8 +2695,8 @@ gen_method:
                        else {
                                /* array type cast-check */
 
-                               s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
-                               M_INTMOVE(s1, rd->argintregs[0]);
+                               s1 = emit_load_s1(jd, iptr, REG_OUT0);
+                               M_INTMOVE(s1, REG_OUT0);
 
                                disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
 
@@ -2697,18 +2710,15 @@ gen_method:
                                else
                                        disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
 
-                               M_ALD(rd->argintregs[1], REG_PV, disp);
+                               M_ALD(REG_OUT1, REG_PV, disp);
                                disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
                                M_ALD(REG_ITMP3, REG_PV, disp);
-                               M_LDA(REG_SP, -6*8, REG_SP); /* PARAMARRAY SLOTS */
+                               /* XXX jit-c-call */
                                M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
                                M_NOP;
-                               M_LDA(REG_SP, 6*8, REG_SP);
 
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                               M_BEQZ(REG_RESULT_CALLER, 0);
-                               codegen_add_classcastexception_ref(cd, s1);
-                               M_NOP;
+                               emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
 
                                d = codegen_reg_of_dst(jd, iptr, s1);
                        }
@@ -2718,6 +2728,7 @@ gen_method:
                        break;
 
                case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
+                                     /* val.a: (classinfo*) superclass               */
 
                        /*  superclass is an interface:
                         *      
@@ -2758,25 +2769,12 @@ gen_method:
                                s1 = REG_ITMP1;
                        }
 
-                       /* calculate interface instanceof code size */
-
-                       s2 = 7;
-                       if (super == NULL)
-                               s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
-
-                       /* calculate class instanceof code size */
-
-                       s3 = 8;
-                       if (super == NULL)
-                               s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
-
                        M_CLR(d);
 
                        /* if class is not resolved, check which code to call */
 
                        if (super == NULL) {
-                               M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
-                               M_NOP;
+                               emit_label_beqz(cd, BRANCH_LABEL_1, s1);
 
                                cr   = iptr->sx.s23.s3.c.ref;
                                disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
@@ -2786,8 +2784,7 @@ gen_method:
 
                                M_ILD(REG_ITMP3, REG_PV, disp);
                                M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
-                               M_BEQZ(REG_ITMP3, s2 + 2 + 2);
-                               M_NOP;
+                               emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
                        }
 
                        /* interface instanceof code */
@@ -2800,8 +2797,7 @@ gen_method:
                                                                                  cr, 0);
                                }
                                else {
-                                       M_BEQZ(s1, s2 + 2);
-                                       M_NOP;
+                                       emit_label_beqz(cd, BRANCH_LABEL_3, s1);
                                }
 
                                M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
@@ -2814,16 +2810,18 @@ gen_method:
                                                        superindex * sizeof(methodptr*)));
                                M_CMOVRNE_IMM(REG_ITMP1, 1, d);      /* REG_ITMP1 != 0  */
 
-                               if (super == NULL) {
-                                       M_BR(s3 + 2);
-                                       M_NOP;
-                               }
+                               if (super == NULL)
+                                       emit_label_br(cd, BRANCH_LABEL_4);
+                               else
+                                       emit_label(cd, BRANCH_LABEL_3);
                        }
 
                        /* class instanceof code */
 
                        if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
                                if (super == NULL) {
+                                       emit_label(cd, BRANCH_LABEL_2);
+
                                        cr   = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_address(cd, NULL);
 
@@ -2833,8 +2831,7 @@ gen_method:
                                else {
                                        disp = dseg_add_address(cd, supervftbl);
 
-                                       M_BEQZ(s1, s3 + 2);
-                                       M_NOP;
+                                       emit_label_beqz(cd, BRANCH_LABEL_5, s1);
                                }
 
                                M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
@@ -2851,11 +2848,78 @@ gen_method:
                                M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                                M_XCMOVULE_IMM(1, d);
+
+                               if (super != NULL)
+                                       emit_label(cd, BRANCH_LABEL_5);
                        }
+
+                       if (super == NULL) {
+                               emit_label(cd, BRANCH_LABEL_1);
+                               emit_label(cd, BRANCH_LABEL_4);
+                       }
+
                        emit_store_dst(jd, iptr, d);
                        }
                        break;
 
+               case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
+
+                       /* check for negative sizes and copy sizes to stack if necessary  */
+
+                       MCODECHECK((iptr->s1.argcount << 1) + 64);
+
+                       for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
+
+                               var = VAR(iptr->sx.s23.s2.args[s1]);
+       
+                               /* copy SAVEDVAR sizes to stack */
+
+                               /* Already Preallocated? */
+
+                               if (!(var->flags & PREALLOC)) {
+                                       s2 = emit_load(jd, iptr, var, REG_ITMP1);
+                                       M_STX(s2, REG_SP, CSTACK + (s1 * 8));
+                               }
+                       }
+
+                       /* arg 0 = dimension count */
+
+                       ICONST(REG_OUT0, iptr->s1.argcount);
+
+                       /* is patcher function set? */
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               disp = dseg_add_unique_address(cd, 0);
+
+                               codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
+                                                                         iptr->sx.s23.s3.c.ref,
+                                                                         disp);
+                       }
+                       else
+                               disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
+
+                       /* arg 1 = arraydescriptor */
+
+                       M_ALD(REG_OUT1, REG_PV, disp);
+
+                       /* arg 2 = pointer to dimensions = stack pointer (absolute) */
+
+                       M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
+
+                       /* XXX c abi call */
+                       disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
+                       M_ALD(REG_ITMP3, REG_PV, disp);
+                       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+                       M_NOP;
+
+                       /* check for exception before result assignment */
+
+                       emit_exception_check(cd, iptr);
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
+                       M_INTMOVE(REG_RESULT_CALLER, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
 
                default:
                        exceptions_throw_internalerror("Unknown ICMD %d during code generation",
@@ -2873,15 +2937,10 @@ gen_method:
        
        dseg_createlinenumbertable(cd);
 
-       /* generate exception and patcher stubs */
+       /* generate stubs */
 
-       emit_exception_stubs(jd);
        emit_patcher_stubs(jd);
-#if defined(ENABLE_REPLACEMENT)
-       emit_replacement_stubs(jd);
-#endif /* defined(ENABLE_REPLACEMENT) */
-
-       codegen_finish(jd);
+       REPLACEMENT_EMIT_STUBS(jd);
        
        /* everything's ok */
 
@@ -2889,85 +2948,43 @@ gen_method:
 }
 
 
+/* codegen_emit_stub_compiler **************************************************
 
-
-
-/* createcompilerstub **********************************************************
-
-   Creates a stub routine which calls the compiler.
+   Emits a stub routine which calls the compiler.
        
 *******************************************************************************/
 
-#define COMPILERSTUB_DATASIZE    3 * SIZEOF_VOID_P
-#define COMPILERSTUB_CODESIZE    4 * 4
-
-#define COMPILERSTUB_SIZE        COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
-
-
-u1 *createcompilerstub(methodinfo *m)
+void codegen_emit_stub_compiler(jitdata *jd)
 {
-       u1     *s;                          /* memory to hold the stub            */
-       ptrint      *d;
-       codeinfo    *code;
+       methodinfo  *m;
        codegendata *cd;
-       s4           dumpsize;
-       
-       s = CNEW(u1, COMPILERSTUB_SIZE);
-
-       /* set data pointer and code pointer */
-
-       d = (ptrint *) s;
-       s = s + COMPILERSTUB_DATASIZE;
-
-       /* mark start of dump memory area */
 
-       dumpsize = dump_size();
-
-       cd = DNEW(codegendata);
-       cd->mcodeptr = s;
-       
-       /* Store the codeinfo pointer in the same place as in the
-          methodheader for compiled methods. */
-
-       code = code_codeinfo_new(m);
+       /* get required compiler data */
 
-       d[0] = (ptrint) asm_call_jit_compiler;
-       d[1] = (ptrint) m;
-       d[2] = (ptrint) code;
+       m  = jd->m;
+       cd = jd->cd;
 
        /* code for the stub */
+
        /* no window save yet, user caller's PV */
        M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P);  /* codeinfo pointer */
        M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P);  /* pointer to compiler */
        M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO);  /* jump to the compiler, RA is wasted */
        M_NOP;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_cstub_len += COMPILERSTUB_SIZE;
-#endif
-
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       return s;
 }
 
 
+/* codegen_emit_stub_native ****************************************************
 
-/* createnativestub ************************************************************
-
-   Creates a stub routine which calls a native method.
+   Emits a stub routine which calls a native method.
 
 *******************************************************************************/
 
-u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
+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                    */
@@ -2980,11 +2997,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        m    = jd->m;
        code = jd->code;
        cd   = jd->cd;
-       rd   = jd->rd;
-
-       /* rewrite registers and params */
-       md_native_reg_setup(jd);
-       md_native_param_alloc(nmd);
 
        /* initialize variables */
 
@@ -3026,11 +3038,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
 #if !defined(WITH_STATIC_CLASSPATH)
        if (f == NULL) {
-               codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
-
-               if (opt_showdisassemble) {
-                       M_NOP; M_NOP;
-               }
+               codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
        }
 #endif
 
@@ -3038,7 +3046,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
                if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
-                       M_DST(rd->argfltregs[i], REG_SP, j * 8);
+                       M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
                        j++;
                }
        }
@@ -3058,7 +3066,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
                if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
-                       M_DLD(rd->argfltregs[i], REG_SP, j * 8);
+                       M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
                        j++;
                }
        }
@@ -3071,7 +3079,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
                if (IS_INT_LNG_TYPE(t)) {
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argintregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
                                /* s1 refers to the old window, transpose */
                                s1 = REG_WINDOW_TRANSPOSE(s1);
 
@@ -3079,20 +3087,21 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                                        s2 = nat_argintregs[nmd->params[j].regoff];
                                        M_INTMOVE(s1, s2);
                                } else {
-                                       s2 = nmd->params[j].regoff;
-                                       M_AST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                       s2 = nmd->params[j].regoff - 6;
+                                       M_AST(s1, REG_SP, CSTACK + s2 * 8);
                                }
 
                        } else {
+                               /*assert(false);*/
                                s1 = md->params[i].regoff + cd->stackframesize;
-                               s2 = nmd->params[j].regoff;
-                               M_ALD(REG_ITMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
-                               M_AST(REG_ITMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                               s2 = nmd->params[j].regoff - 6;
+                               M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
+                               M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
                        }
 
                } else {
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argfltregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
 
                                if (!nmd->params[j].inmemory) {
                                        /* no mapping to regs needed, native flt args use regoff */
@@ -3102,25 +3111,26 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                                        M_DMOV(s1, s2 + 16);
                                        fltregarg_inswap[num_fltregargs] = s2;
                                        num_fltregargs++;
-                                       printf("flt arg swap to %d\n", s2 + 16);
+                                       /*printf("flt arg swap to %d\n", s2 + 16);*/
 
                                } else {
                                        s2 = nmd->params[j].regoff;
                                        if (IS_2_WORD_TYPE(t))
-                                               M_DST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                               M_DST(s1, REG_SP, CSTACK + (s2 * 8));
                                        else
-                                               M_FST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                               M_FST(s1, REG_SP, CSTACK + (s2 * 8));
                                }
 
                        } else {
+                               /*assert(false);*/
                                s1 = md->params[i].regoff + cd->stackframesize;
-                               s2 = nmd->params[j].regoff;
+                               s2 = nmd->params[j].regoff - 6;
                                if (IS_2_WORD_TYPE(t)) {
-                                       M_DLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
-                                       M_DST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                       M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
+                                       M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
                                } else {
-                                       M_FLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
-                                       M_FST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                       M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
+                                       M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
                                }
                        }
                }
@@ -3130,7 +3140,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        for (i = 0; i < num_fltregargs; i++) {
                s1 = fltregarg_inswap[i];
                M_DMOV(s1 + 16, s1);
-               printf("float arg to target reg: %d ==> %d\n", s1+16, s1);
+               /*printf("float arg to target reg: %d ==> %d\n", s1+16, s1);*/
        }
 
 
@@ -3158,7 +3168,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                if (IS_INT_LNG_TYPE(md->returntype.type))
                        M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
                else
-                       M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+                       M_DST(REG_FRESULT, REG_SP, CSTACK);
        }
        
        /* Note: native functions return float values in %f0 (see ABI) */
@@ -3168,7 +3178,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        /* But for the trace function we need to put a flt result into %f1 */
        if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
                if (!IS_2_WORD_TYPE(md->returntype.type))
-                       M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+                       M_FLD(REG_FRESULT, REG_SP, CSTACK);
                emit_verbosecall_exit(jd);
        }
 #endif
@@ -3187,40 +3197,30 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        if (md->returntype.type != TYPE_VOID) {
                if (IS_FLT_DBL_TYPE(md->returntype.type)) {
                        if (IS_2_WORD_TYPE(md->returntype.type))
-                               M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+                               M_DLD(REG_FRESULT, REG_SP, CSTACK);
                        else
-                               M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
+                               M_FLD(REG_FRESULT, REG_SP, CSTACK);
                }
        }
 
        /* check for exception */
-
        M_BNEZ(REG_ITMP2_XPTR, 4);          /* if no exception then return        */
        M_NOP;
 
        M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
        M_NOP;
-#if 0  
-       M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
-
-       M_RET(REG_RA_CALLER, 8);            /* return to caller                   */
-       M_NOP;                              /* DELAY SLOT                         */
-#endif
 
        /* handle exception */
        
        disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
-       M_ALD(REG_ITMP3, REG_PV, disp);     /* load asm exception handler address */
-       M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);/* jump to asm exception handler     */
-       M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address (DELAY)    */
-
+       M_ALD(REG_ITMP1, REG_PV, disp);     /* load asm exception handler address */
+       M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address             */
+       M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler     */
+       M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
+       
        /* generate patcher stubs */
 
        emit_patcher_stubs(jd);
-
-       codegen_finish(jd);
-
-       return code->entrypoint;
 }
 
 /*