* src/vm/jit/jit.cpp: Eliminate one instance of useless cache flushing.
[cacao.git] / src / vm / jit / sparc64 / codegen.c
index e7c8d765ef91320ed65a33e8fc1ccba878687ae0..5ca25f250608960884e794fb92ff6574a9354c33 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
 
-   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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <stdio.h>
 
 #include "vm/types.h"
 
 /* #include "vm/jit/sparc64/arch.h" */
 #include "vm/jit/sparc64/codegen.h"
+#include "vm/jit/sparc64/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "native/jni.h"
-#include "native/native.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "native/localref.hpp"
+#include "native/native.hpp"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
+#include "vm/loader.hpp"
+#include "vm/options.h"
 
+#include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/jit/codegen-common.hpp"
 #include "vm/jit/dseg.h"
-#include "vm/jit/emit-common.h"
-#include "vm/jit/sparc64/emit.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/parse.h"
+#include "vm/jit/emit-common.hpp"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/linenumbertable.hpp"
+#include "vm/jit/parse.hpp"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
+#include "vm/jit/stacktrace.hpp"
+
+#include "vm/jit/sparc64/solaris/macro_rename.h"
+
+#define BUILTIN_FLOAT_ARGS 1
 
 /* XXX use something like this for window control ? 
  * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
@@ -91,6 +94,22 @@ s4 get_lopart_disp(disp)
                
        return lodisp;
 }
+
+#ifndef NDEBUG
+bool check_13bit_imm(s8 imm)
+{
+       s4 sign = (imm >> 12) & 0x1;
+
+       if (sign == 0) {
+               if ((imm & ~0xfff) == 0) return true; /* pos imm. */
+       }
+       else
+               if ((imm & ~0xfff) + 0xfff == -1) return true; /* neg imm. */
+       
+       printf("immediate out-of-bounds: %ld\n", imm);
+       return false;
+}
+#endif
        
 
 /* codegen_emit ****************************************************************
@@ -101,59 +120,18 @@ s4 get_lopart_disp(disp)
 
 bool codegen_emit(jitdata *jd)
 {
-       methodinfo         *m;
-       codeinfo           *code;
-       codegendata        *cd;
-       registerdata       *rd;
-       s4                  len, s1, s2, s3, d, disp;
-       varinfo            *var;
-       basicblock         *bptr;
-       instruction        *iptr;
-       exception_entry    *ex;
-       u2                  currentline;
-       constant_classref  *cr;
-       methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
-       unresolved_method  *um;
-       builtintable_entry *bte;
-       methoddesc         *md;
-       fieldinfo          *fi;
-       unresolved_field   *uf;
-       s4                  fieldtype;
-       s4                  varindex;
-
-       /* get required compiler data */
 
-       m  = jd->m;
-       code = jd->code;
-       cd = jd->cd;
-       rd = jd->rd;
-       
-       /* prevent compiler warnings */
-
-       d = 0;
-       currentline = 0;
-       lm = NULL;
-       bte = NULL;
-
-       {
-       s4 i, p, t, l;
-       s4 savedregs_num, localbase;
+       s4 savedregs_num;
+       s4 framesize_disp;
 
 #if 0 /* no leaf optimization yet */
-       savedregs_num = (jd->isleafmethod) ? 0 : 1;       /* space to save the RA */
+       savedregs_num = (code_is_leafmethod(code)) ? 0 : 1;       /* space to save the RA */
 #endif
        savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */ 
 
 
-       /* space to save used callee saved registers */
-
-       savedregs_num += (INT_SAV_CNT - rd->savintreguse);
-       savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
-
-       cd->stackframesize = rd->memuse + savedregs_num;
-
 #if defined(ENABLE_THREADS)        /* space to save argument of monitor_enter */
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+       if (checksync && code_is_synchronized(code))
                cd->stackframesize++;
 #endif
 
@@ -162,45 +140,46 @@ bool codegen_emit(jitdata *jd)
        if (cd->stackframesize & 1)
                cd->stackframesize++;
 
-       /* create method header */
 
-       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
-       (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
 
-#if defined(ENABLE_THREADS)
-       /* IsSync contains the offset relative to the stack pointer for the
-          argument of monitor_exit used in the exception handler. Since the
-          offset could be zero and give a wrong meaning of the flag it is
-          offset by one.
-       */
 
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync        */
-       else
-#endif
-               (void) dseg_add_unique_s4(cd, 0);                  /* IsSync          */
-                                              
-       (void) dseg_add_unique_s4(cd, jd->isleafmethod);       /* IsLeaf          */
-       (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
-       (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
-       dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize   */
-
-       /* create exception table */
-
-       for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
-               dseg_add_target(cd, ex->start);
-               dseg_add_target(cd, ex->end);
-               dseg_add_target(cd, ex->handler);
-               (void) dseg_add_unique_address(cd, ex->catchtype.any);
-       }
 
-       /* save register window and create stack frame (if necessary) */
 
-       if (cd->stackframesize)
-               M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
 
 
+
+
+
+/**
+ * Generates machine code for the method prolog.
+ */
+void codegen_emit_prolog(jitdata* jd)
+{
+       varinfo*    var;
+       methoddesc* md;
+       int32_t     s1;
+       int32_t     p, t, l;
+       int32_t     varindex;
+       int         i;
+
+       // Get required compiler data.
+       methodinfo*   m    = jd->m;
+       codeinfo*     code = jd->code;
+       codegendata*  cd   = jd->cd;
+       registerdata* rd   = jd->rd;
+
+       /* save register window and create stack frame (if necessary) */
+
+       if (cd->stackframesize) {
+               if (cd->stackframesize <= 4095)
+                       M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
+               else {
+                       M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
+                       M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
+                       M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
+               }
+       }
+
        /* save callee saved float registers (none right now) */
 #if 0
        p = cd->stackframesize;
@@ -209,35 +188,10 @@ bool codegen_emit(jitdata *jd)
        }
 #endif
 
-#if !defined(NDEBUG)
-       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
-               emit_verbosecall_enter(jd);
-#endif
-       
-       
-       
        /* take arguments out of register or stack frame */
        
        md = m->parseddesc;
 
-       /* when storing locals, use this as base */
-       localbase = JITSTACK;
-       
-       /* since the register allocator does not know about the shifting window
-        * arg regs need to be copied via the stack
-        */
-       if (md->argintreguse > 0) {
-               /* allocate scratch space for copying in to save(i&l) regs */
-               M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
-               
-               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, JITSTACK + (p * 8));
-       }
-       
-
        for (p = 0, l = 0; p < md->paramcount; p++) {
                t = md->paramtypes[p].type;
 
@@ -251,169 +205,123 @@ bool codegen_emit(jitdata *jd)
                        continue;
 
                var = VAR(varindex);
+               s1 = md->params[p].regoff;
+               
+               if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */                        
 
-               s1 = md->params[p].regoff;
-               if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
+                       s2 = var->vv.regoff;
+                       
                        if (!md->params[p].inmemory) {           /* register arguments    */
-                               /*s2 = rd->argintregs[s1];*/
-                               /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
+                               s1 = REG_WINDOW_TRANSPOSE(s1);
+                               
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       /*M_INTMOVE(s2, var->vv.regoff);*/
-                                       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, JITSTACK + (s1 * 8));
-                                       M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
+                                       /* the register allocator does not know about the window. */
+                                       /* avoid copying the locals from save to save regs by     */
+                                       /* swapping variables.                                    */
+
+                                       {
+                                       int old_dest = var->vv.regoff;
+                                       int new_dest = p + 24;
+
+                                       /* run through all variables */
+
+                                       for (i = 0; i < jd->varcount; i++) {
+                                               varinfo* uvar = VAR(i);
+
+                                               if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
+                                                       continue;
+
+                                               s2 = uvar->vv.regoff;
+
+                                               /* free the in reg by moving all other references */
+
+                                               if (s2 == new_dest) {
+                                                       uvar->vv.regoff = old_dest;
+                                                       /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
+                                               }
+
+                                               /* move all variables to the in reg */
+
+                                               if (s2 == old_dest) {
+                                                       uvar->vv.regoff = new_dest;
+                                                       /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
+                                               }
+                                       }
+                                       }
+
+
+
+                               } 
+                               else {                             /* reg arg -> spilled    */
+                                       M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
                                }
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
-                                       M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
+                                       M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
 
                                } else {                             /* stack arg -> spilled  */
                                        /* add the callers window save registers */
-                                       var->vv.regoff = cd->stackframesize + s1;
+                                       var->vv.regoff = cd->stackframesize * 8 + s1;
                                }
                        }
                
                } else {                                     /* floating args         */
                        if (!md->params[p].inmemory) {           /* register arguments    */
-                               s2 = rd->argfltregs[s1];
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
-                                       M_FLTMOVE(s2, var->vv.regoff);
+                                       emit_fmove(cd, s1, var->vv.regoff);
 
                                } else {                                         /* reg arg -> spilled    */
-                                       M_DST(s2, REG_SP, localbase + (var->vv.regoff) * 8);
+                                       M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
                                }
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
-                                       M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
+                                       M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
 
                                } else {                             /* stack-arg -> spilled  */
-                                       var->vv.regoff = cd->stackframesize + s1;
+                                       var->vv.regoff = cd->stackframesize * 8 + s1;
                                }
                        }
                }
        } /* end for */
-       
-       if (md->argintreguse > 0) {
-               /* release scratch space */
-               M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
-       }
-       
-       
-       /* XXX monitor enter */
-
-
-
-       
-       }
-       
-       /* end of header generation */ 
-       
-       /* create replacement points */
-
-       REPLACEMENT_POINTS_INIT(cd, jd);
-
-       /* walk through all basic blocks */
-
-       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
-
-               bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
-
-               if (bptr->flags >= BBREACHED) {
-
-               /* branch resolving */
-
-               codegen_resolve_branchrefs(cd, bptr);
-               
-               /* handle replacement points */
-
-#if 0
-               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
-                       replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
-                       
-                       replacementpoint++;
-               }
-#endif
-
-               /* copy interface registers to their destination */
-
-               len = bptr->indepth;
-               MCODECHECK(64+len);
-               
-#if defined(ENABLE_LSRA)
-#error XXX LSRA not tested yet
-               if (opt_lsra) {
-               while (len) {
-                       len--;
-                       src = bptr->invars[len];
-                       if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
-                                       /*                              d = reg_of_var(m, src, REG_ITMP1); */
-                                       if (!(src->flags & INMEMORY))
-                                               d = src->vv.regoff;
-                                       else
-                                               d = REG_ITMP1;
-                                       M_INTMOVE(REG_ITMP1, d);
-                                       emit_store(jd, NULL, src, d);
-                               }
-                       }
-               } else {
-#endif
-               while (len) {
-                       len--;
-                       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_ITMP2_XPTR, d);
-                               emit_store(jd, NULL, var, d);
-                       }
-                       else {
-                               assert((var->flags & INOUT));
-                       }
-               }
-#if defined(ENABLE_LSRA)
-               }
-#endif
-               /* walk through all instructions */
-               
-               len = bptr->icount;
-
-               for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
-                       if (iptr->line != currentline) {
-                               dseg_addlinenumber(cd, iptr->line);
-                               currentline = iptr->line;
-                       }
-
-               MCODECHECK(64);       /* an instruction usually needs < 64 words      */
+}
 
-               switch (iptr->opc) {
 
-               case ICMD_INLINE_START:
-               case ICMD_INLINE_END:
-                       break;
+/**
+ * Generates machine code for the method epilog.
+ */
+void codegen_emit_epilog(jitdata* jd)
+{
+       M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
+       M_NOP;
+}
 
-               case ICMD_NOP:        /* ...  ==> ...                                 */
-                       break;
 
-               case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
+/**
+ * Generates machine code for one ICMD.
+ */
+void codegen_emit_instruction(jitdata* jd, instruction* iptr)
+{
+       varinfo*            var;
+       builtintable_entry* bte;
+       methodinfo*         lm;             // Local methodinfo for ICMD_INVOKE*.
+       unresolved_method*  um;
+       fieldinfo*          fi;
+       unresolved_field*   uf;
+       int32_t             fieldtype;
+       int32_t             s1, s2, s3, d;
+       int32_t             disp;
+
+       // Get required compiler data.
+       codeinfo*     code = jd->code;
+       codegendata*  cd   = jd->cd;
+
+       switch (iptr->opc) {
 
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       emit_nullpointer_check(cd, iptr, s1);
-                       break;
-       
                /* constant operations ************************************************/
 
-               case ICMD_ICONST:     /* ...  ==> ..., constant                       */
-
-                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
-                       ICONST(d, iptr->sx.val.i);
-                       emit_store_dst(jd, iptr, d);
-                       break;
-
                case ICMD_LCONST:     /* ...  ==> ..., constant                       */
 
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
@@ -442,7 +350,7 @@ bool codegen_emit(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               cr   = iptr->sx.val.c.ref;
+                               constant_classref *cr = iptr->sx.val.c.ref;
                                disp = dseg_add_unique_address(cd, cr);
 
                                codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
@@ -463,38 +371,6 @@ bool codegen_emit(jitdata *jd)
                        break;
 
 
-               /* load/store/copy/move operations ************************************/
-
-               case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_ALOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_FLOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
-               case ICMD_ISTORE:     /* ..., value  ==> ...                          */
-               case ICMD_LSTORE:     /* ..., value  ==> ...                          */
-               case ICMD_FSTORE:     /* ..., value  ==> ...                          */
-               case ICMD_DSTORE:     /* ..., value  ==> ...                          */
-               case ICMD_COPY:
-               case ICMD_MOVE:
-
-                       emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
-                       break;
-       
-               case ICMD_ASTORE:
-                       if (!(iptr->flags.bits & INS_FLAG_RETADDR))
-                               emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
-                       break;
-
-
-               /* pop/dup/swap operations ********************************************/
-
-               /* attention: double and longs are only one entry in CACAO ICMDs      */
-
-               case ICMD_POP:        /* ..., value  ==> ...                          */
-               case ICMD_POP2:       /* ..., value, value  ==> ...                   */
-                       break;
-
-
                /* integer operations *************************************************/
 
                case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
@@ -1109,7 +985,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_I2F:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
                        M_IST (s1, REG_PV_CALLEE, disp);
                        M_FLD (d, REG_PV_CALLEE, disp);
                        M_CVTIF (d, d); /* rd gets translated to double target register */
@@ -1119,7 +995,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_I2D:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
                        M_IST(s1, REG_PV_CALLEE, disp);
                        M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
                        M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
@@ -1129,7 +1005,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_L2F:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0);
                        M_STX(s1, REG_PV_CALLEE, disp);
                        M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
                        M_CVTLF(REG_FTMP3, d);
@@ -1139,7 +1015,7 @@ bool codegen_emit(jitdata *jd)
                case ICMD_L2D:
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
-                       disp = dseg_add_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0);
                        M_STX(s1, REG_PV_CALLEE, disp);
                        M_DLD(d, REG_PV_CALLEE, disp);
                        M_CVTLD(d, d);
@@ -1149,7 +1025,13 @@ bool codegen_emit(jitdata *jd)
                case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_FCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTFI(s1, REG_FTMP2);
                        M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
                        M_ILD(d, REG_PV, disp);
@@ -1160,7 +1042,13 @@ bool codegen_emit(jitdata *jd)
                case ICMD_D2I:       /* ..., value  ==> ..., (int) value             */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_float(cd, 0.0);
+                       disp = dseg_add_unique_float(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_DCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTDI(s1, REG_FTMP2);
                        M_FST(REG_FTMP2, REG_PV, disp);
                        M_ILD(d, REG_PV, disp);
@@ -1170,7 +1058,13 @@ bool codegen_emit(jitdata *jd)
                case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_FCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
                        M_DST(REG_FTMP2, REG_PV, disp);
                        M_LDX(d, REG_PV, disp);
@@ -1180,7 +1074,13 @@ bool codegen_emit(jitdata *jd)
                case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
-                       disp = dseg_add_double(cd, 0.0);
+                       disp = dseg_add_unique_double(cd, 0.0);
+                       
+                       /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5)  */
+                       M_DCMP(s1, s1);
+                       M_FBU(5);
+                       M_MOV(REG_ZERO, d); /* delay slot */
+                       
                        M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
                        M_DST(REG_FTMP2, REG_PV, disp);
                        M_LDX(d, REG_PV, disp);
@@ -1260,7 +1160,7 @@ bool codegen_emit(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        emit_nullpointer_check(cd, iptr, s1);
-                       M_ILD(d, s1, OFFSET(java_arrayheader, size));
+                       M_ILD(d, s1, OFFSET(java_array_t, size));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1272,7 +1172,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
-                       M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
+                       M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1285,7 +1185,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
-                       M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
+                       M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;                  
 
@@ -1298,7 +1198,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP3);
                        M_AADD(s2, REG_ITMP3, REG_ITMP3);
-                       M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
+                       M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1311,7 +1211,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
+                       M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1324,7 +1224,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
+                       M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1337,7 +1237,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
+                       M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1350,7 +1250,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
+                       M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1363,7 +1263,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
-                       M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
+                       M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1376,7 +1276,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+                       M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
                        break;
 
                case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1389,7 +1289,7 @@ bool codegen_emit(jitdata *jd)
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
+                       M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
                        break;
 
                case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1401,7 +1301,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
+                       M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
                        break;
 
                case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1413,7 +1313,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
-                       M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
+                       M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
                        break;
 
                case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1425,7 +1325,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
-                       M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
+                       M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
                        break;
 
                case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
@@ -1437,7 +1337,7 @@ bool codegen_emit(jitdata *jd)
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_FTMP1);
-                       M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
+                       M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
                        break;
 
 
@@ -1449,13 +1349,13 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
 
-                       M_MOV(s1, rd->argintregs[0]);
-                       M_MOV(s3, rd->argintregs[1]);
-                       disp = dseg_add_functionptr(cd, BUILTIN_canstore);
+                       M_MOV(s1, REG_OUT0);
+                       M_MOV(s3, REG_OUT1);
+                       disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
                        M_ALD(REG_ITMP3, REG_PV, disp);
                        M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
                        M_NOP;
-                       emit_exception_check(cd, iptr);
+                       emit_arraystore_check(cd, iptr);
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -1463,7 +1363,7 @@ bool codegen_emit(jitdata *jd)
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
                        /* implicit null-pointer check */
-                       M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
                        break;
 
 
@@ -1474,7 +1374,7 @@ bool codegen_emit(jitdata *jd)
                        /* implicit null-pointer check */
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
-                       M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
+                       M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
                        break;
 
                case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1486,7 +1386,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_AADD(s2, s1, REG_ITMP1);
                        M_AADD(s2, REG_ITMP1, REG_ITMP1);
-                       M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
+                       M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
                        break;
 
                case ICMD_IASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1497,7 +1397,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 2, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
-                       M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
+                       M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
                        break;
 
                case ICMD_LASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1508,7 +1408,7 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
-                       M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
+                       M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
                        break;
 
                case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1519,26 +1419,26 @@ bool codegen_emit(jitdata *jd)
                        emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
-                       M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
+                       M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
                        break;
                
 
                case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               uf = iptr->sx.s23.s3.uf;
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
                                codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
                        } 
                        else {
-                               fi = iptr->sx.s23.s3.fmiref->p.field;
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1571,19 +1471,19 @@ bool codegen_emit(jitdata *jd)
                case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               uf = iptr->sx.s23.s3.uf;
+                               uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
                                disp      = dseg_add_unique_address(cd, uf);
 
                                codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
                        } 
                        else {
-                               fi = iptr->sx.s23.s3.fmiref->p.field;
+                               fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1619,17 +1519,17 @@ bool codegen_emit(jitdata *jd)
                        if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
                                uf        = iptr->sx.s23.s3.uf;
                                fieldtype = uf->fieldref->parseddesc.fd->type;
-                               disp = dseg_add_unique_address(cd, uf);
+                               disp      = dseg_add_unique_address(cd, uf);
 
                                codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
                        } 
                        else {
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
-                               disp      = dseg_add_address(cd, &(fi->value));
+                               disp      = dseg_add_address(cd, fi->value);
 
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
-                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
+                                       codegen_add_patch_ref(cd, PATCHER_clinit, fi->clazz, disp);
                        }
 
                        M_ALD(REG_ITMP1, REG_PV, disp);
@@ -1803,133 +1703,14 @@ bool codegen_emit(jitdata *jd)
 
                case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
 
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       M_INTMOVE(s1, REG_ITMP2_XPTR);
-
-#ifdef ENABLE_VERIFIER
-                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_class *uc = iptr->sx.s23.s2.uc;
-
-                               codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
-                       }
-#endif /* ENABLE_VERIFIER */
-
                        disp = dseg_add_functionptr(cd, asm_handle_exception);
                        M_ALD(REG_ITMP1, REG_PV, disp);
                        M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
                        M_NOP;
                        M_NOP;              /* nop ensures that XPC is less than the end */
                                            /* of basic block                            */
-                       ALIGNCODENOP;
-                       break;
-
-               case ICMD_GOTO:         /* ... ==> ...                                */
-               case ICMD_RET:          /* ... ==> ...                                */
-
-                       emit_br(cd, iptr->dst.block);
-                       ALIGNCODENOP;
-                       break;
-
-               case ICMD_JSR:          /* ... ==> ...                                */
-
-                       emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
-                       ALIGNCODENOP;
-                       break;
-
-               case ICMD_IFNULL:       /* ..., value ==> ...                         */
-               case ICMD_IFNONNULL:
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
-                       break;
-                       
-               /* Note: int compares must not branch on the register directly.       */
-               /* Reason is, that register content is not 32-bit clean.              */
-
-               case ICMD_IFEQ:         /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       
-                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                               M_CMP_IMM(s1, iptr->sx.val.i);
-                       }
-                       else {
-                               ICONST(REG_ITMP2, iptr->sx.val.i);
-                               M_CMP(s1, REG_ITMP2);
-                       }
-                       emit_beq(cd, iptr->dst.block);
-                       break;
-
-               case ICMD_IFLT:         /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       
-                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                               M_CMP_IMM(s1, iptr->sx.val.i);
-                       } 
-                       else {
-                               ICONST(REG_ITMP2, iptr->sx.val.i);
-                               M_CMP(s1, REG_ITMP2);
-                       }
-                       emit_blt(cd, iptr->dst.block);
-                       break;
-
-               case ICMD_IFLE:         /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-
-                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                               M_CMP_IMM(s1, iptr->sx.val.i);
-                       }
-                       else {
-                               ICONST(REG_ITMP2, iptr->sx.val.i);
-                               M_CMP(s1, REG_ITMP2);
-                       }
-                       emit_ble(cd, iptr->dst.block);
-                       break;
-
-               case ICMD_IFNE:         /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-               
-                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                               M_CMP_IMM(s1, iptr->sx.val.i);
-                       }
-                       else {
-                               ICONST(REG_ITMP2, iptr->sx.val.i);
-                               M_CMP(s1, REG_ITMP2);
-                       }
-                       emit_bne(cd, iptr->dst.block);
-                       break;
-                                               
-               case ICMD_IFGT:         /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-               
-                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                               M_CMP_IMM(s1, iptr->sx.val.i);
-                       } 
-                       else {
-                               ICONST(REG_ITMP2, iptr->sx.val.i);
-                               M_CMP(s1, REG_ITMP2);
-                       }
-                       emit_bgt(cd, iptr->dst.block);          
                        break;
 
-               case ICMD_IFGE:         /* ..., value ==> ...                         */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-
-                       if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
-                               M_CMP_IMM(s1, iptr->sx.val.i);
-                       }
-                       else {
-                               ICONST(REG_ITMP2, iptr->sx.val.i);
-                               M_CMP(s1, REG_ITMP2);
-                       }
-                       emit_bge(cd, iptr->dst.block);
-                       break;
-                       
                case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -2042,14 +1823,6 @@ bool codegen_emit(jitdata *jd)
                        emit_beq_xcc(cd, iptr->dst.block);
                        break;
 
-               case ICMD_IF_ICMPEQ:    /* 32-bit compare                             */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMP(s1, s2);
-                       emit_beq(cd, iptr->dst.block);
-                       break;
-
                case ICMD_IF_ACMPNE:    /* ..., value, value ==> ...                  */
                case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
 
@@ -2058,29 +1831,13 @@ bool codegen_emit(jitdata *jd)
                        M_CMP(s1, s2);
                        emit_bne_xcc(cd, iptr->dst.block);
                        break;
-                       
-               case ICMD_IF_ICMPNE:    /* 32-bit compare                             */
+
+               case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        M_CMP(s1, s2);
-                       emit_bne(cd, iptr->dst.block);
-                       break;
-
-               case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMP(s1, s2);
-                       emit_blt_xcc(cd, iptr->dst.block);
-                       break;
-                       
-               case ICMD_IF_ICMPLT:    /* 32-bit compare                             */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMP(s1, s2);
-                       emit_blt(cd, iptr->dst.block);
+                       emit_blt_xcc(cd, iptr->dst.block);
                        break;
 
                case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
@@ -2090,14 +1847,6 @@ bool codegen_emit(jitdata *jd)
                        M_CMP(s1, s2);
                        emit_bgt_xcc(cd, iptr->dst.block);
                        break;
-                       
-               case ICMD_IF_ICMPGT:    /* 32-bit compare                             */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMP(s1, s2);
-                       emit_bgt(cd, iptr->dst.block);
-                       break;
 
                case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
 
@@ -2106,15 +1855,6 @@ bool codegen_emit(jitdata *jd)
                        M_CMP(s1, s2);
                        emit_ble_xcc(cd, iptr->dst.block);
                        break;
-                       
-               case ICMD_IF_ICMPLE:    /* 32-bit compare                             */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMP(s1, s2);
-                       emit_ble(cd, iptr->dst.block);
-                       break;                  
-       
 
                case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
 
@@ -2123,89 +1863,6 @@ bool codegen_emit(jitdata *jd)
                        M_CMP(s1, s2);
                        emit_bge_xcc(cd, iptr->dst.block);
                        break;
-                       
-               case ICMD_IF_ICMPGE:    /* 32-bit compare                             */
-
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMP(s1, s2);
-                       emit_bge(cd, iptr->dst.block);
-                       break;
-
-
-               case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
-               case ICMD_LRETURN:
-
-                       s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
-                       M_INTMOVE(s1, REG_RESULT_CALLEE);
-                       goto nowperformreturn;
-
-               case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
-
-                       s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
-                       M_INTMOVE(s1, REG_RESULT_CALLEE);
-
-#ifdef ENABLE_VERIFIER
-                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               unresolved_class *uc = iptr->sx.s23.s2.uc;
-
-                               codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
-                       }
-#endif /* ENABLE_VERIFIER */
-                       goto nowperformreturn;
-
-               case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
-               case ICMD_DRETURN:
-
-                       s1 = emit_load_s1(jd, iptr, REG_FRESULT);
-                       M_DBLMOVE(s1, REG_FRESULT);
-                       goto nowperformreturn;
-
-               case ICMD_RETURN:       /* ...  ==> ...                               */
-
-nowperformreturn:
-                       {
-                       s4 i, p;
-                       
-                       p = cd->stackframesize;
-
-#if !defined(NDEBUG)
-                       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
-                               emit_verbosecall_exit(jd);
-#endif
-
-#if defined(ENABLE_THREADS)
-                       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
-/* XXX: REG_RESULT is save, but what about FRESULT? */
-                               M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
-
-                               switch (iptr->opc) {
-                               case ICMD_FRETURN:
-                               case ICMD_DRETURN:
-                                       M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
-                                       break;
-                               }
-
-                               disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
-                               M_ALD(REG_ITMP3, REG_PV, disp);
-                               M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
-
-                               switch (iptr->opc) {
-                               case ICMD_FRETURN:
-                               case ICMD_DRETURN:
-                                       M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
-                                       break;
-                               }
-                       }
-#endif
-
-
-
-                       M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
-                       M_NOP;
-                       ALIGNCODENOP;
-                       }
-                       break;
 
                case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
                        {
@@ -2221,15 +1878,15 @@ nowperformreturn:
                        if (l == 0) {
                                M_INTMOVE(s1, REG_ITMP1);
                        }
-                       else if (l <= 4095) {
+                       else if (-l >= 4096 && -l <= 4095) {
                                M_ADD_IMM(s1, -l, REG_ITMP1);
                        }
                        else {
                                ICONST(REG_ITMP2, l);
-                               /* XXX: do I need to truncate s1 to 32-bit ? */
                                M_SUB(s1, REG_ITMP2, REG_ITMP1);
                        }
-                       i = i - l + 1;
+
+                       i = i - l + 1; /* number of targets (>0) */
 
 
                        /* range check */
@@ -2262,36 +1919,9 @@ nowperformreturn:
                        M_NOP;
                        ALIGNCODENOP;
                        break;
-                       
-               case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
-                       {
-                       s4 i;
-                       lookup_target_t *lookup;
-
-                       lookup = iptr->dst.lookup;
-
-                       i = iptr->sx.s23.s2.lookupcount;
-                       
-                       MCODECHECK((i<<2)+8);
-                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
-
-                       while (--i >= 0) {
-                               if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
-                                       M_CMP_IMM(s1, lookup->value);
-                               } else {                                        
-                                       ICONST(REG_ITMP2, lookup->value);
-                                       M_CMP(s1, REG_ITMP2);
-                               }
-                               emit_beq(cd, lookup->target.block);
-                               ++lookup;
-                       }
-
-                       emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
-                       ALIGNCODENOP;
-                       break;
-                       }
-
 
+               // XXX This is the old builtin invocation containing some
+               // special argument handling code, port me!
                case ICMD_BUILTIN:      /* ..., arg1, arg2, arg3 ==> ...              */
 
                        bte = iptr->sx.s23.s3.bte;
@@ -2304,6 +1934,8 @@ nowperformreturn:
 
                        MCODECHECK((s3 << 1) + 64);
 
+#ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
+
                        /* copy float arguments according to ABI convention */
 
                        int num_fltregargs = 0;
@@ -2312,12 +1944,9 @@ nowperformreturn:
                        for (s3 = s3 - 1; s3 >= 0; s3--) {
                                var = VAR(iptr->sx.s23.s2.args[s3]);
 
-                               if (var->flags & PREALLOC)
-                                       continue;
-
                                if (IS_FLT_DBL_TYPE(var->type)) {
                                        if (!md->params[s3].inmemory) {
-                                               s1 = md->params[s3].regoff; /*native flt args use regoff directly*/
+                                               s1 = s3; /*native flt args use argument index directly*/
                                                d = emit_load(jd, iptr, var, REG_FTMP1);
                                                
                                                M_DMOV(d, s1 + 16);
@@ -2339,195 +1968,140 @@ nowperformreturn:
                                /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
                        }
                        
-                       goto gen_method;
-
-               case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
-
-               case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
-               case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
-               case ICMD_INVOKEINTERFACE:
-
-                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                               lm = NULL;
-                               um = iptr->sx.s23.s3.um;
-                               md = um->methodref->parseddesc.md;
-                       }
-                       else {
-                               lm = iptr->sx.s23.s3.fmiref->p.method;
-                               um = NULL;
-                               md = lm->parseddesc;
-                       }
-
-gen_method:
-                       s3 = md->paramcount;
-
-                       MCODECHECK((s3 << 1) + 64);
+#else
+                       assert(md->argfltreguse == 0);
+#endif
 
-                       /* copy arguments to registers or stack location                  */
 
-                       for (s3 = s3 - 1; s3 >= 0; s3--) {
-                               var = VAR(iptr->sx.s23.s2.args[s3]);
 
-                               if (var->flags & PREALLOC)
-                                       continue;
 
+XXXXXX
                                if (IS_INT_LNG_TYPE(var->type)) {
                                        if (!md->params[s3].inmemory) {
-                                               s1 = rd->argintregs[md->params[s3].regoff];
-                                               d = emit_load(jd, iptr, var, s1);
-                                               M_INTMOVE(d, s1);
+                                               s1 = emit_load(jd, iptr, var, d);
+                                               M_INTMOVE(s1, d);
                                        } 
                                        else {
-                                               d = emit_load(jd, iptr, var, REG_ITMP1);
-                                               M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
-                                       }
-                               }
-                               else {
-                                       if (iptr->opc == ICMD_BUILTIN)
-                                               continue;
-                                               
-                                       if (!md->params[s3].inmemory) {
-                                               s1 = rd->argfltregs[md->params[s3].regoff];
-                                               d = emit_load(jd, iptr, var, s1);
-                                               if (IS_2_WORD_TYPE(var->type))
-                                                       M_DMOV(d, s1);
-                                               else
-                                                       M_FMOV(d, s1);
-                                       }
-                                       else {
-                                               d = emit_load(jd, iptr, var, REG_FTMP1);
-                                               if (IS_2_WORD_TYPE(var->type))
-                                                       M_DST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
-                                               else
-                                                       M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
+                                               s1 = emit_load(jd, iptr, var, REG_ITMP1);
+                                               M_STX(s1, REG_SP, JITSTACK + d);
                                        }
                                }
                        }
+XXXXXX
 
-                       switch (iptr->opc) {
-                       case ICMD_BUILTIN:
+               case ICMD_BUILTIN:
+                       bte = iptr->sx.s23.s3.bte;
+                       if (bte->stub == NULL) {
                                disp = dseg_add_functionptr(cd, bte->fp);
+                       }
+                       else {
+                               disp = dseg_add_functionptr(cd, bte->stub);
+                       }
 
-                               M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
+                       M_ALD(REG_PV_CALLER, REG_PV, disp);  /* built-in-function pointer */
 
-                               /* XXX jit-c-call */
-                               /* generate the actual call */
-    
-                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                           M_NOP;
-                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
-                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
-                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
-
-                               emit_exception_check(cd, iptr);
-                               if (md->returntype.type == TYPE_FLT) {
-                                       /* special handling for float return value in %f0 */
-                                       M_FMOV_INTERN(0,1);
-                               }
-                               break;
+                       /* XXX jit-c-call */
+                       /* generate the actual call */
+   
+                   M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                   M_NOP;
 
-                       case ICMD_INVOKESPECIAL:
-                               emit_nullpointer_check(cd, iptr, REG_OUT0);
-                               /* fall-through */
+                       if (md->returntype.type == TYPE_FLT) {
+                               /* special handling for float return value in %f0 */
+                               M_FMOV_INTERN(0,1);
+                       }
+                       break;
 
-                       case ICMD_INVOKESTATIC:
-                               if (lm == NULL) {
-                                       disp = dseg_add_unique_address(cd, NULL);
+               case ICMD_INVOKESPECIAL:
+                       emit_nullpointer_check(cd, iptr, REG_OUT0);
+                       /* fall-through */
 
-                                       codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
-                                                                               um, disp);
-                               }
-                               else
-                                       disp = dseg_add_address(cd, lm->stubroutine);
+               case ICMD_INVOKESTATIC:
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
+                               disp = dseg_add_unique_address(cd, NULL);
 
-                               M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
-                               
-                               /* generate the actual call */
-    
-                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                           M_NOP;
-                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
-                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
-                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
-                               break;
+                               codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
+                                                                       um, disp);
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
+                               disp = dseg_add_address(cd, lm->stubroutine);
+                       }
 
-                       case ICMD_INVOKEVIRTUAL:
-                               emit_nullpointer_check(cd, iptr, REG_OUT0);
+                       M_ALD(REG_PV_CALLER, REG_PV, disp);          /* method pointer in pv */
+                       
+                       /* generate the actual call */
+   
+                   M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                   M_NOP;
+                       break;
 
-                               if (lm == NULL) {
-                                       codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
+               case ICMD_INVOKEVIRTUAL:
+                       emit_nullpointer_check(cd, iptr, REG_OUT0);
 
-                                       s1 = 0;
-                               }
-                               else
-                                       s1 = OFFSET(vftbl_t, table[0]) +
-                                               sizeof(methodptr) * lm->vftblindex;
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
+                               codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
 
-                               /* implicit null-pointer check */
-                               M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
-                               M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
-                               
-                               /* generate the actual call */
-    
-                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                           M_NOP;
-                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
-                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
-                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8); 
-                               break;
+                               s1 = 0;
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
+                               s1 = OFFSET(vftbl_t, table[0]) +
+                                       sizeof(methodptr) * lm->vftblindex;
+                       }
 
-                       case ICMD_INVOKEINTERFACE:
-                               emit_nullpointer_check(cd, iptr, REG_OUT0);
+                       /* implicit null-pointer check */
+                       M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
+                       M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
+                       
+                       /* generate the actual call */
+   
+                   M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                   M_NOP;
+                       break;
 
-                               if (lm == NULL) {
-                                       codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
+               case ICMD_INVOKEINTERFACE:
+                       emit_nullpointer_check(cd, iptr, REG_OUT0);
 
-                                       s1 = 0;
-                                       s2 = 0;
-                               } 
-                               else {
-                                       s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               um = iptr->sx.s23.s3.um;
+                               codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
 
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
-                               }
+                               s1 = 0;
+                               s2 = 0;
+                       } 
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
+                               s1 = OFFSET(vftbl_t, interfacetable[0]) -
+                                       sizeof(methodptr*) * lm->clazz->index;
 
-                               /* implicit null-pointer check */
-                               M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
-                               M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
-                               M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
-
-                           /* generate the actual call */
-    
-                           M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
-                           M_NOP;
-                           disp = (s4) (cd->mcodeptr - cd->mcodebase);
-                           /* REG_RA holds the value of the jmp instruction, therefore +8 */
-                           M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
-                               break;
+                               s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                        }
 
-                       /* store return value */
+                       /* implicit null-pointer check */
+                       M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
+                       M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
+                       M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
 
-                       d = md->returntype.type;
+                   /* generate the actual call */
+   
+                   M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
+                   M_NOP;
+                       break;
 
-                       if (d != TYPE_VOID) {
-                               if (IS_INT_LNG_TYPE(d)) {
-                                       s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
-                                       M_INTMOVE(REG_RESULT_CALLER, s1);
-                               } 
-                               else {
-                                       s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
-                                       if (IS_2_WORD_TYPE(d)) {
-                                               M_DBLMOVE(REG_FRESULT, s1);
-                                       } else {
-                                               M_FLTMOVE(REG_FRESULT, s1);
-                                       }
+XXXXXX
+                       /* store return value */
+                       else {
+                               s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
+                               if (IS_2_WORD_TYPE(d)) {
+                                       emit_dmove(cd, REG_FRESULT, s1);
+                               } else {
+                                       emit_fmove(cd, REG_FRESULT, s1);
                                }
-                               emit_store_dst(jd, iptr, s1);
                        }
-                       break;
-
+XXXXX
 
                case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
                                      /* val.a: (classinfo*) superclass               */
@@ -2558,10 +2132,6 @@ gen_method:
                                        superindex = super->index;
                                }
 
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
-
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                                /* if class is not resolved, check which code to call */
@@ -2569,7 +2139,7 @@ gen_method:
                                if (super == NULL) {
                                        emit_label_beqz(cd, BRANCH_LABEL_1, s1);
 
-                                       cr   = iptr->sx.s23.s3.c.ref;
+                                       constant_classref *cr = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_s4(cd, 0);         /* super->flags */
 
                                        codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
@@ -2584,7 +2154,7 @@ gen_method:
 
                                if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
                                        if (super == NULL) {
-                                               cr = iptr->sx.s23.s3.c.ref;
+                                               constant_classref *cr = iptr->sx.s23.s3.c.ref;
 
                                                codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
                                                                                          cr, 0);
@@ -2593,7 +2163,7 @@ gen_method:
                                                emit_label_beqz(cd, BRANCH_LABEL_3, s1);
                                        }
 
-                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ILD(REG_ITMP3, REG_ITMP2,
                                                        OFFSET(vftbl_t, interfacetablelength));
                                        M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
@@ -2616,7 +2186,7 @@ gen_method:
                                        if (super == NULL) {
                                                emit_label(cd, BRANCH_LABEL_2);
 
-                                               cr   = iptr->sx.s23.s3.c.ref;
+                                               constant_classref *cr = iptr->sx.s23.s3.c.ref;
                                                disp = dseg_add_unique_address(cd, NULL);
 
                                                codegen_add_patch_ref(cd,
@@ -2629,19 +2199,15 @@ gen_method:
                                                emit_label_beqz(cd, BRANCH_LABEL_5, s1);
                                        }
 
-                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                        M_ALD(REG_ITMP3, REG_PV, disp);
-#if defined(ENABLE_THREADS)
-                                       codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+                                       
                                        M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                        M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
                                        M_ALD(REG_ITMP3, REG_PV, disp);
                                        M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
-                                       codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
                                        /*                              } */
                                        M_CMP(REG_ITMP3, REG_ITMP2);
                                        emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
@@ -2660,13 +2226,13 @@ gen_method:
                        else {
                                /* array type cast-check */
 
-                               s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
-                               M_INTMOVE(s1, rd->argintregs[0]);
+                               s1 = emit_load_s1(jd, iptr, REG_OUT0);
+                               M_INTMOVE(s1, REG_OUT0);
 
                                disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
 
                                if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
-                                       cr   = iptr->sx.s23.s3.c.ref;
+                                       constant_classref *cr = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_address(cd, NULL);
 
                                        codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
@@ -2675,7 +2241,7 @@ gen_method:
                                else
                                        disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
 
-                               M_ALD(rd->argintregs[1], REG_PV, disp);
+                               M_ALD(REG_OUT1, REG_PV, disp);
                                disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
                                M_ALD(REG_ITMP3, REG_PV, disp);
                                /* XXX jit-c-call */
@@ -2724,9 +2290,6 @@ gen_method:
                                supervftbl = super->vftbl;
                        }
 
-#if defined(ENABLE_THREADS)
-                       codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if (s1 == d) {
@@ -2741,7 +2304,7 @@ gen_method:
                        if (super == NULL) {
                                emit_label_beqz(cd, BRANCH_LABEL_1, s1);
 
-                               cr   = iptr->sx.s23.s3.c.ref;
+                               constant_classref *cr = iptr->sx.s23.s3.c.ref;
                                disp = dseg_add_unique_s4(cd, 0);             /* super->flags */
 
                                codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
@@ -2756,7 +2319,7 @@ gen_method:
 
                        if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
                                if (super == NULL) {
-                                       cr = iptr->sx.s23.s3.c.ref;
+                                       constant_classref *cr = iptr->sx.s23.s3.c.ref;
 
                                        codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
                                                                                  cr, 0);
@@ -2765,7 +2328,7 @@ gen_method:
                                        emit_label_beqz(cd, BRANCH_LABEL_3, s1);
                                }
 
-                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
                                M_CMP_IMM(REG_ITMP3, superindex);
                                M_BLE(4);
@@ -2787,7 +2350,7 @@ gen_method:
                                if (super == NULL) {
                                        emit_label(cd, BRANCH_LABEL_2);
 
-                                       cr   = iptr->sx.s23.s3.c.ref;
+                                       constant_classref *cr = iptr->sx.s23.s3.c.ref;
                                        disp = dseg_add_unique_address(cd, NULL);
 
                                        codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
@@ -2799,17 +2362,13 @@ gen_method:
                                        emit_label_beqz(cd, BRANCH_LABEL_5, s1);
                                }
 
-                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_ALD(REG_ITMP2, REG_PV, disp);
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
                                M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
-                               codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
                                M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                                M_XCMOVULE_IMM(1, d);
@@ -2887,29 +2446,8 @@ gen_method:
                        break;
 
                default:
-                       exceptions_throw_internalerror("Unknown ICMD %d during code generation",
-                                                                                  iptr->opc);
-                       return false;
-                       
+                       vm_abort("Unknown ICMD %d during code generation", iptr->opc);
        } /* switch */
-               
-       } /* for instruction */
-       
-
-               
-       } /* if (bptr -> flags >= BBREACHED) */
-       } /* for basic block */
-       
-       dseg_createlinenumbertable(cd);
-
-       /* generate stubs */
-
-       emit_patcher_stubs(jd);
-       REPLACEMENT_EMIT_STUBS(jd);
-       
-       /* everything's ok */
-
-       return true;    
 }
 
 
@@ -2939,32 +2477,197 @@ void codegen_emit_stub_compiler(jitdata *jd)
 }
 
 
+/* codegen_emit_stub_builtin ***************************************************
+
+   Creates a stub routine which calls a builtin function.
+
+*******************************************************************************/
+
+void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
+{
+       codeinfo    *code;
+       codegendata *cd;
+       methoddesc  *md;
+       s4           i;
+       s4           disp;
+       s4           s1, s2;
+
+       /* get required compiler data */
+       code = jd->code;
+       cd   = jd->cd;
+
+       /* set some variables */
+       md = bte->md;
+
+       /* calculate stack frame size */
+       cd->stackframesize =
+               WINSAVE_CNT +
+               ABIPARAMS_CNT +
+               FLT_ARG_CNT +
+               sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
+               4;                              /* 4 arguments or return value        */
+
+
+       /* keep stack 16-byte aligned (ABI requirement) */
+
+       if (cd->stackframesize & 1)
+               cd->stackframesize++;
+
+       /* create method header */
+       (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
+       (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize       */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
+       (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
+       (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
+
+       /* generate stub code */
+       M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe   */
+
+#if defined(ENABLE_GC_CACAO)
+       /* Save callee saved integer registers in stackframeinfo (GC may
+          need to recover them during a collection). */
+
+       disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
+               OFFSET(stackframeinfo_t, intregs) + BIAS;
+
+       for (i = 0; i < INT_SAV_CNT; i++)
+               M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
+#endif
+
+       for (i = 0; i < md->paramcount; i++) {
+               s1 = md->params[i].regoff;
+
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
+                       break;
+               case TYPE_FLT:
+               case TYPE_DBL:
+                       M_DST(s1, REG_SP, JITSTACK + i * 8);
+                       break;
+               }
+       }
+
+       /* create dynamic stack info */
+
+       M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
+       M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
+       M_MOV(REG_FP, REG_OUT2); /* java sp */
+       M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
+
+       disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+       M_NOP; /* XXX fill me! */
+
+
+       /* builtins are allowed to have 5 arguments max */
+
+       assert(md->paramcount <= 5);
 
-/* createnativestub ************************************************************
+       /* copy arguments into position */
 
-   Creates a stub routine which calls a native method.
+       for (i = 0; i < md->paramcount; i++) {
+               assert(!md->params[i].inmemory);
+
+               s1 = md->params[i].regoff;
+
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_LNG:
+               case TYPE_ADR:
+                       M_MOV(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]), s1);
+                       break;
+               case TYPE_FLT:
+               case TYPE_DBL:
+                       M_DLD(s1, REG_SP, JITSTACK + i * 8);
+                       break;
+               }
+
+       }
+
+       /* call the builtin function */
+
+       disp = dseg_add_functionptr(cd, bte->fp);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin                */
+       M_NOP;                              /* delay slot                         */
+
+
+       /* save return value */
+
+       if (md->returntype.type != TYPE_VOID) {
+               if (IS_INT_LNG_TYPE(md->returntype.type))
+                       M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
+               else
+                       M_DST(REG_FRESULT, REG_SP, CSTACK);
+       }       
+
+
+       /* remove native stackframe info */
+
+       M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
+       disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
+       M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
+       M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
+       M_NOP;
+
+       /* restore float return value, int return value already in our return reg */
+
+       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, CSTACK);
+                       else
+                               M_FLD(REG_FRESULT, REG_SP, CSTACK);
+               }
+       }
+
+
+#if defined(ENABLE_GC_CACAO)
+       /* Restore callee saved integer registers from stackframeinfo (GC
+          might have modified them during a collection). */
+        
+       disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
+               OFFSET(stackframeinfo_t, intregs) + BIAS;
+
+       for (i = 0; i < INT_SAV_CNT; i++)
+               M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
+#endif
+
+       /* return */
+       M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
+       M_NOP;
+
+       /* assert(0); */
+}
+
+
+/* codegen_emit_stub_native ****************************************************
+
+   Emits a stub routine which calls a native method.
 
 *******************************************************************************/
 
-u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
+void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
 {
        methodinfo   *m;
        codeinfo     *code;
        codegendata  *cd;
-       registerdata *rd;
        methoddesc   *md;
        s4            nativeparams;
        s4            i, j;                 /* count variables                    */
        s4            t;
        s4            s1, s2, disp;
        s4            funcdisp;             /* displacement of the function       */
+       s4            fltregarg_offset[FLT_ARG_CNT];
 
        /* get required compiler data */
 
        m    = jd->m;
        code = jd->code;
        cd   = jd->cd;
-       rd   = jd->rd;
 
        /* initialize variables */
 
@@ -2977,19 +2680,22 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
                md->paramcount +                /* for saving arguments over calls    */
-               nmd->memuse +  /* nmd knows about the native stackframe layout */
+               nmd->memuse +              /* nmd->memuse includes the (6) abi params */
                WINSAVE_CNT;
 
+
+       /* keep stack 16-byte aligned (ABI requirement) */
+
+       if (cd->stackframesize & 1)
+               cd->stackframesize++;
+
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
        (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize       */
-       (void) dseg_add_unique_s4(cd, 0);                      /* IsSync          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IsLeaf          */
        (void) dseg_add_unique_s4(cd, 0);                      /* IntSave         */
        (void) dseg_add_unique_s4(cd, 0);                      /* FltSave         */
-       (void) dseg_addlinenumbertablesize(cd);
-       (void) dseg_add_unique_s4(cd, 0);                      /* ExTableSize     */
 
        /* generate stub code */
 
@@ -3004,24 +2710,25 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        funcdisp = dseg_add_functionptr(cd, f);
 
-#if !defined(WITH_STATIC_CLASSPATH)
-       if (f == NULL) {
+       if (f == NULL)
                codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
-       }
-#endif
 
        /* save float argument registers */
 
+       assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
+
        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, CSTACK + (j * 8));
+                       s1 = WINSAVE_CNT + nmd->memuse + j;
+                       M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
+                       fltregarg_offset[i] = s1; /* remember stack offset */
                        j++;
                }
        }
 
        /* prepare data structures for native function call */
 
-       M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
+       M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
        M_MOV(REG_PV_CALLEE, REG_OUT1);
        M_MOV(REG_FP, REG_OUT2); /* java sp */
        M_MOV(REG_RA_CALLEE, REG_OUT3);
@@ -3030,96 +2737,122 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
        M_NOP; /* XXX fill me! */
 
-       /* restore float argument registers */
+       /* remember class argument */
+
+       if (m->flags & ACC_STATIC)
+               M_MOV(REG_RESULT_CALLER, REG_ITMP3);
 
+       /* keep float arguments on stack */
+#if 0
        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, CSTACK + (j * 8));
+                       M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
                        j++;
                }
        }
+#endif
 
        /* copy or spill arguments to new locations */
-       int num_fltregargs = 0;
-       int fltregarg_inswap[16];
+
        for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
                t = md->paramtypes[i].type;
 
                if (IS_INT_LNG_TYPE(t)) {
+
+                       /* integral types */
+
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argintregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
                                /* s1 refers to the old window, transpose */
                                s1 = REG_WINDOW_TRANSPOSE(s1);
 
                                if (!nmd->params[j].inmemory) {
-                                       s2 = nat_argintregs[nmd->params[j].regoff];
+                                       s2 = nmd->params[j].regoff;
                                        M_INTMOVE(s1, s2);
                                } else {
-                                       s2 = nmd->params[j].regoff - 6;
-                                       M_AST(s1, REG_SP, CSTACK + s2 * 8);
+                                       /* nmd's regoff is relative to the start of the param array */
+                                       s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
+                                       M_AST(s1, REG_SP, s2);
                                }
 
                        } else {
-                               s1 = md->params[i].regoff + cd->stackframesize;
-                               s2 = nmd->params[j].regoff - 6;
-                               M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
-                               M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
+                               if (!nmd->params[j].inmemory) {
+                                       /* JIT stack arg -> NAT reg arg */
+
+                                       /* Due to the Env pointer that is always passed, the 6th JIT arg   */
+                                       /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
+
+                                       assert(false); /* path never taken */
+                               }
+
+                               s1 = md->params[i].regoff + cd->stackframesize * 8;
+                               s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
+                               M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
+                               M_AST(REG_ITMP1, REG_SP, s2);
                        }
 
                } else {
+
+                       /* floating point types */
+
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argfltregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
 
                                if (!nmd->params[j].inmemory) {
+
                                        /* no mapping to regs needed, native flt args use regoff */
                                        s2 = nmd->params[j].regoff;
-                                       
-                                       /* we cannot move flt regs to their native arg locations directly */
-                                       M_DMOV(s1, s2 + 16);
-                                       fltregarg_inswap[num_fltregargs] = s2;
-                                       num_fltregargs++;
-                                       /*printf("flt arg swap to %d\n", s2 + 16);*/
 
-                               } else {
+                                       /* JIT float regs are still on the stack */
+                                       M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
+                               } 
+                               else {
+                                       /* not supposed to happen with 16 NAT flt args */
+                                       assert(false); 
+                                       /*
                                        s2 = nmd->params[j].regoff;
                                        if (IS_2_WORD_TYPE(t))
                                                M_DST(s1, REG_SP, CSTACK + (s2 * 8));
                                        else
                                                M_FST(s1, REG_SP, CSTACK + (s2 * 8));
+                                       */
                                }
 
-                       } else {
-                               s1 = md->params[i].regoff + cd->stackframesize;
-                               s2 = nmd->params[j].regoff - 6;
-                               if (IS_2_WORD_TYPE(t)) {
-                                       M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
-                                       M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
-                               } else {
-                                       M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
-                                       M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
+                       } 
+                       else {
+                               s1 = md->params[i].regoff;
+
+                               if (!nmd->params[j].inmemory) {
+
+                                       /* JIT stack -> NAT reg */
+
+                                       s2 = nmd->params[j].regoff;
+                                       M_DLD(s2, REG_FP, JITSTACK + s1);
+                               }
+                               else {
+
+                                       /* JIT stack -> NAT stack */
+
+                                       s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
+
+                                       /* The FTMP register may already be loaded with args */
+                                       /* we know $f0 is unused because of the env pointer  */
+                                       M_DLD(REG_F0, REG_FP, JITSTACK + s1);
+                                       M_DST(REG_F0, REG_SP, BIAS + s2);
                                }
                        }
                }
        }
        
-       /* move swapped float args to target regs */
-       for (i = 0; i < num_fltregargs; i++) {
-               s1 = fltregarg_inswap[i];
-               M_DMOV(s1 + 16, s1);
-               /*printf("float arg to target reg: %d ==> %d\n", s1+16, s1);*/
-       }
-
 
        /* put class into second argument register */
 
-       if (m->flags & ACC_STATIC) {
-               disp = dseg_add_address(cd, m->class);
-               M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
-       }
+       if (m->flags & ACC_STATIC)
+               M_MOV(REG_ITMP3, REG_OUT1);
 
        /* put env into first argument register */
 
-       disp = dseg_add_address(cd, _Jv_env);
+       disp = dseg_add_address(cd, VM_get_jnienv());
        M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
 
        /* do the native function call */
@@ -3184,14 +2917,9 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler     */
        M_RESTORE(REG_ZERO, 0, REG_ZERO);   /* restore callers window (DELAY)     */
        
-
        /* generate patcher stubs */
 
        emit_patcher_stubs(jd);
-
-       codegen_finish(jd);
-
-       return code->entrypoint;
 }
 
 /*