* src/vm/jit/powerpc64/codegen.c (codegen): Various more fixes all
[cacao.git] / src / vm / jit / powerpc64 / codegen.c
index 62ed26322ed1362f2850eead6152cadf2041804d..f131e30ce5c3f8e438480b1a0f53993e1a599da8 100644 (file)
@@ -30,8 +30,9 @@
    Changes: Christian Thalinger
             Christian Ullrich
             Edwin Steiner
+           Roland Lezuo
 
-   $Id: codegen.c 5632 2006-10-02 13:43:15Z edwin $
+   $Id: codegen.c 5928 2006-11-06 16:38:31Z tbfg $
 
 */
 
@@ -88,11 +89,10 @@ bool codegen(jitdata *jd)
        registerdata       *rd;
        s4                  len, s1, s2, s3, d, disp;
        ptrint              a;
-       s4                  stackframesize;
        varinfo            *var;
        basicblock         *bptr;
        instruction        *iptr;
-       exceptiontable     *ex;
+       exception_entry    *ex;
        u2                  currentline;
        methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
        builtintable_entry *bte;
@@ -100,6 +100,8 @@ bool codegen(jitdata *jd)
        rplpoint           *replacementpoint;
        s4                  fieldtype;
        s4                  varindex;
+       unresolved_field   *uf;
+       fieldinfo          *fi;
 
        /* get required compiler data */
 
@@ -125,7 +127,7 @@ bool codegen(jitdata *jd)
        savedregs_num += (INT_SAV_CNT - rd->savintreguse);
        savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
 
-       stackframesize = rd->memuse + savedregs_num;
+       cd->stackframesize = rd->memuse + savedregs_num;
 
 #if defined(ENABLE_THREADS)
        /* space to save argument of monitor_enter and Return Values to survive */
@@ -134,7 +136,7 @@ bool codegen(jitdata *jd)
        /* reside in R3 */
        if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
                /* reserve 2 slots for long/double return values for monitorexit */
-               stackframesize += 2;
+               cd->stackframesize += 2;
        }
 
 #endif
@@ -143,14 +145,15 @@ bool codegen(jitdata *jd)
 
        /* align stack to 16-bytes */
 
+/* FIXME */
 /*     if (!m->isleafmethod || opt_verbosecall) */
-               stackframesize = (stackframesize + 3) & ~3;
-
+/*             stackframesize = (stackframesize + 3) & ~3;
+*/
 /*     else if (m->isleafmethod && (stackframesize == LA_WORD_SIZE)) */
 /*             stackframesize = 0; */
 
        (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
-       (void) dseg_adds4(cd, stackframesize * 8);             /* FrameSize       */
+       (void) dseg_adds4(cd, cd->stackframesize * 8);             /* FrameSize       */
 
 #if defined(ENABLE_THREADS)
        /* IsSync contains the offset relative to the stack pointer for the
@@ -171,11 +174,11 @@ bool codegen(jitdata *jd)
 
        dseg_addlinenumbertablesize(cd);
 
-       (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
+       (void) dseg_adds4(cd, jd->exceptiontablelength);       /* ExTableSize     */
 
        /* create exception table */
 
-       for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
+       for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
                dseg_addtarget(cd, ex->start);
                dseg_addtarget(cd, ex->end);
                dseg_addtarget(cd, ex->handler);
@@ -189,12 +192,12 @@ bool codegen(jitdata *jd)
                M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
        }
 
-       if (stackframesize)
-               M_STDU(REG_SP, REG_SP, -stackframesize * 8);
+       if (cd->stackframesize)
+               M_STDU(REG_SP, REG_SP, -cd->stackframesize * 8);
 
        /* save return address and used callee saved registers */
 
-       p = stackframesize;
+       p = cd->stackframesize;
        for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
                p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
        }
@@ -208,92 +211,45 @@ bool codegen(jitdata *jd)
 
        for (p = 0, l = 0; p < md->paramcount; p++) {
                t = md->paramtypes[p].type;
-               var = &(rd->locals[l][t]);
+               varindex = jd->local_map[l*5 + t];
                l++;
                if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
                        l++;
-               if (var->type < 0)
+               if (varindex == UNUSED)
                        continue;
+               var = VAR(varindex);
                s1 = md->params[p].regoff;
                if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
-                       if (IS_2_WORD_TYPE(t))
-                               s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
-                                                          rd->argintregs[GET_HIGH_REG(s1)]);
-                       else
-                               s2 = rd->argintregs[s1];
                        if (!md->params[p].inmemory) {           /* register arguments    */
-                               if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       M_NOP;
-                                       if (IS_2_WORD_TYPE(t))          /* FIXME, only M_INTMOVE here */
-                                               M_LNGMOVE(s2, var->regoff);
-                                       else
-                                               M_INTMOVE(s2, var->regoff);
-
+                               s2 = rd->argintregs[s1];
+                               if (!IS_INMEMORY(var->flags))   {
+                                       M_INTMOVE(s2, var->vv.regoff);
                                } else {                             /* reg arg -> spilled    */
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_LST(s2, REG_SP, var->regoff * 4);
-                                       else
-                                               M_IST(s2, REG_SP, var->regoff * 4);
-                               }
-
+                                       M_LST(s2, REG_SP, var->vv.regoff * 8);
+                               } 
                        } else {                                 /* stack arguments       */
-                               if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_LLD(var->regoff, REG_SP, (stackframesize + s1) * 4);
-                                       else
-                                               M_ILD(var->regoff, REG_SP, (stackframesize + s1) * 4);
+                               if (!IS_INMEMORY(var->flags)) {      /* stack arg -> register */
+                                       M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
 
                                } else {                             /* stack arg -> spilled  */
-#if 1
-                                       M_ILD(REG_ITMP1, REG_SP, (stackframesize + s1) * 4);
-                                       M_IST(REG_ITMP1, REG_SP, var->regoff * 4);
-                                       if (IS_2_WORD_TYPE(t)) {
-                                               M_ILD(REG_ITMP1, REG_SP, (stackframesize + s1) * 4 +4);
-                                               M_IST(REG_ITMP1, REG_SP, var->regoff * 4 + 4);
-                                       }
-#else
-                                       /* Reuse Memory Position on Caller Stack */
-                                       var->regoff = stackframesize + s1;
-#endif
+                                       var->vv.regoff = cd->stackframesize + s1;
                                }
                        }
 
                } else {                                     /* floating args         */
                        if (!md->params[p].inmemory) {           /* register arguments    */
                                s2 = rd->argfltregs[s1];
-                               if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       M_FLTMOVE(s2, var->regoff);
-
+                               if (!IS_INMEMORY(var->flags)) {      /* reg arg -> register   */
+                                       M_FLTMOVE(s2, var->vv.regoff);
                                } else {                                         /* reg arg -> spilled    */
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_DST(s2, REG_SP, var->regoff * 4);
-                                       else
-                                               M_FST(s2, REG_SP, var->regoff * 4);
+                                       M_DST(s2, REG_SP, var->vv.regoff * 8);
                                }
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
-                                       if (IS_2_WORD_TYPE(t))
-                                               M_DLD(var->regoff, REG_SP, (stackframesize + s1) * 4);
-
-                                       else
-                                               M_FLD(var->regoff, REG_SP, (stackframesize + s1) * 4);
-
+                                       M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
                                } else {                             /* stack-arg -> spilled  */
-#if 1
-                                       if (IS_2_WORD_TYPE(t)) {
-                                               M_DLD(REG_FTMP1, REG_SP, (stackframesize + s1) * 4);
-                                               M_DST(REG_FTMP1, REG_SP, var->regoff * 4);
-                                               var->regoff = stackframesize + s1;
-
-                                       } else {
-                                               M_FLD(REG_FTMP1, REG_SP, (stackframesize + s1) * 4);
-                                               M_FST(REG_FTMP1, REG_SP, var->regoff * 4);
-                                       }
-#else
-                                       /* Reuse Memory Position on Caller Stack */
-                                       var->regoff = stackframesize + s1;
-#endif
+                                       var->vv.regoff = cd->stackframesize + s1;
                                }
                        }
                }
@@ -367,7 +323,7 @@ bool codegen(jitdata *jd)
        replacementpoint = jd->code->rplpoints;
 
        /* walk through all basic blocks */
-       for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
 
                bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
 
@@ -404,10 +360,10 @@ bool codegen(jitdata *jd)
                        while (len) {
                                len--;
                                var = VAR(bptr->invars[len]);
-                               if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
+                               if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
                                        /* d = reg_of_var(m, var, REG_ITMP1); */
                                        if (!(var->flags & INMEMORY))
-                                               d = var->regoff;
+                                               d = var->vv.regoff;
                                        else
                                                d = REG_ITMP1;
                                        M_INTMOVE(REG_ITMP1, d);
@@ -419,13 +375,13 @@ bool codegen(jitdata *jd)
                while (len) {
                        len--;
                        var = VAR(bptr->invars[len]);
-                       if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
+                       if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
                                d = codegen_reg_of_var(0, var, REG_ITMP1);
                                M_INTMOVE(REG_ITMP1, d);
                                emit_store(jd, NULL, var, d);
                        } 
                        else {
-                               assert((var->flags & OUTVAR));
+                               assert((var->flags & INOUT));
                        }
                }
 
@@ -438,6 +394,7 @@ bool codegen(jitdata *jd)
                currentline = 0;
                        
                for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
+                       bool sign_ext = false;
                        if (iptr->line != currentline) {
                                dseg_addlinenumber(cd, iptr->line);
                                currentline = iptr->line;
@@ -445,7 +402,6 @@ bool codegen(jitdata *jd)
 
                        MCODECHECK(64);   /* an instruction usually needs < 64 words      */
 
-                       /* M_NOP; M_NOP; XXX */
                        switch (iptr->opc) {
                        case ICMD_NOP:    /* ...  ==> ...                                 */
                        case ICMD_INLINE_START:
@@ -542,20 +498,15 @@ bool codegen(jitdata *jd)
                /* integer operations *************************************************/
 
                case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
-
+                       sign_ext = true;
+               case ICMD_LNEG:    
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_NEG(s1, d);
+                       if (sign_ext) M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_NEG(s1, d); /* XXX */
-                       emit_store_dst(jd, iptr, d);
-                       break;
 
                case ICMD_I2L:        /* ..., value  ==> ..., value                   */
 
@@ -608,17 +559,18 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
-                                     /* sx.val.i = constant                          */
+               case ICMD_IINC:
+               case ICMD_IADDCONST:
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
                                M_IADD_IMM(s1, iptr->sx.val.i, d);
                        } else {
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_IADD(s1, REG_ITMP2, d);
                        }
+                       M_EXTSW(d,d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -666,6 +618,7 @@ bool codegen(jitdata *jd)
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_SUB(s1, REG_ITMP2, d);
                        }
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -684,7 +637,7 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        /* XXX check me */
-                       if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
+                       if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767)) {
                                M_LADD_IMM(s1, -iptr->sx.val.l, d);
                        } else {
                                LCONST(REG_ITMP2, iptr->sx.val.l);
@@ -694,6 +647,7 @@ bool codegen(jitdata *jd)
                        break;
 
                case ICMD_IDIV:
+                       sign_ext = true;
                case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -704,32 +658,54 @@ bool codegen(jitdata *jd)
                        codegen_add_arithmeticexception_ref(cd);
 
                        M_DIV(s1, s2, d);
-
+                       /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
+                       /* we only need to check this if we did a LDIV, not for IDIV */
+                       if (!sign_ext)  {
+                               M_MFXER(REG_ITMP2);
+                               M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2);  /* test OV */
+                               M_BLE(1);
+                               M_MOV(s1, d);                           /* java specs says result == dividend */
+                       }
+                       if (sign_ext) M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_IREM:
+                       sign_ext = true;
                case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
                        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);
                        M_TST(s2);
                        M_BEQ(0);
                        codegen_add_arithmeticexception_ref(cd);
 
-                       /* FIXME s1 == -2^63 && s2 == -1 does not work that way */
-                       M_DIV(s1, s2, d);
-                       M_MUL( d, s2, d);
-                       M_SUB(s1,  d, d);
-                       emit_store_dst(jd, iptr, d);
+                       M_DIV(s1, s2,  REG_ITMP3);      
+                       /* we need to test if divident was 0x8000000000000, bit OV is set in XER in this case */
+                       /* we only need to check this if we did a LDIV, not for IDIV */
+                       if (!sign_ext)  {
+                               M_MFXER(REG_ITMP2);
+                               M_ANDIS(REG_ITMP2, 0x4000, REG_ITMP2);  /* test OV */
+                               M_BLE(2); 
+                               LCONST(REG_ITMP3, 0);                   /* result == 0 in this case */
+                               M_BR(2);
+                       }
+                       M_MUL(REG_ITMP3, s2, REG_ITMP2);
+                       M_SUB(s1, REG_ITMP2,  REG_ITMP3);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+
+                       M_MOV(REG_ITMP3, d);
+                       emit_store_dst(jd, iptr, REG_ITMP1);
                        break;
 
+               
                case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
-
+                       sign_ext = true;
+               case ICMD_LMUL:
                        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_MUL(s1, s2, d);
+                       if (sign_ext) M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -744,6 +720,18 @@ bool codegen(jitdata *jd)
                                ICONST(REG_ITMP3, iptr->sx.val.i);
                                M_MUL(s1, REG_ITMP3, d);
                        }
+                       M_EXTSW(d, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+               case ICMD_LMULCONST:
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32767))
+                               M_MUL_IMM(s1, iptr->sx.val.l, d);
+                       else {
+                               LCONST(REG_ITMP3, iptr->sx.val.l);
+                               M_MUL(s1, REG_ITMP3, d);
+                       }
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -763,6 +751,7 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_AND_IMM(s2, 0x1f, REG_ITMP3);
                        M_SLL(s1, REG_ITMP3, d);
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -772,6 +761,7 @@ bool codegen(jitdata *jd)
                        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 & 0x1f, d);
+                       M_EXTSW(d,d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -868,7 +858,6 @@ bool codegen(jitdata *jd)
 
                case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
                                      /* sx.val.i = constant                             */
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_MOV(s1, REG_ITMP2);
@@ -888,6 +877,7 @@ bool codegen(jitdata *jd)
                                M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
                        }
                        M_SUB(s1, REG_ITMP2, d);
+                       M_EXTSW(d, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -978,19 +968,6 @@ bool codegen(jitdata *jd)
                        break;
                        break;
 
-               case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
-                                     /* s1.localindex = variable, sx.val.i = constant*/
-
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-
-                       /* XXX implement me more efficiently */
-                       ICONST(REG_ITMP2, iptr->sx.val.i);
-                       M_IADD(s1, REG_ITMP2, d);
-
-                       emit_store_dst(jd, iptr, d);
-                       break;
-
 
                /* floating operations ************************************************/
 
@@ -1464,7 +1441,7 @@ bool codegen(jitdata *jd)
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        M_SLL_IMM(s2, 3, REG_ITMP2);
                        M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
-                       M_LST(s3, s1, REG_ITMP2);
+                       M_LSTX(s3, s1, REG_ITMP2);
                        break;
 
                case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1530,7 +1507,7 @@ bool codegen(jitdata *jd)
                case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+                               uf = iptr->sx.s23.s3.uf;
 
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp = dseg_addaddress(cd, NULL);
@@ -1562,9 +1539,8 @@ bool codegen(jitdata *jd)
                                M_ILD_INTERN(d, REG_ITMP1, 0);
                                break;
                        case TYPE_LNG:
-                               d = codegen_reg_of_dst(jd, iptr, PACK_REGS(REG_ITMP2, REG_ITMP1));
-                               M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
-                               M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                               M_LLD(d, REG_ITMP1, 0);
                                break;
                        case TYPE_ADR:
                                d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -1586,7 +1562,7 @@ bool codegen(jitdata *jd)
 
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+                               uf = iptr->sx.s23.s3.uf;
 
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp = dseg_addaddress(cd, NULL);
@@ -1643,21 +1619,17 @@ bool codegen(jitdata *jd)
                        gen_nullptr_check(s1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
-
+                               uf = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
+                               disp = 0;
 
-                               codegen_addpatchref(cd, PATCHER_get_putfield,
-                                                                       iptr->sx.s23.s3.uf, 0);
+                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
 
                                if (opt_showdisassemble)
                                        M_NOP;
 
-                               disp = 0;
-
                        } else {
-                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
+                               fi = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp = fi->offset;
                        }
@@ -1692,32 +1664,31 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        gen_nullptr_check(s1);
 
-                       if (!IS_FLT_DBL_TYPE(fieldtype)) {
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               uf        = iptr->sx.s23.s3.uf;
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+                               disp      = 0;
+                       }
+                       else {
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
+                               fieldtype = fi->type;
+                               disp      = fi->offset;
+                       }
+
+                       if (IS_INT_LNG_TYPE(fieldtype)) {
                                s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       } else {
-                               s2 = emit_load_s2(jd, iptr, REG_FTMP2);
                        }
+                       else
+                               s2 = emit_load_s2(jd, iptr, REG_FTMP2);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_field *uf = iptr->sx.s23.s3.uf;
-
-                               fieldtype = uf->fieldref->parseddesc.fd->type;
-
-                               codegen_addpatchref(cd, PATCHER_get_putfield,
-                                                                       iptr->sx.s23.s3.uf, 0);
+                               codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
 
                                if (opt_showdisassemble)
                                        M_NOP;
-
-                               disp = 0;
-
-                       } else {
-                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
-
-                               fieldtype = fi->type;
-                               disp = fi->offset;
                        }
 
+
                        switch (fieldtype) {
                        case TYPE_INT:
                                M_IST(s2, s1, disp);
@@ -1778,17 +1749,11 @@ bool codegen(jitdata *jd)
 
                case ICMD_JSR:          /* ... ==> ...                                */
 
-                       if (jd->isleafmethod)
-                               M_MFLR(REG_ITMP2);
-                       M_BL(0);
-                       M_MFLR(REG_ITMP1);
-                       M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1);
-                       if (jd->isleafmethod)
-                               M_MTLR(REG_ITMP2);
                        M_BR(0);
                        codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+                       ALIGNCODENOP;
                        break;
-                       
+
                case ICMD_IFNULL:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -1841,159 +1806,50 @@ bool codegen(jitdata *jd)
                        }
                        codegen_addreference(cd, iptr->dst.block);
                        break;
-
-               #if 0
+                       
                case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
-                       if (iptr->sx.val.l == 0) {
-                               M_OR_TST(s1, s2, REG_ITMP3);
-                       } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
-                               M_XOR_IMM(s2, 0, REG_ITMP2);
-                               M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
-                       } else {
-                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
-                               M_XOR(s1, REG_ITMP3, REG_ITMP1);
-                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
-                               M_XOR(s2, REG_ITMP3, REG_ITMP2);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
-                       }
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       LCONST(REG_ITMP2, iptr->sx.val.l);
+                       M_CMP(s1, REG_ITMP2);
                        M_BEQ(0);
                        codegen_addreference(cd, iptr->dst.block);
                        break;
-                       
                case ICMD_IF_LLT:       /* ..., value ==> ...                         */
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
-                       if (iptr->sx.val.l == 0) {
-                               /* if high word is less than zero, the whole long is too */
-                               M_CMPI(s2, 0);
-                       } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
-                               M_CMPI(s2, 0);
-                               M_BLT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BGT(2);
-                               M_CMPUI(s1, iptr->sx.val.l & 0xffff);
-                       } else {
-                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
-                               M_CMP(s2, REG_ITMP3);
-                               M_BLT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BGT(3);
-                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
-                               M_CMPU(s1, REG_ITMP3);
-                       }
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       LCONST(REG_ITMP2, iptr->sx.val.l);
+                       M_CMP(s1, REG_ITMP2);
                        M_BLT(0);
                        codegen_addreference(cd, iptr->dst.block);
                        break;
-                       
                case ICMD_IF_LLE:       /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
-/*                     if (iptr->sx.val.l == 0) { */
-/*                             M_OR(s1, s2, REG_ITMP3); */
-/*                             M_CMPI(REG_ITMP3, 0); */
-
-/*                     } else  */
-                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
-                               M_CMPI(s2, 0);
-                               M_BLT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BGT(2);
-                               M_CMPUI(s1, iptr->sx.val.l & 0xffff);
-                       } else {
-                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
-                               M_CMP(s2, REG_ITMP3);
-                               M_BLT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BGT(3);
-                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
-                               M_CMPU(s1, REG_ITMP3);
-                       }
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       LCONST(REG_ITMP2, iptr->sx.val.l);
+                       M_CMP(s1, REG_ITMP2);
                        M_BLE(0);
                        codegen_addreference(cd, iptr->dst.block);
                        break;
 
-               case ICMD_IF_LNE:       /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
-                       if (iptr->sx.val.l == 0) {
-                               M_OR_TST(s1, s2, REG_ITMP3);
-                       } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
-                               M_XOR_IMM(s2, 0, REG_ITMP2);
-                               M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
-                       } else {
-                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
-                               M_XOR(s1, REG_ITMP3, REG_ITMP1);
-                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
-                               M_XOR(s2, REG_ITMP3, REG_ITMP2);
-                               M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
-                       }
+               case ICMD_IF_LNE:       /* ..., value ==> ... */
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       LCONST(REG_ITMP2, iptr->sx.val.l);
+                       M_CMP(s1, REG_ITMP2);
                        M_BNE(0);
                        codegen_addreference(cd, iptr->dst.block);
                        break;
-                       
-               case ICMD_IF_LGT:       /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
-/*                     if (iptr->sx.val.l == 0) { */
-/*                             M_OR(s1, s2, REG_ITMP3); */
-/*                             M_CMPI(REG_ITMP3, 0); */
-
-/*                     } else  */
-                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
-                               M_CMPI(s2, 0);
-                               M_BGT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BLT(2);
-                               M_CMPUI(s1, iptr->sx.val.l & 0xffff);
-                       } else {
-                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
-                               M_CMP(s2, REG_ITMP3);
-                               M_BGT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BLT(3);
-                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
-                               M_CMPU(s1, REG_ITMP3);
-                       }
-                       M_BGT(0);
+               case ICMD_IF_LGE:       /* ..., value ==> ... */
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       LCONST(REG_ITMP2, iptr->sx.val.l);
+                       M_CMP(s1, REG_ITMP2);
+                       M_BGE(0);
                        codegen_addreference(cd, iptr->dst.block);
                        break;
-                       
-               case ICMD_IF_LGE:       /* ..., value ==> ...                         */
-
-                       /* TODO, remove me */
-                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
-                       if (iptr->sx.val.l == 0) {
-                               /* if high word is greater equal zero, the whole long is too */
-                               M_CMPI(s2, 0);
-                       } else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
-                               M_CMPI(s2, 0);
-                               M_BGT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BLT(2);
-                               M_CMPUI(s1, iptr->sx.val.l & 0xffff);
-                       } else {
-                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
-                               M_CMP(s2, REG_ITMP3);
-                               M_BGT(0);
-                               codegen_addreference(cd, iptr->dst.block);
-                               M_BLT(3);
-                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
-                               M_CMPU(s1, REG_ITMP3);
-                       }
-                       M_BGE(0);
+               case ICMD_IF_LGT:       /* ..., value ==> ...                         */
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       LCONST(REG_ITMP2, iptr->sx.val.l);
+                       M_CMP(s1, REG_ITMP2);
+                       M_BGT(0);
                        codegen_addreference(cd, iptr->dst.block);
                        break;
-               #endif
-
                case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
                case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
                case ICMD_IF_LCMPEQ: 
@@ -2095,7 +1951,7 @@ nowperformreturn:
                        {
                        s4 i, p;
                        
-                       p = stackframesize;
+                       p = cd->stackframesize;
 
                        /* call trace function */
 
@@ -2172,8 +2028,8 @@ nowperformreturn:
 
                        /* deallocate stack                                               */
 
-                       if (stackframesize)
-                               M_LDA(REG_SP, REG_SP, stackframesize * 8);
+                       if (cd->stackframesize)
+                               M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
 
                        M_RET;
                        ALIGNCODENOP;
@@ -2222,7 +2078,7 @@ nowperformreturn:
 
                        /* length of dataseg after last dseg_addtarget is used by load */
 
-                       M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
+                       M_SLL_IMM(REG_ITMP1, 3, REG_ITMP1);
                        M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
                        M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
                        M_MTCTR(REG_ITMP2);
@@ -2478,18 +2334,14 @@ gen_method:
                                /* object type cast-check */
 
                                classinfo *super;
-                               vftbl_t   *supervftbl;
                                s4         superindex;
 
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                        super = NULL;
                                        superindex = 0;
-                                       supervftbl = NULL;
-                               }
-                               else {
+                               } else {
                                        super = iptr->sx.s23.s3.c.cls;
                                        superindex = super->index;
-                                       supervftbl = super->vftbl;
                                }
                        
 #if defined(ENABLE_THREADS)
@@ -2500,18 +2352,18 @@ gen_method:
                                /* calculate interface checkcast code size */
 
                                s2 = 7;
-                               if (!super)
+                               if (super == NULL)
                                        s2 += (opt_showdisassemble ? 1 : 0);
 
                                /* calculate class checkcast code size */
 
-                               s3 = 8 + (s1 == REG_ITMP1);
-                               if (!super)
+                               s3 = 9 + (s1 == REG_ITMP1);
+                               if (super == NULL)
                                        s3 += (opt_showdisassemble ? 1 : 0);
 
                                /* if class is not resolved, check which code to call */
 
-                               if (!super) {
+                               if (super == NULL) {
                                        M_TST(s1);
                                        M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
 
@@ -2532,19 +2384,18 @@ gen_method:
 
                                /* interface checkcast code */
 
-                               if (!super || (super->flags & ACC_INTERFACE)) {
-                                       if (super) {
-                                               M_TST(s1);
-                                               M_BEQ(s2);
-
-                                       } else {
+                               if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
+                                       if (super == NULL) {
                                                codegen_addpatchref(cd,
                                                                                        PATCHER_checkcast_instanceof_interface,
                                                                                        iptr->sx.s23.s3.c.ref,
                                                                                        0);
-
                                                if (opt_showdisassemble)
                                                        M_NOP;
+
+                                       } else {
+                                               M_TST(s1);
+                                               M_BEQ(s2);
                                        }
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
@@ -2565,20 +2416,18 @@ gen_method:
 
                                /* class checkcast code */
 
-                               if (!super || !(super->flags & ACC_INTERFACE)) {
-                                       disp = dseg_addaddress(cd, supervftbl);
-
-                                       if (super) {
-                                               M_TST(s1);
-                                               M_BEQ(s3);
-
-                                       } else {
+                               if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
+                                       if (super == NULL) {
+                                               disp = dseg_add_unique_address(cd, NULL);
                                                codegen_addpatchref(cd, PATCHER_checkcast_class,
                                                                                        iptr->sx.s23.s3.c.ref,
                                                                                        disp);
-
                                                if (opt_showdisassemble)
                                                        M_NOP;
+                                       } else {
+                                               disp = dseg_addaddress(cd, super->vftbl);
+                                               M_TST(s1);
+                                               M_BEQ(s3);
                                        }
 
                                        M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
@@ -2594,16 +2443,18 @@ gen_method:
                                                codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
 #endif
                                                M_SUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
+                                               M_EXTSW(REG_ITMP3, REG_ITMP3);
                                        } else {
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                                M_SUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
+                                               M_EXTSW(REG_ITMP3, REG_ITMP3);
                                                M_ALD(REG_ITMP2, REG_PV, disp);
                                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 #if defined(ENABLE_THREADS)
                                                codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
 #endif
                                        }
-                                       M_CMP(REG_ITMP3, REG_ITMP2);
+                                       M_CMPU(REG_ITMP3, REG_ITMP2);
                                        M_BGT(0);
                                        codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */
                                }
@@ -2615,15 +2466,17 @@ gen_method:
                                s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
                                M_INTMOVE(s1, rd->argintregs[0]);
 
-                               disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
 
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                       disp = dseg_addaddress(cd, NULL);
                                        codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
                                                                                iptr->sx.s23.s3.c.ref,
                                                                                disp);
 
                                        if (opt_showdisassemble)
                                                M_NOP;
+                               } else {
+                                       disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
                                }
 
                                M_ALD(rd->argintregs[1], REG_PV, disp);
@@ -2804,9 +2657,9 @@ gen_method:
                                if (!(var->flags & PREALLOC)) {
                                        s2 = emit_load(jd, iptr, var, REG_ITMP1);
 #if defined(__DARWIN__)
-                                       M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
+                                       M_LST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 8);
 #else
-                                       M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
+                                       M_LST(s2, REG_SP, LA_SIZE + (s1 + 3) * 8);
 #endif
                                }
                        }
@@ -2818,7 +2671,7 @@ gen_method:
                        /* is patcher function set? */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               disp = dseg_addaddress(cd, NULL);
+                               disp = dseg_add_unique_address(cd, NULL);
 
                                codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
                                                                        iptr->sx.s23.s3.c.ref, disp);
@@ -2837,13 +2690,14 @@ gen_method:
                        /* a2 = pointer to dimensions = stack pointer */
 
 #if defined(__DARWIN__)
-                       M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 4);
+                       M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 8);
 #else
-                       M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 4);
+                       M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 8);
 #endif
 
                        disp = dseg_addaddress(cd, BUILTIN_multianewarray);
                        M_ALD(REG_ITMP3, REG_PV, disp);
+                       M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
                        M_MTCTR(REG_ITMP3);
                        M_JSR;
 
@@ -2918,7 +2772,7 @@ gen_method:
 
                                if (jd->isleafmethod) {
                                        M_MFLR(REG_ZERO);
-                                       M_AST(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
+                                       M_AST(REG_ZERO, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
                                }
 
                                M_MOV(REG_PV, rd->argintregs[0]);
@@ -2928,7 +2782,7 @@ gen_method:
                                        M_MOV(REG_ZERO, rd->argintregs[2]);
                                else
                                        M_ALD(rd->argintregs[2],
-                                                 REG_SP, stackframesize * 8 + LA_LR_OFFSET);
+                                                 REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
 
                                M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
                                M_MOV(REG_ITMP1, rd->argintregs[4]);
@@ -2945,9 +2799,9 @@ gen_method:
 
                                if (jd->isleafmethod) {
                                        /* XXX FIXME: REG_ZERO can cause problems here! */
-                                       assert(stackframesize * 8 <= 32767);
+                                       assert(cd->stackframesize * 8 <= 32767);
 
-                                       M_ALD(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
+                                       M_ALD(REG_ZERO, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
                                        M_MTLR(REG_ZERO);
                                }
 
@@ -3169,7 +3023,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        codeinfo     *code;
        codegendata  *cd;
        registerdata *rd;
-       s4            stackframesize;       /* size of stackframe if needed       */
        methoddesc   *md;
        s4            nativeparams;
        s4            i, j;                 /* count variables                    */
@@ -3191,19 +3044,19 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* calculate stackframe size */
 
-       stackframesize =
+       cd->stackframesize =
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
                4 +                            /* 4 stackframeinfo arguments (darwin)*/
                nmd->paramcount  + 
                nmd->memuse;
 
-       stackframesize = (stackframesize + 3) & ~3; /* keep stack 16-byte aligned */
+       cd->stackframesize = (cd->stackframesize + 3) & ~3; /* keep stack 16-byte aligned */
 
        /* create method header */
 
        (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
-       (void) dseg_adds4(cd, stackframesize * 8);             /* FrameSize       */
+       (void) dseg_adds4(cd, cd->stackframesize * 8);             /* FrameSize       */
        (void) dseg_adds4(cd, 0);                              /* IsSync          */
        (void) dseg_adds4(cd, 0);                              /* IsLeaf          */
        (void) dseg_adds4(cd, 0);                              /* IntSave         */
@@ -3215,7 +3068,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        M_MFLR(REG_ZERO);
        M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
-       M_STDU(REG_SP, REG_SP, -(stackframesize * 8));
+       M_STDU(REG_SP, REG_SP, -(cd->stackframesize * 8));
 
 #if !defined(NDEBUG)
        if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
@@ -3263,10 +3116,10 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* create native stack info */
 
-       M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
+       M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[0]);
        M_MOV(REG_PV, rd->argintregs[1]);
-       M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
-       M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 + LA_LR_OFFSET);
+       M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[2]);
+       M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
        disp = dseg_addaddress(cd, codegen_start_native_call);
 
        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -3318,7 +3171,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                                }
 
                        } else {
-                               s1 = md->params[i].regoff + stackframesize;
+                               s1 = md->params[i].regoff + cd->stackframesize;
                                s2 = nmd->params[j].regoff;
 
                                M_LLD(REG_ITMP1, REG_SP, s1 * 8);
@@ -3330,7 +3183,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                           argument registers keep unchanged. */
 
                        if (md->params[i].inmemory) {
-                               s1 = md->params[i].regoff + stackframesize;
+                               s1 = md->params[i].regoff + cd->stackframesize;
                                s2 = nmd->params[j].regoff;
 
                                if (IS_2_WORD_TYPE(t)) {
@@ -3368,10 +3221,6 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        M_JSR;
        M_ALD(REG_TOC, REG_SP, 40);     /* restore TOC */
 
-       M_NOP;
-       M_NOP;
-       M_NOP;
-
        /* save return value */
 
        if (md->returntype.type != TYPE_VOID) {
@@ -3394,11 +3243,7 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 #endif
        /* remove native stackframe info */
 
-       M_NOP;
-       M_NOP;
-       M_NOP;
-
-       M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
+       M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[0]);
        disp = dseg_addaddress(cd, codegen_finish_native_call);
        M_ALD(REG_ITMP1, REG_PV, disp);
        M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */
@@ -3420,9 +3265,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                }
        }
 
-       M_ALD(REG_ITMP2_XPC, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
+       M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
        M_MTLR(REG_ITMP2_XPC);
-       M_LDA(REG_SP, REG_SP, stackframesize * 8); /* remove stackframe           */
+       M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe           */
 
        /* check for exception */