* src/vm/jit/sparc64/codegen.c: Implemented float argument passing for builtin calls.
[cacao.git] / src / vm / jit / sparc64 / codegen.c
index 2c4e53221561dc1883eb422db3eb04f2a26bfaf7..a5d4732f1f4d32fd5011b9221cbec38743f37031 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/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"
 
 /* XXX use something like this for window control ? 
  * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
 
 bool fits_13(s4 disp)
 {
-       /*  printf("fits disp %d?\n", 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;
@@ -259,7 +274,7 @@ bool codegen(jitdata *jd)
 
                                } else {                             /* stack arg -> spilled  */
                                        /* add the callers window save registers */
-                                       var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
+                                       var->vv.regoff = cd->stackframesize + s1;
                                }
                        }
                
@@ -278,7 +293,7 @@ bool codegen(jitdata *jd)
                                        M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
 
                                } else {                             /* stack-arg -> spilled  */
-                                       var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
+                                       var->vv.regoff = cd->stackframesize + s1;
                                }
                        }
                }
@@ -517,7 +532,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);
@@ -671,9 +694,9 @@ bool codegen(jitdata *jd)
                        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;
 
@@ -683,9 +706,9 @@ bool codegen(jitdata *jd)
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
                        emit_arithmetic_check(cd, iptr, s2);
-                       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;
 
@@ -702,7 +725,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);
@@ -712,7 +743,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);
@@ -816,26 +856,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);
@@ -1079,11 +1120,31 @@ bool codegen(jitdata *jd)
                        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 */
+                       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_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_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);
@@ -1149,9 +1210,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;
                        
@@ -1161,9 +1222,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;
                        
@@ -1173,9 +1234,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;
                        
@@ -1185,9 +1246,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;
                        
@@ -1208,7 +1269,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* implicit null-pointer check */
+                       emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
                        emit_store_dst(jd, iptr, d);
@@ -1219,7 +1281,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1231,7 +1294,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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_shortarray, data[0]));
@@ -1243,7 +1307,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1255,7 +1320,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1267,7 +1333,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1279,7 +1346,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1291,7 +1359,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);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1303,7 +1372,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1314,7 +1384,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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);
@@ -1325,7 +1396,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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);
@@ -1336,7 +1408,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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);
@@ -1347,7 +1420,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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);
@@ -1358,7 +1432,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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);
@@ -1370,7 +1445,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]);
@@ -1379,16 +1455,14 @@ bool codegen(jitdata *jd)
                        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;
 
@@ -1397,7 +1471,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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;
@@ -1407,7 +1482,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1417,7 +1493,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1427,7 +1504,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1437,7 +1515,8 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       emit_array_checks(cd, iptr, s1, s2);
+                       /* 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]));
@@ -1729,7 +1808,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);
                        }
@@ -1747,158 +1826,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);
@@ -1907,108 +1943,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;                  
                        
 
@@ -2018,9 +2039,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                             */
@@ -2028,9 +2047,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 ==> ...                  */
@@ -2039,9 +2056,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                             */
@@ -2049,9 +2064,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 ==> ...                  */
@@ -2059,9 +2072,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                             */
@@ -2069,9 +2080,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 ==> ...                  */
@@ -2079,9 +2088,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                             */
@@ -2089,9 +2096,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 ==> ...                  */
@@ -2099,9 +2104,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                             */
@@ -2109,9 +2112,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;                  
        
 
@@ -2120,9 +2121,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                             */
@@ -2130,9 +2129,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;
 
 
@@ -2150,12 +2147,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;
@@ -2164,7 +2158,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:       /* ...  ==> ...                               */
@@ -2241,15 +2235,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 */
 
@@ -2263,6 +2255,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);
@@ -2289,15 +2282,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;
                        }
@@ -2308,8 +2297,47 @@ 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);
+
+                       /* 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 (var->flags & PREALLOC)
+                                       continue;
+
+                               if (IS_FLT_DBL_TYPE(var->type)) {
+                                       if (!md->params[s3].inmemory) {
+                                               s1 = md->params[s3].regoff; /*native flt args use regoff 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);*/
+                       }
                        
                        goto gen_method;
 
@@ -2355,6 +2383,9 @@ gen_method:
                                        }
                                }
                                else {
+                                       if (iptr->opc == ICMD_BUILTIN)
+                                               continue;
+                                               
                                        if (!md->params[s3].inmemory) {
                                                s1 = rd->argfltregs[md->params[s3].regoff];
                                                d = emit_load(jd, iptr, var, s1);
@@ -2378,17 +2409,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;
 
                                /* 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) {
@@ -2401,7 +2441,14 @@ 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:
@@ -2416,10 +2463,17 @@ 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:
@@ -2438,29 +2492,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); 
 
-
-                       /* 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 */
@@ -2520,23 +2564,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 */
@@ -2546,8 +2577,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 */
@@ -2560,37 +2590,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);
 
@@ -2601,8 +2626,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));
@@ -2620,9 +2644,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);
@@ -2653,9 +2683,7 @@ gen_method:
                                M_NOP;
 
                                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);
                        }
@@ -2665,6 +2693,7 @@ gen_method:
                        break;
 
                case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
+                                     /* val.a: (classinfo*) superclass               */
 
                        /*  superclass is an interface:
                         *      
@@ -2705,25 +2734,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 */
@@ -2733,8 +2749,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 */
@@ -2747,8 +2762,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));
@@ -2761,16 +2775,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);
 
@@ -2780,8 +2796,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));
@@ -2798,11 +2813,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",
@@ -2820,15 +2902,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 */
 
@@ -2836,9 +2913,6 @@ gen_method:
 }
 
 
-
-
-
 /* createcompilerstub **********************************************************
 
    Creates a stub routine which calls the compiler.
@@ -2929,10 +3003,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        cd   = jd->cd;
        rd   = jd->rd;
 
-       /* rewrite registers and params */
-       md_native_reg_setup(jd);
-       md_native_param_alloc(nmd);
-
        /* initialize variables */
 
        md = m->parseddesc;
@@ -2973,11 +3043,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
 
@@ -2985,7 +3051,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(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
                        j++;
                }
        }
@@ -3005,7 +3071,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(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
                        j++;
                }
        }
@@ -3026,13 +3092,13 @@ 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;
+                                       s2 = nmd->params[j].regoff - 6;
                                        M_AST(s1, REG_SP, CSTACK + s2 * 8);
                                }
 
                        } else {
                                s1 = md->params[i].regoff + cd->stackframesize;
-                               s2 = nmd->params[j].regoff;
+                               s2 = nmd->params[j].regoff - 6;
                                M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
                                M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
                        }
@@ -3049,19 +3115,19 @@ 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, CSTACK + s2 * 8);
+                                               M_DST(s1, REG_SP, CSTACK + (s2 * 8));
                                        else
-                                               M_FST(s1, REG_SP, CSTACK + s2 * 8);
+                                               M_FST(s1, REG_SP, CSTACK + (s2 * 8));
                                }
 
                        } else {
                                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, CSTACK + s1 * 8);
                                        M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
@@ -3077,7 +3143,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);*/
        }
 
 
@@ -3141,25 +3207,20 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        }
 
        /* 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 */