* src/vm/jit/sparc64/codegen.h: Fixed double register number packing and fp compare...
[cacao.git] / src / vm / jit / sparc64 / codegen.c
index 7734469bd6303a835fe0e499c377fba29b9f81bf..6f09c21e0c836e76eae6197382b855a49c9e51e6 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
@@ -27,8 +27,7 @@
    Authors: Andreas Krall
             Reinhard Grafl
             Alexander Jordan
-
-   Changes: Edwin Steiner
+            Edwin Steiner
 
    $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
 
  */
 #define REG_PV REG_PV_CALLEE
 
+bool fits_13(s4 disp)
+{
+       /*  printf("fits disp %d?\n", disp); */
+
+       return (disp >= -4096) && (disp <= 4095);
+}
 
 /* codegen *********************************************************************
 
@@ -98,7 +103,6 @@ bool codegen(jitdata *jd)
        methoddesc         *md;
        fieldinfo          *fi;
        unresolved_field   *uf;
-       rplpoint           *replacementpoint;
        s4                  fieldtype;
        s4                  varindex;
 
@@ -123,7 +127,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 */
@@ -138,6 +142,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 */
@@ -197,7 +206,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
@@ -208,8 +217,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(rd->argintregs[p]), REG_SP, JITSTACK + (p * 8));
        }
        
 
@@ -234,22 +244,22 @@ bool codegen(jitdata *jd)
                                /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
                                        /*M_INTMOVE(s2, var->vv.regoff);*/
-                                       M_LDX(var->vv.regoff, REG_SP, USESTACK + (s1 * 8));
+                                       M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 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 + (s1 * 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, (WINSAVE_CNT + s1) * 8);
+                                       M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
 
                                } else {                             /* stack arg -> spilled  */
-                                       assert(0); /* XXX winsave area in between */
-                                       var->vv.regoff = cd->stackframesize + s1;
+                                       /* add the callers window save registers */
+                                       var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
                                }
                        }
                
@@ -265,11 +275,10 @@ bool codegen(jitdata *jd)
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
-                                       M_DLD(var->vv.regoff, REG_FP, (WINSAVE_CNT + s1) * 8);
+                                       M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
 
                                } else {                             /* stack-arg -> spilled  */
-                                       assert(0); /* XXX winsave area in between */
-                                       var->vv.regoff = cd->stackframesize + s1;
+                                       var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
                                }
                        }
                }
@@ -290,7 +299,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 */
 
@@ -320,6 +331,7 @@ bool codegen(jitdata *jd)
                MCODECHECK(64+len);
                
 #if defined(ENABLE_LSRA)
+#error XXX LSRA not tested yet
                if (opt_lsra) {
                while (len) {
                        len--;
@@ -341,7 +353,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 {
@@ -375,7 +387,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 ************************************************/
@@ -505,7 +517,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);
@@ -634,7 +654,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);
@@ -646,7 +666,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;
@@ -656,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_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);
@@ -670,7 +690,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_ITMP3);
-                       gen_div_check(s2);
+                       emit_arithmetic_check(cd, iptr, s2);
                        M_DIVX(s1, s2, d);
                        M_MULX(s2, d, d);
                        M_SUB(s1, d, d);
@@ -1137,9 +1157,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;
                        
@@ -1149,9 +1169,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;
                        
@@ -1161,9 +1181,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;
                        
@@ -1173,9 +1193,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;
                        
@@ -1186,7 +1206,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;
@@ -1196,12 +1216,9 @@ 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;
-                       }
+                       emit_array_checks(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;
 
@@ -1210,10 +1227,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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       emit_array_checks(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]));
@@ -1225,13 +1239,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;
-                       }
+                       emit_array_checks(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;
 
@@ -1240,10 +1251,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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       emit_array_checks(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,10 +1263,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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       emit_array_checks(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]));
@@ -1270,10 +1275,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_FTMP1);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       emit_array_checks(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]));
@@ -1285,10 +1287,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_FTMP1);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       emit_array_checks(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]));
@@ -1300,10 +1299,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);
-                       if (INSTRUCTION_MUST_CHECK(iptr)) {
-                               gen_nullptr_check(s1);
-                               gen_bound_check;
-                       }
+                       emit_array_checks(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]));
@@ -1315,10 +1311,7 @@ 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;
-                       }
+                       emit_array_checks(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]));
@@ -1329,10 +1322,7 @@ 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;
-                       }
+                       emit_array_checks(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);
@@ -1343,10 +1333,7 @@ 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;
-                       }
+                       emit_array_checks(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);
@@ -1357,10 +1344,7 @@ 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;
-                       }
+                       emit_array_checks(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);
@@ -1371,10 +1355,7 @@ 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;
-                       }
+                       emit_array_checks(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);
@@ -1385,10 +1366,7 @@ 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;
-                       }
+                       emit_array_checks(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);
@@ -1400,10 +1378,7 @@ 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;
-                       }
+                       emit_array_checks(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
 
                        M_MOV(s1, rd->argintregs[0]);
@@ -1430,10 +1405,7 @@ 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;
-                       }
+                       emit_array_checks(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
                        break;
@@ -1443,10 +1415,7 @@ 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;
-                       }
+                       emit_array_checks(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]));
@@ -1456,10 +1425,7 @@ 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;
-                       }
+                       emit_array_checks(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]));
@@ -1469,10 +1435,7 @@ 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;
-                       }
+                       emit_array_checks(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]));
@@ -1482,10 +1445,7 @@ 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;
-                       }
+                       emit_array_checks(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]));
@@ -1626,7 +1586,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;
@@ -1673,7 +1633,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;
@@ -1722,7 +1682,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;
@@ -2025,7 +1985,7 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
-                               M_BLTZ(s1, 0);
+                               M_BGTZ(s1, 0);
                        } else {
                                if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
                                        M_CMP_IMM(s1, iptr->sx.val.l);
@@ -2043,12 +2003,12 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
-                               M_BLEZ(s1, 0);
-                               }
+                               M_BGEZ(s1, 0);
+                       }
                        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);
                                        M_CMP(s1, REG_ITMP2);
@@ -2289,13 +2249,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);
+                       M_XBUGT(0);
                        codegen_add_branch_ref(cd, table[0].block); /* default target */
                        M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
 
@@ -2399,7 +2359,7 @@ gen_method:
                                        } 
                                        else {
                                                d = emit_load(jd, iptr, var, REG_ITMP1);
-                                               M_STX(d, REG_SP, md->params[s3].regoff * 8);
+                                               M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
                                        }
                                }
                                else {
@@ -2414,9 +2374,9 @@ gen_method:
                                        else {
                                                d = emit_load(jd, iptr, var, REG_FTMP1);
                                                if (IS_2_WORD_TYPE(var->type))
-                                                       M_DST(d, REG_SP, md->params[s3].regoff * 8);
+                                                       M_DST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
                                                else
-                                                       M_FST(d, REG_SP, md->params[s3].regoff * 8);
+                                                       M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
                                        }
                                }
                        }
@@ -2428,8 +2388,7 @@ gen_method:
                                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 */
 
                                break;
 
@@ -2454,7 +2413,7 @@ gen_method:
                                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);
@@ -2472,7 +2431,7 @@ gen_method:
                                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);
@@ -2503,11 +2462,6 @@ gen_method:
                        /* 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 */
 
@@ -2702,10 +2656,9 @@ gen_method:
                                M_ALD(rd->argintregs[1], 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);
@@ -2721,8 +2674,6 @@ gen_method:
 
                case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
 
-                                     /* val.a: (classinfo*) superclass               */
-
                        /*  superclass is an interface:
                         *      
                         *  return (sub != NULL) &&
@@ -2862,7 +2813,8 @@ gen_method:
 
 
                default:
-                       *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
+                       exceptions_throw_internalerror("Unknown ICMD %d during code generation",
+                                                                                  iptr->opc);
                        return false;
                        
        } /* switch */
@@ -3029,11 +2981,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
 
@@ -3041,7 +2989,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++;
                }
        }
@@ -3061,7 +3009,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++;
                }
        }
@@ -3083,14 +3031,14 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                                        M_INTMOVE(s1, s2);
                                } else {
                                        s2 = nmd->params[j].regoff;
-                                       M_AST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
+                                       M_AST(s1, REG_SP, CSTACK + s2 * 8);
                                }
 
                        } else {
                                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);
+                               M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
+                               M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
                        }
 
                } else {
@@ -3110,20 +3058,20 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                                } 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 {
                                s1 = md->params[i].regoff + cd->stackframesize;
                                s2 = nmd->params[j].regoff;
                                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);
                                }
                        }
                }
@@ -3161,7 +3109,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) */
@@ -3171,7 +3119,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
@@ -3190,9 +3138,9 @@ 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);
                }
        }