* src/vm/jit/stack.c: Removed interpreter-specific code.
[cacao.git] / src / vm / jit / stack.c
index 43e6cc0f7b5eec798225a241ee7ba40fef1e728f..abd53cd55fe27493a4aae73e0aa6ec61ba57eeea 100644 (file)
@@ -30,7 +30,7 @@
             Christian Thalinger
             Christian Ullrich
 
-   $Id: stack.c 5135 2006-07-14 17:03:36Z edwin $
+   $Id: stack.c 5675 2006-10-04 19:38:28Z edwin $
 
 */
 
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
-
-#include "vm/types.h"
+#include <limits.h>
 
 #include "arch.h"
 #include "md-abi.h"
 
 #include "mm/memory.h"
+
 #include "native/native.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/global.h"
 #include "vm/builtin.h"
 #include "vm/options.h"
 #include "vm/resolve.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/types.h"
+
 #include "vm/jit/abi.h"
+#include "vm/jit/cfg.h"
+#include "vm/jit/codegen-common.h"
 #include "vm/jit/show.h"
 
 #if defined(ENABLE_DISASSEMBLER)
 #include "vm/jit/jit.h"
 #include "vm/jit/stack.h"
 
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_SSA)
+# include "vm/jit/optimizing/lsra.h"
+# include "vm/jit/optimizing/ssa.h"
+#elif defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
 #endif
 
 
 /* macro for saving #ifdefs ***************************************************/
 
-#if defined(ENABLE_INTRP)
-#define IF_INTRP(x) if (opt_intrp) { x }
-#define IF_NO_INTRP(x) if (!opt_intrp) { x }
-#else
-#define IF_INTRP(x)
-#define IF_NO_INTRP(x) { x }
-#endif
-
-#if defined(ENABLE_INTRP)
-#if defined(ENABLE_JIT)
-#define IF_JIT(x) if (!opt_intrp) { x }
-#else
-#define IF_JIT(x)
-#endif
-#else /* !defined(ENABLE_INTRP) */
-#define IF_JIT(x) { x }
-#endif /* defined(ENABLE_INTRP) */
-
 #if defined(ENABLE_STATISTICS)
 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)                    \
-       do {                                                             \
-               if (opt_stat) {                                              \
-                       if (stackdepth >= 10)                                    \
-                               count_store_depth[10]++;                             \
-                       else                                                     \
-                               count_store_depth[stackdepth]++;                     \
-               }                                                            \
-       } while (0)
+    do {                                                             \
+        if (opt_stat) {                                              \
+            if (stackdepth >= 10)                                    \
+                count_store_depth[10]++;                             \
+            else                                                     \
+                count_store_depth[stackdepth]++;                     \
+        }                                                            \
+    } while (0)
 #else /* !defined(ENABLE_STATISTICS) */
 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
 #endif
 
-/* stack_init ******************************************************************
+/* stackdata_t *****************************************************************
 
-   Initialized the stack analysis subsystem (called by jit_init).
+   This struct holds internal data during stack analysis.
 
 *******************************************************************************/
 
-bool stack_init(void)
-{
-       return true;
-}
+typedef struct stackdata_t stackdata_t;
 
+struct stackdata_t {
+    basicblock *bptr;             /* the current basic block being analysed   */
+    stackptr new;                 /* next free stackelement                   */
+    s4 vartop;                    /* next free variable index                 */
+    s4 localcount;                /* number of locals (at the start of var)   */
+    s4 varcount;                  /* total number of variables allocated      */
+    varinfo *var;                 /* variable array (same as jd->var)         */
+       methodinfo *m;                /* the method being analysed                */
+       jitdata *jd;                  /* current jitdata                          */
+       basicblock *last_real_block;  /* the last block before the empty one      */
+       bool repeat;                  /* if true, iterate the analysis again      */
+       exceptiontable **handlers;    /* exception handlers for the current block */
+       exceptiontable *extableend;   /* points to the last exception entry       */
+       stackelement exstack;         /* instack for exception handlers           */
+};
 
-/* stack_analyse ***************************************************************
 
-   Analyse_stack uses the intermediate code created by parse.c to
-   build a model of the JVM operand stack for the current method.
-   
-   The following checks are performed:
-     - check for operand stack underflow (before each instruction)
-     - check for operand stack overflow (after[1] each instruction)
-     - check for matching stack depth at merging points
-     - check for matching basic types[2] at merging points
-     - check basic types for instruction input (except for BUILTIN*
-           opcodes, INVOKE* opcodes and MULTIANEWARRAY)
-   
-   [1]) Checking this after the instruction should be ok. parse.c
-   counts the number of required stack slots in such a way that it is
-   only vital that we don't exceed `maxstack` at basic block
-   boundaries.
-   
-   [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
-   DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
-   types are not discerned.
+/* macros for allocating/releasing variable indices *****************/
 
-*******************************************************************************/
+#define GET_NEW_INDEX(sd, new_varindex)                              \
+    do {                                                             \
+        assert((sd).vartop < (sd).varcount);                         \
+        (new_varindex) = ((sd).vartop)++;                            \
+    } while (0)
 
-#define BLOCK_OF(index)                                              \
-    (jd->new_basicblocks + jd->new_basicblockindex[index])
+/* Not implemented now - could be used to reuse varindices.         */
+/* Pay attention to not release a localvar once implementing it!    */
+#define RELEASE_INDEX(sd, varindex)
+
+#define GET_NEW_VAR(sd, new_varindex, newtype)                       \
+    do {                                                             \
+        GET_NEW_INDEX((sd), (new_varindex));                         \
+        (sd).var[new_index].type = (newtype);                        \
+    } while (0)
+
+
+/* macros for querying variable properties **************************/
+
+#define IS_INOUT(sp)                                                 \
+    (sd.var[(sp)->varnum].flags & INOUT)
+
+#define IS_PREALLOC(sp)                                              \
+    (sd.var[(sp)->varnum].flags & PREALLOC)
+
+#define IS_TEMPVAR(sp)                                                                                          \
+    ( ((sp)->varnum >= sd.localcount)                                                           \
+      && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
+
+
+#define IS_LOCALVAR_SD(sd, sp)                                       \
+         ((sp)->varnum < (sd).localcount)
+
+#define IS_LOCALVAR(sp)                                              \
+    IS_LOCALVAR_SD(sd, (sp))
+
+
+/* macros for setting variable properties ****************************/
+
+#define SET_TEMPVAR(sp)                                              \
+    do {                                                             \
+        if (IS_LOCALVAR((sp))) {                                     \
+            GET_NEW_VAR(sd, new_index, (sp)->type);                  \
+            sd.var[new_index].flags = (sp)->flags;                   \
+            (sp)->varnum = new_index;                                \
+            (sp)->varkind = TEMPVAR;                                 \
+            if ((sp)->creator)                                       \
+                (sp)->creator->dst.varindex = new_index;             \
+        }                                                            \
+        sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC);           \
+    } while (0);
+
+#define SET_PREALLOC(sp)                                             \
+    do {                                                             \
+        assert(!IS_LOCALVAR((sp)));                                  \
+        sd.var[(sp)->varnum].flags |= PREALLOC;                      \
+    } while (0);
 
-#define CLR_S1                                                       \
-    (iptr->s1.var = NULL)
 
-#define USE_S1_LOCAL(type1)
+/* macros for source operands ***************************************/
+
+#define CLR_S1                                                       \
+    (iptr->s1.varindex = -1)
 
 #define USE_S1(type1)                                                \
     do {                                                             \
-        REQUIRE_1;                                                   \
+        REQUIRE(1);                                                  \
         CHECK_BASIC_TYPE(type1, curstack->type);                     \
-        iptr->s1.var = curstack;                                     \
+        iptr->s1.varindex = curstack->varnum;                        \
     } while (0)
 
 #define USE_S1_ANY                                                   \
     do {                                                             \
-        REQUIRE_1;                                                   \
-        iptr->s1.var = curstack;                                     \
+        REQUIRE(1);                                                  \
+        iptr->s1.varindex = curstack->varnum;                        \
     } while (0)
 
 #define USE_S1_S2(type1, type2)                                      \
     do {                                                             \
-        REQUIRE_2;                                                   \
+        REQUIRE(2);                                                  \
         CHECK_BASIC_TYPE(type1, curstack->prev->type);               \
         CHECK_BASIC_TYPE(type2, curstack->type);                     \
-        iptr->sx.s23.s2.var = curstack;                              \
-        iptr->s1.var = curstack->prev;                               \
+        iptr->sx.s23.s2.varindex = curstack->varnum;                 \
+        iptr->s1.varindex = curstack->prev->varnum;                  \
     } while (0)
 
 #define USE_S1_S2_ANY_ANY                                            \
     do {                                                             \
-        REQUIRE_2;                                                   \
-        iptr->sx.s23.s2.var = curstack;                              \
-        iptr->s1.var = curstack->prev;                               \
+        REQUIRE(2);                                                  \
+        iptr->sx.s23.s2.varindex = curstack->varnum;                 \
+        iptr->s1.varindex = curstack->prev->varnum;                  \
     } while (0)
 
 #define USE_S1_S2_S3(type1, type2, type3)                            \
     do {                                                             \
-        REQUIRE_3;                                                   \
+        REQUIRE(3);                                                  \
         CHECK_BASIC_TYPE(type1, curstack->prev->prev->type);         \
         CHECK_BASIC_TYPE(type2, curstack->prev->type);               \
         CHECK_BASIC_TYPE(type3, curstack->type);                     \
-        iptr->sx.s23.s3.var = curstack;                              \
-        iptr->sx.s23.s2.var = curstack->prev;                        \
-        iptr->s1.var = curstack->prev->prev;                         \
+        iptr->sx.s23.s3.varindex = curstack->varnum;                 \
+        iptr->sx.s23.s2.varindex = curstack->prev->varnum;           \
+        iptr->s1.varindex = curstack->prev->prev->varnum;            \
+    } while (0)
+
+/* The POPANY macro does NOT check stackdepth, or set stackdepth!   */
+#define POPANY                                                       \
+    do {                                                             \
+        if (curstack->varkind == UNDEFVAR)                           \
+            curstack->varkind = TEMPVAR;                             \
+        curstack = curstack->prev;                                   \
     } while (0)
 
 #define POP_S1(type1)                                                \
@@ -242,3090 +287,2068 @@ bool stack_init(void)
 #define CLR_SX                                                       \
     (iptr->sx.val.l = 0)
 
+
+/* macros for setting the destination operand ***********************/
+
 #define CLR_DST                                                      \
-    (iptr->dst.var = NULL)
+    (iptr->dst.varindex = -1)
 
-#define NEW_DST(typed, depth)                                        \
+#define DST(typed, index)                                            \
     do {                                                             \
-        NEWSTACKn(typed, (depth));                                   \
-        iptr->dst.var = curstack;                                    \
+        NEWSTACKn((typed),(index));                                  \
+        curstack->creator = iptr;                                    \
+        iptr->dst.varindex = (index);                                \
     } while (0)
 
-#define NEW_DST_LOCALVAR(typed, index)                               \
+#define DST_LOCALVAR(typed, index)                                   \
     do {                                                             \
-        NEWSTACK(typed, LOCALVAR, (index));                          \
-        iptr->dst.var = curstack;                                    \
+        NEWSTACK((typed), LOCALVAR, (index));                        \
+        curstack->creator = iptr;                                    \
+        iptr->dst.varindex = (index);                                \
     } while (0)
 
-#define NEW_OP0_0                                                    \
-    do {                                                             \
-        CLR_S1;                                                      \
-        CLR_DST;                                                     \
-    } while (0)
 
-#define NEW_OP0_BRANCH                                               \
+/* macro for propagating constant values ****************************/
+
+#define COPY_VAL_AND_TYPE(sd, sindex, dindex)                        \
     do {                                                             \
-        CLR_S1;                                                      \
-    } while (0)
+        (sd).var[(dindex)].type = (sd).var[(sindex)].type;           \
+        (sd).var[(dindex)].vv  = (sd).var[(sindex)].vv;              \
+    } while (0)                                                      \
+
 
-#define NEW_OP0_1(typed)                                             \
+/* stack modelling macros *******************************************/
+
+#define OP0_1(typed)                                                 \
     do {                                                             \
         CLR_S1;                                                      \
-        NEW_DST(typed, stackdepth);                                  \
+        GET_NEW_VAR(sd, new_index, (typed));                         \
+        DST((typed), new_index);                                                                        \
         stackdepth++;                                                \
     } while (0)
 
-#define NEW_OP1_0(type1)                                             \
+#define OP1_0_ANY                                                    \
     do {                                                             \
-        POP_S1(type1);                                               \
+        POP_S1_ANY;                                                  \
         CLR_DST;                                                     \
         stackdepth--;                                                \
     } while (0)
 
-#define NEW_OP1_0_ANY                                                \
+#define OP1_BRANCH(type1)                                            \
     do {                                                             \
-        POP_S1_ANY;                                                  \
-        CLR_DST;                                                     \
+        POP_S1(type1);                                               \
         stackdepth--;                                                \
     } while (0)
 
-#define NEW_OP1_BRANCH(type1)                                        \
+#define OP1_1(type1, typed)                                          \
     do {                                                             \
         POP_S1(type1);                                               \
+        GET_NEW_VAR(sd, new_index, (typed));                         \
+        DST(typed, new_index);                                       \
+    } while (0)
+
+#define OP2_1(type1, type2, typed)                                   \
+    do {                                                             \
+        POP_S1_S2(type1, type2);                                     \
+        GET_NEW_VAR(sd, new_index, (typed));                         \
+        DST(typed, new_index);                                       \
         stackdepth--;                                                \
     } while (0)
 
-#define NEW_OP1_1(type1, typed)                                      \
+#define OP0_0                                                        \
+    do {                                                             \
+        CLR_S1;                                                      \
+        CLR_DST;                                                     \
+    } while (0)
+
+#define OP0_BRANCH                                                   \
+    do {                                                             \
+        CLR_S1;                                                      \
+    } while (0)
+
+#define OP1_0(type1)                                                 \
     do {                                                             \
         POP_S1(type1);                                               \
-        NEW_DST(typed, stackdepth - 1);                              \
+        CLR_DST;                                                     \
+        stackdepth--;                                                \
     } while (0)
 
-#define NEW_OP2_0(type1, type2)                                      \
+#define OP2_0(type1, type2)                                          \
     do {                                                             \
         POP_S1_S2(type1, type2);                                     \
         CLR_DST;                                                     \
         stackdepth -= 2;                                             \
     } while (0)
 
-#define NEW_OP2_BRANCH(type1, type2)                                 \
+#define OP2_BRANCH(type1, type2)                                     \
     do {                                                             \
         POP_S1_S2(type1, type2);                                     \
         stackdepth -= 2;                                             \
     } while (0)
 
-#define NEW_OP2_0_ANY_ANY                                            \
+#define OP2_0_ANY_ANY                                                \
     do {                                                             \
         POP_S1_S2_ANY_ANY;                                           \
         CLR_DST;                                                     \
         stackdepth -= 2;                                             \
     } while (0)
 
-#define NEW_OP2_1(type1, type2, typed)                               \
-    do {                                                             \
-        POP_S1_S2(type1, type2);                                     \
-        NEW_DST(typed, stackdepth - 2);                              \
-        stackdepth--;                                                \
-    } while (0)
-
-#define NEW_OP3_0(type1, type2, type3)                               \
+#define OP3_0(type1, type2, type3)                                   \
     do {                                                             \
         POP_S1_S2_S3(type1, type2, type3);                           \
         CLR_DST;                                                     \
         stackdepth -= 3;                                             \
     } while (0)
 
-#define NEW_LOAD(type1, index)                                       \
+#define LOAD(type1, index)                                           \
     do {                                                             \
-        NEW_DST_LOCALVAR(type1, index);                              \
+        DST_LOCALVAR(type1, index);                                  \
         stackdepth++;                                                \
     } while (0)
 
-#define NEW_STORE(type1, index)                                      \
+#define STORE(type1, index)                                          \
     do {                                                             \
         POP_S1(type1);                                               \
         stackdepth--;                                                \
     } while (0)
 
-#define BRANCH_TARGET(bt, tempbptr, tempsp)                          \
+
+/* macros for DUP elimination ***************************************/
+
+/* XXX replace NEW_VAR with NEW_INDEX */
+#define DUP_SLOT(sp)                                                 \
+    do {                                                             \
+        GET_NEW_VAR(sd, new_index, (sp)->type);                      \
+        COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index);              \
+        NEWSTACK((sp)->type, TEMPVAR, new_index);                    \
+    } while(0)
+
+/* does not check input stackdepth */
+#define MOVE_UP(sp)                                                  \
     do {                                                             \
-        (bt).block = tempbptr = BLOCK_OF((bt).insindex);             \
-        MARKREACHED(tempbptr, tempsp);                               \
+        iptr->opc = ICMD_MOVE;                                       \
+        iptr->s1.varindex = (sp)->varnum;                            \
+        DUP_SLOT(sp);                                                \
+        curstack->creator = iptr;                                    \
+        iptr->dst.varindex = curstack->varnum;                       \
+        stackdepth++;                                                \
     } while (0)
 
-#define BRANCH(tempbptr, tempsp)                                     \
+/* does not check input stackdepth */
+#define COPY_UP(sp)                                                  \
     do {                                                             \
-        iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex);   \
-        MARKREACHED(tempbptr, tempsp);                               \
+        SET_TEMPVAR((sp));                                           \
+        iptr->opc = ICMD_COPY;                                       \
+        iptr->s1.varindex = (sp)->varnum;                            \
+        DUP_SLOT(sp);                                                \
+        curstack->creator = iptr;                                    \
+        iptr->dst.varindex = curstack->varnum;                       \
+        stackdepth++;                                                \
     } while (0)
 
-#define DUP_SLOT(sp)                                                 \
+#define COPY_DOWN(s, d)                                              \
     do {                                                             \
-        if ((sp)->varkind != TEMPVAR)                                \
-            NEWSTACK((sp)->type, TEMPVAR, stackdepth);               \
-        else                                                         \
-            NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum);       \
-    } while(0)
+        SET_TEMPVAR((s));                                            \
+        iptr->opc = ICMD_COPY;                                       \
+        iptr->s1.varindex = (s)->varnum;                             \
+        iptr->dst.varindex = (d)->varnum;                            \
+        (d)->creator = iptr;                                         \
+    } while (0)
 
-bool new_stack_analyse(jitdata *jd)
-{
-       methodinfo   *m;              /* method being analyzed                    */
-       codeinfo     *code;
-       codegendata  *cd;
-       registerdata *rd;
-       int           b_count;        /* basic block counter                      */
-       int           b_index;        /* basic block index                        */
-       int           stackdepth;
-       stackptr      curstack;       /* current stack top                        */
-       stackptr      new;
-       stackptr      copy;
-       int           opcode;         /* opcode of current instruction            */
-       int           i, j;
-       int           len;            /* # of instructions after the current one  */
-       bool          superblockend;  /* if true, no fallthrough to next block    */
-       bool          repeat;         /* if true, outermost loop must run again   */
-       bool          deadcode;       /* true if no live code has been reached    */
-       new_instruction *iptr;        /* the current instruction                  */
-       basicblock   *bptr;           /* the current basic block                  */
-       basicblock   *tbptr;
-       s4           *last_store;     /* instruction index of last XSTORE         */
-                                     /* [ local_index * 5 + type ]               */
-       s4            last_pei;       /* ins. index of last possible exception    */
-                                     /* used for conflict resolution for copy    */
-                                  /* elimination (XLOAD, IINC, XSTORE)        */
-       s4            last_dupx;
-       branch_target_t *table;
-       lookup_target_t *lookup;
-#if defined(ENABLE_VERIFIER)
-       int           expectedtype;   /* used by CHECK_BASIC_TYPE                 */
-#endif
-       builtintable_entry *bte;
-       methoddesc         *md;
-       constant_FMIref    *fmiref;
-#if defined(ENABLE_STATISTICS)
-       int           iteration_count;  /* number of iterations of analysis       */
-#endif
+#define MOVE_TO_TEMP(sp)                                             \
+    do {                                                             \
+        GET_NEW_INDEX(sd, new_index);                                \
+        iptr->opc = ICMD_MOVE;                                       \
+        iptr->s1.varindex = (sp)->varnum;                            \
+        iptr->dst.varindex = new_index;                              \
+        COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index);              \
+        (sp)->varnum = new_index;                                    \
+               (sp)->varkind = TEMPVAR;                                     \
+    } while (0)
 
-#if defined(STACK_VERBOSE)
-       new_show_method(jd, SHOW_PARSE);
-#endif
+/* macros for branching / reaching basic blocks *********************/
 
-       /* get required compiler data - initialization */
+#define BRANCH_TARGET(bt, tempbptr)                                  \
+    do {                                                             \
+        tempbptr = BLOCK_OF((bt).insindex);                          \
+        tempbptr = stack_mark_reached(&sd, tempbptr, curstack,       \
+                                      stackdepth);                   \
+        if (tempbptr == NULL)                                        \
+            return false;                                            \
+        (bt).block = tempbptr;                                       \
+    } while (0)
 
-       m    = jd->m;
-       code = jd->code;
-       cd   = jd->cd;
-       rd   = jd->rd;
+#define BRANCH(tempbptr)                                             \
+    BRANCH_TARGET(iptr->dst, tempbptr)
 
-#if defined(ENABLE_LSRA)
-       m->maxlifetimes = 0;
-#endif
 
-#if defined(ENABLE_STATISTICS)
-       iteration_count = 0;
+/* forward declarations *******************************************************/
+
+static void stack_create_invars(stackdata_t *sd, basicblock *b, 
+                                                               stackptr curstack, int stackdepth);
+static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
+
+#if defined(STACK_VERBOSE)
+static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
+static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
+static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
+static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
+static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
 #endif
 
-       last_store = DMNEW(s4 , cd->maxlocals * 5);
 
-       /* initialize in-stack of first block */
+/* stack_init ******************************************************************
 
-       new = jd->new_stack;
-       jd->new_basicblocks[0].flags = BBREACHED;
-       jd->new_basicblocks[0].instack = 0;
-       jd->new_basicblocks[0].indepth = 0;
+   Initialized the stack analysis subsystem (called by jit_init).
 
-       /* initialize in-stack of exception handlers */
+*******************************************************************************/
 
-       for (i = 0; i < cd->exceptiontablelength; i++) {
-               bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
-               bptr->flags = BBREACHED;
-               bptr->type = BBTYPE_EXH;
-               bptr->instack = new;
-               bptr->indepth = 1;
-               bptr->pre_count = 10000;
-               STACKRESET;
-               NEWXSTACK;
-       }
+bool stack_init(void)
+{
+       return true;
+}
 
-       /* count predecessors of each block **************************************/
 
-#if CONDITIONAL_LOADCONST
-       /* XXX move this to a separate function */
-       {
-               b_count = jd->new_basicblockcount;
-               bptr = jd->new_basicblocks;
-               for (; --b_count >= 0; bptr++) {
-                       if (bptr->icount == 0)
-                               continue;
+/* stack_grow_variable_array ***************************************************
 
-                       /* get the last instruction of the block */
+   Grow the variable array so the given number of additional variables fits in.
 
-                       iptr = /* XXX */ (new_instruction *) bptr->iinstr + (bptr->icount - 1);
+   IN:
+      sd...........stack analysis data
+         num..........number of additional variables
 
-                       switch (iptr->opc) {
-                               /* instruction stopping control flow */
-                               case ICMD_RET:
-                               case ICMD_RETURN:
-                               case ICMD_IRETURN:
-                               case ICMD_LRETURN:
-                               case ICMD_FRETURN:
-                               case ICMD_DRETURN:
-                               case ICMD_ARETURN:
-                               case ICMD_ATHROW:
-                                       break;
+*******************************************************************************/
 
-                                       /* conditional branches */
-                               case ICMD_IFEQ:
-                               case ICMD_IFNE:
-                               case ICMD_IFLT:
-                               case ICMD_IFGE:
-                               case ICMD_IFGT:
-                               case ICMD_IFLE:
-                               case ICMD_IFNULL:
-                               case ICMD_IFNONNULL:
-                               case ICMD_IF_ICMPEQ:
-                               case ICMD_IF_ICMPNE:
-                               case ICMD_IF_ICMPLT:
-                               case ICMD_IF_ICMPGE:
-                               case ICMD_IF_ICMPGT:
-                               case ICMD_IF_ICMPLE:
-                               case ICMD_IF_ACMPEQ:
-                               case ICMD_IF_ACMPNE:
-                                       /* XXX add missing conditional branches */
-                                       bptr[1].pre_count++;
-                                       /* FALLTHROUGH */
-
-                                       /* unconditional branch */
-                               case ICMD_GOTO:
-                                       BLOCK_OF(iptr->dst.insindex)->pre_count++;
-                                       break;
+static void stack_grow_variable_array(stackdata_t *sd, s4 num)
+{
+       s4 newcount;
 
-                                       /* switches */
-                               case ICMD_TABLESWITCH:
-                                       table = iptr->dst.table;
-                                       BLOCK_OF((table++)->insindex)->pre_count++;
-                                       i = iptr->sx.s23.s3.tablehigh
-                                               - iptr->sx.s23.s2.tablelow + 1;
-                                       while (--i >= 0) {
-                                               BLOCK_OF((table++)->insindex)->pre_count++;
-                                       }
-                                       break;
+       assert(num >= 0);
 
-                               case ICMD_LOOKUPSWITCH:
-                                       lookup = iptr->dst.lookup;
-                                       BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->pre_count++;
-                                       i = iptr->sx.s23.s2.lookupcount;
-                                       while (--i >= 0) {
-                                               BLOCK_OF((lookup++)->target.insindex)->pre_count++;
-                                       }
-                                       break;
+       if (num == 0)
+               return;
 
-                                       /* default - fall into next block */
-                               default:
-                                       bptr[1].pre_count++;
-                                       break;
-                       } /* end switch */
-               } /* end basic block loop */
-       }
-#endif /* CONDITIONAL_LOADCONST */
+       /* XXX avoid too many reallocations */
+       newcount = sd->varcount + num;
 
-       /* stack analysis loop (until fixpoint reached) **************************/
+       sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
+       sd->varcount = newcount;
+       sd->jd->var = sd->var;
+       sd->jd->varcount = newcount;
+}
 
-       do {
-#if defined(ENABLE_STATISTICS)
-               iteration_count++;
-#endif
 
-               /* initialize loop over basic blocks */
+/* stack_append_block **********************************************************
 
-               b_count = jd->new_basicblockcount;
-               bptr = jd->new_basicblocks;
-               superblockend = true;
-               repeat = false;
-               STACKRESET;
-               deadcode = true;
+   Append the given block after the last real block of the method (before
+   the pseudo-block at the end).
 
-               /* iterate over basic blocks *****************************************/
+   IN:
+      sd...........stack analysis data
+         b............the block to append
+
+*******************************************************************************/
 
-               while (--b_count >= 0) {
+static void stack_append_block(stackdata_t *sd, basicblock *b)
+{
 #if defined(STACK_VERBOSE)
-                       printf("ANALYZING BLOCK L%03d\n", bptr->debug_nr);
+       printf("APPENDING BLOCK L%0d\n", b->nr);
 #endif
 
-                       if (bptr->flags == BBDELETED) {
-                               /* This block has been deleted - do nothing. */
-                       }
-                       else if (superblockend && (bptr->flags < BBREACHED)) {
-                               /* This block has not been reached so far, and we      */
-                               /* don't fall into it, so we'll have to iterate again. */
-                               repeat = true;
-                       }
-                       else if (bptr->flags <= BBREACHED) {
-                               if (superblockend) {
-                                       /* We know that bptr->flags == BBREACHED. */
-                                       /* This block has been reached before.    */
-                                       stackdepth = bptr->indepth;
-                               }
-                               else if (bptr->flags < BBREACHED) {
-                                       /* This block is reached for the first time now */
-                                       /* by falling through from the previous block.  */
-                                       COPYCURSTACK(copy);
-                                       bptr->instack = copy;
-                                       bptr->indepth = stackdepth;
-                               }
-                               else {
-                                       /* This block has been reached before. now we are */
-                                       /* falling into it from the previous block.       */
-                                       /* Check that stack depth is well-defined.        */
-                                       CHECK_STACK_DEPTH(bptr->indepth, stackdepth);
-                               }
+       b->next = sd->last_real_block->next;
+       sd->last_real_block->next = b;
+       sd->last_real_block = b;
+       sd->jd->basicblockcount++;
+}
 
-                               /* set up local variables for analyzing this block */
 
-                               curstack = bptr->instack;
-                               deadcode = false;
-                               superblockend = false;
-                               bptr->flags = BBFINISHED;
-                               len = bptr->icount;
-                               iptr = /* XXX */ (new_instruction *) bptr->iinstr;
-                               b_index = bptr - jd->new_basicblocks;
+/* stack_clone_block ***********************************************************
 
-                               /* reset variables for dependency checking */
+   Create a copy of the given block and insert it at the end of the method.
 
-                               last_pei = -1;
-                               last_dupx = -1;
-                               for( i = 0; i < cd->maxlocals; i++)
-                                       for( j = 0; j < 5; j++)
-                                               last_store[5 * i + j] = -1;
+   CAUTION: This function does not copy the any variables or the instruction
+   list. It _does_, however, reserve space for the block's invars in the
+   variable array.
 
-                               /* XXX store the start of the block's stack representation */
+   IN:
+      sd...........stack analysis data
+         b............the block to clone
 
-                               bptr->stack = new;
+   RETURN VALUE:
+      a pointer to the copy
 
-                               /* iterate over ICMDs ****************************************/
+*******************************************************************************/
+
+static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
+{
+       basicblock *clone;
+
+       clone = DNEW(basicblock);
+       *clone  = *b;
+
+       clone->iinstr = NULL;
+       clone->inlocals = NULL;
+       clone->invars = NULL;
+
+       clone->original = (b->original) ? b->original : b;
+       clone->copied_to = clone->original->copied_to;
+       clone->original->copied_to = clone;
+       clone->nr = sd->m->c_block_nr++;
+       clone->next = NULL;
+       clone->flags = BBREACHED;
+
+       stack_append_block(sd, clone);
+
+       /* allocate space for the invars of the clone */
+
+       stack_grow_variable_array(sd, b->indepth);
 
-                               while (--len >= 0)  {
 #if defined(STACK_VERBOSE)
-                                       new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
-                                       for( copy = curstack; copy; copy = copy->prev ) {
-                                               printf("%d ", copy->type);
-                                       }
-                                       printf("\n");
+       printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
 #endif
 
-                                       /* fetch the current opcode */
+       return clone;
+}
 
-                                       opcode = iptr->opc;
 
-                                       /* automatically replace some ICMDs with builtins */
+/* stack_create_invars *********************************************************
 
-#if defined(USEBUILTINTABLE)
-                                       IF_NO_INTRP(
-                                               bte = builtintable_get_automatic(opcode);
-
-                                               if (bte && bte->opcode == opcode) {
-                                                       iptr->opc           = ICMD_BUILTIN;
-                                                       iptr->flags.bits    = INS_FLAG_NOCHECK;
-                                                       iptr->sx.s23.s3.bte = bte;
-                                                       /* iptr->line is already set */
-                                                       jd->isleafmethod = false;
-                                                       goto icmd_BUILTIN;
-                                               }
-                                       );
-#endif /* defined(USEBUILTINTABLE) */
+   Create the invars for the given basic block. Also make a copy of the locals.
 
-                                       /* main opcode switch *************************************/
+   IN:
+      sd...........stack analysis data
+         b............block to create the invars for
+         curstack.....current stack top
+         stackdepth...current stack depth
 
-                                       switch (opcode) {
+   This function creates STACKDEPTH invars and sets their types to the
+   types to the types of the corresponding slot in the current stack.
 
-                                               /* pop 0 push 0 */
+*******************************************************************************/
 
-                                       case ICMD_NOP:
-icmd_NOP:
-                                               CLR_SX;
-                                               NEW_OP0_0;
-                                               break;
+static void stack_create_invars(stackdata_t *sd, basicblock *b, 
+                                                               stackptr curstack, int stackdepth)
+{
+       stackptr sp;
+       int i;
+       int index;
+       varinfo *v;
+
+       assert(sd->vartop + stackdepth <= sd->varcount);
+
+       b->indepth = stackdepth;
+       b->invars = DMNEW(s4, stackdepth);
+
+       /* allocate the variable indices */
+       index = (sd->vartop += stackdepth);
+
+       i = stackdepth;
+       for (sp = curstack; i--; sp = sp->prev) {
+               b->invars[i] = --index;
+               v = sd->var + index;
+               v->type = sp->type;
+               v->flags = INOUT;
+               v->vv = sd->var[sp->varnum].vv;
+#if defined(STACK_VERBOSE) && 0
+               printf("\tinvar[%d]: %d\n", i, sd->var[b->invars[i]]);
+#endif
+       }
 
-                                       case ICMD_CHECKNULL:
-                                               COUNT(count_check_null);
-                                               USE_S1(TYPE_ADR);
-                                               CLR_SX;
-                                               CLR_DST; /* XXX live through? */
-                                               break;
+       /* copy the current state of the local variables */
+       /* (one extra local is needed by the verifier)   */
 
-                                       case ICMD_IFEQ_ICONST:
-                                       case ICMD_IFNE_ICONST:
-                                       case ICMD_IFLT_ICONST:
-                                       case ICMD_IFGE_ICONST:
-                                       case ICMD_IFGT_ICONST:
-                                       case ICMD_IFLE_ICONST:
-                                       case ICMD_ELSE_ICONST:
-                                               USE_S1(TYPE_INT);
-                                               CLR_SX;
-                                               CLR_DST; /* XXX live through? */
-                                               break;
+       v = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
+       b->inlocals = v;
+       for (i=0; i<sd->localcount; ++i)
+               *v++ = sd->var[i];
+}
 
-                                       case ICMD_RET:
-                                               USE_S1_LOCAL(TYPE_ADR);
-                                               CLR_SX;
-                                               CLR_DST;
-                                               IF_NO_INTRP( rd->locals[iptr->s1.localindex][TYPE_ADR].type = TYPE_ADR; );
-                                               superblockend = true;
-                                               break;
-
-                                       case ICMD_RETURN:
-                                               COUNT(count_pcmd_return);
-                                               CLR_SX;
-                                               NEW_OP0_0;
-                                               superblockend = true;
-                                               break;
-
-
-                                               /* pop 0 push 1 const */
-
-       /************************** ICONST OPTIMIZATIONS **************************/
-
-                                       case ICMD_ICONST:
-                                               COUNT(count_pcmd_load);
-                                               if (len == 0)
-                                                       goto normal_ICONST;
-
-                                               switch (iptr[1].opc) {
-                                                       case ICMD_IADD:
-                                                               iptr->opc = ICMD_IADDCONST;
-                                                               /* FALLTHROUGH */
-
-                                                       icmd_iconst_tail:
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               NEW_OP1_1(TYPE_INT, TYPE_INT);
-                                                               COUNT(count_pcmd_op);
-                                                               break;
-
-                                                       case ICMD_ISUB:
-                                                               iptr->opc = ICMD_ISUBCONST;
-                                                               goto icmd_iconst_tail;
-#if SUPPORT_CONST_MUL
-                                                       case ICMD_IMUL:
-                                                               iptr->opc = ICMD_IMULCONST;
-                                                               goto icmd_iconst_tail;
-#else /* SUPPORT_CONST_MUL */
-                                                       case ICMD_IMUL:
-                                                               if (iptr->sx.val.i == 0x00000002)
-                                                                       iptr->sx.val.i = 1;
-                                                               else if (iptr->sx.val.i == 0x00000004)
-                                                                       iptr->sx.val.i = 2;
-                                                               else if (iptr->sx.val.i == 0x00000008)
-                                                                       iptr->sx.val.i = 3;
-                                                               else if (iptr->sx.val.i == 0x00000010)
-                                                                       iptr->sx.val.i = 4;
-                                                               else if (iptr->sx.val.i == 0x00000020)
-                                                                       iptr->sx.val.i = 5;
-                                                               else if (iptr->sx.val.i == 0x00000040)
-                                                                       iptr->sx.val.i = 6;
-                                                               else if (iptr->sx.val.i == 0x00000080)
-                                                                       iptr->sx.val.i = 7;
-                                                               else if (iptr->sx.val.i == 0x00000100)
-                                                                       iptr->sx.val.i = 8;
-                                                               else if (iptr->sx.val.i == 0x00000200)
-                                                                       iptr->sx.val.i = 9;
-                                                               else if (iptr->sx.val.i == 0x00000400)
-                                                                       iptr->sx.val.i = 10;
-                                                               else if (iptr->sx.val.i == 0x00000800)
-                                                                       iptr->sx.val.i = 11;
-                                                               else if (iptr->sx.val.i == 0x00001000)
-                                                                       iptr->sx.val.i = 12;
-                                                               else if (iptr->sx.val.i == 0x00002000)
-                                                                       iptr->sx.val.i = 13;
-                                                               else if (iptr->sx.val.i == 0x00004000)
-                                                                       iptr->sx.val.i = 14;
-                                                               else if (iptr->sx.val.i == 0x00008000)
-                                                                       iptr->sx.val.i = 15;
-                                                               else if (iptr->sx.val.i == 0x00010000)
-                                                                       iptr->sx.val.i = 16;
-                                                               else if (iptr->sx.val.i == 0x00020000)
-                                                                       iptr->sx.val.i = 17;
-                                                               else if (iptr->sx.val.i == 0x00040000)
-                                                                       iptr->sx.val.i = 18;
-                                                               else if (iptr->sx.val.i == 0x00080000)
-                                                                       iptr->sx.val.i = 19;
-                                                               else if (iptr->sx.val.i == 0x00100000)
-                                                                       iptr->sx.val.i = 20;
-                                                               else if (iptr->sx.val.i == 0x00200000)
-                                                                       iptr->sx.val.i = 21;
-                                                               else if (iptr->sx.val.i == 0x00400000)
-                                                                       iptr->sx.val.i = 22;
-                                                               else if (iptr->sx.val.i == 0x00800000)
-                                                                       iptr->sx.val.i = 23;
-                                                               else if (iptr->sx.val.i == 0x01000000)
-                                                                       iptr->sx.val.i = 24;
-                                                               else if (iptr->sx.val.i == 0x02000000)
-                                                                       iptr->sx.val.i = 25;
-                                                               else if (iptr->sx.val.i == 0x04000000)
-                                                                       iptr->sx.val.i = 26;
-                                                               else if (iptr->sx.val.i == 0x08000000)
-                                                                       iptr->sx.val.i = 27;
-                                                               else if (iptr->sx.val.i == 0x10000000)
-                                                                       iptr->sx.val.i = 28;
-                                                               else if (iptr->sx.val.i == 0x20000000)
-                                                                       iptr->sx.val.i = 29;
-                                                               else if (iptr->sx.val.i == 0x40000000)
-                                                                       iptr->sx.val.i = 30;
-                                                               else if (iptr->sx.val.i == 0x80000000)
-                                                                       iptr->sx.val.i = 31;
-                                                               else
-                                                                       goto normal_ICONST;
-
-                                                               iptr->opc = ICMD_IMULPOW2;
-                                                               goto icmd_iconst_tail;
-#endif /* SUPPORT_CONST_MUL */
-                                                       case ICMD_IDIV:
-                                                               if (iptr->sx.val.i == 0x00000002)
-                                                                       iptr->sx.val.i = 1;
-                                                               else if (iptr->sx.val.i == 0x00000004)
-                                                                       iptr->sx.val.i = 2;
-                                                               else if (iptr->sx.val.i == 0x00000008)
-                                                                       iptr->sx.val.i = 3;
-                                                               else if (iptr->sx.val.i == 0x00000010)
-                                                                       iptr->sx.val.i = 4;
-                                                               else if (iptr->sx.val.i == 0x00000020)
-                                                                       iptr->sx.val.i = 5;
-                                                               else if (iptr->sx.val.i == 0x00000040)
-                                                                       iptr->sx.val.i = 6;
-                                                               else if (iptr->sx.val.i == 0x00000080)
-                                                                       iptr->sx.val.i = 7;
-                                                               else if (iptr->sx.val.i == 0x00000100)
-                                                                       iptr->sx.val.i = 8;
-                                                               else if (iptr->sx.val.i == 0x00000200)
-                                                                       iptr->sx.val.i = 9;
-                                                               else if (iptr->sx.val.i == 0x00000400)
-                                                                       iptr->sx.val.i = 10;
-                                                               else if (iptr->sx.val.i == 0x00000800)
-                                                                       iptr->sx.val.i = 11;
-                                                               else if (iptr->sx.val.i == 0x00001000)
-                                                                       iptr->sx.val.i = 12;
-                                                               else if (iptr->sx.val.i == 0x00002000)
-                                                                       iptr->sx.val.i = 13;
-                                                               else if (iptr->sx.val.i == 0x00004000)
-                                                                       iptr->sx.val.i = 14;
-                                                               else if (iptr->sx.val.i == 0x00008000)
-                                                                       iptr->sx.val.i = 15;
-                                                               else if (iptr->sx.val.i == 0x00010000)
-                                                                       iptr->sx.val.i = 16;
-                                                               else if (iptr->sx.val.i == 0x00020000)
-                                                                       iptr->sx.val.i = 17;
-                                                               else if (iptr->sx.val.i == 0x00040000)
-                                                                       iptr->sx.val.i = 18;
-                                                               else if (iptr->sx.val.i == 0x00080000)
-                                                                       iptr->sx.val.i = 19;
-                                                               else if (iptr->sx.val.i == 0x00100000)
-                                                                       iptr->sx.val.i = 20;
-                                                               else if (iptr->sx.val.i == 0x00200000)
-                                                                       iptr->sx.val.i = 21;
-                                                               else if (iptr->sx.val.i == 0x00400000)
-                                                                       iptr->sx.val.i = 22;
-                                                               else if (iptr->sx.val.i == 0x00800000)
-                                                                       iptr->sx.val.i = 23;
-                                                               else if (iptr->sx.val.i == 0x01000000)
-                                                                       iptr->sx.val.i = 24;
-                                                               else if (iptr->sx.val.i == 0x02000000)
-                                                                       iptr->sx.val.i = 25;
-                                                               else if (iptr->sx.val.i == 0x04000000)
-                                                                       iptr->sx.val.i = 26;
-                                                               else if (iptr->sx.val.i == 0x08000000)
-                                                                       iptr->sx.val.i = 27;
-                                                               else if (iptr->sx.val.i == 0x10000000)
-                                                                       iptr->sx.val.i = 28;
-                                                               else if (iptr->sx.val.i == 0x20000000)
-                                                                       iptr->sx.val.i = 29;
-                                                               else if (iptr->sx.val.i == 0x40000000)
-                                                                       iptr->sx.val.i = 30;
-                                                               else if (iptr->sx.val.i == 0x80000000)
-                                                                       iptr->sx.val.i = 31;
-                                                               else
-                                                                       goto normal_ICONST;
-
-                                                               iptr->opc = ICMD_IDIVPOW2;
-                                                               goto icmd_iconst_tail;
-
-                                                       case ICMD_IREM:
-                                                               /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
-                                                               if ((iptr->sx.val.i == 0x00000002) ||
-                                                                       (iptr->sx.val.i == 0x00000004) ||
-                                                                       (iptr->sx.val.i == 0x00000008) ||
-                                                                       (iptr->sx.val.i == 0x00000010) ||
-                                                                       (iptr->sx.val.i == 0x00000020) ||
-                                                                       (iptr->sx.val.i == 0x00000040) ||
-                                                                       (iptr->sx.val.i == 0x00000080) ||
-                                                                       (iptr->sx.val.i == 0x00000100) ||
-                                                                       (iptr->sx.val.i == 0x00000200) ||
-                                                                       (iptr->sx.val.i == 0x00000400) ||
-                                                                       (iptr->sx.val.i == 0x00000800) ||
-                                                                       (iptr->sx.val.i == 0x00001000) ||
-                                                                       (iptr->sx.val.i == 0x00002000) ||
-                                                                       (iptr->sx.val.i == 0x00004000) ||
-                                                                       (iptr->sx.val.i == 0x00008000) ||
-                                                                       (iptr->sx.val.i == 0x00010000) ||
-                                                                       (iptr->sx.val.i == 0x00020000) ||
-                                                                       (iptr->sx.val.i == 0x00040000) ||
-                                                                       (iptr->sx.val.i == 0x00080000) ||
-                                                                       (iptr->sx.val.i == 0x00100000) ||
-                                                                       (iptr->sx.val.i == 0x00200000) ||
-                                                                       (iptr->sx.val.i == 0x00400000) ||
-                                                                       (iptr->sx.val.i == 0x00800000) ||
-                                                                       (iptr->sx.val.i == 0x01000000) ||
-                                                                       (iptr->sx.val.i == 0x02000000) ||
-                                                                       (iptr->sx.val.i == 0x04000000) ||
-                                                                       (iptr->sx.val.i == 0x08000000) ||
-                                                                       (iptr->sx.val.i == 0x10000000) ||
-                                                                       (iptr->sx.val.i == 0x20000000) ||
-                                                                       (iptr->sx.val.i == 0x40000000) ||
-                                                                       (iptr->sx.val.i == 0x80000000))
-                                                               {
-                                                                       iptr->opc = ICMD_IREMPOW2;
-                                                                       iptr->sx.val.i -= 1;
-                                                                       goto icmd_iconst_tail;
-                                                               }
-                                                               goto normal_ICONST;
-#if SUPPORT_CONST_LOGICAL
-                                                       case ICMD_IAND:
-                                                               iptr->opc = ICMD_IANDCONST;
-                                                               goto icmd_iconst_tail;
-
-                                                       case ICMD_IOR:
-                                                               iptr->opc = ICMD_IORCONST;
-                                                               goto icmd_iconst_tail;
-
-                                                       case ICMD_IXOR:
-                                                               iptr->opc = ICMD_IXORCONST;
-                                                               goto icmd_iconst_tail;
-
-#endif /* SUPPORT_CONST_LOGICAL */
-                                                       case ICMD_ISHL:
-                                                               iptr->opc = ICMD_ISHLCONST;
-                                                               goto icmd_iconst_tail;
-
-                                                       case ICMD_ISHR:
-                                                               iptr->opc = ICMD_ISHRCONST;
-                                                               goto icmd_iconst_tail;
-
-                                                       case ICMD_IUSHR:
-                                                               iptr->opc = ICMD_IUSHRCONST;
-                                                               goto icmd_iconst_tail;
-#if SUPPORT_LONG_SHIFT
-                                                       case ICMD_LSHL:
-                                                               iptr->opc = ICMD_LSHLCONST;
-                                                               goto icmd_lconst_tail;
-
-                                                       case ICMD_LSHR:
-                                                               iptr->opc = ICMD_LSHRCONST;
-                                                               goto icmd_lconst_tail;
-
-                                                       case ICMD_LUSHR:
-                                                               iptr->opc = ICMD_LUSHRCONST;
-                                                               goto icmd_lconst_tail;
-#endif /* SUPPORT_LONG_SHIFT */
-                                                       case ICMD_IF_ICMPEQ:
-                                                               iptr[1].opc = ICMD_IFEQ;
-                                                               /* FALLTHROUGH */
-
-                                                       icmd_if_icmp_tail:
-                                                               /* set the constant for the following icmd */
-                                                               iptr[1].sx.val.i = iptr->sx.val.i;
-
-                                                               /* this instruction becomes a nop */
-                                                               iptr->opc = ICMD_NOP;
-                                                               goto icmd_NOP;
-
-                                                       case ICMD_IF_ICMPLT:
-                                                               iptr[1].opc = ICMD_IFLT;
-                                                               goto icmd_if_icmp_tail;
-
-                                                       case ICMD_IF_ICMPLE:
-                                                               iptr[1].opc = ICMD_IFLE;
-                                                               goto icmd_if_icmp_tail;
-
-                                                       case ICMD_IF_ICMPNE:
-                                                               iptr[1].opc = ICMD_IFNE;
-                                                               goto icmd_if_icmp_tail;
-
-                                                       case ICMD_IF_ICMPGT:
-                                                               iptr[1].opc = ICMD_IFGT;
-                                                               goto icmd_if_icmp_tail;
-
-                                                       case ICMD_IF_ICMPGE:
-                                                               iptr[1].opc = ICMD_IFGE;
-                                                               goto icmd_if_icmp_tail;
-
-#if SUPPORT_CONST_STORE
-                                                       case ICMD_IASTORE:
-                                                       case ICMD_BASTORE:
-                                                       case ICMD_CASTORE:
-                                                       case ICMD_SASTORE:
-                                                               IF_INTRP( goto normal_ICONST; )
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                               if (iptr->sx.val.i != 0)
-                                                                       goto normal_ICONST;
-# endif
-                                                               switch (iptr[1].opc) {
-                                                                       case ICMD_IASTORE:
-                                                                               iptr->opc = ICMD_IASTORECONST;
-                                                                               break;
-                                                                       case ICMD_BASTORE:
-                                                                               iptr->opc = ICMD_BASTORECONST;
-                                                                               break;
-                                                                       case ICMD_CASTORE:
-                                                                               iptr->opc = ICMD_CASTORECONST;
-                                                                               break;
-                                                                       case ICMD_SASTORE:
-                                                                               iptr->opc = ICMD_SASTORECONST;
-                                                                               break;
-                                                               }
-
-                                                               iptr[1].opc = ICMD_NOP;
-
-                                                               /* copy the constant to s3 */
-                                                               /* XXX constval -> astoreconstval? */
-                                                               iptr->sx.s23.s3.constval = iptr->sx.val.i;
-                                                               NEW_OP2_0(TYPE_ADR, TYPE_INT);
-                                                               COUNT(count_pcmd_op);
-                                                               break;
-
-                                                       case ICMD_PUTSTATIC:
-                                                       case ICMD_PUTFIELD:
-                                                               IF_INTRP( goto normal_ICONST; )
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                               if (iptr->sx.val.i != 0)
-                                                                       goto normal_ICONST;
-# endif
-                                                               /* XXX check field type? */
-
-                                                               /* copy the constant to s2 */
-                                                               /* XXX constval -> fieldconstval? */
-                                                               iptr->sx.s23.s2.constval = iptr->sx.val.i;
-
-putconst_tail:
-                                                               /* set the field reference (s3) */
-                                                               if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED)
-                                                                       iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
-                                                               else
-                                                                       iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
-                                                               
-                                                               switch (iptr[1].opc) {
-                                                                       case ICMD_PUTSTATIC:
-                                                                               iptr->opc = ICMD_PUTSTATICCONST;
-                                                                               NEW_OP0_0;
-                                                                               break;
-                                                                       case ICMD_PUTFIELD:
-                                                                               iptr->opc = ICMD_PUTFIELDCONST;
-                                                                               NEW_OP1_0(TYPE_ADR);
-                                                                               break;
-                                                               }
-
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               COUNT(count_pcmd_op);
-                                                               break;
-#endif /* SUPPORT_CONST_STORE */
-
-                                                       default:
-                                                               goto normal_ICONST;
-                                               }
-
-                                               /* if we get here, the ICONST has been optimized */
-                                               break;
-
-normal_ICONST:
-                                               /* normal case of an unoptimized ICONST */
-                                               NEW_OP0_1(TYPE_INT);
-                                               break;
-
-       /************************** LCONST OPTIMIZATIONS **************************/
-
-                                       case ICMD_LCONST:
-                                               COUNT(count_pcmd_load);
-                                               if (len == 0)
-                                                       goto normal_LCONST;
-
-                                               /* switch depending on the following instruction */
-
-                                               switch (iptr[1].opc) {
-#if SUPPORT_LONG_ADD
-                                                       case ICMD_LADD:
-                                                               iptr->opc = ICMD_LADDCONST;
-                                                               /* FALLTHROUGH */
-
-                                                       icmd_lconst_tail:
-                                                               /* instruction of type LONG -> LONG */
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               NEW_OP1_1(TYPE_LNG, TYPE_LNG);
-                                                               COUNT(count_pcmd_op);
-                                                               break;
-
-                                                       case ICMD_LSUB:
-                                                               iptr->opc = ICMD_LSUBCONST;
-                                                               goto icmd_lconst_tail;
-
-#endif /* SUPPORT_LONG_ADD */
-#if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
-                                                       case ICMD_LMUL:
-                                                               iptr->opc = ICMD_LMULCONST;
-                                                               goto icmd_lconst_tail;
-#else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
-# if SUPPORT_LONG_SHIFT
-                                                       case ICMD_LMUL:
-                                                               if (iptr->sx.val.l == 0x00000002)
-                                                                       iptr->sx.val.i = 1;
-                                                               else if (iptr->sx.val.l == 0x00000004)
-                                                                       iptr->sx.val.i = 2;
-                                                               else if (iptr->sx.val.l == 0x00000008)
-                                                                       iptr->sx.val.i = 3;
-                                                               else if (iptr->sx.val.l == 0x00000010)
-                                                                       iptr->sx.val.i = 4;
-                                                               else if (iptr->sx.val.l == 0x00000020)
-                                                                       iptr->sx.val.i = 5;
-                                                               else if (iptr->sx.val.l == 0x00000040)
-                                                                       iptr->sx.val.i = 6;
-                                                               else if (iptr->sx.val.l == 0x00000080)
-                                                                       iptr->sx.val.i = 7;
-                                                               else if (iptr->sx.val.l == 0x00000100)
-                                                                       iptr->sx.val.i = 8;
-                                                               else if (iptr->sx.val.l == 0x00000200)
-                                                                       iptr->sx.val.i = 9;
-                                                               else if (iptr->sx.val.l == 0x00000400)
-                                                                       iptr->sx.val.i = 10;
-                                                               else if (iptr->sx.val.l == 0x00000800)
-                                                                       iptr->sx.val.i = 11;
-                                                               else if (iptr->sx.val.l == 0x00001000)
-                                                                       iptr->sx.val.i = 12;
-                                                               else if (iptr->sx.val.l == 0x00002000)
-                                                                       iptr->sx.val.i = 13;
-                                                               else if (iptr->sx.val.l == 0x00004000)
-                                                                       iptr->sx.val.i = 14;
-                                                               else if (iptr->sx.val.l == 0x00008000)
-                                                                       iptr->sx.val.i = 15;
-                                                               else if (iptr->sx.val.l == 0x00010000)
-                                                                       iptr->sx.val.i = 16;
-                                                               else if (iptr->sx.val.l == 0x00020000)
-                                                                       iptr->sx.val.i = 17;
-                                                               else if (iptr->sx.val.l == 0x00040000)
-                                                                       iptr->sx.val.i = 18;
-                                                               else if (iptr->sx.val.l == 0x00080000)
-                                                                       iptr->sx.val.i = 19;
-                                                               else if (iptr->sx.val.l == 0x00100000)
-                                                                       iptr->sx.val.i = 20;
-                                                               else if (iptr->sx.val.l == 0x00200000)
-                                                                       iptr->sx.val.i = 21;
-                                                               else if (iptr->sx.val.l == 0x00400000)
-                                                                       iptr->sx.val.i = 22;
-                                                               else if (iptr->sx.val.l == 0x00800000)
-                                                                       iptr->sx.val.i = 23;
-                                                               else if (iptr->sx.val.l == 0x01000000)
-                                                                       iptr->sx.val.i = 24;
-                                                               else if (iptr->sx.val.l == 0x02000000)
-                                                                       iptr->sx.val.i = 25;
-                                                               else if (iptr->sx.val.l == 0x04000000)
-                                                                       iptr->sx.val.i = 26;
-                                                               else if (iptr->sx.val.l == 0x08000000)
-                                                                       iptr->sx.val.i = 27;
-                                                               else if (iptr->sx.val.l == 0x10000000)
-                                                                       iptr->sx.val.i = 28;
-                                                               else if (iptr->sx.val.l == 0x20000000)
-                                                                       iptr->sx.val.i = 29;
-                                                               else if (iptr->sx.val.l == 0x40000000)
-                                                                       iptr->sx.val.i = 30;
-                                                               else if (iptr->sx.val.l == 0x80000000)
-                                                                       iptr->sx.val.i = 31;
-                                                               else {
-                                                                       goto normal_LCONST;
-                                                               }
-                                                               iptr->opc = ICMD_LMULPOW2;
-                                                               goto icmd_lconst_tail;
-# endif /* SUPPORT_LONG_SHIFT */
-#endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
-#if SUPPORT_LONG_DIV_POW2
-                                                       case ICMD_LDIV:
-                                                               if (iptr->sx.val.l == 0x00000002)
-                                                                       iptr->sx.val.i = 1;
-                                                               else if (iptr->sx.val.l == 0x00000004)
-                                                                       iptr->sx.val.i = 2;
-                                                               else if (iptr->sx.val.l == 0x00000008)
-                                                                       iptr->sx.val.i = 3;
-                                                               else if (iptr->sx.val.l == 0x00000010)
-                                                                       iptr->sx.val.i = 4;
-                                                               else if (iptr->sx.val.l == 0x00000020)
-                                                                       iptr->sx.val.i = 5;
-                                                               else if (iptr->sx.val.l == 0x00000040)
-                                                                       iptr->sx.val.i = 6;
-                                                               else if (iptr->sx.val.l == 0x00000080)
-                                                                       iptr->sx.val.i = 7;
-                                                               else if (iptr->sx.val.l == 0x00000100)
-                                                                       iptr->sx.val.i = 8;
-                                                               else if (iptr->sx.val.l == 0x00000200)
-                                                                       iptr->sx.val.i = 9;
-                                                               else if (iptr->sx.val.l == 0x00000400)
-                                                                       iptr->sx.val.i = 10;
-                                                               else if (iptr->sx.val.l == 0x00000800)
-                                                                       iptr->sx.val.i = 11;
-                                                               else if (iptr->sx.val.l == 0x00001000)
-                                                                       iptr->sx.val.i = 12;
-                                                               else if (iptr->sx.val.l == 0x00002000)
-                                                                       iptr->sx.val.i = 13;
-                                                               else if (iptr->sx.val.l == 0x00004000)
-                                                                       iptr->sx.val.i = 14;
-                                                               else if (iptr->sx.val.l == 0x00008000)
-                                                                       iptr->sx.val.i = 15;
-                                                               else if (iptr->sx.val.l == 0x00010000)
-                                                                       iptr->sx.val.i = 16;
-                                                               else if (iptr->sx.val.l == 0x00020000)
-                                                                       iptr->sx.val.i = 17;
-                                                               else if (iptr->sx.val.l == 0x00040000)
-                                                                       iptr->sx.val.i = 18;
-                                                               else if (iptr->sx.val.l == 0x00080000)
-                                                                       iptr->sx.val.i = 19;
-                                                               else if (iptr->sx.val.l == 0x00100000)
-                                                                       iptr->sx.val.i = 20;
-                                                               else if (iptr->sx.val.l == 0x00200000)
-                                                                       iptr->sx.val.i = 21;
-                                                               else if (iptr->sx.val.l == 0x00400000)
-                                                                       iptr->sx.val.i = 22;
-                                                               else if (iptr->sx.val.l == 0x00800000)
-                                                                       iptr->sx.val.i = 23;
-                                                               else if (iptr->sx.val.l == 0x01000000)
-                                                                       iptr->sx.val.i = 24;
-                                                               else if (iptr->sx.val.l == 0x02000000)
-                                                                       iptr->sx.val.i = 25;
-                                                               else if (iptr->sx.val.l == 0x04000000)
-                                                                       iptr->sx.val.i = 26;
-                                                               else if (iptr->sx.val.l == 0x08000000)
-                                                                       iptr->sx.val.i = 27;
-                                                               else if (iptr->sx.val.l == 0x10000000)
-                                                                       iptr->sx.val.i = 28;
-                                                               else if (iptr->sx.val.l == 0x20000000)
-                                                                       iptr->sx.val.i = 29;
-                                                               else if (iptr->sx.val.l == 0x40000000)
-                                                                       iptr->sx.val.i = 30;
-                                                               else if (iptr->sx.val.l == 0x80000000)
-                                                                       iptr->sx.val.i = 31;
-                                                               else {
-                                                                       goto normal_LCONST;
-                                                               }
-                                                               iptr->opc = ICMD_LDIVPOW2;
-                                                               goto icmd_lconst_tail;
-#endif /* SUPPORT_LONG_DIV_POW2 */
-
-#if SUPPORT_LONG_REM_POW2
-                                                       case ICMD_LREM:
-                                                               if ((iptr->sx.val.l == 0x00000002) ||
-                                                                       (iptr->sx.val.l == 0x00000004) ||
-                                                                       (iptr->sx.val.l == 0x00000008) ||
-                                                                       (iptr->sx.val.l == 0x00000010) ||
-                                                                       (iptr->sx.val.l == 0x00000020) ||
-                                                                       (iptr->sx.val.l == 0x00000040) ||
-                                                                       (iptr->sx.val.l == 0x00000080) ||
-                                                                       (iptr->sx.val.l == 0x00000100) ||
-                                                                       (iptr->sx.val.l == 0x00000200) ||
-                                                                       (iptr->sx.val.l == 0x00000400) ||
-                                                                       (iptr->sx.val.l == 0x00000800) ||
-                                                                       (iptr->sx.val.l == 0x00001000) ||
-                                                                       (iptr->sx.val.l == 0x00002000) ||
-                                                                       (iptr->sx.val.l == 0x00004000) ||
-                                                                       (iptr->sx.val.l == 0x00008000) ||
-                                                                       (iptr->sx.val.l == 0x00010000) ||
-                                                                       (iptr->sx.val.l == 0x00020000) ||
-                                                                       (iptr->sx.val.l == 0x00040000) ||
-                                                                       (iptr->sx.val.l == 0x00080000) ||
-                                                                       (iptr->sx.val.l == 0x00100000) ||
-                                                                       (iptr->sx.val.l == 0x00200000) ||
-                                                                       (iptr->sx.val.l == 0x00400000) ||
-                                                                       (iptr->sx.val.l == 0x00800000) ||
-                                                                       (iptr->sx.val.l == 0x01000000) ||
-                                                                       (iptr->sx.val.l == 0x02000000) ||
-                                                                       (iptr->sx.val.l == 0x04000000) ||
-                                                                       (iptr->sx.val.l == 0x08000000) ||
-                                                                       (iptr->sx.val.l == 0x10000000) ||
-                                                                       (iptr->sx.val.l == 0x20000000) ||
-                                                                       (iptr->sx.val.l == 0x40000000) ||
-                                                                       (iptr->sx.val.l == 0x80000000))
-                                                               {
-                                                                       iptr->opc = ICMD_LREMPOW2;
-                                                                       iptr->sx.val.l -= 1;
-                                                                       goto icmd_lconst_tail;
-                                                               }
-                                                               goto normal_LCONST;
-#endif /* SUPPORT_LONG_REM_POW2 */
-
-#if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
-
-                                                       case ICMD_LAND:
-                                                               iptr->opc = ICMD_LANDCONST;
-                                                               goto icmd_lconst_tail;
-
-                                                       case ICMD_LOR:
-                                                               iptr->opc = ICMD_LORCONST;
-                                                               goto icmd_lconst_tail;
-
-                                                       case ICMD_LXOR:
-                                                               iptr->opc = ICMD_LXORCONST;
-                                                               goto icmd_lconst_tail;
-#endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
-
-#if SUPPORT_LONG_CMP_CONST
-                                                       case ICMD_LCMP:
-                                                               if ((len <= 1) || (iptr[2].sx.val.i != 0))
-                                                                       goto normal_LCONST;
-
-                                                               /* switch on the instruction after LCONST - LCMP */
-
-                                                               switch (iptr[2].opc) {
-                                                                       case ICMD_IFEQ:
-                                                                               iptr->opc = ICMD_IF_LEQ;
-                                                                               /* FALLTHROUGH */
-
-                                                                       icmd_lconst_lcmp_tail:
-                                                                               /* convert LCONST, LCMP, IFXX to IF_LXX */
-                                                                               iptr->dst.insindex = iptr[2].dst.insindex;
-                                                                               iptr[1].opc = ICMD_NOP;
-                                                                               iptr[2].opc = ICMD_NOP;
-
-                                                                               NEW_OP1_BRANCH(TYPE_LNG);
-                                                                               BRANCH(tbptr, copy);
-                                                                               COUNT(count_pcmd_bra);
-                                                                               COUNT(count_pcmd_op);
-                                                                               break;
-
-                                                                       case ICMD_IFNE:
-                                                                               iptr->opc = ICMD_IF_LNE;
-                                                                               goto icmd_lconst_lcmp_tail;
-
-                                                                       case ICMD_IFLT:
-                                                                               iptr->opc = ICMD_IF_LLT;
-                                                                               goto icmd_lconst_lcmp_tail;
-
-                                                                       case ICMD_IFGT:
-                                                                               iptr->opc = ICMD_IF_LGT;
-                                                                               goto icmd_lconst_lcmp_tail;
-
-                                                                       case ICMD_IFLE:
-                                                                               iptr->opc = ICMD_IF_LLE;
-                                                                               goto icmd_lconst_lcmp_tail;
-
-                                                                       case ICMD_IFGE:
-                                                                               iptr->opc = ICMD_IF_LGE;
-                                                                               goto icmd_lconst_lcmp_tail;
-
-                                                                       default:
-                                                                               goto normal_LCONST;
-                                                               } /* end switch on opcode after LCONST - LCMP */
-                                                               break;
-#endif /* SUPPORT_LONG_CMP_CONST */
-
-#if SUPPORT_CONST_STORE
-                                                       case ICMD_LASTORE:
-                                                               IF_INTRP( goto normal_LCONST; )
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                               if (iptr->sx.val.l != 0)
-                                                                       goto normal_LCONST;
-# endif
-#if SIZEOF_VOID_P == 4
-                                                               /* the constant must fit into a ptrint */
-                                                               if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
-                                                                       goto normal_LCONST;
-#endif
-                                                               /* move the constant to s3 */
-                                                               iptr->sx.s23.s3.constval = iptr->sx.val.l;
-
-                                                               iptr->opc = ICMD_LASTORECONST;
-                                                               NEW_OP2_0(TYPE_ADR, TYPE_INT);
-
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               COUNT(count_pcmd_op);
-                                                               break;
-
-                                                       case ICMD_PUTSTATIC:
-                                                       case ICMD_PUTFIELD:
-                                                               IF_INTRP( goto normal_LCONST; )
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                               if (iptr->sx.val.l != 0)
-                                                                       goto normal_LCONST;
-# endif
-#if SIZEOF_VOID_P == 4
-                                                               /* the constant must fit into a ptrint */
-                                                               if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
-                                                                       goto normal_LCONST;
-#endif
-                                                               /* XXX check field type? */
-
-                                                               /* copy the constant to s2 */
-                                                               /* XXX constval -> fieldconstval? */
-                                                               iptr->sx.s23.s2.constval = iptr->sx.val.l;
 
-                                                               goto putconst_tail;
-
-#endif /* SUPPORT_CONST_STORE */
-
-                                                       default:
-                                                               goto normal_LCONST;
-                                               } /* end switch opcode after LCONST */
+/* stack_create_invars_from_outvars ********************************************
 
-                                               /* if we get here, the LCONST has been optimized */
-                                               break;
+   Create the invars for the given basic block. Also make a copy of the locals.
+   Types are propagated from the outvars of the current block.
 
-normal_LCONST:
-                                               /* the normal case of an unoptimized LCONST */
-                                               NEW_OP0_1(TYPE_LNG);
-                                               break;
+   IN:
+      sd...........stack analysis data
+         b............block to create the invars for
 
-       /************************ END OF LCONST OPTIMIZATIONS *********************/
+*******************************************************************************/
 
-                                       case ICMD_FCONST:
-                                               COUNT(count_pcmd_load);
-                                               NEW_OP0_1(TYPE_FLT);
-                                               break;
+static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
+{
+       int i;
+       int n;
+       varinfo *sv, *dv;
 
-                                       case ICMD_DCONST:
-                                               COUNT(count_pcmd_load);
-                                               NEW_OP0_1(TYPE_DBL);
-                                               break;
+       n = sd->bptr->outdepth;
+       assert(sd->vartop + n <= sd->varcount);
 
-       /************************** ACONST OPTIMIZATIONS **************************/
+       b->indepth = n;
+       b->invars = DMNEW(s4, n);
 
-                                       case ICMD_ACONST:
-                                               COUNT(count_pcmd_load);
-#if SUPPORT_CONST_STORE
-                                               IF_INTRP( goto normal_ACONST; )
+       if (n) {
+               dv = sd->var + sd->vartop;
 
-                                               /* We can only optimize if the ACONST is resolved
-                                                * and there is an instruction after it. */
+               /* allocate the invars */
 
-                                               if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
-                                                       goto normal_ACONST;
+               for (i=0; i<n; ++i, ++dv) {
+                       sv = sd->var + sd->bptr->outvars[i];
+                       b->invars[i] = sd->vartop++;
+                       dv->type = sv->type;
+                       dv->flags = INOUT;
+                       dv->vv = sv->vv;
+               }
+       }
 
-                                               switch (iptr[1].opc) {
-                                                       case ICMD_AASTORE:
-                                                               /* We can only optimize for NULL values
-                                                                * here because otherwise a checkcast is
-                                                                * required. */
-                                                               if (iptr->sx.val.anyptr != NULL)
-                                                                       goto normal_ACONST;
+       /* copy the current state of the local variables */
+       /* (one extra local is needed by the verifier)   */
 
-                                                               /* copy the constant (NULL) to s3 */
-                                                               iptr->sx.s23.s3.constval = 0;
-                                                               iptr->opc = ICMD_AASTORECONST;
-                                                               NEW_OP2_0(TYPE_ADR, TYPE_INT);
+       dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
+       b->inlocals = dv;
+       for (i=0; i<sd->localcount; ++i)
+               *dv++ = sd->var[i];
+}
 
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               COUNT(count_pcmd_op);
-                                                               break;
 
-                                                       case ICMD_PUTSTATIC:
-                                                       case ICMD_PUTFIELD:
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                               if (iptr->sx.val.anyptr != NULL)
-                                                                       goto normal_ACONST;
-# endif
-                                                               /* XXX check field type? */
-                                                               /* copy the constant to s2 */
-                                                               /* XXX constval -> fieldconstval? */
-                                                               iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
+/* stack_check_invars **********************************************************
 
-                                                               goto putconst_tail;
+   Check the current stack against the invars of the given basic block.
+   Depth and types must match.
 
-                                                       default:
-                                                               goto normal_ACONST;
-                                               }
+   IN:
+      sd...........stack analysis data
+         b............block which invars to check against
+         curstack.....current stack top
+         stackdepth...current stack depth
 
-                                               /* if we get here the ACONST has been optimized */
-                                               break;
+   RETURN VALUE:
+      the destinaton block
+         NULL.........a VerifyError has been thrown
 
-normal_ACONST:
-#endif /* SUPPORT_CONST_STORE */
-                                               NEW_OP0_1(TYPE_ADR);
-                                               break;
+*******************************************************************************/
 
+static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
+                                                                          stackptr curstack, int stackdepth)
+{
+       int i;
+       stackptr sp;
+       basicblock *orig;
+       bool separable;
 
-                                               /* pop 0 push 1 load */
+#if defined(STACK_VERBOSE)
+       printf("stack_check_invars(L%03d)\n", b->nr);
+#endif
 
-                                       case ICMD_ILOAD:
-                                       case ICMD_LLOAD:
-                                       case ICMD_FLOAD:
-                                       case ICMD_DLOAD:
-                                       case ICMD_ALOAD:
-                                               COUNT(count_load_instruction);
-                                               i = opcode - ICMD_ILOAD;
-                                               IF_NO_INTRP( rd->locals[iptr->s1.localindex][i].type = i; )
-                                               NEW_LOAD(i, iptr->s1.localindex);
-                                               break;
+       /* find original of b */
+       if (b->original)
+               b = b->original;
+       orig = b;
 
-                                               /* pop 2 push 1 */
+#if defined(STACK_VERBOSE)
+       printf("original is L%03d\n", orig->nr);
+#endif
 
-                                       case ICMD_LALOAD:
-                                       case ICMD_FALOAD:
-                                       case ICMD_DALOAD:
-                                       case ICMD_AALOAD:
-                                               COUNT(count_check_null);
-                                               COUNT(count_check_bound);
-                                               COUNT(count_pcmd_mem);
-                                               NEW_OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
-                                               break;
+       i = orig->indepth;
 
-                                       case ICMD_IALOAD:
-                                       case ICMD_BALOAD:
-                                       case ICMD_CALOAD:
-                                       case ICMD_SALOAD:
-                                               COUNT(count_check_null);
-                                               COUNT(count_check_bound);
-                                               COUNT(count_pcmd_mem);
-                                               NEW_OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
-                                               break;
+       if (i != stackdepth) {
+               exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
+               return NULL;
+       }
 
-                                               /* pop 0 push 0 iinc */
+       do {
+               separable = false;
 
-                                       case ICMD_IINC:
-                                               STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
+#if defined(STACK_VERBOSE)
+               printf("checking against ");
+               stack_verbose_show_block(sd, b); printf("\n");
+#endif
 
-                                               last_store[5 * iptr->s1.localindex + TYPE_INT] = bptr->icount - len - 1;
+               sp = curstack;
+               for (i = orig->indepth; i--; sp = sp->prev) {
+                       if (sd->var[b->invars[i]].type != sp->type) {
+                               exceptions_throw_verifyerror_for_stack(sd->m, 
+                                               sd->var[b->invars[i]].type);
+                               return NULL;
+                       }
 
-                                               copy = curstack;
-                                               i = stackdepth - 1;
-                                               while (copy) {
-                                                       if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == iptr->s1.localindex))
-                                                       {
-                                                               copy->varkind = TEMPVAR;
-                                                               copy->varnum = i;
-                                                       }
-                                                       i--;
-                                                       copy = copy->prev;
-                                               }
+                       if (sp->type == TYPE_RET) {
+                               if (sd->var[b->invars[i]].vv.retaddr != sd->var[sp->varnum].vv.retaddr) {
+                                       separable = true;
+                                       break;
+                               }
+                       }
+               }
 
-                                               iptr->dst.localindex = iptr->s1.localindex;
+               if (b->inlocals) {
+                       for (i=0; i<sd->localcount; ++i) {
+                               if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
+                                       if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
+                                               separable = true;
                                                break;
+                                       }
+                               }
+                       }
+               }
 
-                                               /* pop 1 push 0 store */
-
-                                       case ICMD_ISTORE:
-                                       case ICMD_LSTORE:
-                                       case ICMD_FSTORE:
-                                       case ICMD_DSTORE:
-                                       case ICMD_ASTORE:
-                                               REQUIRE_1;
-
-                                               i = opcode - ICMD_ISTORE; /* type */
-                                               IF_NO_INTRP( rd->locals[iptr->dst.localindex][i].type = i; )
-
-#if defined(ENABLE_STATISTICS)
-                                               if (opt_stat) {
-                                                       count_pcmd_store++;
-                                                       i = new - curstack;
-                                                       if (i >= 20)
-                                                               count_store_length[20]++;
-                                                       else
-                                                               count_store_length[i]++;
-                                                       i = stackdepth - 1;
-                                                       if (i >= 10)
-                                                               count_store_depth[10]++;
-                                                       else
-                                                               count_store_depth[i]++;
-                                               }
+               if (!separable) {
+                       /* XXX mark mixed type variables void */
+                       /* XXX cascading collapse? */
+#if defined(STACK_VERBOSE)
+                       printf("------> using L%03d\n", b->nr);
 #endif
-                                               /* check for conflicts as described in Figure 5.2 */
-                                               copy = curstack->prev;
-                                               i = stackdepth - 2;
-                                               while (copy) {
-                                                       if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == iptr->dst.localindex))
-                                                       {
-                                                               copy->varkind = TEMPVAR;
-                                                               copy->varnum = i;
-                                                       }
-                                                       i--;
-                                                       copy = copy->prev;
-                                               }
-
-                                               if ((curstack->varkind == LOCALVAR)
-                                                       && (curstack->varnum == iptr->dst.localindex))
-                                               {
-                                                       curstack->varkind = TEMPVAR;
-                                                       curstack->varnum = stackdepth-1;
-                                               }
-
-                                               last_store[5 * iptr->dst.localindex + (opcode - ICMD_ISTORE)] = bptr->icount - len - 1;
-
-                                               NEW_STORE(opcode - ICMD_ISTORE, iptr->dst.localindex);
-                                               break;
+                       return b;
+               }
+       } while ((b = b->copied_to) != NULL);
 
-                                       /* pop 3 push 0 */
+       b = stack_clone_block(sd, orig);
+       if (!b)
+               return NULL;
 
-                                       case ICMD_AASTORE:
-                                               COUNT(count_check_null);
-                                               COUNT(count_check_bound);
-                                               COUNT(count_pcmd_mem);
+       stack_create_invars(sd, b, curstack, stackdepth);
+       return b;
+}
 
-                                               bte = builtintable_get_internal(BUILTIN_canstore);
-                                               md = bte->md;
 
-                                               if (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
-                                               /* XXX non-leaf method? */
+/* stack_check_invars_from_outvars *********************************************
 
-                                               /* make all stack variables saved */
+   Check the outvars of the current block against the invars of the given block.
+   Depth and types must match.
 
-                                               copy = curstack;
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
+   IN:
+      sd...........stack analysis data
+         b............block which invars to check against
 
-                                               NEW_OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
-                                               break;
+   RETURN VALUE:
+      the destinaton block
+         NULL.........a VerifyError has been thrown
 
+*******************************************************************************/
 
-                                       case ICMD_LASTORE:
-                                       case ICMD_FASTORE:
-                                       case ICMD_DASTORE:
-                                               COUNT(count_check_null);
-                                               COUNT(count_check_bound);
-                                               COUNT(count_pcmd_mem);
-                                               NEW_OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
-                                               break;
+static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
+{
+       int i;
+       int n;
+       varinfo *sv, *dv;
+       basicblock *orig;
+       bool separable;
 
-                                       case ICMD_IASTORE:
-                                       case ICMD_BASTORE:
-                                       case ICMD_CASTORE:
-                                       case ICMD_SASTORE:
-                                               COUNT(count_check_null);
-                                               COUNT(count_check_bound);
-                                               COUNT(count_pcmd_mem);
-                                               NEW_OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
-                                               break;
+#if defined(STACK_VERBOSE)
+       printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
+#endif
 
-                                               /* pop 1 push 0 */
+       /* find original of b */
+       if (b->original)
+               b = b->original;
+       orig = b;
 
-                                       case ICMD_POP:
-#ifdef ENABLE_VERIFIER
-                                               if (opt_verify) {
-                                                       REQUIRE_1;
-                                                       if (IS_2_WORD_TYPE(curstack->type))
-                                                               goto throw_stack_category_error;
-                                               }
+#if defined(STACK_VERBOSE)
+       printf("original is L%03d\n", orig->nr);
 #endif
-                                               NEW_OP1_0_ANY;
-                                               break;
 
-                                       case ICMD_IRETURN:
-                                       case ICMD_LRETURN:
-                                       case ICMD_FRETURN:
-                                       case ICMD_DRETURN:
-                                       case ICMD_ARETURN:
-                                               IF_JIT( md_return_alloc(jd, curstack); )
-                                               COUNT(count_pcmd_return);
-                                               NEW_OP1_0(opcode - ICMD_IRETURN);
-                                               superblockend = true;
-                                               break;
+       i = orig->indepth;
+       n = sd->bptr->outdepth;
 
-                                       case ICMD_ATHROW:
-                                               COUNT(count_check_null);
-                                               NEW_OP1_0(TYPE_ADR);
-                                               STACKRESET;
-                                               superblockend = true;
-                                               break;
+       if (i != n) {
+               exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
+               return NULL;
+       }
 
-                                       case ICMD_PUTSTATIC:
-                                               COUNT(count_pcmd_mem);
-                                               NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
-                                               NEW_OP1_0(fmiref->parseddesc.fd->type);
-                                               break;
+       do {
+               separable = false;
 
-                                               /* pop 1 push 0 branch */
+#if defined(STACK_VERBOSE)
+               printf("checking against ");
+               stack_verbose_show_block(sd, b); printf("\n");
+#endif
 
-                                       case ICMD_IFNULL:
-                                       case ICMD_IFNONNULL:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP1_BRANCH(TYPE_ADR);
-                                               BRANCH(tbptr, copy);
-                                               break;
+               if (n) {
+                       dv = sd->var + b->invars[0];
 
-                                       case ICMD_IFEQ:
-                                       case ICMD_IFNE:
-                                       case ICMD_IFLT:
-                                       case ICMD_IFGE:
-                                       case ICMD_IFGT:
-                                       case ICMD_IFLE:
-                                               COUNT(count_pcmd_bra);
-                                               /* iptr->sx.val.i is set implicitly in parse by
-                                                  clearing the memory or from IF_ICMPxx
-                                                  optimization. */
+                       for (i=0; i<n; ++i, ++dv) {
+                               sv = sd->var + sd->bptr->outvars[i];
+                               if (sv->type != dv->type) {
+                                       exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
+                                       return NULL;
+                               }
 
-                                               NEW_OP1_BRANCH(TYPE_INT);
-/*                                             iptr->sx.val.i = 0; */
-                                               BRANCH(tbptr, copy);
+                               if (dv->type == TYPE_RET) {
+                                       if (sv->vv.retaddr != dv->vv.retaddr) {
+                                               separable = true;
                                                break;
+                                       }
+                               }
+                       }
+               }
 
-                                               /* pop 0 push 0 branch */
-
-                                       case ICMD_GOTO:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP0_BRANCH;
-                                               BRANCH(tbptr, copy);
-                                               superblockend = true;
+               if (b->inlocals) {
+                       for (i=0; i<sd->localcount; ++i) {
+                               if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
+                                       if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
+                                               separable = true;
                                                break;
+                                       }
+                               }
+                       }
+               }
 
-                                               /* pop 1 push 0 table branch */
+               if (!separable) {
+                       /* XXX mark mixed type variables void */
+                       /* XXX cascading collapse? */
+#if defined(STACK_VERBOSE)
+                       printf("------> using L%03d\n", b->nr);
+#endif
+                       return b;
+               }
+       } while ((b = b->copied_to) != NULL);
 
-                                       case ICMD_TABLESWITCH:
-                                               COUNT(count_pcmd_table);
-                                               NEW_OP1_BRANCH(TYPE_INT);
+       b = stack_clone_block(sd, orig);
+       if (!b)
+               return NULL;
 
-                                               table = iptr->dst.table;
-                                               BRANCH_TARGET(*table, tbptr, copy);
-                                               table++;
+       stack_create_invars_from_outvars(sd, b);
+       return b;
+}
 
-                                               i = iptr->sx.s23.s3.tablehigh
-                                                 - iptr->sx.s23.s2.tablelow + 1;
 
-                                               while (--i >= 0) {
-                                                       BRANCH_TARGET(*table, tbptr, copy);
-                                                       table++;
-                                               }
-                                               superblockend = true;
-                                               break;
+/* stack_create_instack ********************************************************
 
-                                               /* pop 1 push 0 table branch */
+   Create the instack of the current basic block.
 
-                                       case ICMD_LOOKUPSWITCH:
-                                               COUNT(count_pcmd_table);
-                                               NEW_OP1_BRANCH(TYPE_INT);
+   IN:
+      sd...........stack analysis data
 
-                                               BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
+   RETURN VALUE:
+      the current stack top at the start of the basic block.
 
-                                               lookup = iptr->dst.lookup;
+*******************************************************************************/
 
-                                               i = iptr->sx.s23.s2.lookupcount;
+static stackptr stack_create_instack(stackdata_t *sd)
+{
+    stackptr sp;
+       int depth;
+       int index;
+
+       if ((depth = sd->bptr->indepth) == 0)
+               return NULL;
+
+    sp = (sd->new += depth);
+
+       while (depth--) {
+               sp--;
+               index = sd->bptr->invars[depth];
+               sp->varnum = index;
+               sp->type = sd->var[index].type;
+               sp->prev = sp - 1;
+               sp->creator = NULL;
+               sp->flags = 0;
+               sp->varkind = STACKVAR;
+       }
+       sp->prev = NULL;
 
-                                               while (--i >= 0) {
-                                                       BRANCH_TARGET(lookup->target, tbptr, copy);
-                                                       lookup++;
-                                               }
-                                               superblockend = true;
-                                               break;
+       /* return the top of the created stack */
+       return sd->new - 1;
+}
 
-                                       case ICMD_MONITORENTER:
-                                       case ICMD_MONITOREXIT:
-                                               COUNT(count_check_null);
-                                               NEW_OP1_0(TYPE_ADR);
-                                               break;
 
-                                               /* pop 2 push 0 branch */
+/* stack_mark_reached **********************************************************
 
-                                       case ICMD_IF_ICMPEQ:
-                                       case ICMD_IF_ICMPNE:
-                                       case ICMD_IF_ICMPLT:
-                                       case ICMD_IF_ICMPGE:
-                                       case ICMD_IF_ICMPGT:
-                                       case ICMD_IF_ICMPLE:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP2_BRANCH(TYPE_INT, TYPE_INT);
-                                               BRANCH(tbptr, copy);
-                                               break;
+   Mark the given block reached and propagate the current stack and locals to
+   it. This function specializes the target block, if necessary, and returns
+   a pointer to the specialized target.
 
-                                       case ICMD_IF_ACMPEQ:
-                                       case ICMD_IF_ACMPNE:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP2_BRANCH(TYPE_ADR, TYPE_ADR);
-                                               BRANCH(tbptr, copy);
-                                               break;
+   IN:
+      sd...........stack analysis data
+         b............the block to reach
+         curstack.....the current stack top
+         stackdepth...the current stack depth
 
-                                               /* pop 2 push 0 */
+   RETURN VALUE:
+      a pointer to (a specialized version of) the target
+         NULL.........a VerifyError has been thrown
 
-                                       case ICMD_PUTFIELD:
-                                               COUNT(count_check_null);
-                                               COUNT(count_pcmd_mem);
-                                               NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
-                                               NEW_OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
-                                               break;
+*******************************************************************************/
 
-                                       case ICMD_POP2:
-                                               REQUIRE_1;
-                                               if (!IS_2_WORD_TYPE(curstack->type)) {
-                                                       /* ..., cat1 */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               REQUIRE_2;
-                                                               if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
-                                                       }
+static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth) 
+{
+#if defined(STACK_VERBOSE)
+       printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
 #endif
-                                                       NEW_OP2_0_ANY_ANY; /* pop two slots */
-                                               }
-                                               else {
-                                                       iptr->opc = ICMD_POP;
-                                                       NEW_OP1_0_ANY; /* pop one (two-word) slot */
-                                               }
-                                               break;
+       /* mark targets of backward branches */
+       if (b <= sd->bptr)
+               b->bitflags |= BBFLAG_REPLACEMENT;
 
-                                               /* pop 0 push 1 dup */
+       if (b->flags < BBREACHED) {
+               /* b is reached for the first time. Create its invars. */
 
-                                       case ICMD_DUP:
-#ifdef ENABLE_VERIFIER
-                                               if (opt_verify) {
-                                                       REQUIRE_1;
-                                                       if (IS_2_WORD_TYPE(curstack->type))
-                                                               goto throw_stack_category_error;
-                                               }
+#if defined(STACK_VERBOSE)
+               printf("reached L%03d for the first time\n", b->nr);
 #endif
-                                               last_dupx = bptr->icount - len - 1;
-                                               COUNT(count_dup_instruction);
 
-icmd_DUP:
-                                               USE_S1_ANY; /* XXX live through */
-                                               DUP_SLOT(iptr->s1.var);
-                                               iptr->dst.var = curstack;
-                                               stackdepth++;
-                                               break;
+               stack_create_invars(sd, b, curstack, stackdepth);
 
-                                       case ICMD_DUP2:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_1;
-                                               if (IS_2_WORD_TYPE(curstack->type)) {
-                                                       /* ..., cat2 */
-                                                       iptr->opc = ICMD_DUP;
-                                                       goto icmd_DUP;
-                                               }
-                                               else {
-                                                       REQUIRE_2;
-                                                       /* ..., ????, cat1 */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
-                                                       }
-#endif
-                                                       iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
-                                                       iptr->dst.dupslots[0] = curstack->prev; /* XXX live through */
-                                                       iptr->dst.dupslots[1] = curstack;       /* XXX live through */
-
-                                                       DUP_SLOT(iptr->dst.dupslots[0]);
-                                                       iptr->dst.dupslots[2+0] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[1]);
-                                                       iptr->dst.dupslots[2+1] = curstack;
-                                                       stackdepth += 2;
-                                               }
-                                               break;
+               b->flags = BBREACHED;
 
-                                               /* pop 2 push 3 dup */
+               return b;
+       } 
+       else {
+               /* b has been reached before. Check that its invars match. */
 
-                                       case ICMD_DUP_X1:
-#ifdef ENABLE_VERIFIER
-                                               if (opt_verify) {
-                                                       REQUIRE_2;
-                                                       if (IS_2_WORD_TYPE(curstack->type) ||
-                                                               IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
-                                               }
-#endif
-                                               last_dupx = bptr->icount - len - 1;
+               return stack_check_invars(sd, b, curstack, stackdepth);
+       }
+}
 
-icmd_DUP_X1:
-                                               iptr->dst.dupslots = DMNEW(stackptr, 2 + 3);
-                                               iptr->dst.dupslots[0] = curstack->prev;
-                                               iptr->dst.dupslots[1] = curstack;
-                                               POPANY; POPANY;
 
-                                               DUP_SLOT(iptr->dst.dupslots[1]);
-                                               iptr->dst.dupslots[2+0] = curstack;
-                                               DUP_SLOT(iptr->dst.dupslots[0]);
-                                               iptr->dst.dupslots[2+1] = curstack;
-                                               DUP_SLOT(iptr->dst.dupslots[1]);
-                                               iptr->dst.dupslots[2+2] = curstack;
-                                               stackdepth++;
-                                               break;
+/* stack_mark_reached_from_outvars *********************************************
 
-                                       case ICMD_DUP2_X1:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_2;
-                                               if (IS_2_WORD_TYPE(curstack->type)) {
-                                                       /* ..., ????, cat2 */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
-                                                       }
-#endif
-                                                       iptr->opc = ICMD_DUP_X1;
-                                                       goto icmd_DUP_X1;
-                                               }
-                                               else {
-                                                       /* ..., ????, cat1 */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               REQUIRE_3;
-                                                               if (IS_2_WORD_TYPE(curstack->prev->type)
-                                                                       || IS_2_WORD_TYPE(curstack->prev->prev->type))
-                                                                               goto throw_stack_category_error;
-                                                       }
-#endif
+   Mark the given block reached and propagate the outvars of the current block
+   and the current locals to it. This function specializes the target block, 
+   if necessary, and returns a pointer to the specialized target.
 
-icmd_DUP2_X1:
-                                                       iptr->dst.dupslots = DMNEW(stackptr, 3 + 5);
-                                                       iptr->dst.dupslots[0] = curstack->prev->prev;
-                                                       iptr->dst.dupslots[1] = curstack->prev;
-                                                       iptr->dst.dupslots[2] = curstack;
-                                                       POPANY; POPANY; POPANY;
+   IN:
+      sd...........stack analysis data
+         b............the block to reach
 
-                                                       DUP_SLOT(iptr->dst.dupslots[1]);
-                                                       iptr->dst.dupslots[3+0] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[2]);
-                                                       iptr->dst.dupslots[3+1] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[0]);
-                                                       iptr->dst.dupslots[3+2] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[1]);
-                                                       iptr->dst.dupslots[3+3] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[2]);
-                                                       iptr->dst.dupslots[3+4] = curstack;
-                                                       stackdepth += 2;
-                                               }
-                                               break;
+   RETURN VALUE:
+      a pointer to (a specialized version of) the target
+         NULL.........a VerifyError has been thrown
 
-                                               /* pop 3 push 4 dup */
+*******************************************************************************/
 
-                                       case ICMD_DUP_X2:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_2;
-                                               if (IS_2_WORD_TYPE(curstack->prev->type)) {
-                                                       /* ..., cat2, ???? */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               if (IS_2_WORD_TYPE(curstack->type))
-                                                                       goto throw_stack_category_error;
-                                                       }
-#endif
-                                                       iptr->opc = ICMD_DUP_X1;
-                                                       goto icmd_DUP_X1;
-                                               }
-                                               else {
-                                                       /* ..., cat1, ???? */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               REQUIRE_3;
-                                                               if (IS_2_WORD_TYPE(curstack->type)
-                                                                       || IS_2_WORD_TYPE(curstack->prev->prev->type))
-                                                                                       goto throw_stack_category_error;
-                                                       }
+static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
+{
+#if defined(STACK_VERBOSE)
+       printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
 #endif
-icmd_DUP_X2:
-                                                       iptr->dst.dupslots = DMNEW(stackptr, 3 + 4);
-                                                       iptr->dst.dupslots[0] = curstack->prev->prev;
-                                                       iptr->dst.dupslots[1] = curstack->prev;
-                                                       iptr->dst.dupslots[2] = curstack;
-                                                       POPANY; POPANY; POPANY;
+       /* mark targets of backward branches */
+       if (b <= sd->bptr)
+               b->bitflags |= BBFLAG_REPLACEMENT;
 
-                                                       DUP_SLOT(iptr->dst.dupslots[2]);
-                                                       iptr->dst.dupslots[3+0] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[0]);
-                                                       iptr->dst.dupslots[3+1] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[1]);
-                                                       iptr->dst.dupslots[3+2] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[2]);
-                                                       iptr->dst.dupslots[3+3] = curstack;
-                                                       stackdepth++;
-                                               }
-                                               break;
+       if (b->flags < BBREACHED) {
+               /* b is reached for the first time. Create its invars. */
 
-                                       case ICMD_DUP2_X2:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_2;
-                                               if (IS_2_WORD_TYPE(curstack->type)) {
-                                                       /* ..., ????, cat2 */
-                                                       if (IS_2_WORD_TYPE(curstack->prev->type)) {
-                                                               /* ..., cat2, cat2 */
-                                                               iptr->opc = ICMD_DUP_X1;
-                                                               goto icmd_DUP_X1;
-                                                       }
-                                                       else {
-                                                               /* ..., cat1, cat2 */
-#ifdef ENABLE_VERIFIER
-                                                               if (opt_verify) {
-                                                                       REQUIRE_3;
-                                                                       if (IS_2_WORD_TYPE(curstack->prev->prev->type))
-                                                                                       goto throw_stack_category_error;
-                                                               }
+#if defined(STACK_VERBOSE)
+               printf("reached L%03d for the first time\n", b->nr);
 #endif
-                                                               iptr->opc = ICMD_DUP_X2;
-                                                               goto icmd_DUP_X2;
-                                                       }
-                                               }
 
-                                               REQUIRE_3;
-                                               /* ..., ????, ????, cat1 */
+               stack_create_invars_from_outvars(sd, b);
 
-                                               if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
-                                                       /* ..., cat2, ????, cat1 */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
-                                                       }
-#endif
-                                                       iptr->opc = ICMD_DUP2_X1;
-                                                       goto icmd_DUP2_X1;
-                                               }
-                                               else {
-                                                       /* ..., cat1, ????, cat1 */
-#ifdef ENABLE_VERIFIER
-                                                       if (opt_verify) {
-                                                               REQUIRE_4;
-                                                               if (IS_2_WORD_TYPE(curstack->prev->type)
-                                                                       || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
-                                                                       goto throw_stack_category_error;
-                                                       }
+               b->flags = BBREACHED;
+
+               return b;
+       } 
+       else {
+               /* b has been reached before. Check that its invars match. */
+
+               return stack_check_invars_from_outvars(sd, b);
+       }
+}
+
+
+/* stack_reach_next_block ******************************************************
+
+   Mark the following block reached and propagate the outvars of the current block
+   and the current locals to it. This function specializes the target block, 
+   if necessary, and returns a pointer to the specialized target.
+
+   IN:
+      sd...........stack analysis data
+
+   RETURN VALUE:
+      a pointer to (a specialized version of) the following block
+         NULL.........a VerifyError has been thrown
+
+*******************************************************************************/
+
+static bool stack_reach_next_block(stackdata_t *sd)
+{
+       basicblock *tbptr;
+       instruction *iptr;
+
+       tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
+       tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
+       if (!tbptr)
+               return false;
+
+       if (tbptr != sd->bptr->next) {
+#if defined(STACK_VERBOSE)
+               printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
 #endif
-                                                       iptr->dst.dupslots = DMNEW(stackptr, 4 + 6);
-                                                       iptr->dst.dupslots[0] = curstack->prev->prev->prev;
-                                                       iptr->dst.dupslots[1] = curstack->prev->prev;
-                                                       iptr->dst.dupslots[2] = curstack->prev;
-                                                       iptr->dst.dupslots[3] = curstack;
-                                                       POPANY; POPANY; POPANY; POPANY;
+               iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
+               assert(iptr->opc == ICMD_NOP);
+               iptr->opc = ICMD_GOTO;
+               iptr->dst.block = tbptr;
 
-                                                       DUP_SLOT(iptr->dst.dupslots[2]);
-                                                       iptr->dst.dupslots[4+0] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[3]);
-                                                       iptr->dst.dupslots[4+1] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[0]);
-                                                       iptr->dst.dupslots[4+2] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[1]);
-                                                       iptr->dst.dupslots[4+3] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[2]);
-                                                       iptr->dst.dupslots[4+4] = curstack;
-                                                       DUP_SLOT(iptr->dst.dupslots[3]);
-                                                       iptr->dst.dupslots[4+5] = curstack;
-                                                       stackdepth += 2;
-                                               }
-                                               break;
+               if (tbptr->flags < BBFINISHED)
+                       sd->repeat = true; /* XXX check if we really need to repeat */
+       }
 
-                                               /* pop 2 push 2 swap */
+       return true;
+}
 
-                                       case ICMD_SWAP:
-                                               last_dupx = bptr->icount - len - 1;
-#ifdef ENABLE_VERIFIER
-                                               if (opt_verify) {
-                                                       REQUIRE_2;
-                                                       if (IS_2_WORD_TYPE(curstack->type)
-                                                               || IS_2_WORD_TYPE(curstack->prev->type))
-                                                               goto throw_stack_category_error;
-                                               }
-#endif
-                                               iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
-                                               iptr->dst.dupslots[0] = curstack->prev;
-                                               iptr->dst.dupslots[1] = curstack;
-                                               POPANY; POPANY;
 
-                                               DUP_SLOT(iptr->dst.dupslots[1]);
-                                               iptr->dst.dupslots[2+0] = curstack;
-                                               DUP_SLOT(iptr->dst.dupslots[0]);
-                                               iptr->dst.dupslots[2+1] = curstack;
-                                               break;
+/* stack_reach_handlers ********************************************************
 
-                                               /* pop 2 push 1 */
+   Reach the exception handlers for the current block.
 
-                                       case ICMD_IDIV:
-                                       case ICMD_IREM:
-#if !SUPPORT_DIVISION
-                                               bte = iptr->sx.s23.s3.bte;
-                                               md = bte->md;
+   IN:
+      sd...........stack analysis data
 
-                                               if (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
+   RETURN VALUE:
+     true.........everything ok
+        false........a VerifyError has been thrown
 
-                                               /* make all stack variables saved */
+*******************************************************************************/
 
-                                               copy = curstack;
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
-                                               /* FALLTHROUGH */
+static bool stack_reach_handlers(stackdata_t *sd)
+{
+       s4 i;
+       basicblock *tbptr;
 
-#endif /* !SUPPORT_DIVISION */
+#if defined(STACK_VERBOSE)
+       printf("reaching exception handlers...\n");
+#endif
 
-                                       case ICMD_ISHL:
-                                       case ICMD_ISHR:
-                                       case ICMD_IUSHR:
-                                       case ICMD_IADD:
-                                       case ICMD_ISUB:
-                                       case ICMD_IMUL:
-                                       case ICMD_IAND:
-                                       case ICMD_IOR:
-                                       case ICMD_IXOR:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
-                                               break;
+       for (i=0; sd->handlers[i]; ++i) {
+               tbptr = sd->handlers[i]->handler;
 
-                                       case ICMD_LDIV:
-                                       case ICMD_LREM:
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
-                                               bte = iptr->sx.s23.s3.bte;
-                                               md = bte->md;
+               tbptr->type = BBTYPE_EXH;
+               tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
 
-                                               if (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
-                                               /* XXX non-leaf method? */
+               /* reach (and specialize) the handler block */
 
-                                               /* make all stack variables saved */
+               tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
 
-                                               copy = curstack;
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
-                                               /* FALLTHROUGH */
+               if (tbptr == NULL)
+                       return false;
 
-#endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
+               sd->handlers[i]->handler = tbptr;
+       }
 
-                                       case ICMD_LMUL:
-                                       case ICMD_LADD:
-                                       case ICMD_LSUB:
-#if SUPPORT_LONG_LOGICAL
-                                       case ICMD_LAND:
-                                       case ICMD_LOR:
-                                       case ICMD_LXOR:
-#endif /* SUPPORT_LONG_LOGICAL */
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
-                                               break;
+       return true;
+}
 
-                                       case ICMD_LSHL:
-                                       case ICMD_LSHR:
-                                       case ICMD_LUSHR:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
-                                               break;
 
-                                       case ICMD_FADD:
-                                       case ICMD_FSUB:
-                                       case ICMD_FMUL:
-                                       case ICMD_FDIV:
-                                       case ICMD_FREM:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
-                                               break;
+/* stack_reanalyse_block  ******************************************************
 
-                                       case ICMD_DADD:
-                                       case ICMD_DSUB:
-                                       case ICMD_DMUL:
-                                       case ICMD_DDIV:
-                                       case ICMD_DREM:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
-                                               break;
+   Re-analyse the current block. This is called if either the block itself
+   has already been analysed before, or the current block is a clone of an
+   already analysed block, and this clone is reached for the first time.
+   In the latter case, this function does all that is necessary for fully
+   cloning the block (cloning the instruction list and variables, etc.).
 
-                                       case ICMD_LCMP:
-                                               COUNT(count_pcmd_op);
-#if SUPPORT_LONG_CMP_CONST
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_LCMP;
+   IN:
+      sd...........stack analysis data
 
-                                               switch (iptr[1].opc) {
-                                               case ICMD_IFEQ:
-                                                       iptr->opc = ICMD_IF_LCMPEQ;
-                                               icmd_lcmp_if_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
-                                                       iptr[1].opc = ICMD_NOP;
+   RETURN VALUE:
+     true.........everything ok
+        false........a VerifyError has been thrown
 
-                                                       NEW_OP2_BRANCH(TYPE_LNG, TYPE_LNG);
-                                                       BRANCH(tbptr, copy);
+*******************************************************************************/
 
-                                                       COUNT(count_pcmd_bra);
-                                                       break;
-                                               case ICMD_IFNE:
-                                                       iptr->opc = ICMD_IF_LCMPNE;
-                                                       goto icmd_lcmp_if_tail;
-                                               case ICMD_IFLT:
-                                                       iptr->opc = ICMD_IF_LCMPLT;
-                                                       goto icmd_lcmp_if_tail;
-                                               case ICMD_IFGT:
-                                                       iptr->opc = ICMD_IF_LCMPGT;
-                                                       goto icmd_lcmp_if_tail;
-                                               case ICMD_IFLE:
-                                                       iptr->opc = ICMD_IF_LCMPLE;
-                                                       goto icmd_lcmp_if_tail;
-                                               case ICMD_IFGE:
-                                                       iptr->opc = ICMD_IF_LCMPGE;
-                                                       goto icmd_lcmp_if_tail;
-                                               default:
-                                                       goto normal_LCMP;
-                                               }
-                                               break;
-normal_LCMP:
-#endif /* SUPPORT_LONG_CMP_CONST */
-                                                       NEW_OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
-                                               break;
+#define RELOCATE(index)                                              \
+    do {                                                             \
+        if ((index) >= blockvarstart)                                \
+            (index) += blockvarshift;                                \
+        else if ((index) >= invarstart)                              \
+            (index) += invarshift;                                   \
+    } while (0)
 
-                                               /* XXX why is this deactivated? */
-#if 0
-                                       case ICMD_FCMPL:
-                                               COUNT(count_pcmd_op);
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_FCMPL;
+bool stack_reanalyse_block(stackdata_t *sd)
+{
+       instruction *iptr;
+       basicblock *b;
+       basicblock *orig;
+       s4 len;
+       s4 invarstart;
+       s4 blockvarstart;
+       s4 invarshift;
+       s4 blockvarshift;
+       s4 i, j;
+       s4 *argp;
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       bool superblockend;
+       bool maythrow;
+       bool cloneinstructions;
+       exceptiontable *ex;
 
-                                               switch (iptr[1].opc) {
-                                               case ICMD_IFEQ:
-                                                       iptr->opc = ICMD_IF_FCMPEQ;
-                                               icmd_if_fcmpl_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
-                                                       iptr[1].opc = ICMD_NOP;
+#if defined(STACK_VERBOSE)
+       stack_verbose_block_enter(sd, true);
+#endif
 
-                                                       NEW_OP2_BRANCH(TYPE_FLT, TYPE_FLT);
-                                                       BRANCH(tbptr, copy);
+       b = sd->bptr;
 
-                                                       COUNT(count_pcmd_bra);
-                                                       break;
-                                               case ICMD_IFNE:
-                                                       iptr->opc = ICMD_IF_FCMPNE;
-                                                       goto icmd_if_fcmpl_tail;
-                                               case ICMD_IFLT:
-                                                       iptr->opc = ICMD_IF_FCMPL_LT;
-                                                       goto icmd_if_fcmpl_tail;
-                                               case ICMD_IFGT:
-                                                       iptr->opc = ICMD_IF_FCMPL_GT;
-                                                       goto icmd_if_fcmpl_tail;
-                                               case ICMD_IFLE:
-                                                       iptr->opc = ICMD_IF_FCMPL_LE;
-                                                       goto icmd_if_fcmpl_tail;
-                                               case ICMD_IFGE:
-                                                       iptr->opc = ICMD_IF_FCMPL_GE;
-                                                       goto icmd_if_fcmpl_tail;
-                                               default:
-                                                       goto normal_FCMPL;
-                                               }
-                                               break;
+       if (!b->iinstr) {
+               orig = b->original;
+               assert(orig != NULL);
 
-normal_FCMPL:
-                                               OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
-                                               break;
+               /* clone the instruction list */
 
-                                       case ICMD_FCMPG:
-                                               COUNT(count_pcmd_op);
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_FCMPG;
+               cloneinstructions = true;
 
-                                               switch (iptr[1].opc) {
-                                               case ICMD_IFEQ:
-                                                       iptr->opc = ICMD_IF_FCMPEQ;
-                                               icmd_if_fcmpg_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
-                                                       iptr[1].opc = ICMD_NOP;
+               assert(orig->iinstr);
+               len = orig->icount;
+               iptr = DMNEW(instruction, len + 1);
 
-                                                       NEW_OP2_BRANCH(TYPE_FLT, TYPE_FLT);
-                                                       BRANCH(tbptr, copy);
+               MCOPY(iptr, orig->iinstr, instruction, len);
+               iptr[len].opc = ICMD_NOP;
+               b->iinstr = iptr;
+               b->icount = ++len;
 
-                                                       COUNT(count_pcmd_bra);
-                                                       break;
-                                               case ICMD_IFNE:
-                                                       iptr->opc = ICMD_IF_FCMPNE;
-                                                       goto icmd_if_fcmpg_tail;
-                                               case ICMD_IFLT:
-                                                       iptr->opc = ICMD_IF_FCMPG_LT;
-                                                       goto icmd_if_fcmpg_tail;
-                                               case ICMD_IFGT:
-                                                       iptr->opc = ICMD_IF_FCMPG_GT;
-                                                       goto icmd_if_fcmpg_tail;
-                                               case ICMD_IFLE:
-                                                       iptr->opc = ICMD_IF_FCMPG_LE;
-                                                       goto icmd_if_fcmpg_tail;
-                                               case ICMD_IFGE:
-                                                       iptr->opc = ICMD_IF_FCMPG_GE;
-                                                       goto icmd_if_fcmpg_tail;
-                                               default:
-                                                       goto normal_FCMPG;
-                                               }
-                                               break;
+               /* allocate space for the clone's block variables */
 
-normal_FCMPG:
-                                               NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
-                                               break;
+               stack_grow_variable_array(sd, orig->varcount);
 
-                                       case ICMD_DCMPL:
-                                               COUNT(count_pcmd_op);
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_DCMPL;
+               /* we already have the invars set */
 
-                                               switch (iptr[1].opc) {
-                                               case ICMD_IFEQ:
-                                                       iptr->opc = ICMD_IF_DCMPEQ;
-                                               icmd_if_dcmpl_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
-                                                       iptr[1].opc = ICMD_NOP;
+               assert(b->indepth == orig->indepth);
 
-                                                       NEW_OP2_BRANCH(TYPE_DBL, TYPE_DBL);
-                                                       BRANCH(tbptr, copy);
+               /* calculate relocation shifts for invars and block variables */
 
-                                                       COUNT(count_pcmd_bra);
-                                                       break;
-                                               case ICMD_IFNE:
-                                                       iptr->opc = ICMD_IF_DCMPNE;
-                                                       goto icmd_if_dcmpl_tail;
-                                               case ICMD_IFLT:
-                                                       iptr->opc = ICMD_IF_DCMPL_LT;
-                                                       goto icmd_if_dcmpl_tail;
-                                               case ICMD_IFGT:
-                                                       iptr->opc = ICMD_IF_DCMPL_GT;
-                                                       goto icmd_if_dcmpl_tail;
-                                               case ICMD_IFLE:
-                                                       iptr->opc = ICMD_IF_DCMPL_LE;
-                                                       goto icmd_if_dcmpl_tail;
-                                               case ICMD_IFGE:
-                                                       iptr->opc = ICMD_IF_DCMPL_GE;
-                                                       goto icmd_if_dcmpl_tail;
-                                               default:
-                                                       goto normal_DCMPL;
-                                               }
-                                               break;
+               if (orig->indepth) {
+                       invarstart = orig->invars[0];
+                       invarshift = b->invars[0] - invarstart;
+               }
+               else {
+                       invarstart = INT_MAX;
+                       invarshift = 0;
+               }
+               blockvarstart = orig->varstart;
+               blockvarshift = sd->vartop - blockvarstart;
 
-normal_DCMPL:
-                                               OPTT2_1(TYPE_DBL, TYPE_INT);
-                                               break;
+               /* copy block variables */
 
-                                       case ICMD_DCMPG:
-                                               COUNT(count_pcmd_op);
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_DCMPG;
+               b->varstart = sd->vartop;
+               b->varcount = orig->varcount;
+               sd->vartop += b->varcount;
+               MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
+
+               /* copy outvars */
+
+               b->outdepth = orig->outdepth;
+               b->outvars = DMNEW(s4, orig->outdepth);
+               MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
 
-                                               switch (iptr[1].opc) {
-                                               case ICMD_IFEQ:
-                                                       iptr->opc = ICMD_IF_DCMPEQ;
-                                               icmd_if_dcmpg_tail:
-                                                       iptr->dst.insindex = iptr[1].dst.insindex;
-                                                       iptr[1].opc = ICMD_NOP;
+               /* clone exception handlers */
 
-                                                       NEW_OP2_BRANCH(TYPE_DBL, TYPE_DBL);
-                                                       BRANCH(tbptr, copy);
+               for (i=0; sd->handlers[i]; ++i) {
+                       ex = DNEW(exceptiontable);
+                       ex->handler = sd->handlers[i]->handler;
+                       ex->start = b;
+                       ex->end = b; /* XXX hack, see end of stack_analyse */
+                       ex->catchtype = sd->handlers[i]->catchtype;
+                       ex->down = NULL;
 
-                                                       COUNT(count_pcmd_bra);
-                                                       break;
-                                               case ICMD_IFNE:
-                                                       iptr->opc = ICMD_IF_DCMPNE;
-                                                       goto icmd_if_dcmpg_tail;
-                                               case ICMD_IFLT:
-                                                       iptr->opc = ICMD_IF_DCMPG_LT;
-                                                       goto icmd_if_dcmpg_tail;
-                                               case ICMD_IFGT:
-                                                       iptr->opc = ICMD_IF_DCMPG_GT;
-                                                       goto icmd_if_dcmpg_tail;
-                                               case ICMD_IFLE:
-                                                       iptr->opc = ICMD_IF_DCMPG_LE;
-                                                       goto icmd_if_dcmpg_tail;
-                                               case ICMD_IFGE:
-                                                       iptr->opc = ICMD_IF_DCMPG_GE;
-                                                       goto icmd_if_dcmpg_tail;
-                                               default:
-                                                       goto normal_DCMPG;
-                                               }
-                                               break;
+                       assert(sd->extableend->down == NULL);
+                       sd->extableend->down = ex;
+                       sd->extableend = ex;
+                       sd->jd->cd->exceptiontablelength++;
 
-normal_DCMPG:
-                                               NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
-                                               break;
-#else
-                                       case ICMD_FCMPL:
-                                       case ICMD_FCMPG:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
-                                               break;
+                       sd->handlers[i] = ex;
+               }
+       }
+       else {
+               cloneinstructions = false;
+               invarshift = 0;
+               blockvarshift = 0;
+               invarstart = sd->vartop;
+               blockvarstart = sd->vartop;
+               iptr = b->iinstr;
+       }
 
-                                       case ICMD_DCMPL:
-                                       case ICMD_DCMPG:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
-                                               break;
+       if (b->original) {
+               /* find exception handlers for the cloned block */
+               len = 0;
+               ex = sd->jd->cd->exceptiontable;
+               for (; ex != NULL; ex = ex->down) {
+                       /* XXX the cloned exception handlers have identical */
+                       /* start end end blocks.                            */
+                       if ((ex->start == b) && (ex->end == b)) {
+                               sd->handlers[len++] = ex;
+                       }
+               }
+               sd->handlers[len] = NULL;
+       }
+
+#if defined(STACK_VERBOSE)
+       printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
+       printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
 #endif
 
-                                               /* pop 1 push 1 */
+       /* mark block as finished */
 
-                                       case ICMD_INEG:
-                                       case ICMD_INT2BYTE:
-                                       case ICMD_INT2CHAR:
-                                       case ICMD_INT2SHORT:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_INT, TYPE_INT);
-                                               break;
-                                       case ICMD_LNEG:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_LNG, TYPE_LNG);
-                                               break;
-                                       case ICMD_FNEG:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_FLT, TYPE_FLT);
-                                               break;
-                                       case ICMD_DNEG:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_DBL, TYPE_DBL);
-                                               break;
+       b->flags = BBFINISHED;
 
-                                       case ICMD_I2L:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_INT, TYPE_LNG);
-                                               break;
-                                       case ICMD_I2F:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_INT, TYPE_FLT);
-                                               break;
-                                       case ICMD_I2D:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_INT, TYPE_DBL);
-                                               break;
-                                       case ICMD_L2I:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_LNG, TYPE_INT);
-                                               break;
-                                       case ICMD_L2F:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_LNG, TYPE_FLT);
-                                               break;
-                                       case ICMD_L2D:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_LNG, TYPE_DBL);
-                                               break;
-                                       case ICMD_F2I:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_FLT, TYPE_INT);
-                                               break;
-                                       case ICMD_F2L:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_FLT, TYPE_LNG);
-                                               break;
-                                       case ICMD_F2D:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_FLT, TYPE_DBL);
-                                               break;
-                                       case ICMD_D2I:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_DBL, TYPE_INT);
-                                               break;
-                                       case ICMD_D2L:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_DBL, TYPE_LNG);
-                                               break;
-                                       case ICMD_D2F:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP1_1(TYPE_DBL, TYPE_FLT);
-                                               break;
+       /* initialize locals at the start of this block */
 
-                                       case ICMD_CHECKCAST:
-                                               if (iptr->flags.bits & INS_FLAG_ARRAY) {
-                                                       /* array type cast-check */
+       if (b->inlocals)
+               MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
 
-                                                       bte = builtintable_get_internal(BUILTIN_arraycheckcast);
-                                                       md = bte->md;
+       /* reach exception handlers for this block */
 
-                                                       if (md->memuse > rd->memuse)
-                                                               rd->memuse = md->memuse;
-                                                       if (md->argintreguse > rd->argintreguse)
-                                                               rd->argintreguse = md->argintreguse;
+       if (!stack_reach_handlers(sd))
+               return false;
 
-                                                       /* make all stack variables saved */
+       superblockend = false;
 
-                                                       copy = curstack;
-                                                       while (copy) {
-                                                               copy->flags |= SAVEDVAR;
-                                                               copy = copy->prev;
-                                                       }
-                                               }
-                                               NEW_OP1_1(TYPE_ADR, TYPE_ADR);
-                                               break;
+       for (len = b->icount; len--; iptr++) {
+#if defined(STACK_VERBOSE)
+               show_icmd(sd->jd, iptr, false, SHOW_STACK);
+               printf("\n");
+#endif
 
-                                       case ICMD_INSTANCEOF:
-                                       case ICMD_ARRAYLENGTH:
-                                               NEW_OP1_1(TYPE_ADR, TYPE_INT);
-                                               break;
+               maythrow = false;
 
-                                       case ICMD_NEWARRAY:
-                                       case ICMD_ANEWARRAY:
-                                               NEW_OP1_1(TYPE_INT, TYPE_ADR);
-                                               break;
+               switch (iptr->opc) {
+                       case ICMD_RET:
+                               j = iptr->s1.varindex;
 
-                                       case ICMD_GETFIELD:
-                                               COUNT(count_check_null);
-                                               COUNT(count_pcmd_mem);
-                                               NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
-                                               NEW_OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
-                                               break;
+                               if (sd->var[j].type != TYPE_RET) {
+                                       exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
+                                       return false;
+                               }
 
-                                               /* pop 0 push 1 */
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
+                               superblockend = true;
+                               break;
 
-                                       case ICMD_GETSTATIC:
-                                               COUNT(count_pcmd_mem);
-                                               NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
-                                               NEW_OP0_1(fmiref->parseddesc.fd->type);
-                                               break;
+                       case ICMD_JSR:
+                               iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
+                               superblockend = true;
+                               break;
 
-                                       case ICMD_NEW:
-                                               NEW_OP0_1(TYPE_ADR);
-                                               break;
+                       case ICMD_RETURN:
+                               superblockend = true;
+                               break;
 
-                                       case ICMD_JSR:
-                                               NEW_OP0_1(TYPE_ADR);
+                       case ICMD_CHECKNULL:
+                       case ICMD_PUTSTATICCONST:
+                               maythrow = true;
+                               break;
 
-                                               BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
+                       case ICMD_NOP:
+                       case ICMD_IINC:
+                       case ICMD_INLINE_START:
+                       case ICMD_INLINE_END:
+                       case ICMD_INLINE_GOTO:
+                               break;
 
-                                               tbptr->type = BBTYPE_SBR;
+                       case ICMD_GOTO:
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
+                               superblockend = true;
+                               break;
 
-                                               /* We need to check for overflow right here because
-                                                * the pushed value is poped afterwards */
-                                               NEW_CHECKOVERFLOW;
+                               /* pop 0 push 1 const */
 
-                                               /* calculate stack after return */
-                                               POPANY;
-                                               stackdepth--;
-                                               break;
+                       case ICMD_ACONST:
+                               maythrow = true;
+                       case ICMD_ICONST:
+                       case ICMD_LCONST:
+                       case ICMD_FCONST:
+                       case ICMD_DCONST:
 
-                                       /* pop many push any */
+                               /* pop 0 push 1 load */
 
-                                       case ICMD_BUILTIN:
-#if defined(USEBUILTINTABLE)
-icmd_BUILTIN:
-#endif
-                                               bte = iptr->sx.s23.s3.bte;
-                                               md = bte->md;
-                                               goto _callhandling;
+                       case ICMD_ILOAD:
+                       case ICMD_LLOAD:
+                       case ICMD_FLOAD:
+                       case ICMD_DLOAD:
+                       case ICMD_ALOAD:
+                               RELOCATE(iptr->dst.varindex);
+                               break;
 
-                                       case ICMD_INVOKESTATIC:
-                                       case ICMD_INVOKESPECIAL:
-                                       case ICMD_INVOKEVIRTUAL:
-                                       case ICMD_INVOKEINTERFACE:
-                                               COUNT(count_pcmd_met);
-                                               NEW_INSTRUCTION_GET_METHODDESC(iptr, md);
-                                               /* XXX resurrect this COUNT? */
-/*                          if (lm->flags & ACC_STATIC) */
-/*                              {COUNT(count_check_null);} */
+                               /* pop 2 push 1 */
+
+                       case ICMD_IALOAD:
+                       case ICMD_LALOAD:
+                       case ICMD_FALOAD:
+                       case ICMD_DALOAD:
+                       case ICMD_AALOAD:
+                       case ICMD_BALOAD:
+                       case ICMD_CALOAD:
+                       case ICMD_SALOAD:
+                               RELOCATE(iptr->sx.s23.s2.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               RELOCATE(iptr->dst.varindex);
+                               maythrow = true;
+                               break;
 
-                                       _callhandling:
+                               /* pop 3 push 0 */
+
+                       case ICMD_IASTORE:
+                       case ICMD_LASTORE:
+                       case ICMD_FASTORE:
+                       case ICMD_DASTORE:
+                       case ICMD_AASTORE:
+                       case ICMD_BASTORE:
+                       case ICMD_CASTORE:
+                       case ICMD_SASTORE:
+                               RELOCATE(iptr->sx.s23.s3.varindex);
+                               RELOCATE(iptr->sx.s23.s2.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               maythrow = true;
+                               break;
 
-                                               last_pei = bptr->icount - len - 1;
+                               /* pop 1 push 0 store */
 
-                                               i = md->paramcount;
+                       case ICMD_ISTORE:
+                       case ICMD_LSTORE:
+                       case ICMD_FSTORE:
+                       case ICMD_DSTORE:
+                       case ICMD_ASTORE:
+                               RELOCATE(iptr->s1.varindex);
 
-                                               if (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
-                                               if (md->argfltreguse > rd->argfltreguse)
-                                                       rd->argfltreguse = md->argfltreguse;
+                               j = iptr->dst.varindex;
+                               COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
+                               break;
 
-                                               REQUIRE(i);
+                               /* pop 1 push 0 */
 
-                                               /* XXX optimize for <= 2 args */
-                                               iptr->s1.argcount = i;
-                                               iptr->sx.s23.s2.args = DMNEW(stackptr, i);
+                       case ICMD_ARETURN:
+                       case ICMD_ATHROW:
+                               maythrow = true;
+                       case ICMD_IRETURN:
+                       case ICMD_LRETURN:
+                       case ICMD_FRETURN:
+                       case ICMD_DRETURN:
+                               RELOCATE(iptr->s1.varindex);
+                               superblockend = true;
+                               break;
 
-                                               copy = curstack;
-                                               for (i-- ; i >= 0; i--) {
-                                                       iptr->sx.s23.s2.args[i] = copy;
+                       case ICMD_PUTSTATIC:
+                       case ICMD_PUTFIELDCONST:
+                               maythrow = true;
+                       case ICMD_POP:
+                               RELOCATE(iptr->s1.varindex);
+                               break;
 
-#if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
-                                                       /* If we pass float arguments in integer argument registers, we
-                                                        * are not allowed to precolor them here. Floats have to be moved
-                                                        * to this regs explicitly in codegen().
-                                                        * Only arguments that are passed by stack anyway can be precolored
-                                                        * (michi 2005/07/24) */
-                                                       if (!(copy->flags & SAVEDVAR) &&
-                                                          (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
-#else
-                                                       if (!(copy->flags & SAVEDVAR)) {
-#endif
-                                                               copy->varkind = ARGVAR;
-                                                               copy->varnum = i;
+                               /* pop 1 push 0 branch */
 
-#if defined(ENABLE_INTRP)
-                                                               if (!opt_intrp) {
-#endif
-                                                                       if (md->params[i].inmemory) {
-                                                                               copy->flags = INMEMORY;
-                                                                               copy->regoff = md->params[i].regoff;
-                                                                       }
-                                                                       else {
-                                                                               copy->flags = 0;
-                                                                               if (IS_FLT_DBL_TYPE(copy->type)) {
-#if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
-                                                                                       assert(0); /* XXX is this assert ok? */
-#else
-                                                                                       copy->regoff =
-                                                                                               rd->argfltregs[md->params[i].regoff];
-#endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
-                                                                               }
-                                                                               else {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                                       if (IS_2_WORD_TYPE(copy->type))
-                                                                                               copy->regoff = PACK_REGS(
-                                                                                                       rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
-                                                                                                       rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
-                                                                                       else
-#endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
-                                                                                               copy->regoff =
-                                                                                                       rd->argintregs[md->params[i].regoff];
-                                                                               }
-                                                                       }
-#if defined(ENABLE_INTRP)
-                                                               } /* end if (!opt_intrp) */
-#endif
-                                                       }
-                                                       copy = copy->prev;
-                                               }
+                       case ICMD_IFNULL:
+                       case ICMD_IFNONNULL:
 
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
+                       case ICMD_IFEQ:
+                       case ICMD_IFNE:
+                       case ICMD_IFLT:
+                       case ICMD_IFGE:
+                       case ICMD_IFGT:
+                       case ICMD_IFLE:
 
-                                               i = md->paramcount;
+                       case ICMD_IF_LEQ:
+                       case ICMD_IF_LNE:
+                       case ICMD_IF_LLT:
+                       case ICMD_IF_LGE:
+                       case ICMD_IF_LGT:
+                       case ICMD_IF_LLE:
+                               RELOCATE(iptr->s1.varindex);
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
+                               break;
 
-                                               stackdepth -= i;
-                                               while (--i >= 0) {
-                                                       POPANY;
-                                               }
+                               /* pop 1 push 0 table branch */
 
-                                               if (md->returntype.type != TYPE_VOID) {
-                                                       NEW_DST(md->returntype.type, stackdepth);
-                                                       stackdepth++;
-                                               }
-                                               break;
+                       case ICMD_TABLESWITCH:
+                               i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
 
-                                       case ICMD_INLINE_START:
-                                       case ICMD_INLINE_END:
-                                               CLR_S1;
-                                               CLR_DST;
-                                               break;
+                               if (cloneinstructions) {
+                                       table = DMNEW(branch_target_t, i);
+                                       MCOPY(table, iptr->dst.table, branch_target_t, i);
+                                       iptr->dst.table = table;
+                               }
+                               else {
+                                       table = iptr->dst.table;
+                               }
+
+                               RELOCATE(iptr->s1.varindex);
+                               while (i--) {
+                                       table->block = stack_mark_reached_from_outvars(sd, table->block);
+                                       table++;
+                               }
+                               superblockend = true;
+                               break;
+
+                       case ICMD_LOOKUPSWITCH:
+                               i = iptr->sx.s23.s2.lookupcount;
+                               if (cloneinstructions) {
+                                       lookup = DMNEW(lookup_target_t, i);
+                                       MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
+                                       iptr->dst.lookup = lookup;
+                               }
+                               else {
+                                       lookup = iptr->dst.lookup;
+                               }
+                               RELOCATE(iptr->s1.varindex);
+                               while (i--) {
+                                       lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
+                                       lookup++;
+                               }
+                               iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
+                               superblockend = true;
+                               break;
+
+                       case ICMD_MONITORENTER:
+                       case ICMD_MONITOREXIT:
+                               RELOCATE(iptr->s1.varindex);
+                               maythrow = true;
+                               break;
 
-                                       case ICMD_MULTIANEWARRAY:
-                                               if (rd->argintreguse < 3)
-                                                       rd->argintreguse = 3;
+                               /* pop 2 push 0 branch */
 
-                                               i = iptr->s1.argcount;
+                       case ICMD_IF_ICMPEQ:
+                       case ICMD_IF_ICMPNE:
+                       case ICMD_IF_ICMPLT:
+                       case ICMD_IF_ICMPGE:
+                       case ICMD_IF_ICMPGT:
+                       case ICMD_IF_ICMPLE:
 
-                                               REQUIRE(i);
+                       case ICMD_IF_LCMPEQ:
+                       case ICMD_IF_LCMPNE:
+                       case ICMD_IF_LCMPLT:
+                       case ICMD_IF_LCMPGE:
+                       case ICMD_IF_LCMPGT:
+                       case ICMD_IF_LCMPLE:
 
-                                               iptr->sx.s23.s2.args = DMNEW(stackptr, i);
+                       case ICMD_IF_FCMPEQ:
+                       case ICMD_IF_FCMPNE:
 
-#if defined(SPECIALMEMUSE)
-# if defined(__DARWIN__)
-                                               if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
-                                                       rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
-# else
-                                               if (rd->memuse < (i + LA_WORD_SIZE + 3))
-                                                       rd->memuse = i + LA_WORD_SIZE + 3;
-# endif
-#else
-# if defined(__I386__)
-                                               if (rd->memuse < i + 3)
-                                                       rd->memuse = i + 3; /* n integer args spilled on stack */
-# elif defined(__MIPS__) && SIZEOF_VOID_P == 4
-                                               if (rd->memuse < i + 2)
-                                                       rd->memuse = i + 2; /* 4*4 bytes callee save space */
-# else
-                                               if (rd->memuse < i)
-                                                       rd->memuse = i; /* n integer args spilled on stack */
-# endif /* defined(__I386__) */
-#endif
-                                               copy = curstack;
-                                               while (--i >= 0) {
-                                                       /* check INT type here? Currently typecheck does this. */
-                                                       iptr->sx.s23.s2.args[i] = copy;
-                                                       if (!(copy->flags & SAVEDVAR)) {
-                                                               copy->varkind = ARGVAR;
-                                                               copy->varnum = i + INT_ARG_CNT;
-                                                               copy->flags |= INMEMORY;
-#if defined(SPECIALMEMUSE)
-# if defined(__DARWIN__)
-                                                               copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
-# else
-                                                               copy->regoff = i + LA_WORD_SIZE + 3;
-# endif
-#else
-# if defined(__I386__)
-                                                               copy->regoff = i + 3;
-# elif defined(__MIPS__) && SIZEOF_VOID_P == 4
-                                                               copy->regoff = i + 2;
-# else
-                                                               copy->regoff = i;
-# endif /* defined(__I386__) */
-#endif /* defined(SPECIALMEMUSE) */
-                                                       }
-                                                       copy = copy->prev;
-                                               }
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
+                       case ICMD_IF_FCMPL_LT:
+                       case ICMD_IF_FCMPL_GE:
+                       case ICMD_IF_FCMPL_GT:
+                       case ICMD_IF_FCMPL_LE:
 
-                                               i = iptr->s1.argcount;
-                                               stackdepth -= i;
-                                               while (--i >= 0) {
-                                                       POPANY;
-                                               }
-                                               NEW_DST(TYPE_ADR, stackdepth);
-                                               stackdepth++;
-                                               break;
+                       case ICMD_IF_FCMPG_LT:
+                       case ICMD_IF_FCMPG_GE:
+                       case ICMD_IF_FCMPG_GT:
+                       case ICMD_IF_FCMPG_LE:
 
-                                       default:
-                                               *exceptionptr =
-                                                       new_internalerror("Unknown ICMD %d", opcode);
-                                               return false;
-                                       } /* switch */
+                       case ICMD_IF_DCMPEQ:
+                       case ICMD_IF_DCMPNE:
 
-                                       NEW_CHECKOVERFLOW;
-                                       iptr++;
-                               } /* while instructions */
+                       case ICMD_IF_DCMPL_LT:
+                       case ICMD_IF_DCMPL_GE:
+                       case ICMD_IF_DCMPL_GT:
+                       case ICMD_IF_DCMPL_LE:
 
-                               /* set out-stack of block */
+                       case ICMD_IF_DCMPG_LT:
+                       case ICMD_IF_DCMPG_GE:
+                       case ICMD_IF_DCMPG_GT:
+                       case ICMD_IF_DCMPG_LE:
 
-                               bptr->outstack = curstack;
-                               bptr->outdepth = stackdepth;
+                       case ICMD_IF_ACMPEQ:
+                       case ICMD_IF_ACMPNE:
+                               RELOCATE(iptr->sx.s23.s2.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
+                               break;
 
-                               /* stack slots at basic block end become interfaces */
+                               /* pop 2 push 0 */
+
+                       case ICMD_PUTFIELD:
+                       case ICMD_IASTORECONST:
+                       case ICMD_LASTORECONST:
+                       case ICMD_AASTORECONST:
+                       case ICMD_BASTORECONST:
+                       case ICMD_CASTORECONST:
+                       case ICMD_SASTORECONST:
+                               maythrow = true;
+                       case ICMD_POP2:
+                               RELOCATE(iptr->sx.s23.s2.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               break;
 
-                               i = stackdepth - 1;
-                               for (copy = curstack; copy; i--, copy = copy->prev) {
-                                       if ((copy->varkind == STACKVAR) && (copy->varnum > i))
-                                               copy->varkind = TEMPVAR;
-                                       else {
-                                               copy->varkind = STACKVAR;
-                                               copy->varnum = i;
-                                       }
-                                       IF_NO_INTRP(
-                                                       rd->interfaces[i][copy->type].type = copy->type;
-                                                       rd->interfaces[i][copy->type].flags |= copy->flags;
-                                       );
-                               }
+                               /* pop 0 push 1 copy */
 
-                               /* check if interface slots at basic block begin must be saved */
+                       case ICMD_COPY:
+                       case ICMD_MOVE:
+                               RELOCATE(iptr->dst.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
+                               break;
 
-                               IF_NO_INTRP(
-                                       i = bptr->indepth - 1;
-                                       for (copy = bptr->instack; copy; i--, copy = copy->prev) {
-                                               rd->interfaces[i][copy->type].type = copy->type;
-                                               if (copy->varkind == STACKVAR) {
-                                                       if (copy->flags & SAVEDVAR)
-                                                               rd->interfaces[i][copy->type].flags |= SAVEDVAR;
-                                               }
-                                       }
-                               );
+                               /* pop 2 push 1 */
+
+                       case ICMD_IDIV:
+                       case ICMD_IREM:
+                       case ICMD_LDIV:
+                       case ICMD_LREM:
+                               maythrow = true;
+                       case ICMD_IADD:
+                       case ICMD_ISUB:
+                       case ICMD_IMUL:
+                       case ICMD_ISHL:
+                       case ICMD_ISHR:
+                       case ICMD_IUSHR:
+                       case ICMD_IAND:
+                       case ICMD_IOR:
+                       case ICMD_IXOR:
+                       case ICMD_LADD:
+                       case ICMD_LSUB:
+                       case ICMD_LMUL:
+                       case ICMD_LOR:
+                       case ICMD_LAND:
+                       case ICMD_LXOR:
+                       case ICMD_LSHL:
+                       case ICMD_LSHR:
+                       case ICMD_LUSHR:
+                       case ICMD_FADD:
+                       case ICMD_FSUB:
+                       case ICMD_FMUL:
+                       case ICMD_FDIV:
+                       case ICMD_FREM:
+                       case ICMD_DADD:
+                       case ICMD_DSUB:
+                       case ICMD_DMUL:
+                       case ICMD_DDIV:
+                       case ICMD_DREM:
+                       case ICMD_LCMP:
+                       case ICMD_FCMPL:
+                       case ICMD_FCMPG:
+                       case ICMD_DCMPL:
+                       case ICMD_DCMPG:
+                               RELOCATE(iptr->sx.s23.s2.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               RELOCATE(iptr->dst.varindex);
+                               break;
 
-                       } /* if */
-                       else
-                               superblockend = true;
+                               /* pop 1 push 1 */
+
+                       case ICMD_CHECKCAST:
+                       case ICMD_ARRAYLENGTH:
+                       case ICMD_INSTANCEOF:
+                       case ICMD_NEWARRAY:
+                       case ICMD_ANEWARRAY:
+                               maythrow = true;
+                       case ICMD_GETFIELD:
+                       case ICMD_IADDCONST:
+                       case ICMD_ISUBCONST:
+                       case ICMD_IMULCONST:
+                       case ICMD_IMULPOW2:
+                       case ICMD_IDIVPOW2:
+                       case ICMD_IREMPOW2:
+                       case ICMD_IANDCONST:
+                       case ICMD_IORCONST:
+                       case ICMD_IXORCONST:
+                       case ICMD_ISHLCONST:
+                       case ICMD_ISHRCONST:
+                       case ICMD_IUSHRCONST:
+                       case ICMD_LADDCONST:
+                       case ICMD_LSUBCONST:
+                       case ICMD_LMULCONST:
+                       case ICMD_LMULPOW2:
+                       case ICMD_LDIVPOW2:
+                       case ICMD_LREMPOW2:
+                       case ICMD_LANDCONST:
+                       case ICMD_LORCONST:
+                       case ICMD_LXORCONST:
+                       case ICMD_LSHLCONST:
+                       case ICMD_LSHRCONST:
+                       case ICMD_LUSHRCONST:
+                       case ICMD_INEG:
+                       case ICMD_INT2BYTE:
+                       case ICMD_INT2CHAR:
+                       case ICMD_INT2SHORT:
+                       case ICMD_LNEG:
+                       case ICMD_FNEG:
+                       case ICMD_DNEG:
+                       case ICMD_I2L:
+                       case ICMD_I2F:
+                       case ICMD_I2D:
+                       case ICMD_L2I:
+                       case ICMD_L2F:
+                       case ICMD_L2D:
+                       case ICMD_F2I:
+                       case ICMD_F2L:
+                       case ICMD_F2D:
+                       case ICMD_D2I:
+                       case ICMD_D2L:
+                       case ICMD_D2F:
+                               RELOCATE(iptr->s1.varindex);
+                               RELOCATE(iptr->dst.varindex);
+                               break;
 
-                       bptr++;
-               } /* while blocks */
-       } while (repeat && !deadcode);
+                               /* pop 0 push 1 */
 
-       /* gather statistics *****************************************************/
+                       case ICMD_GETSTATIC:
+                       case ICMD_NEW:
+                               maythrow = true;
+                               RELOCATE(iptr->dst.varindex);
+                               break;
 
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat) {
-               if (jd->new_basicblockcount > count_max_basic_blocks)
-                       count_max_basic_blocks = jd->new_basicblockcount;
-               count_basic_blocks += jd->new_basicblockcount;
-               if (jd->new_instructioncount > count_max_javainstr)
-                       count_max_javainstr = jd->new_instructioncount;
-               count_javainstr += jd->new_instructioncount;
-               if (jd->new_stackcount > count_upper_bound_new_stack)
-                       count_upper_bound_new_stack = jd->new_stackcount;
-               if ((new - jd->new_stack) > count_max_new_stack)
-                       count_max_new_stack = (new - jd->new_stack);
-
-               b_count = jd->new_basicblockcount;
-               bptr = jd->new_basicblocks;
-               while (--b_count >= 0) {
-                       if (bptr->flags > BBREACHED) {
-                               if (bptr->indepth >= 10)
-                                       count_block_stack[10]++;
-                               else
-                                       count_block_stack[bptr->indepth]++;
-                               len = bptr->icount;
-                               if (len < 10)
-                                       count_block_size_distribution[len]++;
-                               else if (len <= 12)
-                                       count_block_size_distribution[10]++;
-                               else if (len <= 14)
-                                       count_block_size_distribution[11]++;
-                               else if (len <= 16)
-                                       count_block_size_distribution[12]++;
-                               else if (len <= 18)
-                                       count_block_size_distribution[13]++;
-                               else if (len <= 20)
-                                       count_block_size_distribution[14]++;
-                               else if (len <= 25)
-                                       count_block_size_distribution[15]++;
-                               else if (len <= 30)
-                                       count_block_size_distribution[16]++;
-                               else
-                                       count_block_size_distribution[17]++;
-                       }
-                       bptr++;
-               }
+                               /* pop many push any */
+
+                       case ICMD_INVOKESTATIC:
+                       case ICMD_INVOKESPECIAL:
+                       case ICMD_INVOKEVIRTUAL:
+                       case ICMD_INVOKEINTERFACE:
+                       case ICMD_BUILTIN:
+                       case ICMD_MULTIANEWARRAY:
+                               i = iptr->s1.argcount;
+                               if (cloneinstructions) {
+                                       argp = DMNEW(s4, i);
+                                       MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
+                                       iptr->sx.s23.s2.args = argp;
+                               }
+                               else {
+                                       argp = iptr->sx.s23.s2.args;
+                               }
 
-               if (iteration_count == 1)
-                       count_analyse_iterations[0]++;
-               else if (iteration_count == 2)
-                       count_analyse_iterations[1]++;
-               else if (iteration_count == 3)
-                       count_analyse_iterations[2]++;
-               else if (iteration_count == 4)
-                       count_analyse_iterations[3]++;
-               else
-                       count_analyse_iterations[4]++;
+                               maythrow = true;
+                               while (--i >= 0) {
+                                       RELOCATE(*argp);
+                                       argp++;
+                               }
+                               RELOCATE(iptr->dst.varindex);
+                               break;
 
-               if (jd->new_basicblockcount <= 5)
-                       count_method_bb_distribution[0]++;
-               else if (jd->new_basicblockcount <= 10)
-                       count_method_bb_distribution[1]++;
-               else if (jd->new_basicblockcount <= 15)
-                       count_method_bb_distribution[2]++;
-               else if (jd->new_basicblockcount <= 20)
-                       count_method_bb_distribution[3]++;
-               else if (jd->new_basicblockcount <= 30)
-                       count_method_bb_distribution[4]++;
-               else if (jd->new_basicblockcount <= 40)
-                       count_method_bb_distribution[5]++;
-               else if (jd->new_basicblockcount <= 50)
-                       count_method_bb_distribution[6]++;
-               else if (jd->new_basicblockcount <= 75)
-                       count_method_bb_distribution[7]++;
-               else
-                       count_method_bb_distribution[8]++;
+                       default:
+                               *exceptionptr =
+                                       new_internalerror("Unknown ICMD %d during stack re-analysis",
+                                                       iptr->opc);
+                               return false;
+               } /* switch */
+
+#if defined(STACK_VERBOSE)
+               show_icmd(sd->jd, iptr, false, SHOW_STACK);
+               printf("\n");
+#endif
        }
-#endif /* defined(ENABLE_STATISTICS) */
 
-       /* everything's ok *******************************************************/
+       /* relocate outvars */
 
-       return true;
+       for (i=0; i<b->outdepth; ++i) {
+               RELOCATE(b->outvars[i]);
+       }
 
-       /* goto labels for throwing verifier exceptions **************************/
+#if defined(STACK_VERBOSE)
+       stack_verbose_block_exit(sd, superblockend);
+#endif
 
-#if defined(ENABLE_VERIFIER)
+       /* propagate to the next block */
 
-throw_stack_underflow:
-       *exceptionptr =
-               new_verifyerror(m, "Unable to pop operand off an empty stack");
-       return false;
+       if (!superblockend)
+               if (!stack_reach_next_block(sd))
+                       return false;
 
-throw_stack_overflow:
-       *exceptionptr = new_verifyerror(m, "Stack size too large");
-       return false;
+       return true;
+}
 
-throw_stack_depth_error:
-       *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
-       return false;
 
-throw_stack_type_error:
-       exceptions_throw_verifyerror_for_stack(m, expectedtype);
-       return false;
+/* stack_analyse ***************************************************************
 
-throw_stack_category_error:
-       *exceptionptr =
-               new_verifyerror(m, "Attempt to split long or double on the stack");
-       return false;
+   Analyse_stack uses the intermediate code created by parse.c to
+   build a model of the JVM operand stack for the current method.
+   
+   The following checks are performed:
+     - check for operand stack underflow (before each instruction)
+     - check for operand stack overflow (after[1] each instruction)
+     - check for matching stack depth at merging points
+     - check for matching basic types[2] at merging points
+     - check basic types for instruction input (except for BUILTIN*
+           opcodes, INVOKE* opcodes and MULTIANEWARRAY)
+   
+   [1]) Checking this after the instruction should be ok. parse.c
+   counts the number of required stack slots in such a way that it is
+   only vital that we don't exceed `maxstack` at basic block
+   boundaries.
+   
+   [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
+   DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
+   types are not discerned.
 
-#endif
-}
+*******************************************************************************/
 
 bool stack_analyse(jitdata *jd)
 {
-       methodinfo   *m;
+       methodinfo   *m;              /* method being analyzed                    */
        codeinfo     *code;
        codegendata  *cd;
        registerdata *rd;
-       int           b_count;
-       int           b_index;
+       stackdata_t   sd;
+#if defined(ENABLE_SSA)
+       lsradata     *ls;
+#endif
+       int           b_index;        /* basic block index                        */
        int           stackdepth;
-       stackptr      curstack;
-       stackptr      new;
+       stackptr      curstack;       /* current stack top                        */
        stackptr      copy;
-       int           opcode, i, j, len, loops;
-       int           superblockend, repeat, deadcode;
-       instruction  *iptr;
-       basicblock   *bptr;
+       int           opcode;         /* opcode of current instruction            */
+       int           i, j;
+       int           javaindex;
+       int           len;            /* # of instructions after the current one  */
+       bool          superblockend;  /* if true, no fallthrough to next block    */
+       bool          deadcode;       /* true if no live code has been reached    */
+       instruction  *iptr;           /* the current instruction                  */
        basicblock   *tbptr;
-       s4           *s4ptr;
-       void        **tptr;
-       s4           *last_store;/* instruction index of last XSTORE */
-                                /* [ local_index * 5 + type ] */
-       s4            last_pei;  /* instruction index of last possible exception */
-                                /* used for conflict resolution for copy        */
-                             /* elimination (XLOAD, IINC, XSTORE) */
-       s4            last_dupx;
+       basicblock   *original;
+       exceptiontable *ex;
+
+       stackptr     *last_store_boundary;
+       stackptr      coalescing_boundary;
+
+       stackptr      src1, src2, src3, src4, dst1, dst2;
+
+       branch_target_t *table;
+       lookup_target_t *lookup;
 #if defined(ENABLE_VERIFIER)
-       int           expectedtype; /* used by CHECK_BASIC_TYPE */
+       int           expectedtype;   /* used by CHECK_BASIC_TYPE                 */
 #endif
-
        builtintable_entry *bte;
        methoddesc         *md;
+       constant_FMIref    *fmiref;
+#if defined(ENABLE_STATISTICS)
+       int           iteration_count;  /* number of iterations of analysis       */
+#endif
+       int           new_index; /* used to get a new var index with GET_NEW_INDEX*/
+
+#if defined(STACK_VERBOSE)
+       show_method(jd, SHOW_PARSE);
+#endif
 
-       /* get required compiler data */
+       /* get required compiler data - initialization */
 
        m    = jd->m;
        code = jd->code;
        cd   = jd->cd;
        rd   = jd->rd;
+#if defined(ENABLE_SSA)
+       ls   = jd->ls;
+#endif
+
+       /* initialize the stackdata_t struct */
+
+       sd.m = m;
+       sd.jd = jd;
+       sd.varcount = jd->varcount;
+       sd.vartop =  jd->vartop;
+       sd.localcount = jd->localcount;
+       sd.var = jd->var;
+       sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
+       sd.exstack.type = TYPE_ADR;
+       sd.exstack.prev = NULL;
+       sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
+
+#if defined(ENABLE_LSRA)
+       m->maxlifetimes = 0;
+#endif
+
+#if defined(ENABLE_STATISTICS)
+       iteration_count = 0;
+#endif
+
+       /* find the last real basic block */
+       
+       sd.last_real_block = NULL;
+       tbptr = jd->basicblocks;
+       while (tbptr->next) {
+               sd.last_real_block = tbptr;
+               tbptr = tbptr->next;
+       }
+       assert(sd.last_real_block);
+
+       /* find the last exception handler */
+
+       if (cd->exceptiontablelength)
+               sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
+       else
+               sd.extableend = NULL;
+
+       /* init jd->interface_map */
+
+       jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
+       for (i = 0; i < m->maxstack * 5; i++)
+               jd->interface_map[i].flags = UNUSED;
+
+       last_store_boundary = DMNEW(stackptr, cd->maxlocals);
+
+       /* initialize flags and invars (none) of first block */
+
+       jd->basicblocks[0].flags = BBREACHED;
+       jd->basicblocks[0].invars = NULL;
+       jd->basicblocks[0].indepth = 0;
+       jd->basicblocks[0].inlocals = 
+               DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
+       MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo, 
+                       jd->localcount + VERIFIER_EXTRA_LOCALS);
+
+       /* stack analysis loop (until fixpoint reached) **************************/
+
+       do {
+#if defined(ENABLE_STATISTICS)
+               iteration_count++;
+#endif
+
+               /* initialize loop over basic blocks */
+
+               sd.bptr = jd->basicblocks;
+               superblockend = true;
+               sd.repeat = false;
+               curstack = NULL; stackdepth = 0;
+               deadcode = true;
+
+               /* iterate over basic blocks *****************************************/
+
+               for (; sd.bptr; sd.bptr = sd.bptr->next) {
+
+                       if (sd.bptr->flags == BBDELETED) {
+                               /* This block has been deleted - do nothing. */
+
+                               continue;
+                       }
+
+                       if (superblockend && (sd.bptr->flags < BBREACHED)) {
+                               /* This block has not been reached so far, and we      */
+                               /* don't fall into it, so we'll have to iterate again. */
+
+                               sd.repeat = true;
+                               continue;
+                       }
+
+                       if (sd.bptr->flags > BBREACHED) {
+                               /* This block is already finished. */
+
+                               superblockend = true;
+                               continue;
+                       }
+
+                       if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
+                               /* This block is a clone and the original has not been */
+                               /* analysed, yet. Analyse it on the next iteration.    */
+
+                               sd.repeat = true;
+                               continue;
+                       }
 
-#if defined(ENABLE_LSRA)
-       m->maxlifetimes = 0;
-#endif
+                       /* This block has to be analysed now. */
 
-       last_store = DMNEW(s4 , cd->maxlocals * 5);
-       
-       new = m->stack;
-       loops = 0;
-       m->basicblocks[0].flags = BBREACHED;
-       m->basicblocks[0].instack = 0;
-       m->basicblocks[0].indepth = 0;
-
-       for (i = 0; i < cd->exceptiontablelength; i++) {
-               bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
-               bptr->flags = BBREACHED;
-               bptr->type = BBTYPE_EXH;
-               bptr->instack = new;
-               bptr->indepth = 1;
-               bptr->pre_count = 10000;
-               STACKRESET;
-               NEWXSTACK;
-       }
+                       /* XXX The rest of this block is still indented one level too */
+                       /* much in order to avoid a giant diff by changing that.      */
 
-#if CONDITIONAL_LOADCONST
-       b_count = m->basicblockcount;
-       bptr = m->basicblocks;
-       while (--b_count >= 0) {
-               if (bptr->icount != 0) {
-                       iptr = bptr->iinstr + bptr->icount - 1;
-                       switch (iptr->opc) {
-                       case ICMD_RET:
-                       case ICMD_RETURN:
-                       case ICMD_IRETURN:
-                       case ICMD_LRETURN:
-                       case ICMD_FRETURN:
-                       case ICMD_DRETURN:
-                       case ICMD_ARETURN:
-                       case ICMD_ATHROW:
-                               break;
+                               /* We know that sd.bptr->flags == BBREACHED. */
+                               /* This block has been reached before.    */
 
-                       case ICMD_IFEQ:
-                       case ICMD_IFNE:
-                       case ICMD_IFLT:
-                       case ICMD_IFGE:
-                       case ICMD_IFGT:
-                       case ICMD_IFLE:
+                               assert(sd.bptr->flags == BBREACHED);
+                               stackdepth = sd.bptr->indepth;
 
-                       case ICMD_IFNULL:
-                       case ICMD_IFNONNULL:
+                               /* find exception handlers for this block */
 
-                       case ICMD_IF_ICMPEQ:
-                       case ICMD_IF_ICMPNE:
-                       case ICMD_IF_ICMPLT:
-                       case ICMD_IF_ICMPGE:
-                       case ICMD_IF_ICMPGT:
-                       case ICMD_IF_ICMPLE:
+                               /* determine the active exception handlers for this block */
+                               /* XXX could use a faster algorithm with sorted lists or  */
+                               /* something?                                             */
 
-                       case ICMD_IF_ACMPEQ:
-                       case ICMD_IF_ACMPNE:
-                               bptr[1].pre_count++;
-                       case ICMD_GOTO:
-                               m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
-                               break;
+                               original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
 
-                       case ICMD_TABLESWITCH:
-                               s4ptr = iptr->val.a;
-                               m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
-                               i = *s4ptr++;                               /* low     */
-                               i = *s4ptr++ - i + 1;                       /* high    */
-                               while (--i >= 0) {
-                                       m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
-                               }
-                               break;
-                                       
-                       case ICMD_LOOKUPSWITCH:
-                               s4ptr = iptr->val.a;
-                               m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
-                               i = *s4ptr++;                               /* count   */
-                               while (--i >= 0) {
-                                       m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
-                                       s4ptr += 2;
+                               len = 0;
+                               ex = cd->exceptiontable;
+                               for (; ex != NULL; ex = ex->down) {
+                                       if ((ex->start <= original) && (ex->end > original)) {
+                                               sd.handlers[len++] = ex;
+                                       }
                                }
-                               break;
-                       default:
-                               bptr[1].pre_count++;
-                               break;
-                       }
-               }
-               bptr++;
-       }
-#endif /* CONDITIONAL_LOADCONST */
+                               sd.handlers[len] = NULL;
 
 
-       do {
-               loops++;
-               b_count = m->basicblockcount;
-               bptr = m->basicblocks;
-               superblockend = true;
-               repeat = false;
-               STACKRESET;
-               deadcode = true;
+                               /* reanalyse cloned block */
 
-               while (--b_count >= 0) {
-                       if (bptr->flags == BBDELETED) {
-                               /* do nothing */
-                       } 
-                       else if (superblockend && (bptr->flags < BBREACHED)) {
-                               repeat = true;
-                       } 
-                       else if (bptr->flags <= BBREACHED) {
-                               if (superblockend) {
-                                       stackdepth = bptr->indepth;
-                               } 
-                               else if (bptr->flags < BBREACHED) {
-                                       COPYCURSTACK(copy);
-                                       bptr->instack = copy;
-                                       bptr->indepth = stackdepth;
-                               } 
-                               else {
-                                       CHECK_STACK_DEPTH(bptr->indepth, stackdepth);
+                               if (sd.bptr->original) {
+                                       if (!stack_reanalyse_block(&sd))
+                                               return false;
+                                       continue;
                                }
 
-                               curstack = bptr->instack;
+                               /* reset the new pointer for allocating stackslots */
+
+                               sd.new = jd->stack;
+
+                               /* create the instack of this block */
+
+                               curstack = stack_create_instack(&sd);
+
+                               /* initialize locals at the start of this block */
+
+                               if (sd.bptr->inlocals)
+                                       MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
+
+                               /* set up local variables for analyzing this block */
+
                                deadcode = false;
                                superblockend = false;
-                               bptr->flags = BBFINISHED;
-                               len = bptr->icount;
-                               iptr = bptr->iinstr;
-                               b_index = bptr - m->basicblocks;
+                               len = sd.bptr->icount;
+                               iptr = sd.bptr->iinstr;
+                               b_index = sd.bptr - jd->basicblocks;
+
+                               /* mark the block as analysed */
+
+                               sd.bptr->flags = BBFINISHED;
+
+                               /* reset variables for dependency checking */
 
-                               last_pei = -1;
-                               last_dupx = -1;
+                               coalescing_boundary = sd.new;
                                for( i = 0; i < cd->maxlocals; i++)
-                                       for( j = 0; j < 5; j++)
-                                               last_store[5 * i + j] = -1;
+                                       last_store_boundary[i] = sd.new;
 
-                               bptr->stack = new;
+                               /* remember the start of this block's variables */
+  
+                               sd.bptr->varstart = sd.vartop;
+
+#if defined(STACK_VERBOSE)
+                               stack_verbose_block_enter(&sd, false);
+#endif
+  
+                               /* reach exception handlers for this block */
+
+                               if (!stack_reach_handlers(&sd))
+                                       return false;
+
+                               /* iterate over ICMDs ****************************************/
 
                                while (--len >= 0)  {
+
+#if defined(STACK_VERBOSE)
+                                       show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
+                                       for( copy = curstack; copy; copy = copy->prev ) {
+                                               printf("%2d(%d", copy->varnum, copy->type);
+                                               if (IS_INOUT(copy))
+                                                       printf("S");
+                                               if (IS_PREALLOC(copy))
+                                                       printf("A");
+                                               printf(") ");
+                                       }
+                                       printf("\n");
+#endif
+
+                                       /* fetch the current opcode */
+
                                        opcode = iptr->opc;
 
+                                       /* automatically replace some ICMDs with builtins */
+
 #if defined(USEBUILTINTABLE)
-# if defined(ENABLE_INTRP)
-                                       if (!opt_intrp) {
-# endif
-                                               bte = builtintable_get_automatic(opcode);
-
-                                               if (bte && bte->opcode == opcode) {
-                                                       iptr->opc   = ICMD_BUILTIN;
-                                                       iptr->op1   = false; /* don't check for exception */
-                                                       iptr->val.a = bte;
-                                                       jd->isleafmethod = false;
-                                                       goto builtin;
-                                               }
-# if defined(ENABLE_INTRP)
+                                       bte = builtintable_get_automatic(opcode);
+
+                                       if (bte && bte->opcode == opcode) {
+                                               iptr->opc           = ICMD_BUILTIN;
+                                               iptr->flags.bits    = 0;
+                                               iptr->sx.s23.s3.bte = bte;
+                                               /* iptr->line is already set */
+                                               jd->isleafmethod = false;
+                                               goto icmd_BUILTIN;
                                        }
-# endif
 #endif /* defined(USEBUILTINTABLE) */
 
-                                       /* this is the main switch */
+                                       /* main opcode switch *************************************/
 
                                        switch (opcode) {
 
                                                /* pop 0 push 0 */
 
-                                       case ICMD_CHECKNULL:
-                                               COUNT(count_check_null);
                                        case ICMD_NOP:
+icmd_NOP:
+                                               CLR_SX;
+                                               OP0_0;
+                                               break;
 
-                                       case ICMD_IFEQ_ICONST:
-                                       case ICMD_IFNE_ICONST:
-                                       case ICMD_IFLT_ICONST:
-                                       case ICMD_IFGE_ICONST:
-                                       case ICMD_IFGT_ICONST:
-                                       case ICMD_IFLE_ICONST:
-                                       case ICMD_ELSE_ICONST:
-                                               SETDST;
+                                       case ICMD_CHECKNULL:
+                                               coalescing_boundary = sd.new;
+                                               COUNT(count_check_null);
+                                               USE_S1(TYPE_ADR);
+                                               CLR_SX;
+                                               CLR_DST; /* XXX live through? */
                                                break;
 
                                        case ICMD_RET:
-#if defined(ENABLE_INTRP)
-                                               if (!opt_intrp)
-#endif
-                                                       rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
+                                               j = iptr->s1.varindex = 
+                                                       jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
+
+                                               if (sd.var[j].type != TYPE_RET) {
+                                                       exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
+                                                       return false;
+                                               }
+               
+                                               CLR_SX;
+
+                                               iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
+                                               superblockend = true;
+                                               break;
+
                                        case ICMD_RETURN:
                                                COUNT(count_pcmd_return);
-                                               SETDST;
+                                               CLR_SX;
+                                               OP0_0;
                                                superblockend = true;
                                                break;
 
+
                                                /* pop 0 push 1 const */
-                                               
+
+       /************************** ICONST OPTIMIZATIONS **************************/
+
                                        case ICMD_ICONST:
                                                COUNT(count_pcmd_load);
-                                               if (len > 0) {
-                                                       switch (iptr[1].opc) {
+                                               if (len == 0)
+                                                       goto normal_ICONST;
+
+                                               switch (iptr[1].opc) {
                                                        case ICMD_IADD:
-                                                               iptr[0].opc = ICMD_IADDCONST;
+                                                               iptr->opc = ICMD_IADDCONST;
+                                                               /* FALLTHROUGH */
+
                                                        icmd_iconst_tail:
                                                                iptr[1].opc = ICMD_NOP;
                                                                OP1_1(TYPE_INT, TYPE_INT);
                                                                COUNT(count_pcmd_op);
                                                                break;
+
                                                        case ICMD_ISUB:
-                                                               iptr[0].opc = ICMD_ISUBCONST;
+                                                               iptr->opc = ICMD_ISUBCONST;
                                                                goto icmd_iconst_tail;
 #if SUPPORT_CONST_MUL
                                                        case ICMD_IMUL:
-                                                               iptr[0].opc = ICMD_IMULCONST;
+                                                               iptr->opc = ICMD_IMULCONST;
                                                                goto icmd_iconst_tail;
 #else /* SUPPORT_CONST_MUL */
                                                        case ICMD_IMUL:
-                                                               if (iptr[0].val.i == 0x00000002)
-                                                                       iptr[0].val.i = 1;
-                                                               else if (iptr[0].val.i == 0x00000004)
-                                                                       iptr[0].val.i = 2;
-                                                               else if (iptr[0].val.i == 0x00000008)
-                                                                       iptr[0].val.i = 3;
-                                                               else if (iptr[0].val.i == 0x00000010)
-                                                                       iptr[0].val.i = 4;
-                                                               else if (iptr[0].val.i == 0x00000020)
-                                                                       iptr[0].val.i = 5;
-                                                               else if (iptr[0].val.i == 0x00000040)
-                                                                       iptr[0].val.i = 6;
-                                                               else if (iptr[0].val.i == 0x00000080)
-                                                                       iptr[0].val.i = 7;
-                                                               else if (iptr[0].val.i == 0x00000100)
-                                                                       iptr[0].val.i = 8;
-                                                               else if (iptr[0].val.i == 0x00000200)
-                                                                       iptr[0].val.i = 9;
-                                                               else if (iptr[0].val.i == 0x00000400)
-                                                                       iptr[0].val.i = 10;
-                                                               else if (iptr[0].val.i == 0x00000800)
-                                                                       iptr[0].val.i = 11;
-                                                               else if (iptr[0].val.i == 0x00001000)
-                                                                       iptr[0].val.i = 12;
-                                                               else if (iptr[0].val.i == 0x00002000)
-                                                                       iptr[0].val.i = 13;
-                                                               else if (iptr[0].val.i == 0x00004000)
-                                                                       iptr[0].val.i = 14;
-                                                               else if (iptr[0].val.i == 0x00008000)
-                                                                       iptr[0].val.i = 15;
-                                                               else if (iptr[0].val.i == 0x00010000)
-                                                                       iptr[0].val.i = 16;
-                                                               else if (iptr[0].val.i == 0x00020000)
-                                                                       iptr[0].val.i = 17;
-                                                               else if (iptr[0].val.i == 0x00040000)
-                                                                       iptr[0].val.i = 18;
-                                                               else if (iptr[0].val.i == 0x00080000)
-                                                                       iptr[0].val.i = 19;
-                                                               else if (iptr[0].val.i == 0x00100000)
-                                                                       iptr[0].val.i = 20;
-                                                               else if (iptr[0].val.i == 0x00200000)
-                                                                       iptr[0].val.i = 21;
-                                                               else if (iptr[0].val.i == 0x00400000)
-                                                                       iptr[0].val.i = 22;
-                                                               else if (iptr[0].val.i == 0x00800000)
-                                                                       iptr[0].val.i = 23;
-                                                               else if (iptr[0].val.i == 0x01000000)
-                                                                       iptr[0].val.i = 24;
-                                                               else if (iptr[0].val.i == 0x02000000)
-                                                                       iptr[0].val.i = 25;
-                                                               else if (iptr[0].val.i == 0x04000000)
-                                                                       iptr[0].val.i = 26;
-                                                               else if (iptr[0].val.i == 0x08000000)
-                                                                       iptr[0].val.i = 27;
-                                                               else if (iptr[0].val.i == 0x10000000)
-                                                                       iptr[0].val.i = 28;
-                                                               else if (iptr[0].val.i == 0x20000000)
-                                                                       iptr[0].val.i = 29;
-                                                               else if (iptr[0].val.i == 0x40000000)
-                                                                       iptr[0].val.i = 30;
-                                                               else if (iptr[0].val.i == 0x80000000)
-                                                                       iptr[0].val.i = 31;
-                                                               else {
-                                                                       PUSHCONST(TYPE_INT);
-                                                                       break;
-                                                               }
-                                                               iptr[0].opc = ICMD_IMULPOW2;
+                                                               if (iptr->sx.val.i == 0x00000002)
+                                                                       iptr->sx.val.i = 1;
+                                                               else if (iptr->sx.val.i == 0x00000004)
+                                                                       iptr->sx.val.i = 2;
+                                                               else if (iptr->sx.val.i == 0x00000008)
+                                                                       iptr->sx.val.i = 3;
+                                                               else if (iptr->sx.val.i == 0x00000010)
+                                                                       iptr->sx.val.i = 4;
+                                                               else if (iptr->sx.val.i == 0x00000020)
+                                                                       iptr->sx.val.i = 5;
+                                                               else if (iptr->sx.val.i == 0x00000040)
+                                                                       iptr->sx.val.i = 6;
+                                                               else if (iptr->sx.val.i == 0x00000080)
+                                                                       iptr->sx.val.i = 7;
+                                                               else if (iptr->sx.val.i == 0x00000100)
+                                                                       iptr->sx.val.i = 8;
+                                                               else if (iptr->sx.val.i == 0x00000200)
+                                                                       iptr->sx.val.i = 9;
+                                                               else if (iptr->sx.val.i == 0x00000400)
+                                                                       iptr->sx.val.i = 10;
+                                                               else if (iptr->sx.val.i == 0x00000800)
+                                                                       iptr->sx.val.i = 11;
+                                                               else if (iptr->sx.val.i == 0x00001000)
+                                                                       iptr->sx.val.i = 12;
+                                                               else if (iptr->sx.val.i == 0x00002000)
+                                                                       iptr->sx.val.i = 13;
+                                                               else if (iptr->sx.val.i == 0x00004000)
+                                                                       iptr->sx.val.i = 14;
+                                                               else if (iptr->sx.val.i == 0x00008000)
+                                                                       iptr->sx.val.i = 15;
+                                                               else if (iptr->sx.val.i == 0x00010000)
+                                                                       iptr->sx.val.i = 16;
+                                                               else if (iptr->sx.val.i == 0x00020000)
+                                                                       iptr->sx.val.i = 17;
+                                                               else if (iptr->sx.val.i == 0x00040000)
+                                                                       iptr->sx.val.i = 18;
+                                                               else if (iptr->sx.val.i == 0x00080000)
+                                                                       iptr->sx.val.i = 19;
+                                                               else if (iptr->sx.val.i == 0x00100000)
+                                                                       iptr->sx.val.i = 20;
+                                                               else if (iptr->sx.val.i == 0x00200000)
+                                                                       iptr->sx.val.i = 21;
+                                                               else if (iptr->sx.val.i == 0x00400000)
+                                                                       iptr->sx.val.i = 22;
+                                                               else if (iptr->sx.val.i == 0x00800000)
+                                                                       iptr->sx.val.i = 23;
+                                                               else if (iptr->sx.val.i == 0x01000000)
+                                                                       iptr->sx.val.i = 24;
+                                                               else if (iptr->sx.val.i == 0x02000000)
+                                                                       iptr->sx.val.i = 25;
+                                                               else if (iptr->sx.val.i == 0x04000000)
+                                                                       iptr->sx.val.i = 26;
+                                                               else if (iptr->sx.val.i == 0x08000000)
+                                                                       iptr->sx.val.i = 27;
+                                                               else if (iptr->sx.val.i == 0x10000000)
+                                                                       iptr->sx.val.i = 28;
+                                                               else if (iptr->sx.val.i == 0x20000000)
+                                                                       iptr->sx.val.i = 29;
+                                                               else if (iptr->sx.val.i == 0x40000000)
+                                                                       iptr->sx.val.i = 30;
+                                                               else if (iptr->sx.val.i == 0x80000000)
+                                                                       iptr->sx.val.i = 31;
+                                                               else
+                                                                       goto normal_ICONST;
+
+                                                               iptr->opc = ICMD_IMULPOW2;
                                                                goto icmd_iconst_tail;
 #endif /* SUPPORT_CONST_MUL */
                                                        case ICMD_IDIV:
-                                                               if (iptr[0].val.i == 0x00000002)
-                                                                       iptr[0].val.i = 1;
-                                                               else if (iptr[0].val.i == 0x00000004)
-                                                                       iptr[0].val.i = 2;
-                                                               else if (iptr[0].val.i == 0x00000008)
-                                                                       iptr[0].val.i = 3;
-                                                               else if (iptr[0].val.i == 0x00000010)
-                                                                       iptr[0].val.i = 4;
-                                                               else if (iptr[0].val.i == 0x00000020)
-                                                                       iptr[0].val.i = 5;
-                                                               else if (iptr[0].val.i == 0x00000040)
-                                                                       iptr[0].val.i = 6;
-                                                               else if (iptr[0].val.i == 0x00000080)
-                                                                       iptr[0].val.i = 7;
-                                                               else if (iptr[0].val.i == 0x00000100)
-                                                                       iptr[0].val.i = 8;
-                                                               else if (iptr[0].val.i == 0x00000200)
-                                                                       iptr[0].val.i = 9;
-                                                               else if (iptr[0].val.i == 0x00000400)
-                                                                       iptr[0].val.i = 10;
-                                                               else if (iptr[0].val.i == 0x00000800)
-                                                                       iptr[0].val.i = 11;
-                                                               else if (iptr[0].val.i == 0x00001000)
-                                                                       iptr[0].val.i = 12;
-                                                               else if (iptr[0].val.i == 0x00002000)
-                                                                       iptr[0].val.i = 13;
-                                                               else if (iptr[0].val.i == 0x00004000)
-                                                                       iptr[0].val.i = 14;
-                                                               else if (iptr[0].val.i == 0x00008000)
-                                                                       iptr[0].val.i = 15;
-                                                               else if (iptr[0].val.i == 0x00010000)
-                                                                       iptr[0].val.i = 16;
-                                                               else if (iptr[0].val.i == 0x00020000)
-                                                                       iptr[0].val.i = 17;
-                                                               else if (iptr[0].val.i == 0x00040000)
-                                                                       iptr[0].val.i = 18;
-                                                               else if (iptr[0].val.i == 0x00080000)
-                                                                       iptr[0].val.i = 19;
-                                                               else if (iptr[0].val.i == 0x00100000)
-                                                                       iptr[0].val.i = 20;
-                                                               else if (iptr[0].val.i == 0x00200000)
-                                                                       iptr[0].val.i = 21;
-                                                               else if (iptr[0].val.i == 0x00400000)
-                                                                       iptr[0].val.i = 22;
-                                                               else if (iptr[0].val.i == 0x00800000)
-                                                                       iptr[0].val.i = 23;
-                                                               else if (iptr[0].val.i == 0x01000000)
-                                                                       iptr[0].val.i = 24;
-                                                               else if (iptr[0].val.i == 0x02000000)
-                                                                       iptr[0].val.i = 25;
-                                                               else if (iptr[0].val.i == 0x04000000)
-                                                                       iptr[0].val.i = 26;
-                                                               else if (iptr[0].val.i == 0x08000000)
-                                                                       iptr[0].val.i = 27;
-                                                               else if (iptr[0].val.i == 0x10000000)
-                                                                       iptr[0].val.i = 28;
-                                                               else if (iptr[0].val.i == 0x20000000)
-                                                                       iptr[0].val.i = 29;
-                                                               else if (iptr[0].val.i == 0x40000000)
-                                                                       iptr[0].val.i = 30;
-                                                               else if (iptr[0].val.i == 0x80000000)
-                                                                       iptr[0].val.i = 31;
-                                                               else {
-                                                                       PUSHCONST(TYPE_INT);
-                                                                       break;
-                                                               }
-                                                               iptr[0].opc = ICMD_IDIVPOW2;
+                                                               if (iptr->sx.val.i == 0x00000002)
+                                                                       iptr->sx.val.i = 1;
+                                                               else if (iptr->sx.val.i == 0x00000004)
+                                                                       iptr->sx.val.i = 2;
+                                                               else if (iptr->sx.val.i == 0x00000008)
+                                                                       iptr->sx.val.i = 3;
+                                                               else if (iptr->sx.val.i == 0x00000010)
+                                                                       iptr->sx.val.i = 4;
+                                                               else if (iptr->sx.val.i == 0x00000020)
+                                                                       iptr->sx.val.i = 5;
+                                                               else if (iptr->sx.val.i == 0x00000040)
+                                                                       iptr->sx.val.i = 6;
+                                                               else if (iptr->sx.val.i == 0x00000080)
+                                                                       iptr->sx.val.i = 7;
+                                                               else if (iptr->sx.val.i == 0x00000100)
+                                                                       iptr->sx.val.i = 8;
+                                                               else if (iptr->sx.val.i == 0x00000200)
+                                                                       iptr->sx.val.i = 9;
+                                                               else if (iptr->sx.val.i == 0x00000400)
+                                                                       iptr->sx.val.i = 10;
+                                                               else if (iptr->sx.val.i == 0x00000800)
+                                                                       iptr->sx.val.i = 11;
+                                                               else if (iptr->sx.val.i == 0x00001000)
+                                                                       iptr->sx.val.i = 12;
+                                                               else if (iptr->sx.val.i == 0x00002000)
+                                                                       iptr->sx.val.i = 13;
+                                                               else if (iptr->sx.val.i == 0x00004000)
+                                                                       iptr->sx.val.i = 14;
+                                                               else if (iptr->sx.val.i == 0x00008000)
+                                                                       iptr->sx.val.i = 15;
+                                                               else if (iptr->sx.val.i == 0x00010000)
+                                                                       iptr->sx.val.i = 16;
+                                                               else if (iptr->sx.val.i == 0x00020000)
+                                                                       iptr->sx.val.i = 17;
+                                                               else if (iptr->sx.val.i == 0x00040000)
+                                                                       iptr->sx.val.i = 18;
+                                                               else if (iptr->sx.val.i == 0x00080000)
+                                                                       iptr->sx.val.i = 19;
+                                                               else if (iptr->sx.val.i == 0x00100000)
+                                                                       iptr->sx.val.i = 20;
+                                                               else if (iptr->sx.val.i == 0x00200000)
+                                                                       iptr->sx.val.i = 21;
+                                                               else if (iptr->sx.val.i == 0x00400000)
+                                                                       iptr->sx.val.i = 22;
+                                                               else if (iptr->sx.val.i == 0x00800000)
+                                                                       iptr->sx.val.i = 23;
+                                                               else if (iptr->sx.val.i == 0x01000000)
+                                                                       iptr->sx.val.i = 24;
+                                                               else if (iptr->sx.val.i == 0x02000000)
+                                                                       iptr->sx.val.i = 25;
+                                                               else if (iptr->sx.val.i == 0x04000000)
+                                                                       iptr->sx.val.i = 26;
+                                                               else if (iptr->sx.val.i == 0x08000000)
+                                                                       iptr->sx.val.i = 27;
+                                                               else if (iptr->sx.val.i == 0x10000000)
+                                                                       iptr->sx.val.i = 28;
+                                                               else if (iptr->sx.val.i == 0x20000000)
+                                                                       iptr->sx.val.i = 29;
+                                                               else if (iptr->sx.val.i == 0x40000000)
+                                                                       iptr->sx.val.i = 30;
+                                                               else if (iptr->sx.val.i == 0x80000000)
+                                                                       iptr->sx.val.i = 31;
+                                                               else
+                                                                       goto normal_ICONST;
+
+                                                               iptr->opc = ICMD_IDIVPOW2;
                                                                goto icmd_iconst_tail;
+
                                                        case ICMD_IREM:
                                                                /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
-                                                               if ((iptr[0].val.i == 0x00000002) ||
-                                                                       (iptr[0].val.i == 0x00000004) ||
-                                                                       (iptr[0].val.i == 0x00000008) ||
-                                                                       (iptr[0].val.i == 0x00000010) ||
-                                                                       (iptr[0].val.i == 0x00000020) ||
-                                                                       (iptr[0].val.i == 0x00000040) ||
-                                                                       (iptr[0].val.i == 0x00000080) ||
-                                                                       (iptr[0].val.i == 0x00000100) ||
-                                                                       (iptr[0].val.i == 0x00000200) ||
-                                                                       (iptr[0].val.i == 0x00000400) ||
-                                                                       (iptr[0].val.i == 0x00000800) ||
-                                                                       (iptr[0].val.i == 0x00001000) ||
-                                                                       (iptr[0].val.i == 0x00002000) ||
-                                                                       (iptr[0].val.i == 0x00004000) ||
-                                                                       (iptr[0].val.i == 0x00008000) ||
-                                                                       (iptr[0].val.i == 0x00010000) ||
-                                                                       (iptr[0].val.i == 0x00020000) ||
-                                                                       (iptr[0].val.i == 0x00040000) ||
-                                                                       (iptr[0].val.i == 0x00080000) ||
-                                                                       (iptr[0].val.i == 0x00100000) ||
-                                                                       (iptr[0].val.i == 0x00200000) ||
-                                                                       (iptr[0].val.i == 0x00400000) ||
-                                                                       (iptr[0].val.i == 0x00800000) ||
-                                                                       (iptr[0].val.i == 0x01000000) ||
-                                                                       (iptr[0].val.i == 0x02000000) ||
-                                                                       (iptr[0].val.i == 0x04000000) ||
-                                                                       (iptr[0].val.i == 0x08000000) ||
-                                                                       (iptr[0].val.i == 0x10000000) ||
-                                                                       (iptr[0].val.i == 0x20000000) ||
-                                                                       (iptr[0].val.i == 0x40000000) ||
-                                                                       (iptr[0].val.i == 0x80000000)) {
-                                                                       iptr[0].opc = ICMD_IREMPOW2;
-                                                                       iptr[0].val.i -= 1;
+                                                               if ((iptr->sx.val.i == 0x00000002) ||
+                                                                       (iptr->sx.val.i == 0x00000004) ||
+                                                                       (iptr->sx.val.i == 0x00000008) ||
+                                                                       (iptr->sx.val.i == 0x00000010) ||
+                                                                       (iptr->sx.val.i == 0x00000020) ||
+                                                                       (iptr->sx.val.i == 0x00000040) ||
+                                                                       (iptr->sx.val.i == 0x00000080) ||
+                                                                       (iptr->sx.val.i == 0x00000100) ||
+                                                                       (iptr->sx.val.i == 0x00000200) ||
+                                                                       (iptr->sx.val.i == 0x00000400) ||
+                                                                       (iptr->sx.val.i == 0x00000800) ||
+                                                                       (iptr->sx.val.i == 0x00001000) ||
+                                                                       (iptr->sx.val.i == 0x00002000) ||
+                                                                       (iptr->sx.val.i == 0x00004000) ||
+                                                                       (iptr->sx.val.i == 0x00008000) ||
+                                                                       (iptr->sx.val.i == 0x00010000) ||
+                                                                       (iptr->sx.val.i == 0x00020000) ||
+                                                                       (iptr->sx.val.i == 0x00040000) ||
+                                                                       (iptr->sx.val.i == 0x00080000) ||
+                                                                       (iptr->sx.val.i == 0x00100000) ||
+                                                                       (iptr->sx.val.i == 0x00200000) ||
+                                                                       (iptr->sx.val.i == 0x00400000) ||
+                                                                       (iptr->sx.val.i == 0x00800000) ||
+                                                                       (iptr->sx.val.i == 0x01000000) ||
+                                                                       (iptr->sx.val.i == 0x02000000) ||
+                                                                       (iptr->sx.val.i == 0x04000000) ||
+                                                                       (iptr->sx.val.i == 0x08000000) ||
+                                                                       (iptr->sx.val.i == 0x10000000) ||
+                                                                       (iptr->sx.val.i == 0x20000000) ||
+                                                                       (iptr->sx.val.i == 0x40000000) ||
+                                                                       (iptr->sx.val.i == 0x80000000))
+                                                               {
+                                                                       iptr->opc = ICMD_IREMPOW2;
+                                                                       iptr->sx.val.i -= 1;
                                                                        goto icmd_iconst_tail;
                                                                }
-                                                               PUSHCONST(TYPE_INT);
-                                                               break;
+                                                               goto normal_ICONST;
 #if SUPPORT_CONST_LOGICAL
                                                        case ICMD_IAND:
-                                                               iptr[0].opc = ICMD_IANDCONST;
+                                                               iptr->opc = ICMD_IANDCONST;
                                                                goto icmd_iconst_tail;
+
                                                        case ICMD_IOR:
-                                                               iptr[0].opc = ICMD_IORCONST;
+                                                               iptr->opc = ICMD_IORCONST;
                                                                goto icmd_iconst_tail;
+
                                                        case ICMD_IXOR:
-                                                               iptr[0].opc = ICMD_IXORCONST;
+                                                               iptr->opc = ICMD_IXORCONST;
                                                                goto icmd_iconst_tail;
+
 #endif /* SUPPORT_CONST_LOGICAL */
                                                        case ICMD_ISHL:
-                                                               iptr[0].opc = ICMD_ISHLCONST;
+                                                               iptr->opc = ICMD_ISHLCONST;
                                                                goto icmd_iconst_tail;
+
                                                        case ICMD_ISHR:
-                                                               iptr[0].opc = ICMD_ISHRCONST;
+                                                               iptr->opc = ICMD_ISHRCONST;
                                                                goto icmd_iconst_tail;
+
                                                        case ICMD_IUSHR:
-                                                               iptr[0].opc = ICMD_IUSHRCONST;
+                                                               iptr->opc = ICMD_IUSHRCONST;
                                                                goto icmd_iconst_tail;
 #if SUPPORT_LONG_SHIFT
                                                        case ICMD_LSHL:
-                                                               iptr[0].opc = ICMD_LSHLCONST;
+                                                               iptr->opc = ICMD_LSHLCONST;
                                                                goto icmd_lconst_tail;
+
                                                        case ICMD_LSHR:
-                                                               iptr[0].opc = ICMD_LSHRCONST;
+                                                               iptr->opc = ICMD_LSHRCONST;
                                                                goto icmd_lconst_tail;
+
                                                        case ICMD_LUSHR:
-                                                               iptr[0].opc = ICMD_LUSHRCONST;
+                                                               iptr->opc = ICMD_LUSHRCONST;
                                                                goto icmd_lconst_tail;
 #endif /* SUPPORT_LONG_SHIFT */
                                                        case ICMD_IF_ICMPEQ:
                                                                iptr[1].opc = ICMD_IFEQ;
+                                                               /* FALLTHROUGH */
+
                                                        icmd_if_icmp_tail:
-/*                                                             iptr[0].op1 = iptr[1].op1; */
-                                                               /* IF_ICMPxx is the last instruction in the  
-                                                                  basic block, just remove it. */
-                                                               iptr[0].opc = ICMD_NOP;
-                                                               iptr[1].val.i = iptr[0].val.i;
-                                                               SETDST;
-/*                                                             bptr->icount--; */
-/*                                                             len--; */
-#if 0
-                                                               OP1_0(TYPE_INT);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[1].op1];
+                                                               /* set the constant for the following icmd */
+                                                               iptr[1].sx.val.i = iptr->sx.val.i;
 
-                                                               iptr[1].target = (void *) tbptr;
+                                                               /* this instruction becomes a nop */
+                                                               iptr->opc = ICMD_NOP;
+                                                               goto icmd_NOP;
 
-                                                               MARKREACHED(tbptr, copy);
-                                                               COUNT(count_pcmd_bra);
-#endif
-                                                               break;
                                                        case ICMD_IF_ICMPLT:
                                                                iptr[1].opc = ICMD_IFLT;
                                                                goto icmd_if_icmp_tail;
+
                                                        case ICMD_IF_ICMPLE:
                                                                iptr[1].opc = ICMD_IFLE;
                                                                goto icmd_if_icmp_tail;
+
                                                        case ICMD_IF_ICMPNE:
                                                                iptr[1].opc = ICMD_IFNE;
                                                                goto icmd_if_icmp_tail;
+
                                                        case ICMD_IF_ICMPGT:
                                                                iptr[1].opc = ICMD_IFGT;
                                                                goto icmd_if_icmp_tail;
+
                                                        case ICMD_IF_ICMPGE:
                                                                iptr[1].opc = ICMD_IFGE;
                                                                goto icmd_if_icmp_tail;
@@ -3335,724 +2358,702 @@ bool stack_analyse(jitdata *jd)
                                                        case ICMD_BASTORE:
                                                        case ICMD_CASTORE:
                                                        case ICMD_SASTORE:
-# if defined(ENABLE_INTRP)
-                                                               if (!opt_intrp) {
-# endif
 # if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       if (iptr[0].val.i == 0) {
+                                                               if (iptr->sx.val.i != 0)
+                                                                       goto normal_ICONST;
 # endif
-                                                                               switch (iptr[1].opc) {
-                                                                               case ICMD_IASTORE:
-                                                                                       iptr[0].opc = ICMD_IASTORECONST;
-                                                                                       break;
-                                                                               case ICMD_BASTORE:
-                                                                                       iptr[0].opc = ICMD_BASTORECONST;
-                                                                                       break;
-                                                                               case ICMD_CASTORE:
-                                                                                       iptr[0].opc = ICMD_CASTORECONST;
-                                                                                       break;
-                                                                               case ICMD_SASTORE:
-                                                                                       iptr[0].opc = ICMD_SASTORECONST;
-                                                                                       break;
-                                                                               }
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_IASTORE:
+                                                                               iptr->opc = ICMD_IASTORECONST;
+                                                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                                                               break;
+                                                                       case ICMD_BASTORE:
+                                                                               iptr->opc = ICMD_BASTORECONST;
+                                                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                                                               break;
+                                                                       case ICMD_CASTORE:
+                                                                               iptr->opc = ICMD_CASTORECONST;
+                                                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                                                               break;
+                                                                       case ICMD_SASTORE:
+                                                                               iptr->opc = ICMD_SASTORECONST;
+                                                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                                                               break;
+                                                               }
 
-                                                                               iptr[1].opc = ICMD_NOP;
-                                                                               OPTT2_0(TYPE_INT, TYPE_ADR);
-                                                                               COUNT(count_pcmd_op);
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       } 
-                                                                       else
-                                                                               PUSHCONST(TYPE_INT);
-# endif
-# if defined(ENABLE_INTRP)
-                                                               } 
-                                                               else
-                                                                       PUSHCONST(TYPE_INT);
-# endif
+                                                               iptr[1].opc = ICMD_NOP;
+
+                                                               /* copy the constant to s3 */
+                                                               /* XXX constval -> astoreconstval? */
+                                                               iptr->sx.s23.s3.constval = iptr->sx.val.i;
+                                                               OP2_0(TYPE_ADR, TYPE_INT);
+                                                               COUNT(count_pcmd_op);
                                                                break;
 
                                                        case ICMD_PUTSTATIC:
                                                        case ICMD_PUTFIELD:
-# if defined(ENABLE_INTRP)
-                                                               if (!opt_intrp) {
-# endif
 # if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       if (iptr[0].val.i == 0) {
+                                                               if (iptr->sx.val.i != 0)
+                                                                       goto normal_ICONST;
 # endif
-                                                                               switch (iptr[1].opc) {
-                                                                               case ICMD_PUTSTATIC:
-                                                                                       iptr[0].opc = ICMD_PUTSTATICCONST;
-                                                                                       SETDST;
-                                                                                       break;
-                                                                               case ICMD_PUTFIELD:
-                                                                                       iptr[0].opc = ICMD_PUTFIELDCONST;
-                                                                                       OP1_0(TYPE_ADR);
-                                                                                       break;
-                                                                               }
+                                                               /* XXX check field type? */
 
-                                                                               iptr[1].opc = ICMD_NOP;
-                                                                               iptr[0].op1 = TYPE_INT;
-                                                                               COUNT(count_pcmd_op);
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       } 
-                                                                       else
-                                                                               PUSHCONST(TYPE_INT);
-# endif
-# if defined(ENABLE_INTRP)
-                                                               } 
-                                                               else
-                                                                       PUSHCONST(TYPE_INT);
-# endif
+                                                               /* copy the constant to s2 */
+                                                               /* XXX constval -> fieldconstval? */
+                                                               iptr->sx.s23.s2.constval = iptr->sx.val.i;
+
+putconst_tail:
+                                                               /* set the field reference (s3) */
+                                                               if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
+                                                                       iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
+                                                                       iptr->flags.bits |= INS_FLAG_UNRESOLVED;
+                                                               }
+                                                               else {
+                                                                       iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
+                                                               }
+                                                               
+                                                               switch (iptr[1].opc) {
+                                                                       case ICMD_PUTSTATIC:
+                                                                               iptr->opc = ICMD_PUTSTATICCONST;
+                                                                               OP0_0;
+                                                                               break;
+                                                                       case ICMD_PUTFIELD:
+                                                                               iptr->opc = ICMD_PUTFIELDCONST;
+                                                                               OP1_0(TYPE_ADR);
+                                                                               break;
+                                                               }
+
+                                                               iptr[1].opc = ICMD_NOP;
+                                                               COUNT(count_pcmd_op);
                                                                break;
 #endif /* SUPPORT_CONST_STORE */
+
                                                        default:
-                                                               PUSHCONST(TYPE_INT);
-                                                       }
+                                                               goto normal_ICONST;
                                                }
-                                               else
-                                                       PUSHCONST(TYPE_INT);
+
+                                               /* if we get here, the ICONST has been optimized */
+                                               break;
+
+normal_ICONST:
+                                               /* normal case of an unoptimized ICONST */
+                                               OP0_1(TYPE_INT);
                                                break;
 
+       /************************** LCONST OPTIMIZATIONS **************************/
+
                                        case ICMD_LCONST:
                                                COUNT(count_pcmd_load);
-                                               if (len > 0) {
-                                                       switch (iptr[1].opc) {
+                                               if (len == 0)
+                                                       goto normal_LCONST;
+
+                                               /* switch depending on the following instruction */
+
+                                               switch (iptr[1].opc) {
 #if SUPPORT_LONG_ADD
                                                        case ICMD_LADD:
-                                                               iptr[0].opc = ICMD_LADDCONST;
+                                                               iptr->opc = ICMD_LADDCONST;
+                                                               /* FALLTHROUGH */
+
                                                        icmd_lconst_tail:
+                                                               /* instruction of type LONG -> LONG */
                                                                iptr[1].opc = ICMD_NOP;
-                                                               OP1_1(TYPE_LNG,TYPE_LNG);
+                                                               OP1_1(TYPE_LNG, TYPE_LNG);
                                                                COUNT(count_pcmd_op);
                                                                break;
+
                                                        case ICMD_LSUB:
-                                                               iptr[0].opc = ICMD_LSUBCONST;
+                                                               iptr->opc = ICMD_LSUBCONST;
                                                                goto icmd_lconst_tail;
+
 #endif /* SUPPORT_LONG_ADD */
 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
                                                        case ICMD_LMUL:
-                                                               iptr[0].opc = ICMD_LMULCONST;
+                                                               iptr->opc = ICMD_LMULCONST;
                                                                goto icmd_lconst_tail;
 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
 # if SUPPORT_LONG_SHIFT
                                                        case ICMD_LMUL:
-                                                               if (iptr[0].val.l == 0x00000002)
-                                                                       iptr[0].val.i = 1;
-                                                               else if (iptr[0].val.l == 0x00000004)
-                                                                       iptr[0].val.i = 2;
-                                                               else if (iptr[0].val.l == 0x00000008)
-                                                                       iptr[0].val.i = 3;
-                                                               else if (iptr[0].val.l == 0x00000010)
-                                                                       iptr[0].val.i = 4;
-                                                               else if (iptr[0].val.l == 0x00000020)
-                                                                       iptr[0].val.i = 5;
-                                                               else if (iptr[0].val.l == 0x00000040)
-                                                                       iptr[0].val.i = 6;
-                                                               else if (iptr[0].val.l == 0x00000080)
-                                                                       iptr[0].val.i = 7;
-                                                               else if (iptr[0].val.l == 0x00000100)
-                                                                       iptr[0].val.i = 8;
-                                                               else if (iptr[0].val.l == 0x00000200)
-                                                                       iptr[0].val.i = 9;
-                                                               else if (iptr[0].val.l == 0x00000400)
-                                                                       iptr[0].val.i = 10;
-                                                               else if (iptr[0].val.l == 0x00000800)
-                                                                       iptr[0].val.i = 11;
-                                                               else if (iptr[0].val.l == 0x00001000)
-                                                                       iptr[0].val.i = 12;
-                                                               else if (iptr[0].val.l == 0x00002000)
-                                                                       iptr[0].val.i = 13;
-                                                               else if (iptr[0].val.l == 0x00004000)
-                                                                       iptr[0].val.i = 14;
-                                                               else if (iptr[0].val.l == 0x00008000)
-                                                                       iptr[0].val.i = 15;
-                                                               else if (iptr[0].val.l == 0x00010000)
-                                                                       iptr[0].val.i = 16;
-                                                               else if (iptr[0].val.l == 0x00020000)
-                                                                       iptr[0].val.i = 17;
-                                                               else if (iptr[0].val.l == 0x00040000)
-                                                                       iptr[0].val.i = 18;
-                                                               else if (iptr[0].val.l == 0x00080000)
-                                                                       iptr[0].val.i = 19;
-                                                               else if (iptr[0].val.l == 0x00100000)
-                                                                       iptr[0].val.i = 20;
-                                                               else if (iptr[0].val.l == 0x00200000)
-                                                                       iptr[0].val.i = 21;
-                                                               else if (iptr[0].val.l == 0x00400000)
-                                                                       iptr[0].val.i = 22;
-                                                               else if (iptr[0].val.l == 0x00800000)
-                                                                       iptr[0].val.i = 23;
-                                                               else if (iptr[0].val.l == 0x01000000)
-                                                                       iptr[0].val.i = 24;
-                                                               else if (iptr[0].val.l == 0x02000000)
-                                                                       iptr[0].val.i = 25;
-                                                               else if (iptr[0].val.l == 0x04000000)
-                                                                       iptr[0].val.i = 26;
-                                                               else if (iptr[0].val.l == 0x08000000)
-                                                                       iptr[0].val.i = 27;
-                                                               else if (iptr[0].val.l == 0x10000000)
-                                                                       iptr[0].val.i = 28;
-                                                               else if (iptr[0].val.l == 0x20000000)
-                                                                       iptr[0].val.i = 29;
-                                                               else if (iptr[0].val.l == 0x40000000)
-                                                                       iptr[0].val.i = 30;
-                                                               else if (iptr[0].val.l == 0x80000000)
-                                                                       iptr[0].val.i = 31;
+                                                               if (iptr->sx.val.l == 0x00000002)
+                                                                       iptr->sx.val.i = 1;
+                                                               else if (iptr->sx.val.l == 0x00000004)
+                                                                       iptr->sx.val.i = 2;
+                                                               else if (iptr->sx.val.l == 0x00000008)
+                                                                       iptr->sx.val.i = 3;
+                                                               else if (iptr->sx.val.l == 0x00000010)
+                                                                       iptr->sx.val.i = 4;
+                                                               else if (iptr->sx.val.l == 0x00000020)
+                                                                       iptr->sx.val.i = 5;
+                                                               else if (iptr->sx.val.l == 0x00000040)
+                                                                       iptr->sx.val.i = 6;
+                                                               else if (iptr->sx.val.l == 0x00000080)
+                                                                       iptr->sx.val.i = 7;
+                                                               else if (iptr->sx.val.l == 0x00000100)
+                                                                       iptr->sx.val.i = 8;
+                                                               else if (iptr->sx.val.l == 0x00000200)
+                                                                       iptr->sx.val.i = 9;
+                                                               else if (iptr->sx.val.l == 0x00000400)
+                                                                       iptr->sx.val.i = 10;
+                                                               else if (iptr->sx.val.l == 0x00000800)
+                                                                       iptr->sx.val.i = 11;
+                                                               else if (iptr->sx.val.l == 0x00001000)
+                                                                       iptr->sx.val.i = 12;
+                                                               else if (iptr->sx.val.l == 0x00002000)
+                                                                       iptr->sx.val.i = 13;
+                                                               else if (iptr->sx.val.l == 0x00004000)
+                                                                       iptr->sx.val.i = 14;
+                                                               else if (iptr->sx.val.l == 0x00008000)
+                                                                       iptr->sx.val.i = 15;
+                                                               else if (iptr->sx.val.l == 0x00010000)
+                                                                       iptr->sx.val.i = 16;
+                                                               else if (iptr->sx.val.l == 0x00020000)
+                                                                       iptr->sx.val.i = 17;
+                                                               else if (iptr->sx.val.l == 0x00040000)
+                                                                       iptr->sx.val.i = 18;
+                                                               else if (iptr->sx.val.l == 0x00080000)
+                                                                       iptr->sx.val.i = 19;
+                                                               else if (iptr->sx.val.l == 0x00100000)
+                                                                       iptr->sx.val.i = 20;
+                                                               else if (iptr->sx.val.l == 0x00200000)
+                                                                       iptr->sx.val.i = 21;
+                                                               else if (iptr->sx.val.l == 0x00400000)
+                                                                       iptr->sx.val.i = 22;
+                                                               else if (iptr->sx.val.l == 0x00800000)
+                                                                       iptr->sx.val.i = 23;
+                                                               else if (iptr->sx.val.l == 0x01000000)
+                                                                       iptr->sx.val.i = 24;
+                                                               else if (iptr->sx.val.l == 0x02000000)
+                                                                       iptr->sx.val.i = 25;
+                                                               else if (iptr->sx.val.l == 0x04000000)
+                                                                       iptr->sx.val.i = 26;
+                                                               else if (iptr->sx.val.l == 0x08000000)
+                                                                       iptr->sx.val.i = 27;
+                                                               else if (iptr->sx.val.l == 0x10000000)
+                                                                       iptr->sx.val.i = 28;
+                                                               else if (iptr->sx.val.l == 0x20000000)
+                                                                       iptr->sx.val.i = 29;
+                                                               else if (iptr->sx.val.l == 0x40000000)
+                                                                       iptr->sx.val.i = 30;
+                                                               else if (iptr->sx.val.l == 0x80000000)
+                                                                       iptr->sx.val.i = 31;
                                                                else {
-                                                                       PUSHCONST(TYPE_LNG);
-                                                                       break;
+                                                                       goto normal_LCONST;
                                                                }
-                                                               iptr[0].opc = ICMD_LMULPOW2;
+                                                               iptr->opc = ICMD_LMULPOW2;
                                                                goto icmd_lconst_tail;
 # endif /* SUPPORT_LONG_SHIFT */
 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
-
 #if SUPPORT_LONG_DIV_POW2
                                                        case ICMD_LDIV:
-                                                               if (iptr[0].val.l == 0x00000002)
-                                                                       iptr[0].val.i = 1;
-                                                               else if (iptr[0].val.l == 0x00000004)
-                                                                       iptr[0].val.i = 2;
-                                                               else if (iptr[0].val.l == 0x00000008)
-                                                                       iptr[0].val.i = 3;
-                                                               else if (iptr[0].val.l == 0x00000010)
-                                                                       iptr[0].val.i = 4;
-                                                               else if (iptr[0].val.l == 0x00000020)
-                                                                       iptr[0].val.i = 5;
-                                                               else if (iptr[0].val.l == 0x00000040)
-                                                                       iptr[0].val.i = 6;
-                                                               else if (iptr[0].val.l == 0x00000080)
-                                                                       iptr[0].val.i = 7;
-                                                               else if (iptr[0].val.l == 0x00000100)
-                                                                       iptr[0].val.i = 8;
-                                                               else if (iptr[0].val.l == 0x00000200)
-                                                                       iptr[0].val.i = 9;
-                                                               else if (iptr[0].val.l == 0x00000400)
-                                                                       iptr[0].val.i = 10;
-                                                               else if (iptr[0].val.l == 0x00000800)
-                                                                       iptr[0].val.i = 11;
-                                                               else if (iptr[0].val.l == 0x00001000)
-                                                                       iptr[0].val.i = 12;
-                                                               else if (iptr[0].val.l == 0x00002000)
-                                                                       iptr[0].val.i = 13;
-                                                               else if (iptr[0].val.l == 0x00004000)
-                                                                       iptr[0].val.i = 14;
-                                                               else if (iptr[0].val.l == 0x00008000)
-                                                                       iptr[0].val.i = 15;
-                                                               else if (iptr[0].val.l == 0x00010000)
-                                                                       iptr[0].val.i = 16;
-                                                               else if (iptr[0].val.l == 0x00020000)
-                                                                       iptr[0].val.i = 17;
-                                                               else if (iptr[0].val.l == 0x00040000)
-                                                                       iptr[0].val.i = 18;
-                                                               else if (iptr[0].val.l == 0x00080000)
-                                                                       iptr[0].val.i = 19;
-                                                               else if (iptr[0].val.l == 0x00100000)
-                                                                       iptr[0].val.i = 20;
-                                                               else if (iptr[0].val.l == 0x00200000)
-                                                                       iptr[0].val.i = 21;
-                                                               else if (iptr[0].val.l == 0x00400000)
-                                                                       iptr[0].val.i = 22;
-                                                               else if (iptr[0].val.l == 0x00800000)
-                                                                       iptr[0].val.i = 23;
-                                                               else if (iptr[0].val.l == 0x01000000)
-                                                                       iptr[0].val.i = 24;
-                                                               else if (iptr[0].val.l == 0x02000000)
-                                                                       iptr[0].val.i = 25;
-                                                               else if (iptr[0].val.l == 0x04000000)
-                                                                       iptr[0].val.i = 26;
-                                                               else if (iptr[0].val.l == 0x08000000)
-                                                                       iptr[0].val.i = 27;
-                                                               else if (iptr[0].val.l == 0x10000000)
-                                                                       iptr[0].val.i = 28;
-                                                               else if (iptr[0].val.l == 0x20000000)
-                                                                       iptr[0].val.i = 29;
-                                                               else if (iptr[0].val.l == 0x40000000)
-                                                                       iptr[0].val.i = 30;
-                                                               else if (iptr[0].val.l == 0x80000000)
-                                                                       iptr[0].val.i = 31;
+                                                               if (iptr->sx.val.l == 0x00000002)
+                                                                       iptr->sx.val.i = 1;
+                                                               else if (iptr->sx.val.l == 0x00000004)
+                                                                       iptr->sx.val.i = 2;
+                                                               else if (iptr->sx.val.l == 0x00000008)
+                                                                       iptr->sx.val.i = 3;
+                                                               else if (iptr->sx.val.l == 0x00000010)
+                                                                       iptr->sx.val.i = 4;
+                                                               else if (iptr->sx.val.l == 0x00000020)
+                                                                       iptr->sx.val.i = 5;
+                                                               else if (iptr->sx.val.l == 0x00000040)
+                                                                       iptr->sx.val.i = 6;
+                                                               else if (iptr->sx.val.l == 0x00000080)
+                                                                       iptr->sx.val.i = 7;
+                                                               else if (iptr->sx.val.l == 0x00000100)
+                                                                       iptr->sx.val.i = 8;
+                                                               else if (iptr->sx.val.l == 0x00000200)
+                                                                       iptr->sx.val.i = 9;
+                                                               else if (iptr->sx.val.l == 0x00000400)
+                                                                       iptr->sx.val.i = 10;
+                                                               else if (iptr->sx.val.l == 0x00000800)
+                                                                       iptr->sx.val.i = 11;
+                                                               else if (iptr->sx.val.l == 0x00001000)
+                                                                       iptr->sx.val.i = 12;
+                                                               else if (iptr->sx.val.l == 0x00002000)
+                                                                       iptr->sx.val.i = 13;
+                                                               else if (iptr->sx.val.l == 0x00004000)
+                                                                       iptr->sx.val.i = 14;
+                                                               else if (iptr->sx.val.l == 0x00008000)
+                                                                       iptr->sx.val.i = 15;
+                                                               else if (iptr->sx.val.l == 0x00010000)
+                                                                       iptr->sx.val.i = 16;
+                                                               else if (iptr->sx.val.l == 0x00020000)
+                                                                       iptr->sx.val.i = 17;
+                                                               else if (iptr->sx.val.l == 0x00040000)
+                                                                       iptr->sx.val.i = 18;
+                                                               else if (iptr->sx.val.l == 0x00080000)
+                                                                       iptr->sx.val.i = 19;
+                                                               else if (iptr->sx.val.l == 0x00100000)
+                                                                       iptr->sx.val.i = 20;
+                                                               else if (iptr->sx.val.l == 0x00200000)
+                                                                       iptr->sx.val.i = 21;
+                                                               else if (iptr->sx.val.l == 0x00400000)
+                                                                       iptr->sx.val.i = 22;
+                                                               else if (iptr->sx.val.l == 0x00800000)
+                                                                       iptr->sx.val.i = 23;
+                                                               else if (iptr->sx.val.l == 0x01000000)
+                                                                       iptr->sx.val.i = 24;
+                                                               else if (iptr->sx.val.l == 0x02000000)
+                                                                       iptr->sx.val.i = 25;
+                                                               else if (iptr->sx.val.l == 0x04000000)
+                                                                       iptr->sx.val.i = 26;
+                                                               else if (iptr->sx.val.l == 0x08000000)
+                                                                       iptr->sx.val.i = 27;
+                                                               else if (iptr->sx.val.l == 0x10000000)
+                                                                       iptr->sx.val.i = 28;
+                                                               else if (iptr->sx.val.l == 0x20000000)
+                                                                       iptr->sx.val.i = 29;
+                                                               else if (iptr->sx.val.l == 0x40000000)
+                                                                       iptr->sx.val.i = 30;
+                                                               else if (iptr->sx.val.l == 0x80000000)
+                                                                       iptr->sx.val.i = 31;
                                                                else {
-                                                                       PUSHCONST(TYPE_LNG);
-                                                                       break;
+                                                                       goto normal_LCONST;
                                                                }
-                                                               iptr[0].opc = ICMD_LDIVPOW2;
+                                                               iptr->opc = ICMD_LDIVPOW2;
                                                                goto icmd_lconst_tail;
 #endif /* SUPPORT_LONG_DIV_POW2 */
 
 #if SUPPORT_LONG_REM_POW2
                                                        case ICMD_LREM:
-                                                               if ((iptr[0].val.l == 0x00000002) ||
-                                                                       (iptr[0].val.l == 0x00000004) ||
-                                                                       (iptr[0].val.l == 0x00000008) ||
-                                                                       (iptr[0].val.l == 0x00000010) ||
-                                                                       (iptr[0].val.l == 0x00000020) ||
-                                                                       (iptr[0].val.l == 0x00000040) ||
-                                                                       (iptr[0].val.l == 0x00000080) ||
-                                                                       (iptr[0].val.l == 0x00000100) ||
-                                                                       (iptr[0].val.l == 0x00000200) ||
-                                                                       (iptr[0].val.l == 0x00000400) ||
-                                                                       (iptr[0].val.l == 0x00000800) ||
-                                                                       (iptr[0].val.l == 0x00001000) ||
-                                                                       (iptr[0].val.l == 0x00002000) ||
-                                                                       (iptr[0].val.l == 0x00004000) ||
-                                                                       (iptr[0].val.l == 0x00008000) ||
-                                                                       (iptr[0].val.l == 0x00010000) ||
-                                                                       (iptr[0].val.l == 0x00020000) ||
-                                                                       (iptr[0].val.l == 0x00040000) ||
-                                                                       (iptr[0].val.l == 0x00080000) ||
-                                                                       (iptr[0].val.l == 0x00100000) ||
-                                                                       (iptr[0].val.l == 0x00200000) ||
-                                                                       (iptr[0].val.l == 0x00400000) ||
-                                                                       (iptr[0].val.l == 0x00800000) ||
-                                                                       (iptr[0].val.l == 0x01000000) ||
-                                                                       (iptr[0].val.l == 0x02000000) ||
-                                                                       (iptr[0].val.l == 0x04000000) ||
-                                                                       (iptr[0].val.l == 0x08000000) ||
-                                                                       (iptr[0].val.l == 0x10000000) ||
-                                                                       (iptr[0].val.l == 0x20000000) ||
-                                                                       (iptr[0].val.l == 0x40000000) ||
-                                                                       (iptr[0].val.l == 0x80000000)) {
-                                                                       iptr[0].opc = ICMD_LREMPOW2;
-                                                                       iptr[0].val.l -= 1;
+                                                               if ((iptr->sx.val.l == 0x00000002) ||
+                                                                       (iptr->sx.val.l == 0x00000004) ||
+                                                                       (iptr->sx.val.l == 0x00000008) ||
+                                                                       (iptr->sx.val.l == 0x00000010) ||
+                                                                       (iptr->sx.val.l == 0x00000020) ||
+                                                                       (iptr->sx.val.l == 0x00000040) ||
+                                                                       (iptr->sx.val.l == 0x00000080) ||
+                                                                       (iptr->sx.val.l == 0x00000100) ||
+                                                                       (iptr->sx.val.l == 0x00000200) ||
+                                                                       (iptr->sx.val.l == 0x00000400) ||
+                                                                       (iptr->sx.val.l == 0x00000800) ||
+                                                                       (iptr->sx.val.l == 0x00001000) ||
+                                                                       (iptr->sx.val.l == 0x00002000) ||
+                                                                       (iptr->sx.val.l == 0x00004000) ||
+                                                                       (iptr->sx.val.l == 0x00008000) ||
+                                                                       (iptr->sx.val.l == 0x00010000) ||
+                                                                       (iptr->sx.val.l == 0x00020000) ||
+                                                                       (iptr->sx.val.l == 0x00040000) ||
+                                                                       (iptr->sx.val.l == 0x00080000) ||
+                                                                       (iptr->sx.val.l == 0x00100000) ||
+                                                                       (iptr->sx.val.l == 0x00200000) ||
+                                                                       (iptr->sx.val.l == 0x00400000) ||
+                                                                       (iptr->sx.val.l == 0x00800000) ||
+                                                                       (iptr->sx.val.l == 0x01000000) ||
+                                                                       (iptr->sx.val.l == 0x02000000) ||
+                                                                       (iptr->sx.val.l == 0x04000000) ||
+                                                                       (iptr->sx.val.l == 0x08000000) ||
+                                                                       (iptr->sx.val.l == 0x10000000) ||
+                                                                       (iptr->sx.val.l == 0x20000000) ||
+                                                                       (iptr->sx.val.l == 0x40000000) ||
+                                                                       (iptr->sx.val.l == 0x80000000))
+                                                               {
+                                                                       iptr->opc = ICMD_LREMPOW2;
+                                                                       iptr->sx.val.l -= 1;
                                                                        goto icmd_lconst_tail;
                                                                }
-                                                               PUSHCONST(TYPE_LNG);
-                                                               break;
+                                                               goto normal_LCONST;
 #endif /* SUPPORT_LONG_REM_POW2 */
 
 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
 
                                                        case ICMD_LAND:
-                                                               iptr[0].opc = ICMD_LANDCONST;
+                                                               iptr->opc = ICMD_LANDCONST;
                                                                goto icmd_lconst_tail;
+
                                                        case ICMD_LOR:
-                                                               iptr[0].opc = ICMD_LORCONST;
+                                                               iptr->opc = ICMD_LORCONST;
                                                                goto icmd_lconst_tail;
+
                                                        case ICMD_LXOR:
-                                                               iptr[0].opc = ICMD_LXORCONST;
+                                                               iptr->opc = ICMD_LXORCONST;
                                                                goto icmd_lconst_tail;
 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
 
 #if SUPPORT_LONG_CMP_CONST
                                                        case ICMD_LCMP:
-                                                               if ((len > 1) && (iptr[2].val.i == 0)) {
-                                                                       switch (iptr[2].opc) {
+                                                               if ((len <= 1) || (iptr[2].sx.val.i != 0))
+                                                                       goto normal_LCONST;
+
+                                                               /* switch on the instruction after LCONST - LCMP */
+
+                                                               switch (iptr[2].opc) {
                                                                        case ICMD_IFEQ:
-                                                                               iptr[0].opc = ICMD_IF_LEQ;
+                                                                               iptr->opc = ICMD_IF_LEQ;
+                                                                               /* FALLTHROUGH */
+
                                                                        icmd_lconst_lcmp_tail:
-                                                                               iptr[0].op1 = iptr[2].op1;
+                                                                               /* convert LCONST, LCMP, IFXX to IF_LXX */
+                                                                               iptr->dst.insindex = iptr[2].dst.insindex;
                                                                                iptr[1].opc = ICMD_NOP;
                                                                                iptr[2].opc = ICMD_NOP;
 
-/*                                                                             bptr->icount -= 2; */
-/*                                                                             len -= 2; */
-
-                                                                               OP1_0(TYPE_LNG);
-                                                                               tbptr = m->basicblocks +
-                                                                                       m->basicblockindex[iptr[0].op1];
-
-                                                                               iptr[0].target = (void *) tbptr;
-
-                                                                               MARKREACHED(tbptr, copy);
+                                                                               OP1_BRANCH(TYPE_LNG);
+                                                                               BRANCH(tbptr);
                                                                                COUNT(count_pcmd_bra);
                                                                                COUNT(count_pcmd_op);
                                                                                break;
+
                                                                        case ICMD_IFNE:
-                                                                               iptr[0].opc = ICMD_IF_LNE;
+                                                                               iptr->opc = ICMD_IF_LNE;
                                                                                goto icmd_lconst_lcmp_tail;
+
                                                                        case ICMD_IFLT:
-                                                                               iptr[0].opc = ICMD_IF_LLT;
+                                                                               iptr->opc = ICMD_IF_LLT;
                                                                                goto icmd_lconst_lcmp_tail;
+
                                                                        case ICMD_IFGT:
-                                                                               iptr[0].opc = ICMD_IF_LGT;
+                                                                               iptr->opc = ICMD_IF_LGT;
                                                                                goto icmd_lconst_lcmp_tail;
+
                                                                        case ICMD_IFLE:
-                                                                               iptr[0].opc = ICMD_IF_LLE;
+                                                                               iptr->opc = ICMD_IF_LLE;
                                                                                goto icmd_lconst_lcmp_tail;
+
                                                                        case ICMD_IFGE:
-                                                                               iptr[0].opc = ICMD_IF_LGE;
+                                                                               iptr->opc = ICMD_IF_LGE;
                                                                                goto icmd_lconst_lcmp_tail;
+
                                                                        default:
-                                                                               PUSHCONST(TYPE_LNG);
-                                                                       } /* switch (iptr[2].opc) */
-                                                               } /* if (iptr[2].val.i == 0) */
-                                                               else
-                                                                       PUSHCONST(TYPE_LNG);
+                                                                               goto normal_LCONST;
+                                                               } /* end switch on opcode after LCONST - LCMP */
                                                                break;
 #endif /* SUPPORT_LONG_CMP_CONST */
 
 #if SUPPORT_CONST_STORE
                                                        case ICMD_LASTORE:
-# if defined(ENABLE_INTRP)
-                                                               if (!opt_intrp) {
-# endif
 # if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       if (iptr[0].val.l == 0) {
-# endif
-                                                                               iptr[0].opc = ICMD_LASTORECONST;
-                                                                               iptr[1].opc = ICMD_NOP;
-                                                                               OPTT2_0(TYPE_INT, TYPE_ADR);
-                                                                               COUNT(count_pcmd_op);
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       } 
-                                                                       else
-                                                                               PUSHCONST(TYPE_LNG);
-# endif
-# if defined(ENABLE_INTRP)
-                                                               } 
-                                                               else
-                                                                       PUSHCONST(TYPE_LNG);
+                                                               if (iptr->sx.val.l != 0)
+                                                                       goto normal_LCONST;
 # endif
+#if SIZEOF_VOID_P == 4
+                                                               /* the constant must fit into a ptrint */
+                                                               if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
+                                                                       goto normal_LCONST;
+#endif
+                                                               /* move the constant to s3 */
+                                                               iptr->sx.s23.s3.constval = iptr->sx.val.l;
+
+                                                               iptr->opc = ICMD_LASTORECONST;
+                                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                                               OP2_0(TYPE_ADR, TYPE_INT);
+
+                                                               iptr[1].opc = ICMD_NOP;
+                                                               COUNT(count_pcmd_op);
                                                                break;
 
                                                        case ICMD_PUTSTATIC:
                                                        case ICMD_PUTFIELD:
-# if defined(ENABLE_INTRP)
-                                                               if (!opt_intrp) {
-# endif
 # if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       if (iptr[0].val.l == 0) {
+                                                               if (iptr->sx.val.l != 0)
+                                                                       goto normal_LCONST;
 # endif
-                                                                               switch (iptr[1].opc) {
-                                                                               case ICMD_PUTSTATIC:
-                                                                                       iptr[0].opc = ICMD_PUTSTATICCONST;
-                                                                                       SETDST;
-                                                                                       break;
-                                                                               case ICMD_PUTFIELD:
-                                                                                       iptr[0].opc = ICMD_PUTFIELDCONST;
-                                                                                       OP1_0(TYPE_ADR);
-                                                                                       break;
-                                                                               }
+#if SIZEOF_VOID_P == 4
+                                                               /* the constant must fit into a ptrint */
+                                                               if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
+                                                                       goto normal_LCONST;
+#endif
+                                                               /* XXX check field type? */
+
+                                                               /* copy the constant to s2 */
+                                                               /* XXX constval -> fieldconstval? */
+                                                               iptr->sx.s23.s2.constval = iptr->sx.val.l;
+
+                                                               goto putconst_tail;
 
-                                                                               iptr[1].opc = ICMD_NOP;
-                                                                               iptr[0].op1 = TYPE_LNG;
-                                                                               COUNT(count_pcmd_op);
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       } 
-                                                                       else
-                                                                               PUSHCONST(TYPE_LNG);
-# endif
-# if defined(ENABLE_INTRP)
-                                                               } 
-                                                               else
-                                                                       PUSHCONST(TYPE_LNG);
-# endif
-                                                               break;
 #endif /* SUPPORT_CONST_STORE */
+
                                                        default:
-                                                               PUSHCONST(TYPE_LNG);
-                                                       }
-                                               }
-                                               else
-                                                       PUSHCONST(TYPE_LNG);
+                                                               goto normal_LCONST;
+                                               } /* end switch opcode after LCONST */
+
+                                               /* if we get here, the LCONST has been optimized */
+                                               break;
+
+normal_LCONST:
+                                               /* the normal case of an unoptimized LCONST */
+                                               OP0_1(TYPE_LNG);
                                                break;
 
+       /************************ END OF LCONST OPTIMIZATIONS *********************/
+
                                        case ICMD_FCONST:
                                                COUNT(count_pcmd_load);
-                                               PUSHCONST(TYPE_FLT);
+                                               OP0_1(TYPE_FLT);
                                                break;
 
                                        case ICMD_DCONST:
                                                COUNT(count_pcmd_load);
-                                               PUSHCONST(TYPE_DBL);
+                                               OP0_1(TYPE_DBL);
                                                break;
 
+       /************************** ACONST OPTIMIZATIONS **************************/
+
                                        case ICMD_ACONST:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_pcmd_load);
 #if SUPPORT_CONST_STORE
-# if defined(ENABLE_INTRP)
-                                               if (!opt_intrp) {
-# endif
-                                                       /* We can only optimize if the ACONST is resolved
-                                                        * and there is an instruction after it. */
+                                               /* We can only optimize if the ACONST is resolved
+                                                * and there is an instruction after it. */
 
-                                                       if ((len > 0) && INSTRUCTION_IS_RESOLVED(iptr))
-                                                       {
-                                                               switch (iptr[1].opc) {
-                                                               case ICMD_AASTORE:
-                                                                       /* We can only optimize for NULL values
-                                                                        * here because otherwise a checkcast is
-                                                                        * required. */
-                                                                       if (iptr->val.a != NULL)
-                                                                               goto aconst_no_transform;
-
-                                                                       iptr[0].opc = ICMD_AASTORECONST;
-                                                                       OPTT2_0(TYPE_INT, TYPE_ADR);
-
-                                                                       iptr[1].opc = ICMD_NOP;
-                                                                       COUNT(count_pcmd_op);
-                                                                       break;
-
-                                                               case ICMD_PUTSTATIC:
-                                                               case ICMD_PUTFIELD:
-# if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       if (iptr->val.a == 0) {
-# endif
+                                               if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
+                                                       goto normal_ACONST;
+
+                                               switch (iptr[1].opc) {
+                                                       case ICMD_AASTORE:
+                                                               /* We can only optimize for NULL values
+                                                                * here because otherwise a checkcast is
+                                                                * required. */
+                                                               if (iptr->sx.val.anyptr != NULL)
+                                                                       goto normal_ACONST;
 
-                                                                               switch (iptr[1].opc) {
-                                                                               case ICMD_PUTSTATIC:
-                                                                                       iptr[0].opc = ICMD_PUTSTATICCONST;
-                                                                                       iptr[0].op1 = TYPE_ADR;
-                                                                                       SETDST;
-                                                                                       break;
-                                                                               case ICMD_PUTFIELD:
-                                                                                       iptr[0].opc = ICMD_PUTFIELDCONST;
-                                                                                       iptr[0].op1 = TYPE_ADR;
-                                                                                       OP1_0(TYPE_ADR);
-                                                                                       break;
-                                                                               }
+                                                               /* copy the constant (NULL) to s3 */
+                                                               iptr->sx.s23.s3.constval = 0;
+                                                               iptr->opc = ICMD_AASTORECONST;
+                                                               iptr->flags.bits |= INS_FLAG_CHECK;
+                                                               OP2_0(TYPE_ADR, TYPE_INT);
 
-                                                                               iptr[1].opc = ICMD_NOP;
-                                                                               COUNT(count_pcmd_op);
+                                                               iptr[1].opc = ICMD_NOP;
+                                                               COUNT(count_pcmd_op);
+                                                               break;
 
+                                                       case ICMD_PUTSTATIC:
+                                                       case ICMD_PUTFIELD:
 # if SUPPORT_CONST_STORE_ZERO_ONLY
-                                                                       }
-                                                                       else
-                                                                               /* no transformation */
-                                                                               PUSHCONST(TYPE_ADR);
+                                                               if (iptr->sx.val.anyptr != NULL)
+                                                                       goto normal_ACONST;
 # endif
-                                                                       break;
+                                                               /* XXX check field type? */
+                                                               /* copy the constant to s2 */
+                                                               /* XXX constval -> fieldconstval? */
+                                                               iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
 
-                                                               default:
-                                                               aconst_no_transform:
-                                                                       /* no transformation */
-                                                                       PUSHCONST(TYPE_ADR);
-                                                               }
-                                                       }
-                                                       else {
-                                                               /* no transformation */
-                                                               PUSHCONST(TYPE_ADR);
-                                                       }
-# if defined(ENABLE_INTRP)
+                                                               goto putconst_tail;
+
+                                                       default:
+                                                               goto normal_ACONST;
                                                }
-                                               else
-                                                       PUSHCONST(TYPE_ADR);
-# endif
-#else /* SUPPORT_CONST_STORE */
-                                               PUSHCONST(TYPE_ADR);
+
+                                               /* if we get here the ACONST has been optimized */
+                                               break;
+
+normal_ACONST:
 #endif /* SUPPORT_CONST_STORE */
+                                               OP0_1(TYPE_ADR);
                                                break;
 
+
                                                /* pop 0 push 1 load */
-                                               
+
                                        case ICMD_ILOAD:
                                        case ICMD_LLOAD:
                                        case ICMD_FLOAD:
                                        case ICMD_DLOAD:
                                        case ICMD_ALOAD:
                                                COUNT(count_load_instruction);
-                                               i = opcode - ICMD_ILOAD;
-#if defined(ENABLE_INTRP)
-                                               if (!opt_intrp)
+                                               i = opcode - ICMD_ILOAD; /* type */
+
+                                               j = iptr->s1.varindex = 
+                                                       jd->local_map[iptr->s1.varindex * 5 + i];
+
+                                               if (sd.var[j].type == TYPE_RET) {
+                                                       exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
+                                                       return false;
+                                               }
+               
+#if defined(ENABLE_SSA)
+                                               if (ls != NULL) {
+                                                       GET_NEW_VAR(sd, new_index, i);
+                                                       DST(i, new_index);
+                                                       stackdepth++;
+                                               }
+                                               else
+
+#else
+                                               LOAD(i, j);
 #endif
-                                                       rd->locals[iptr->op1][i].type = i;
-                                               LOAD(i, LOCALVAR, iptr->op1);
                                                break;
 
                                                /* pop 2 push 1 */
 
                                        case ICMD_LALOAD:
-                                       case ICMD_IALOAD:
                                        case ICMD_FALOAD:
                                        case ICMD_DALOAD:
                                        case ICMD_AALOAD:
+                                               coalescing_boundary = sd.new;
+                                               iptr->flags.bits |= INS_FLAG_CHECK;
                                                COUNT(count_check_null);
                                                COUNT(count_check_bound);
                                                COUNT(count_pcmd_mem);
-                                               OP2IAT_1(opcode - ICMD_IALOAD);
+                                               OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
                                                break;
 
+                                       case ICMD_IALOAD:
                                        case ICMD_BALOAD:
                                        case ICMD_CALOAD:
                                        case ICMD_SALOAD:
+                                               coalescing_boundary = sd.new;
+                                               iptr->flags.bits |= INS_FLAG_CHECK;
                                                COUNT(count_check_null);
                                                COUNT(count_check_bound);
                                                COUNT(count_pcmd_mem);
-                                               OP2IAT_1(TYPE_INT);
+                                               OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
                                                break;
 
                                                /* pop 0 push 0 iinc */
 
                                        case ICMD_IINC:
+                                               STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
+#if defined(ENABLE_SSA)
+                                               if (ls != NULL) {
+                                                       iptr->s1.varindex = 
+                                                               jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
+                                               }
+                                               else {
+#endif
+                                               last_store_boundary[iptr->s1.varindex] = sd.new;
+
+                                               iptr->s1.varindex = 
+                                                       jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
+
+                                               copy = curstack;
+                                               i = stackdepth - 1;
+                                               while (copy) {
+                                                       if ((copy->varkind == LOCALVAR) &&
+                                                               (copy->varnum == iptr->s1.varindex))
+                                                       {
+                                                               assert(IS_LOCALVAR(copy));
+                                                               SET_TEMPVAR(copy);
+                                                       }
+                                                       i--;
+                                                       copy = copy->prev;
+                                               }
+#if defined(ENABLE_SSA)
+                                               }
+#endif
+
+                                               iptr->dst.varindex = iptr->s1.varindex;
+                                               break;
+
+                                               /* pop 1 push 0 store */
+
+                                       case ICMD_ISTORE:
+                                       case ICMD_LSTORE:
+                                       case ICMD_FSTORE:
+                                       case ICMD_DSTORE:
+                                       case ICMD_ASTORE:
+                                               REQUIRE(1);
+
+                                               i = opcode - ICMD_ISTORE; /* type */
+                                               javaindex = iptr->dst.varindex;
+                                               j = iptr->dst.varindex = 
+                                                       jd->local_map[javaindex * 5 + i];
+
+                                               COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
+
 #if defined(ENABLE_STATISTICS)
                                                if (opt_stat) {
-                                                       i = stackdepth;
+                                                       count_pcmd_store++;
+                                                       i = sd.new - curstack;
+                                                       if (i >= 20)
+                                                               count_store_length[20]++;
+                                                       else
+                                                               count_store_length[i]++;
+                                                       i = stackdepth - 1;
                                                        if (i >= 10)
                                                                count_store_depth[10]++;
                                                        else
                                                                count_store_depth[i]++;
                                                }
 #endif
-                                               last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1;
 
-                                               copy = curstack;
-                                               i = stackdepth - 1;
+#if defined(ENABLE_SSA)
+                                               if (ls != NULL) {
+#endif
+                                               /* check for conflicts as described in Figure 5.2 */
+
+                                               copy = curstack->prev;
+                                               i = stackdepth - 2;
                                                while (copy) {
                                                        if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == iptr->op1)) {
+                                                               (copy->varnum == j))
+                                                       {
                                                                copy->varkind = TEMPVAR;
-                                                               copy->varnum = i;
+                                                               assert(IS_LOCALVAR(copy));
+                                                               SET_TEMPVAR(copy);
                                                        }
                                                        i--;
                                                        copy = copy->prev;
                                                }
-                                               
-                                               SETDST;
-                                               break;
-
-                                               /* pop 1 push 0 store */
 
-                                       case ICMD_ISTORE:
-                                       case ICMD_LSTORE:
-                                       case ICMD_FSTORE:
-                                       case ICMD_DSTORE:
-                                       case ICMD_ASTORE:
-                                               REQUIRE_1;
+                                               /* if the variable is already coalesced, don't bother */
 
-                                       i = opcode - ICMD_ISTORE;
-#if defined(ENABLE_INTRP)
-                                               if (!opt_intrp)
-#endif
-                                                       rd->locals[iptr->op1][i].type = i;
-#if defined(ENABLE_STATISTICS)
-                                       if (opt_stat) {
-                                               count_pcmd_store++;
-                                               i = new - curstack;
-                                               if (i >= 20)
-                                                       count_store_length[20]++;
-                                               else
-                                                       count_store_length[i]++;
-                                               i = stackdepth - 1;
-                                               if (i >= 10)
-                                                       count_store_depth[10]++;
-                                               else
-                                                       count_store_depth[i]++;
-                                       }
-#endif
-                                       /* check for conflicts as described in Figure 5.2 */
-                                       copy = curstack->prev;
-                                       i = stackdepth - 2;
-                                       while (copy) {
-                                               if ((copy->varkind == LOCALVAR) &&
-                                                       (copy->varnum == iptr->op1)) {
-                                                       copy->varkind = TEMPVAR;
-                                                       copy->varnum = i;
-                                               }
-                                               i--;
-                                               copy = copy->prev;
-                                       }
+                                               /* We do not need to check against INOUT, as invars */
+                                               /* are always before the coalescing boundary.        */
 
-                                       /* do not change instack Stackslots */
-                                       /* it won't improve performance if we copy the interface */
-                                       /* at the BB begin or here, and lsra relies that no      */
-                                       /* instack stackslot is marked LOCALVAR */
-                                       if (curstack->varkind == STACKVAR)
-                                               goto _possible_conflict;
-
-                                       /* check for a DUPX,SWAP while the lifetime of curstack */
-                                       /* and as creator curstack */
-                                       if (last_dupx != -1) { 
-                                               /* we have to look at the dst stack of DUPX */
-                                               /* == src Stack of PEI */
-                                               copy = bptr->iinstr[last_dupx].dst;
-                                               /*
-                                               if (last_pei == 0)
-                                                       copy = bptr->instack;
-                                               else
-                                                       copy = bptr->iinstr[last_pei-1].dst;
-                                               */
-                                               if ((copy != NULL) && (curstack <= copy)) {
-                                                       /* curstack alive at or created by DUPX */
+                                               if (curstack->varkind == LOCALVAR)
+                                                       goto store_tail;
 
-                                                       /* TODO:.... */
-                                                       /* now look, if there is a LOCALVAR at anyone of */
-                                                       /* the src stacklots used by DUPX */
+                                               /* there is no STORE Lj while curstack is live */
 
-                                                       goto _possible_conflict;
-                                               }
-                                       }
+                                               if (curstack < last_store_boundary[javaindex])
+                                                       goto assume_conflict;
 
-                                       /* check for a PEI while the lifetime of curstack */
-                                       if (last_pei != -1) { 
-                                               /* && there are exception handler in this method */
-                                               /* when this is checked prevent ARGVAR from      */
-                                               /* overwriting LOCALVAR!!! */
+                                               /* curstack must be after the coalescing boundary */
 
-                                               /* we have to look at the stack _before_ the PEI! */
-                                               /* == src Stack of PEI */
-                                               if (last_pei == 0)
-                                                       copy = bptr->instack;
-                                               else
-                                                       copy = bptr->iinstr[last_pei-1].dst;
-                                               if ((copy != NULL) && (curstack <= copy)) {
-                                                       /* curstack alive at PEI */
-                                                       goto _possible_conflict;
-                                               }
-                                       }
-                                       
-                                       /* check if there is a possible conflicting XSTORE */
-                                       if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] != -1) {
-                                               /* we have to look at the stack _before_ the XSTORE! */
-                                               /* == src Stack of XSTORE */
-                                               if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] == 0)
-                                                       copy = bptr->instack;
-                                               else
-                                                       copy = bptr->iinstr[last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] - 1].dst;
-                                               if ((copy != NULL) && (curstack <= copy)) {
-                                                       /* curstack alive at Last Store */
-                                                       goto _possible_conflict;
-                                               }
-                                       }
+                                               if (curstack < coalescing_boundary)
+                                                       goto assume_conflict;
 
-                                       /* check if there is a conflict with a XLOAD */
-                                       /* this is done indirectly by looking if a Stackslot is */
-                                       /* marked LOCALVAR and is live while curstack is live   */
-                                       /* see figure 5.3 */
+                                               /* there is no DEF LOCALVAR(j) while curstack is live */
 
-                                       /* First check "above" stackslots of the instack */
-                                       copy = curstack + 1;
-                                       for(;(copy <= bptr->instack); copy++)
-                                               if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
-                                                       goto _possible_conflict;
+                                               copy = sd.new; /* most recent stackslot created + 1 */
+                                               while (--copy > curstack) {
+                                                       if (copy->varkind == LOCALVAR && copy->varnum == j)
+                                                               goto assume_conflict;
                                                }
-                                       
-                                       /* "intra" Basic Block Stackslots are allocated above    */
-                                       /* bptr->stack (see doc/stack.txt), so if curstack + 1   */
-                                       /* is an instack, copy could point now to the stackslots */
-                                       /* of an inbetween analysed Basic Block */
-                                       if (copy < bptr->stack)
-                                               copy = bptr->stack;
-                                       while (copy < new) {
-                                               if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
-                                                       goto _possible_conflict;
+
+                                               /* coalesce the temporary variable with Lj */
+                                               assert((curstack->varkind == TEMPVAR)
+                                                                       || (curstack->varkind == UNDEFVAR));
+                                               assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
+                                               assert(!IS_INOUT(curstack));
+                                               assert(!IS_PREALLOC(curstack));
+
+                                               assert(curstack->creator);
+                                               assert(curstack->creator->dst.varindex == curstack->varnum);
+                                               RELEASE_INDEX(sd, curstack);
+                                               curstack->varkind = LOCALVAR;
+                                               curstack->varnum = j;
+                                               curstack->creator->dst.varindex = j;
+                                               goto store_tail;
+
+                                               /* revert the coalescing, if it has been done earlier */
+assume_conflict:
+                                               if ((curstack->varkind == LOCALVAR)
+                                                       && (curstack->varnum == j))
+                                               {
+                                                       assert(IS_LOCALVAR(curstack));
+                                                       SET_TEMPVAR(curstack);
                                                }
-                                               copy++;
-                                       }
-                                       /* If Stackslot is already marked as LOCALVAR, do not    */
-                                       /* change it! Conflict resolution works only, if xLOAD   */
-                                       /* has priority! */
-                                       if (curstack->varkind == LOCALVAR)
-                                               goto _possible_conflict;
-                                       /* no conflict - mark the Stackslot as LOCALVAR */
-                                       curstack->varkind = LOCALVAR;
-                                       curstack->varnum = iptr->op1;
-                                       
-                                       goto _local_join;
-                               _possible_conflict:
-                                       if ((curstack->varkind == LOCALVAR) 
-                                               && (curstack->varnum == iptr->op1)) {
-                                               curstack->varkind = TEMPVAR;
-                                               curstack->varnum = stackdepth-1;
-                                       }
-                               _local_join:
-                                       last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] = bptr->icount - len - 1;
 
-                                       STORE(opcode - ICMD_ISTORE);
-                                       break;
+                                               /* remember the stack boundary at this store */
+store_tail:
+                                               last_store_boundary[javaindex] = sd.new;
+#if defined(ENABLE_SSA)
+                                               } /* if (ls != NULL) */
+#endif
+
+                                               if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
+                                                       STORE(TYPE_RET, j);
+                                               else
+                                                       STORE(opcode - ICMD_ISTORE, j);
+                                               break;
 
                                        /* pop 3 push 0 */
 
                                        case ICMD_AASTORE:
+                                               coalescing_boundary = sd.new;
+                                               iptr->flags.bits |= INS_FLAG_CHECK;
                                                COUNT(count_check_null);
                                                COUNT(count_check_bound);
                                                COUNT(count_pcmd_mem);
@@ -4064,35 +3065,46 @@ bool stack_analyse(jitdata *jd)
                                                        rd->memuse = md->memuse;
                                                if (md->argintreguse > rd->argintreguse)
                                                        rd->argintreguse = md->argintreguse;
+                                               /* XXX non-leaf method? */
 
                                                /* make all stack variables saved */
 
                                                copy = curstack;
                                                while (copy) {
+                                                       sd.var[copy->varnum].flags |= SAVEDVAR;
+                                                       /* in case copy->varnum is/will be a LOCALVAR */
+                                                       /* once and set back to a non LOCALVAR        */
+                                                       /* the correct SAVEDVAR flag has to be        */
+                                                       /* remembered in copy->flags, too             */
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
 
-                                               OP3TIA_0(TYPE_ADR);
+                                               OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
                                                break;
 
-                                       case ICMD_IASTORE:
+
                                        case ICMD_LASTORE:
                                        case ICMD_FASTORE:
                                        case ICMD_DASTORE:
+                                               coalescing_boundary = sd.new;
+                                               iptr->flags.bits |= INS_FLAG_CHECK;
                                                COUNT(count_check_null);
                                                COUNT(count_check_bound);
                                                COUNT(count_pcmd_mem);
-                                               OP3TIA_0(opcode - ICMD_IASTORE);
+                                               OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
                                                break;
 
+                                       case ICMD_IASTORE:
                                        case ICMD_BASTORE:
                                        case ICMD_CASTORE:
                                        case ICMD_SASTORE:
+                                               coalescing_boundary = sd.new;
+                                               iptr->flags.bits |= INS_FLAG_CHECK;
                                                COUNT(count_check_null);
                                                COUNT(count_check_bound);
                                                COUNT(count_pcmd_mem);
-                                               OP3TIA_0(TYPE_INT);
+                                               OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
                                                break;
 
                                                /* pop 1 push 0 */
@@ -4100,12 +3112,12 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_POP:
 #ifdef ENABLE_VERIFIER
                                                if (opt_verify) {
-                                                       REQUIRE_1;
+                                                       REQUIRE(1);
                                                        if (IS_2_WORD_TYPE(curstack->type))
                                                                goto throw_stack_category_error;
                                                }
 #endif
-                                               OP1_0ANY;
+                                               OP1_0_ANY;
                                                break;
 
                                        case ICMD_IRETURN:
@@ -4113,28 +3125,30 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_FRETURN:
                                        case ICMD_DRETURN:
                                        case ICMD_ARETURN:
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-                                               if (!opt_intrp)
-# endif
+                                               coalescing_boundary = sd.new;
+                                               /* Assert here that no LOCAL or INOUTS get */
+                                               /* preallocated, since tha macros are not   */
+                                               /* available in md-abi.c! */
+                                               if (IS_TEMPVAR(curstack))
                                                        md_return_alloc(jd, curstack);
-#endif
                                                COUNT(count_pcmd_return);
                                                OP1_0(opcode - ICMD_IRETURN);
                                                superblockend = true;
                                                break;
 
                                        case ICMD_ATHROW:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_check_null);
                                                OP1_0(TYPE_ADR);
-                                               STACKRESET;
-                                               SETDST;
+                                               curstack = NULL; stackdepth = 0;
                                                superblockend = true;
                                                break;
 
                                        case ICMD_PUTSTATIC:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_pcmd_mem);
-                                               OP1_0(iptr->op1);
+                                               INSTRUCTION_GET_FIELDREF(iptr, fmiref);
+                                               OP1_0(fmiref->parseddesc.fd->type);
                                                break;
 
                                                /* pop 1 push 0 branch */
@@ -4142,12 +3156,8 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_IFNULL:
                                        case ICMD_IFNONNULL:
                                                COUNT(count_pcmd_bra);
-                                               OP1_0(TYPE_ADR);
-                                               tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
-
-                                               iptr[0].target = (void *) tbptr;
-
-                                               MARKREACHED(tbptr, copy);
+                                               OP1_BRANCH(TYPE_ADR);
+                                               BRANCH(tbptr);
                                                break;
 
                                        case ICMD_IFEQ:
@@ -4157,106 +3167,21 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_IFGT:
                                        case ICMD_IFLE:
                                                COUNT(count_pcmd_bra);
-#if CONDITIONAL_LOADCONST && 0
-# if defined(ENABLE_INTRP)
-                                               if (!opt_intrp) {
-# endif
-                                                       tbptr = m->basicblocks + b_index;
-
-                                                       if ((b_count >= 3) &&
-                                                               ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
-                                                               (tbptr[1].pre_count == 1) &&
-                                                               (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
-                                                               (tbptr[1].iinstr[1].opc == ICMD_GOTO)   &&
-                                                               ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
-                                                               (tbptr[2].pre_count == 1) &&
-                                                               (tbptr[2].iinstr[0].opc == ICMD_ICONST)  &&
-                                                               (tbptr[2].icount==1)) {
-                                                               /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
-                                                               OP1_1(TYPE_INT, TYPE_INT);
-                                                               switch (iptr[0].opc) {
-                                                               case ICMD_IFEQ:
-                                                                       iptr[0].opc = ICMD_IFNE_ICONST;
-                                                                       break;
-                                                               case ICMD_IFNE:
-                                                                       iptr[0].opc = ICMD_IFEQ_ICONST;
-                                                                       break;
-                                                               case ICMD_IFLT:
-                                                                       iptr[0].opc = ICMD_IFGE_ICONST;
-                                                                       break;
-                                                               case ICMD_IFGE:
-                                                                       iptr[0].opc = ICMD_IFLT_ICONST;
-                                                                       break;
-                                                               case ICMD_IFGT:
-                                                                       iptr[0].opc = ICMD_IFLE_ICONST;
-                                                                       break;
-                                                               case ICMD_IFLE:
-                                                                       iptr[0].opc = ICMD_IFGT_ICONST;
-                                                                       break;
-                                                               }
-#if 1
-                                                               iptr[0].val.i = iptr[1].val.i;
-                                                               iptr[1].opc = ICMD_ELSE_ICONST;
-                                                               iptr[1].val.i = iptr[3].val.i;
-                                                               iptr[2].opc = ICMD_NOP;
-                                                               iptr[3].opc = ICMD_NOP;
-#else
-                                                               /* HACK: save compare value in iptr[1].op1 */    
-                                                               iptr[1].op1 = iptr[0].val.i;     
-                                                               iptr[0].val.i = tbptr[1].iinstr[0].val.i;        
-                                                               iptr[1].opc = ICMD_ELSE_ICONST;          
-                                                               iptr[1].val.i = tbptr[2].iinstr[0].val.i;        
-                                                               tbptr[1].iinstr[0].opc = ICMD_NOP;       
-                                                               tbptr[1].iinstr[1].opc = ICMD_NOP;       
-                                                               tbptr[2].iinstr[0].opc = ICMD_NOP;       
-#endif
-                                                               tbptr[1].flags = BBDELETED;
-                                                               tbptr[2].flags = BBDELETED;
-                                                               tbptr[1].icount = 0;
-                                                               tbptr[2].icount = 0;
-                                                               if (tbptr[3].pre_count == 2) {
-                                                                       len += tbptr[3].icount + 3;
-                                                                       bptr->icount += tbptr[3].icount + 3;
-                                                                       tbptr[3].flags = BBDELETED;
-                                                                       tbptr[3].icount = 0;
-                                                                       b_index++;
-                                                               }
-                                                               else {
-                                                                       bptr->icount++;
-                                                                       len ++;
-                                                               }
-                                                               b_index += 2;
-                                                               break;
-                                                       }
-# if defined(ENABLE_INTRP)
-                                               }
-# endif
-
-#endif /* CONDITIONAL_LOADCONST */
-
-                                               /* iptr->val.i is set implicitly in parse by
+                                               /* iptr->sx.val.i is set implicitly in parse by
                                                   clearing the memory or from IF_ICMPxx
                                                   optimization. */
 
-                                               OP1_0(TYPE_INT);
-/*                                             iptr->val.i = 0; */
-                                               tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
-
-                                               iptr[0].target = (void *) tbptr;
-
-                                               MARKREACHED(tbptr, copy);
+                                               OP1_BRANCH(TYPE_INT);
+/*                                             iptr->sx.val.i = 0; */
+                                               BRANCH(tbptr);
                                                break;
 
                                                /* pop 0 push 0 branch */
 
                                        case ICMD_GOTO:
                                                COUNT(count_pcmd_bra);
-                                               tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
-
-                                               iptr[0].target = (void *) tbptr;
-
-                                               MARKREACHED(tbptr, copy);
-                                               SETDST;
+                                               OP0_BRANCH;
+                                               BRANCH(tbptr);
                                                superblockend = true;
                                                break;
 
@@ -4264,63 +3189,45 @@ bool stack_analyse(jitdata *jd)
 
                                        case ICMD_TABLESWITCH:
                                                COUNT(count_pcmd_table);
-                                               OP1_0(TYPE_INT);
-                                               s4ptr = iptr->val.a;
-                                               tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
-                                               MARKREACHED(tbptr, copy);
-                                               i = *s4ptr++;                          /* low     */
-                                               i = *s4ptr++ - i + 1;                  /* high    */
+                                               OP1_BRANCH(TYPE_INT);
 
-                                               tptr = DMNEW(void*, i+1);
-                                               iptr->target = (void *) tptr;
+                                               table = iptr->dst.table;
+                                               BRANCH_TARGET(*table, tbptr);
+                                               table++;
 
-                                               tptr[0] = (void *) tbptr;
-                                               tptr++;
+                                               i = iptr->sx.s23.s3.tablehigh
+                                                 - iptr->sx.s23.s2.tablelow + 1;
 
                                                while (--i >= 0) {
-                                                       tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
-
-                                                       tptr[0] = (void *) tbptr;
-                                                       tptr++;
-
-                                                       MARKREACHED(tbptr, copy);
+                                                       BRANCH_TARGET(*table, tbptr);
+                                                       table++;
                                                }
-                                               SETDST;
                                                superblockend = true;
                                                break;
-                                                       
+
                                                /* pop 1 push 0 table branch */
 
                                        case ICMD_LOOKUPSWITCH:
                                                COUNT(count_pcmd_table);
-                                               OP1_0(TYPE_INT);
-                                               s4ptr = iptr->val.a;
-                                               tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
-                                               MARKREACHED(tbptr, copy);
-                                               i = *s4ptr++;                          /* count   */
+                                               OP1_BRANCH(TYPE_INT);
 
-                                               tptr = DMNEW(void*, i+1);
-                                               iptr->target = (void *) tptr;
+                                               BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
 
-                                               tptr[0] = (void *) tbptr;
-                                               tptr++;
+                                               lookup = iptr->dst.lookup;
 
-                                               while (--i >= 0) {
-                                                       tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
+                                               i = iptr->sx.s23.s2.lookupcount;
 
-                                                       tptr[0] = (void *) tbptr;
-                                                       tptr++;
-                                                               
-                                                       MARKREACHED(tbptr, copy);
-                                                       s4ptr += 2;
+                                               while (--i >= 0) {
+                                                       BRANCH_TARGET(lookup->target, tbptr);
+                                                       lookup++;
                                                }
-                                               SETDST;
                                                superblockend = true;
                                                break;
 
                                        case ICMD_MONITORENTER:
-                                               COUNT(count_check_null);
                                        case ICMD_MONITOREXIT:
+                                               coalescing_boundary = sd.new;
+                                               COUNT(count_check_null);
                                                OP1_0(TYPE_ADR);
                                                break;
 
@@ -4333,241 +3240,346 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_IF_ICMPGT:
                                        case ICMD_IF_ICMPLE:
                                                COUNT(count_pcmd_bra);
-                                               OP2_0(TYPE_INT);
-                                               tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
-                                                       
-                                               iptr[0].target = (void *) tbptr;
-
-                                               MARKREACHED(tbptr, copy);
+                                               OP2_BRANCH(TYPE_INT, TYPE_INT);
+                                               BRANCH(tbptr);
                                                break;
 
                                        case ICMD_IF_ACMPEQ:
                                        case ICMD_IF_ACMPNE:
                                                COUNT(count_pcmd_bra);
-                                               OP2_0(TYPE_ADR);
-                                               tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
-
-                                               iptr[0].target = (void *) tbptr;
-
-                                               MARKREACHED(tbptr, copy);
+                                               OP2_BRANCH(TYPE_ADR, TYPE_ADR);
+                                               BRANCH(tbptr);
                                                break;
 
                                                /* pop 2 push 0 */
 
                                        case ICMD_PUTFIELD:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_check_null);
                                                COUNT(count_pcmd_mem);
-                                               OPTT2_0(iptr->op1,TYPE_ADR);
+                                               INSTRUCTION_GET_FIELDREF(iptr, fmiref);
+                                               OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
                                                break;
 
                                        case ICMD_POP2:
-                                               REQUIRE_1;
+                                               REQUIRE(1);
                                                if (!IS_2_WORD_TYPE(curstack->type)) {
                                                        /* ..., cat1 */
 #ifdef ENABLE_VERIFIER
                                                        if (opt_verify) {
-                                                               REQUIRE_2;
+                                                               REQUIRE(2);
                                                                if (IS_2_WORD_TYPE(curstack->prev->type))
                                                                        goto throw_stack_category_error;
                                                        }
 #endif
-                                                       OP1_0ANY;                /* second pop */
+                                                       OP2_0_ANY_ANY; /* pop two slots */
                                                }
-                                               else
+                                               else {
                                                        iptr->opc = ICMD_POP;
-                                               OP1_0ANY;
+                                                       OP1_0_ANY; /* pop one (two-word) slot */
+                                               }
                                                break;
 
                                                /* pop 0 push 1 dup */
-                                               
+
                                        case ICMD_DUP:
 #ifdef ENABLE_VERIFIER
                                                if (opt_verify) {
-                                                       REQUIRE_1;
+                                                       REQUIRE(1);
                                                        if (IS_2_WORD_TYPE(curstack->type))
-                                                               goto throw_stack_category_error;
+                                                               goto throw_stack_category_error;
                                                }
 #endif
-                                               last_dupx = bptr->icount - len - 1;
                                                COUNT(count_dup_instruction);
-                                               DUP;
+
+icmd_DUP:
+                                               src1 = curstack;
+
+                                               COPY_UP(src1);
+                                               coalescing_boundary = sd.new - 1;
                                                break;
 
                                        case ICMD_DUP2:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_1;
+                                               REQUIRE(1);
                                                if (IS_2_WORD_TYPE(curstack->type)) {
                                                        /* ..., cat2 */
                                                        iptr->opc = ICMD_DUP;
-                                                       DUP;
+                                                       goto icmd_DUP;
                                                }
                                                else {
-                                                       REQUIRE_2;
+                                                       REQUIRE(2);
                                                        /* ..., ????, cat1 */
 #ifdef ENABLE_VERIFIER
                                                        if (opt_verify) {
                                                                if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
+                                                                       goto throw_stack_category_error;
                                                        }
 #endif
-                                                       copy = curstack;
-                                                       NEWSTACK(copy->prev->type, copy->prev->varkind,
-                                                                        copy->prev->varnum);
-                                                       NEWSTACK(copy->type, copy->varkind,
-                                                                        copy->varnum);
-                                                       SETDST;
-                                                       stackdepth += 2;
+                                                       src1 = curstack->prev;
+                                                       src2 = curstack;
+
+                                                       COPY_UP(src1); iptr++; len--;
+                                                       COPY_UP(src2);
+
+                                                       coalescing_boundary = sd.new;
                                                }
                                                break;
 
                                                /* pop 2 push 3 dup */
-                                               
+
                                        case ICMD_DUP_X1:
 #ifdef ENABLE_VERIFIER
                                                if (opt_verify) {
-                                                       REQUIRE_2;
+                                                       REQUIRE(2);
                                                        if (IS_2_WORD_TYPE(curstack->type) ||
                                                                IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
+                                                                       goto throw_stack_category_error;
                                                }
 #endif
-                                               last_dupx = bptr->icount - len - 1;
-                                               DUP_X1;
+
+icmd_DUP_X1:
+                                               src1 = curstack->prev;
+                                               src2 = curstack;
+                                               POPANY; POPANY;
+                                               stackdepth -= 2;
+
+                                               /* move non-temporary sources out of the way */
+                                               if (!IS_TEMPVAR(src2)) {
+                                                       MOVE_TO_TEMP(src2); iptr++; len--;
+                                               }
+
+                                               DUP_SLOT(src2); dst1 = curstack; stackdepth++;
+
+                                               MOVE_UP(src1); iptr++; len--;
+                                               MOVE_UP(src2); iptr++; len--;
+
+                                               COPY_DOWN(curstack, dst1);
+
+                                               coalescing_boundary = sd.new;
                                                break;
 
                                        case ICMD_DUP2_X1:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_2;
+                                               REQUIRE(2);
                                                if (IS_2_WORD_TYPE(curstack->type)) {
                                                        /* ..., ????, cat2 */
 #ifdef ENABLE_VERIFIER
                                                        if (opt_verify) {
                                                                if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                       goto throw_stack_category_error;
+                                                                       goto throw_stack_category_error;
                                                        }
 #endif
                                                        iptr->opc = ICMD_DUP_X1;
-                                                       DUP_X1;
+                                                       goto icmd_DUP_X1;
                                                }
                                                else {
                                                        /* ..., ????, cat1 */
 #ifdef ENABLE_VERIFIER
                                                        if (opt_verify) {
-                                                               REQUIRE_3;
+                                                               REQUIRE(3);
                                                                if (IS_2_WORD_TYPE(curstack->prev->type)
                                                                        || IS_2_WORD_TYPE(curstack->prev->prev->type))
-                                                                               goto throw_stack_category_error;
+                                                                               goto throw_stack_category_error;
                                                        }
 #endif
-                                                       DUP2_X1;
+
+icmd_DUP2_X1:
+                                                       src1 = curstack->prev->prev;
+                                                       src2 = curstack->prev;
+                                                       src3 = curstack;
+                                                       POPANY; POPANY; POPANY;
+                                                       stackdepth -= 3;
+
+                                                       /* move non-temporary sources out of the way */
+                                                       if (!IS_TEMPVAR(src2)) {
+                                                               MOVE_TO_TEMP(src2); iptr++; len--;
+                                                       }
+                                                       if (!IS_TEMPVAR(src3)) {
+                                                               MOVE_TO_TEMP(src3); iptr++; len--;
+                                                       }
+
+                                                       DUP_SLOT(src2); dst1 = curstack; stackdepth++;
+                                                       DUP_SLOT(src3); dst2 = curstack; stackdepth++;
+
+                                                       MOVE_UP(src1); iptr++; len--;
+                                                       MOVE_UP(src2); iptr++; len--;
+                                                       MOVE_UP(src3); iptr++; len--;
+
+                                                       COPY_DOWN(curstack, dst2); iptr++; len--;
+                                                       COPY_DOWN(curstack->prev, dst1);
+
+                                                       coalescing_boundary = sd.new;
                                                }
                                                break;
 
                                                /* pop 3 push 4 dup */
-                                               
+
                                        case ICMD_DUP_X2:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_2;
+                                               REQUIRE(2);
                                                if (IS_2_WORD_TYPE(curstack->prev->type)) {
                                                        /* ..., cat2, ???? */
 #ifdef ENABLE_VERIFIER
                                                        if (opt_verify) {
                                                                if (IS_2_WORD_TYPE(curstack->type))
-                                                                       goto throw_stack_category_error;
+                                                                       goto throw_stack_category_error;
                                                        }
 #endif
                                                        iptr->opc = ICMD_DUP_X1;
-                                                       DUP_X1;
+                                                       goto icmd_DUP_X1;
                                                }
                                                else {
                                                        /* ..., cat1, ???? */
 #ifdef ENABLE_VERIFIER
                                                        if (opt_verify) {
-                                                               REQUIRE_3;
+                                                               REQUIRE(3);
                                                                if (IS_2_WORD_TYPE(curstack->type)
                                                                        || IS_2_WORD_TYPE(curstack->prev->prev->type))
-                                                                                       goto throw_stack_category_error;
+                                                                                       goto throw_stack_category_error;
                                                        }
 #endif
-                                                       DUP_X2;
+icmd_DUP_X2:
+                                                       src1 = curstack->prev->prev;
+                                                       src2 = curstack->prev;
+                                                       src3 = curstack;
+                                                       POPANY; POPANY; POPANY;
+                                                       stackdepth -= 3;
+
+                                                       /* move non-temporary sources out of the way */
+                                                       if (!IS_TEMPVAR(src2)) {
+                                                               MOVE_TO_TEMP(src2); iptr++; len--;
+                                                       }
+                                                       if (!IS_TEMPVAR(src3)) {
+                                                               MOVE_TO_TEMP(src3); iptr++; len--;
+                                                       }
+
+                                                       DUP_SLOT(src3); dst1 = curstack; stackdepth++;
+
+                                                       MOVE_UP(src1); iptr++; len--;
+                                                       MOVE_UP(src2); iptr++; len--;
+                                                       MOVE_UP(src3); iptr++; len--;
+
+                                                       COPY_DOWN(curstack, dst1);
+
+                                                       coalescing_boundary = sd.new;
                                                }
                                                break;
 
                                        case ICMD_DUP2_X2:
-                                               last_dupx = bptr->icount - len - 1;
-                                               REQUIRE_2;
+                                               REQUIRE(2);
                                                if (IS_2_WORD_TYPE(curstack->type)) {
                                                        /* ..., ????, cat2 */
                                                        if (IS_2_WORD_TYPE(curstack->prev->type)) {
                                                                /* ..., cat2, cat2 */
                                                                iptr->opc = ICMD_DUP_X1;
-                                                               DUP_X1;
+                                                               goto icmd_DUP_X1;
                                                        }
                                                        else {
                                                                /* ..., cat1, cat2 */
 #ifdef ENABLE_VERIFIER
                                                                if (opt_verify) {
-                                                                       REQUIRE_3;
+                                                                       REQUIRE(3);
                                                                        if (IS_2_WORD_TYPE(curstack->prev->prev->type))
-                                                                                       goto throw_stack_category_error;
+                                                                                       goto throw_stack_category_error;
                                                                }
 #endif
                                                                iptr->opc = ICMD_DUP_X2;
-                                                               DUP_X2;
+                                                               goto icmd_DUP_X2;
                                                        }
                                                }
-                                               else {
-                                                       REQUIRE_3;
-                                                       /* ..., ????, ????, cat1 */
-                                                       if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
-                                                               /* ..., cat2, ????, cat1 */
+
+                                               REQUIRE(3);
+                                               /* ..., ????, ????, cat1 */
+
+                                               if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
+                                                       /* ..., cat2, ????, cat1 */
 #ifdef ENABLE_VERIFIER
-                                                               if (opt_verify) {
-                                                                       if (IS_2_WORD_TYPE(curstack->prev->type))
-                                                                               goto throw_stack_category_error;
-                                                               }
-#endif
-                                                               iptr->opc = ICMD_DUP2_X1;
-                                                               DUP2_X1;
+                                                       if (opt_verify) {
+                                                               if (IS_2_WORD_TYPE(curstack->prev->type))
+                                                                       goto throw_stack_category_error;
                                                        }
-                                                       else {
-                                                               /* ..., cat1, ????, cat1 */
+#endif
+                                                       iptr->opc = ICMD_DUP2_X1;
+                                                       goto icmd_DUP2_X1;
+                                               }
+                                               else {
+                                                       /* ..., cat1, ????, cat1 */
 #ifdef ENABLE_VERIFIER
-                                                               if (opt_verify) {
-                                                                       REQUIRE_4;
-                                                                       if (IS_2_WORD_TYPE(curstack->prev->type)
-                                                                               || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
-                                                                               goto throw_stack_category_error;
-                                                               }
+                                                       if (opt_verify) {
+                                                               REQUIRE(4);
+                                                               if (IS_2_WORD_TYPE(curstack->prev->type)
+                                                                       || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
+                                                                       goto throw_stack_category_error;
+                                                       }
 #endif
-                                                               DUP2_X2;
+
+                                                       src1 = curstack->prev->prev->prev;
+                                                       src2 = curstack->prev->prev;
+                                                       src3 = curstack->prev;
+                                                       src4 = curstack;
+                                                       POPANY; POPANY; POPANY; POPANY;
+                                                       stackdepth -= 4;
+
+                                                       /* move non-temporary sources out of the way */
+                                                       if (!IS_TEMPVAR(src2)) {
+                                                               MOVE_TO_TEMP(src2); iptr++; len--;
                                                        }
+                                                       if (!IS_TEMPVAR(src3)) {
+                                                               MOVE_TO_TEMP(src3); iptr++; len--;
+                                                       }
+                                                       if (!IS_TEMPVAR(src4)) {
+                                                               MOVE_TO_TEMP(src4); iptr++; len--;
+                                                       }
+
+                                                       DUP_SLOT(src3); dst1 = curstack; stackdepth++;
+                                                       DUP_SLOT(src4); dst2 = curstack; stackdepth++;
+
+                                                       MOVE_UP(src1); iptr++; len--;
+                                                       MOVE_UP(src2); iptr++; len--;
+                                                       MOVE_UP(src3); iptr++; len--;
+                                                       MOVE_UP(src4); iptr++; len--;
+
+                                                       COPY_DOWN(curstack, dst2); iptr++; len--;
+                                                       COPY_DOWN(curstack->prev, dst1);
+
+                                                       coalescing_boundary = sd.new;
                                                }
                                                break;
 
                                                /* pop 2 push 2 swap */
-                                               
+
                                        case ICMD_SWAP:
-                                               last_dupx = bptr->icount - len - 1;
 #ifdef ENABLE_VERIFIER
                                                if (opt_verify) {
-                                                       REQUIRE_2;
+                                                       REQUIRE(2);
                                                        if (IS_2_WORD_TYPE(curstack->type)
                                                                || IS_2_WORD_TYPE(curstack->prev->type))
                                                                goto throw_stack_category_error;
                                                }
 #endif
-                                               SWAP;
+
+                                               src1 = curstack->prev;
+                                               src2 = curstack;
+                                               POPANY; POPANY;
+                                               stackdepth -= 2;
+
+                                               /* move non-temporary sources out of the way */
+                                               if (!IS_TEMPVAR(src1)) {
+                                                       MOVE_TO_TEMP(src1); iptr++; len--;
+                                               }
+
+                                               MOVE_UP(src2); iptr++; len--;
+                                               MOVE_UP(src1);
+
+                                               coalescing_boundary = sd.new;
                                                break;
 
                                                /* pop 2 push 1 */
 
                                        case ICMD_IDIV:
                                        case ICMD_IREM:
+                                               coalescing_boundary = sd.new;
 #if !SUPPORT_DIVISION
-                                               bte = (builtintable_entry *) iptr->val.a;
+                                               bte = iptr->sx.s23.s3.bte;
                                                md = bte->md;
-                                               i = iptr->op1;
 
                                                if (md->memuse > rd->memuse)
                                                        rd->memuse = md->memuse;
@@ -4578,11 +3590,12 @@ bool stack_analyse(jitdata *jd)
 
                                                copy = curstack;
                                                while (copy) {
+                                                       sd.var[copy->varnum].flags |= SAVEDVAR;
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
+                                               /* FALLTHROUGH */
 
-                                               /* fall through */
 #endif /* !SUPPORT_DIVISION */
 
                                        case ICMD_ISHL:
@@ -4595,30 +3608,32 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_IOR:
                                        case ICMD_IXOR:
                                                COUNT(count_pcmd_op);
-                                               OP2_1(TYPE_INT);
+                                               OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
                                                break;
 
                                        case ICMD_LDIV:
                                        case ICMD_LREM:
+                                               coalescing_boundary = sd.new;
 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
-                                               bte = (builtintable_entry *) iptr->val.a;
+                                               bte = iptr->sx.s23.s3.bte;
                                                md = bte->md;
-                                               i = iptr->op1;
 
                                                if (md->memuse > rd->memuse)
                                                        rd->memuse = md->memuse;
                                                if (md->argintreguse > rd->argintreguse)
                                                        rd->argintreguse = md->argintreguse;
+                                               /* XXX non-leaf method? */
 
                                                /* make all stack variables saved */
 
                                                copy = curstack;
                                                while (copy) {
+                                                       sd.var[copy->varnum].flags |= SAVEDVAR;
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
+                                               /* FALLTHROUGH */
 
-                                               /* fall through */
 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
 
                                        case ICMD_LMUL:
@@ -4630,14 +3645,14 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_LXOR:
 #endif /* SUPPORT_LONG_LOGICAL */
                                                COUNT(count_pcmd_op);
-                                               OP2_1(TYPE_LNG);
+                                               OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
                                                break;
 
                                        case ICMD_LSHL:
                                        case ICMD_LSHR:
                                        case ICMD_LUSHR:
                                                COUNT(count_pcmd_op);
-                                               OP2IT_1(TYPE_LNG);
+                                               OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
                                                break;
 
                                        case ICMD_FADD:
@@ -4646,7 +3661,7 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_FDIV:
                                        case ICMD_FREM:
                                                COUNT(count_pcmd_op);
-                                               OP2_1(TYPE_FLT);
+                                               OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
                                                break;
 
                                        case ICMD_DADD:
@@ -4655,239 +3670,232 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_DDIV:
                                        case ICMD_DREM:
                                                COUNT(count_pcmd_op);
-                                               OP2_1(TYPE_DBL);
+                                               OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
                                                break;
 
                                        case ICMD_LCMP:
                                                COUNT(count_pcmd_op);
 #if SUPPORT_LONG_CMP_CONST
-                                               if ((len > 0) && (iptr[1].val.i == 0)) {
-                                                       switch (iptr[1].opc) {
-                                                       case ICMD_IFEQ:
-                                                               iptr[0].opc = ICMD_IF_LCMPEQ;
-                                                       icmd_lcmp_if_tail:
-                                                               iptr[0].op1 = iptr[1].op1;
-                                                               iptr[1].opc = ICMD_NOP;
-/*                                                             len--; */
-/*                                                             bptr->icount--; */
+                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
+                                                       goto normal_LCMP;
 
-                                                               OP2_0(TYPE_LNG);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) tbptr;
+                                               switch (iptr[1].opc) {
+                                               case ICMD_IFEQ:
+                                                       iptr->opc = ICMD_IF_LCMPEQ;
+                                               icmd_lcmp_if_tail:
+                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr[1].opc = ICMD_NOP;
 
-                                                               MARKREACHED(tbptr, copy);
-                                                               COUNT(count_pcmd_bra);
-                                                               break;
-                                                       case ICMD_IFNE:
-                                                               iptr[0].opc = ICMD_IF_LCMPNE;
-                                                               goto icmd_lcmp_if_tail;
-                                                       case ICMD_IFLT:
-                                                               iptr[0].opc = ICMD_IF_LCMPLT;
-                                                               goto icmd_lcmp_if_tail;
-                                                       case ICMD_IFGT:
-                                                               iptr[0].opc = ICMD_IF_LCMPGT;
-                                                               goto icmd_lcmp_if_tail;
-                                                       case ICMD_IFLE:
-                                                               iptr[0].opc = ICMD_IF_LCMPLE;
-                                                               goto icmd_lcmp_if_tail;
-                                                       case ICMD_IFGE:
-                                                               iptr[0].opc = ICMD_IF_LCMPGE;
-                                                               goto icmd_lcmp_if_tail;
-                                                       default:
-                                                               OPTT2_1(TYPE_LNG, TYPE_INT);
-                                                       }
+                                                       OP2_BRANCH(TYPE_LNG, TYPE_LNG);
+                                                       BRANCH(tbptr);
+
+                                                       COUNT(count_pcmd_bra);
+                                                       break;
+                                               case ICMD_IFNE:
+                                                       iptr->opc = ICMD_IF_LCMPNE;
+                                                       goto icmd_lcmp_if_tail;
+                                               case ICMD_IFLT:
+                                                       iptr->opc = ICMD_IF_LCMPLT;
+                                                       goto icmd_lcmp_if_tail;
+                                               case ICMD_IFGT:
+                                                       iptr->opc = ICMD_IF_LCMPGT;
+                                                       goto icmd_lcmp_if_tail;
+                                               case ICMD_IFLE:
+                                                       iptr->opc = ICMD_IF_LCMPLE;
+                                                       goto icmd_lcmp_if_tail;
+                                               case ICMD_IFGE:
+                                                       iptr->opc = ICMD_IF_LCMPGE;
+                                                       goto icmd_lcmp_if_tail;
+                                               default:
+                                                       goto normal_LCMP;
                                                }
-                                               else
+                                               break;
+normal_LCMP:
 #endif /* SUPPORT_LONG_CMP_CONST */
-                                                       OPTT2_1(TYPE_LNG, TYPE_INT);
+                                                       OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
                                                break;
 
+                                               /* XXX why is this deactivated? */
 #if 0
                                        case ICMD_FCMPL:
                                                COUNT(count_pcmd_op);
-                                               if ((len > 0) && (iptr[1].val.i == 0)) {
-                                                       switch (iptr[1].opc) {
-                                                       case ICMD_IFEQ:
-                                                               iptr[0].opc = ICMD_IF_FCMPEQ;
-                                                       icmd_if_fcmpl_tail:
-                                                               iptr[0].op1 = iptr[1].op1;
-                                                               iptr[1].opc = ICMD_NOP;
+                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
+                                                       goto normal_FCMPL;
+
+                                               switch (iptr[1].opc) {
+                                               case ICMD_IFEQ:
+                                                       iptr->opc = ICMD_IF_FCMPEQ;
+                                               icmd_if_fcmpl_tail:
+                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr[1].opc = ICMD_NOP;
 
-                                                               OP2_0(TYPE_FLT);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) tbptr;
+                                                       OP2_BRANCH(TYPE_FLT, TYPE_FLT);
+                                                       BRANCH(tbptr);
 
-                                                               MARKREACHED(tbptr, copy);
-                                                               COUNT(count_pcmd_bra);
-                                                               break;
-                                                       case ICMD_IFNE:
-                                                               iptr[0].opc = ICMD_IF_FCMPNE;
-                                                               goto icmd_if_fcmpl_tail;
-                                                       case ICMD_IFLT:
-                                                               iptr[0].opc = ICMD_IF_FCMPL_LT;
-                                                               goto icmd_if_fcmpl_tail;
-                                                       case ICMD_IFGT:
-                                                               iptr[0].opc = ICMD_IF_FCMPL_GT;
-                                                               goto icmd_if_fcmpl_tail;
-                                                       case ICMD_IFLE:
-                                                               iptr[0].opc = ICMD_IF_FCMPL_LE;
-                                                               goto icmd_if_fcmpl_tail;
-                                                       case ICMD_IFGE:
-                                                               iptr[0].opc = ICMD_IF_FCMPL_GE;
-                                                               goto icmd_if_fcmpl_tail;
-                                                       default:
-                                                               OPTT2_1(TYPE_FLT, TYPE_INT);
-                                                       }
+                                                       COUNT(count_pcmd_bra);
+                                                       break;
+                                               case ICMD_IFNE:
+                                                       iptr->opc = ICMD_IF_FCMPNE;
+                                                       goto icmd_if_fcmpl_tail;
+                                               case ICMD_IFLT:
+                                                       iptr->opc = ICMD_IF_FCMPL_LT;
+                                                       goto icmd_if_fcmpl_tail;
+                                               case ICMD_IFGT:
+                                                       iptr->opc = ICMD_IF_FCMPL_GT;
+                                                       goto icmd_if_fcmpl_tail;
+                                               case ICMD_IFLE:
+                                                       iptr->opc = ICMD_IF_FCMPL_LE;
+                                                       goto icmd_if_fcmpl_tail;
+                                               case ICMD_IFGE:
+                                                       iptr->opc = ICMD_IF_FCMPL_GE;
+                                                       goto icmd_if_fcmpl_tail;
+                                               default:
+                                                       goto normal_FCMPL;
                                                }
-                                               else
-                                                       OPTT2_1(TYPE_FLT, TYPE_INT);
+                                               break;
+
+normal_FCMPL:
+                                               OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
                                                break;
 
                                        case ICMD_FCMPG:
                                                COUNT(count_pcmd_op);
-                                               if ((len > 0) && (iptr[1].val.i == 0)) {
-                                                       switch (iptr[1].opc) {
-                                                       case ICMD_IFEQ:
-                                                               iptr[0].opc = ICMD_IF_FCMPEQ;
-                                                       icmd_if_fcmpg_tail:
-                                                               iptr[0].op1 = iptr[1].op1;
-                                                               iptr[1].opc = ICMD_NOP;
+                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
+                                                       goto normal_FCMPG;
+
+                                               switch (iptr[1].opc) {
+                                               case ICMD_IFEQ:
+                                                       iptr->opc = ICMD_IF_FCMPEQ;
+                                               icmd_if_fcmpg_tail:
+                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr[1].opc = ICMD_NOP;
 
-                                                               OP2_0(TYPE_FLT);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) tbptr;
+                                                       OP2_BRANCH(TYPE_FLT, TYPE_FLT);
+                                                       BRANCH(tbptr);
 
-                                                               MARKREACHED(tbptr, copy);
-                                                               COUNT(count_pcmd_bra);
-                                                               break;
-                                                       case ICMD_IFNE:
-                                                               iptr[0].opc = ICMD_IF_FCMPNE;
-                                                               goto icmd_if_fcmpg_tail;
-                                                       case ICMD_IFLT:
-                                                               iptr[0].opc = ICMD_IF_FCMPG_LT;
-                                                               goto icmd_if_fcmpg_tail;
-                                                       case ICMD_IFGT:
-                                                               iptr[0].opc = ICMD_IF_FCMPG_GT;
-                                                               goto icmd_if_fcmpg_tail;
-                                                       case ICMD_IFLE:
-                                                               iptr[0].opc = ICMD_IF_FCMPG_LE;
-                                                               goto icmd_if_fcmpg_tail;
-                                                       case ICMD_IFGE:
-                                                               iptr[0].opc = ICMD_IF_FCMPG_GE;
-                                                               goto icmd_if_fcmpg_tail;
-                                                       default:
-                                                               OPTT2_1(TYPE_FLT, TYPE_INT);
-                                                       }
+                                                       COUNT(count_pcmd_bra);
+                                                       break;
+                                               case ICMD_IFNE:
+                                                       iptr->opc = ICMD_IF_FCMPNE;
+                                                       goto icmd_if_fcmpg_tail;
+                                               case ICMD_IFLT:
+                                                       iptr->opc = ICMD_IF_FCMPG_LT;
+                                                       goto icmd_if_fcmpg_tail;
+                                               case ICMD_IFGT:
+                                                       iptr->opc = ICMD_IF_FCMPG_GT;
+                                                       goto icmd_if_fcmpg_tail;
+                                               case ICMD_IFLE:
+                                                       iptr->opc = ICMD_IF_FCMPG_LE;
+                                                       goto icmd_if_fcmpg_tail;
+                                               case ICMD_IFGE:
+                                                       iptr->opc = ICMD_IF_FCMPG_GE;
+                                                       goto icmd_if_fcmpg_tail;
+                                               default:
+                                                       goto normal_FCMPG;
                                                }
-                                               else
-                                                       OPTT2_1(TYPE_FLT, TYPE_INT);
+                                               break;
+
+normal_FCMPG:
+                                               OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
                                                break;
 
                                        case ICMD_DCMPL:
                                                COUNT(count_pcmd_op);
-                                               if ((len > 0) && (iptr[1].val.i == 0)) {
-                                                       switch (iptr[1].opc) {
-                                                       case ICMD_IFEQ:
-                                                               iptr[0].opc = ICMD_IF_DCMPEQ;
-                                                       icmd_if_dcmpl_tail:
-                                                               iptr[0].op1 = iptr[1].op1;
-                                                               iptr[1].opc = ICMD_NOP;
+                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
+                                                       goto normal_DCMPL;
+
+                                               switch (iptr[1].opc) {
+                                               case ICMD_IFEQ:
+                                                       iptr->opc = ICMD_IF_DCMPEQ;
+                                               icmd_if_dcmpl_tail:
+                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr[1].opc = ICMD_NOP;
 
-                                                               OP2_0(TYPE_DBL);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) tbptr;
+                                                       OP2_BRANCH(TYPE_DBL, TYPE_DBL);
+                                                       BRANCH(tbptr);
 
-                                                               MARKREACHED(tbptr, copy);
-                                                               COUNT(count_pcmd_bra);
-                                                               break;
-                                                       case ICMD_IFNE:
-                                                               iptr[0].opc = ICMD_IF_DCMPNE;
-                                                               goto icmd_if_dcmpl_tail;
-                                                       case ICMD_IFLT:
-                                                               iptr[0].opc = ICMD_IF_DCMPL_LT;
-                                                               goto icmd_if_dcmpl_tail;
-                                                       case ICMD_IFGT:
-                                                               iptr[0].opc = ICMD_IF_DCMPL_GT;
-                                                               goto icmd_if_dcmpl_tail;
-                                                       case ICMD_IFLE:
-                                                               iptr[0].opc = ICMD_IF_DCMPL_LE;
-                                                               goto icmd_if_dcmpl_tail;
-                                                       case ICMD_IFGE:
-                                                               iptr[0].opc = ICMD_IF_DCMPL_GE;
-                                                               goto icmd_if_dcmpl_tail;
-                                                       default:
-                                                               OPTT2_1(TYPE_DBL, TYPE_INT);
-                                                       }
+                                                       COUNT(count_pcmd_bra);
+                                                       break;
+                                               case ICMD_IFNE:
+                                                       iptr->opc = ICMD_IF_DCMPNE;
+                                                       goto icmd_if_dcmpl_tail;
+                                               case ICMD_IFLT:
+                                                       iptr->opc = ICMD_IF_DCMPL_LT;
+                                                       goto icmd_if_dcmpl_tail;
+                                               case ICMD_IFGT:
+                                                       iptr->opc = ICMD_IF_DCMPL_GT;
+                                                       goto icmd_if_dcmpl_tail;
+                                               case ICMD_IFLE:
+                                                       iptr->opc = ICMD_IF_DCMPL_LE;
+                                                       goto icmd_if_dcmpl_tail;
+                                               case ICMD_IFGE:
+                                                       iptr->opc = ICMD_IF_DCMPL_GE;
+                                                       goto icmd_if_dcmpl_tail;
+                                               default:
+                                                       goto normal_DCMPL;
                                                }
-                                               else
-                                                       OPTT2_1(TYPE_DBL, TYPE_INT);
+                                               break;
+
+normal_DCMPL:
+                                               OPTT2_1(TYPE_DBL, TYPE_INT);
                                                break;
 
                                        case ICMD_DCMPG:
                                                COUNT(count_pcmd_op);
-                                               if ((len > 0) && (iptr[1].val.i == 0)) {
-                                                       switch (iptr[1].opc) {
-                                                       case ICMD_IFEQ:
-                                                               iptr[0].opc = ICMD_IF_DCMPEQ;
-                                                       icmd_if_dcmpg_tail:
-                                                               iptr[0].op1 = iptr[1].op1;
-                                                               iptr[1].opc = ICMD_NOP;
+                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
+                                                       goto normal_DCMPG;
+
+                                               switch (iptr[1].opc) {
+                                               case ICMD_IFEQ:
+                                                       iptr->opc = ICMD_IF_DCMPEQ;
+                                               icmd_if_dcmpg_tail:
+                                                       iptr->dst.insindex = iptr[1].dst.insindex;
+                                                       iptr[1].opc = ICMD_NOP;
 
-                                                               OP2_0(TYPE_DBL);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) tbptr;
+                                                       OP2_BRANCH(TYPE_DBL, TYPE_DBL);
+                                                       BRANCH(tbptr);
 
-                                                               MARKREACHED(tbptr, copy);
-                                                               COUNT(count_pcmd_bra);
-                                                               break;
-                                                       case ICMD_IFNE:
-                                                               iptr[0].opc = ICMD_IF_DCMPNE;
-                                                               goto icmd_if_dcmpg_tail;
-                                                       case ICMD_IFLT:
-                                                               iptr[0].opc = ICMD_IF_DCMPG_LT;
-                                                               goto icmd_if_dcmpg_tail;
-                                                       case ICMD_IFGT:
-                                                               iptr[0].opc = ICMD_IF_DCMPG_GT;
-                                                               goto icmd_if_dcmpg_tail;
-                                                       case ICMD_IFLE:
-                                                               iptr[0].opc = ICMD_IF_DCMPG_LE;
-                                                               goto icmd_if_dcmpg_tail;
-                                                       case ICMD_IFGE:
-                                                               iptr[0].opc = ICMD_IF_DCMPG_GE;
-                                                               goto icmd_if_dcmpg_tail;
-                                                       default:
-                                                               OPTT2_1(TYPE_DBL, TYPE_INT);
-                                                       }
+                                                       COUNT(count_pcmd_bra);
+                                                       break;
+                                               case ICMD_IFNE:
+                                                       iptr->opc = ICMD_IF_DCMPNE;
+                                                       goto icmd_if_dcmpg_tail;
+                                               case ICMD_IFLT:
+                                                       iptr->opc = ICMD_IF_DCMPG_LT;
+                                                       goto icmd_if_dcmpg_tail;
+                                               case ICMD_IFGT:
+                                                       iptr->opc = ICMD_IF_DCMPG_GT;
+                                                       goto icmd_if_dcmpg_tail;
+                                               case ICMD_IFLE:
+                                                       iptr->opc = ICMD_IF_DCMPG_LE;
+                                                       goto icmd_if_dcmpg_tail;
+                                               case ICMD_IFGE:
+                                                       iptr->opc = ICMD_IF_DCMPG_GE;
+                                                       goto icmd_if_dcmpg_tail;
+                                               default:
+                                                       goto normal_DCMPG;
                                                }
-                                               else
-                                                       OPTT2_1(TYPE_DBL, TYPE_INT);
+                                               break;
+
+normal_DCMPG:
+                                               OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
                                                break;
 #else
                                        case ICMD_FCMPL:
                                        case ICMD_FCMPG:
                                                COUNT(count_pcmd_op);
-                                               OPTT2_1(TYPE_FLT, TYPE_INT);
+                                               OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
                                                break;
 
                                        case ICMD_DCMPL:
                                        case ICMD_DCMPG:
                                                COUNT(count_pcmd_op);
-                                               OPTT2_1(TYPE_DBL, TYPE_INT);
+                                               OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
                                                break;
 #endif
 
                                                /* pop 1 push 1 */
-                                               
+
                                        case ICMD_INEG:
                                        case ICMD_INT2BYTE:
                                        case ICMD_INT2CHAR:
@@ -4958,7 +3966,8 @@ bool stack_analyse(jitdata *jd)
                                                break;
 
                                        case ICMD_CHECKCAST:
-                                               if (iptr->op1 == 0) {
+                                               coalescing_boundary = sd.new;
+                                               if (iptr->flags.bits & INS_FLAG_ARRAY) {
                                                        /* array type cast-check */
 
                                                        bte = builtintable_get_internal(BUILTIN_arraycheckcast);
@@ -4973,6 +3982,7 @@ bool stack_analyse(jitdata *jd)
 
                                                        copy = curstack;
                                                        while (copy) {
+                                                               sd.var[copy->varnum].flags |= SAVEDVAR;
                                                                copy->flags |= SAVEDVAR;
                                                                copy = copy->prev;
                                                        }
@@ -4982,59 +3992,67 @@ bool stack_analyse(jitdata *jd)
 
                                        case ICMD_INSTANCEOF:
                                        case ICMD_ARRAYLENGTH:
+                                               coalescing_boundary = sd.new;
                                                OP1_1(TYPE_ADR, TYPE_INT);
                                                break;
 
                                        case ICMD_NEWARRAY:
                                        case ICMD_ANEWARRAY:
+                                               coalescing_boundary = sd.new;
                                                OP1_1(TYPE_INT, TYPE_ADR);
                                                break;
 
                                        case ICMD_GETFIELD:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_check_null);
                                                COUNT(count_pcmd_mem);
-                                               OP1_1(TYPE_ADR, iptr->op1);
+                                               INSTRUCTION_GET_FIELDREF(iptr, fmiref);
+                                               OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
                                                break;
 
                                                /* pop 0 push 1 */
-                                               
+
                                        case ICMD_GETSTATIC:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_pcmd_mem);
-                                               OP0_1(iptr->op1);
+                                               INSTRUCTION_GET_FIELDREF(iptr, fmiref);
+                                               OP0_1(fmiref->parseddesc.fd->type);
                                                break;
 
                                        case ICMD_NEW:
+                                               coalescing_boundary = sd.new;
                                                OP0_1(TYPE_ADR);
                                                break;
 
                                        case ICMD_JSR:
-                                               OP0_1(TYPE_ADR);
-                                               tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
-
-                                               iptr[0].target = (void *) tbptr;
+                                               OP0_1(TYPE_RET);
 
-                                               /* This is a dirty hack. The typechecker
-                                                * needs it because the OP1_0ANY below
-                                                * overwrites iptr->dst.
-                                                */
-                                               iptr->val.a = (void *) iptr->dst;
+                                               assert(sd.bptr->next);  /* XXX exception */
+                                               sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
 
+                                               tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
                                                tbptr->type = BBTYPE_SBR;
 
+                                               tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
+                                               if (!tbptr)
+                                                       return false;
+
+                                               iptr->sx.s23.s3.jsrtarget.block = tbptr;
+
                                                /* We need to check for overflow right here because
-                                                * the pushed value is poped after MARKREACHED. */
+                                                * the pushed value is poped afterwards */
                                                CHECKOVERFLOW;
-                                               MARKREACHED(tbptr, copy);
-                                               OP1_0ANY;
+
+                                               superblockend = true;
+                                               /* XXX should not be marked as interface, as it does not need to be */
+                                               /* allocated. Same for the invar of the target. */
                                                break;
 
                                        /* pop many push any */
 
                                        case ICMD_BUILTIN:
-#if defined(USEBUILTINTABLE)
-                                       builtin:
-#endif
-                                               bte = (builtintable_entry *) iptr->val.a;
+icmd_BUILTIN:
+                                               bte = iptr->sx.s23.s3.bte;
                                                md = bte->md;
                                                goto _callhandling;
 
@@ -5043,13 +4061,21 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_INVOKEVIRTUAL:
                                        case ICMD_INVOKEINTERFACE:
                                                COUNT(count_pcmd_met);
-                                               INSTRUCTION_GET_METHODDESC(iptr,md);
+
+                                               /* Check for functions to replace with builtin
+                                                * functions. */
+
+                                               if (builtintable_replace_function(iptr))
+                                                       goto icmd_BUILTIN;
+
+                                               INSTRUCTION_GET_METHODDESC(iptr, md);
+                                               /* XXX resurrect this COUNT? */
 /*                          if (lm->flags & ACC_STATIC) */
-/*                              {COUNT(count_check_null);} */   
+/*                              {COUNT(count_check_null);} */
 
                                        _callhandling:
 
-                                               last_pei = bptr->icount - len - 1;
+                                               coalescing_boundary = sd.new;
 
                                                i = md->paramcount;
 
@@ -5062,87 +4088,123 @@ bool stack_analyse(jitdata *jd)
 
                                                REQUIRE(i);
 
+                                               /* XXX optimize for <= 2 args */
+                                               /* XXX not for ICMD_BUILTIN */
+                                               iptr->s1.argcount = stackdepth;
+                                               iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
+
                                                copy = curstack;
                                                for (i-- ; i >= 0; i--) {
+                                                       iptr->sx.s23.s2.args[i] = copy->varnum;
+
+                                                       /* do not change STACKVARs or LOCALVARS to ARGVAR*/
+                                                       /* ->  won't help anyway */
+                                                       if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
+
 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
-                                               /* If we pass float arguments in integer argument registers, we
-                                                * are not allowed to precolor them here. Floats have to be moved
-                                                * to this regs explicitly in codegen().
-                                                * Only arguments that are passed by stack anyway can be precolored
-                                                * (michi 2005/07/24) */
-                                                       if (!(copy->flags & SAVEDVAR) &&
-                                                          (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
+                       /* If we pass float arguments in integer argument registers, we
+                        * are not allowed to precolor them here. Floats have to be moved
+                        * to this regs explicitly in codegen().
+                        * Only arguments that are passed by stack anyway can be precolored
+                        * (michi 2005/07/24) */
+                                                       if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
+                                                          (!IS_FLT_DBL_TYPE(copy->type) 
+                                                               || md->params[i].inmemory)) {
 #else
-                                                       if (!(copy->flags & SAVEDVAR)) {
+                                                       if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
 #endif
-                                                               copy->varkind = ARGVAR;
-                                                               copy->varnum = i;
 
-#if defined(ENABLE_INTRP)
-                                                               if (!opt_intrp) {
-#endif
-                                                                       if (md->params[i].inmemory) {
-                                                                               copy->flags = INMEMORY;
-                                                                               copy->regoff = md->params[i].regoff;
-                                                                       } 
-                                                                       else {
-                                                                               copy->flags = 0;
-                                                                               if (IS_FLT_DBL_TYPE(copy->type))
+                                                               SET_PREALLOC(copy);
+
+                                                               if (md->params[i].inmemory) {
+                                                                       sd.var[copy->varnum].vv.regoff =
+                                                                               md->params[i].regoff;
+                                                                       sd.var[copy->varnum].flags |= 
+                                                                               INMEMORY;
+                                                               }
+                                                               else {
+                                                                       if (IS_FLT_DBL_TYPE(copy->type)) {
 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
-                                                                                       assert(0); /* XXX is this assert ok? */
+                                                                               assert(0); /* XXX is this assert ok? */
 #else
-                                                                               copy->regoff =
-                                                                                       rd->argfltregs[md->params[i].regoff];
-#endif
-                                                                               else {
+                                                                               sd.var[copy->varnum].vv.regoff = 
+                                                                       rd->argfltregs[md->params[i].regoff];
+#endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
+                                                                       }
+                                                                       else {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                                       if (IS_2_WORD_TYPE(copy->type))
-                                                                                               copy->regoff = PACK_REGS(
-                                                                                                                                                rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
-                                                                                                                                                rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
-                                                                                       else
-#endif
-                                                                                               copy->regoff =
-                                                                                                       rd->argintregs[md->params[i].regoff];
-                                                                               }
+                                                                               if (IS_2_WORD_TYPE(copy->type))
+                                                                                       sd.var[copy->varnum].vv.regoff = 
+                       PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
+                                          rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
+
+                                                                               else
+#endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
+                                                                                       sd.var[copy->varnum].vv.regoff = 
+                                                                       rd->argintregs[md->params[i].regoff];
                                                                        }
-#if defined(ENABLE_INTRP)
                                                                }
-#endif
+                                                       }
                                                        }
                                                        copy = copy->prev;
                                                }
 
+                                               /* deal with live-through stack slots "under" the */
+                                               /* arguments */
+                                               /* XXX not for ICMD_BUILTIN */
+
+                                               i = md->paramcount;
+
                                                while (copy) {
+                                                       SET_TEMPVAR(copy);
+                                                       iptr->sx.s23.s2.args[i++] = copy->varnum;
+                                                       sd.var[copy->varnum].flags |= SAVEDVAR;
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
 
+                                               /* pop the arguments */
+
                                                i = md->paramcount;
-                                               POPMANY(i);
-                                               if (md->returntype.type != TYPE_VOID)
-                                                       OP0_1(md->returntype.type);
+
+                                               stackdepth -= i;
+                                               while (--i >= 0) {
+                                                       POPANY;
+                                               }
+
+                                               /* push the return value */
+
+                                               if (md->returntype.type != TYPE_VOID) {
+                                                       GET_NEW_VAR(sd, new_index, md->returntype.type);
+                                                       DST(md->returntype.type, new_index);
+                                                       stackdepth++;
+                                               }
                                                break;
 
                                        case ICMD_INLINE_START:
                                        case ICMD_INLINE_END:
-                                               SETDST;
+                                               CLR_S1;
+                                               CLR_DST;
                                                break;
 
                                        case ICMD_MULTIANEWARRAY:
+                                               coalescing_boundary = sd.new;
                                                if (rd->argintreguse < 3)
                                                        rd->argintreguse = 3;
 
-                                               i = iptr->op1;
+                                               i = iptr->s1.argcount;
 
                                                REQUIRE(i);
+
+                                               iptr->sx.s23.s2.args = DMNEW(s4, i);
+
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                               if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
-                                                       rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
+                                               if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
+                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                               if (rd->memuse < (i + LA_WORD_SIZE + 3))
-                                                       rd->memuse = i + LA_WORD_SIZE + 3;
+                                               if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
+                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
 # endif
 #else
 # if defined(__I386__)
@@ -5158,36 +4220,48 @@ bool stack_analyse(jitdata *jd)
 #endif
                                                copy = curstack;
                                                while (--i >= 0) {
-                                                       /* check INT type here? Currently typecheck does this. */
-                                                       if (!(copy->flags & SAVEDVAR)) {
+                                       /* check INT type here? Currently typecheck does this. */
+                                                       iptr->sx.s23.s2.args[i] = copy->varnum;
+                                                       if (!(sd.var[copy->varnum].flags & SAVEDVAR)
+                                                               && (!IS_INOUT(copy))
+                                                               && (!IS_LOCALVAR(copy)) ) {
                                                                copy->varkind = ARGVAR;
-                                                               copy->varnum = i + INT_ARG_CNT;
-                                                               copy->flags |= INMEMORY;
+                                                               sd.var[copy->varnum].flags |=
+                                                                       INMEMORY & PREALLOC;
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                                               copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
+                                                               sd.var[copy->varnum].vv.regoff = i + 
+                                                                       LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                                               copy->regoff = i + LA_WORD_SIZE + 3;
+                                                               sd.var[copy->varnum].vv.regoff = i + 
+                                                                       LA_SIZE_IN_POINTERS + 3;
 # endif
 #else
 # if defined(__I386__)
-                                                               copy->regoff = i + 3;
+                                                               sd.var[copy->varnum].vv.regoff = i + 3;
 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
-                                                               copy->regoff = i + 2;
+                                                               sd.var[copy->varnum].vv.regoff = i + 2;
 # else
-                                                               copy->regoff = i;
+                                                               sd.var[copy->varnum].vv.regoff = i;
 # endif /* defined(__I386__) */
 #endif /* defined(SPECIALMEMUSE) */
                                                        }
                                                        copy = copy->prev;
                                                }
                                                while (copy) {
+                                                       sd.var[copy->varnum].flags |= SAVEDVAR;
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
-                                               i = iptr->op1;
-                                               POPMANY(i);
-                                               OP0_1(TYPE_ADR);
+
+                                               i = iptr->s1.argcount;
+                                               stackdepth -= i;
+                                               while (--i >= 0) {
+                                                       POPANY;
+                                               }
+                                               GET_NEW_VAR(sd, new_index, TYPE_ADR);
+                                               DST(TYPE_ADR, new_index);
+                                               stackdepth++;
                                                break;
 
                                        default:
@@ -5200,70 +4274,120 @@ bool stack_analyse(jitdata *jd)
                                        iptr++;
                                } /* while instructions */
 
-                               /* set out-stack of block */
-
-                               bptr->outstack = curstack;
-                               bptr->outdepth = stackdepth;
-
                                /* stack slots at basic block end become interfaces */
 
+                               sd.bptr->outdepth = stackdepth;
+                               sd.bptr->outvars = DMNEW(s4, stackdepth);
+
                                i = stackdepth - 1;
                                for (copy = curstack; copy; i--, copy = copy->prev) {
-                                       if ((copy->varkind == STACKVAR) && (copy->varnum > i))
-                                               copy->varkind = TEMPVAR;
+                                       varinfo *v;
+                                       s4 t;
+
+                                       /* with the new vars rd->interfaces will be removed */
+                                       /* and all in and outvars have to be STACKVARS!     */
+                                       /* in the moment i.e. SWAP with in and out vars can */
+                                       /* create an unresolvable conflict */
+
+                                       SET_TEMPVAR(copy);
+                                       t = copy->type;
+                                       if (t == TYPE_RET)
+                                               t = TYPE_ADR;
+
+                                       v = sd.var + copy->varnum;
+                                       v->flags |= INOUT;
+
+                                       if (jd->interface_map[i*5 + t].flags == UNUSED) {
+                                               /* no interface var until now for this depth and */
+                                               /* type */
+                                               jd->interface_map[i*5 + t].flags = v->flags;
+                                       }
                                        else {
-                                               copy->varkind = STACKVAR;
-                                               copy->varnum = i;
+                                               jd->interface_map[i*5 + t].flags |= v->flags;
                                        }
-                                       IF_NO_INTRP(
-                                                       rd->interfaces[i][copy->type].type = copy->type;
-                                                       rd->interfaces[i][copy->type].flags |= copy->flags;
-                                       );
+
+                                       sd.bptr->outvars[i] = copy->varnum;
                                }
 
                                /* check if interface slots at basic block begin must be saved */
 
-                               IF_NO_INTRP(
-                                       i = bptr->indepth - 1;
-                                       for (copy = bptr->instack; copy; i--, copy = copy->prev) {
-                                               rd->interfaces[i][copy->type].type = copy->type;
-                                               if (copy->varkind == STACKVAR) {
-                                                       if (copy->flags & SAVEDVAR)
-                                                               rd->interfaces[i][copy->type].flags |= SAVEDVAR;
-                                               }
+                               for (i=0; i<sd.bptr->indepth; ++i) {
+                                       varinfo *v = sd.var + sd.bptr->invars[i];
+                                       s4 t;
+
+                                       t = v->type;
+                                       if (t == TYPE_RET)
+                                               t = TYPE_ADR;
+
+                                       if (jd->interface_map[i*5 + t].flags == UNUSED) {
+                                               /* no interface var until now for this depth and */
+                                               /* type */
+                                               jd->interface_map[i*5 + t].flags = v->flags;
+                                       }
+                                       else {
+                                               jd->interface_map[i*5 + t].flags |= v->flags;
                                        }
-                               );
+                               }
 
-                       } /* if */
-                       else
-                               superblockend = true;
+                               /* store the number of this block's variables */
+
+                               sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
+
+#if defined(STACK_VERBOSE)
+                               stack_verbose_block_exit(&sd, superblockend);
+#endif
+
+                               /* reach the following block, if any */
+
+                               if (!superblockend)
+                                       if (!stack_reach_next_block(&sd))
+                                               return false;
+
+               } /* for blocks */
+
+       } while (sd.repeat && !deadcode);
+
+       /* XXX reset TYPE_RET to TYPE_ADR */
+
+       for (i=0; i<sd.vartop; ++i) {
+               if (sd.var[i].type == TYPE_RET)
+                       sd.var[i].type = TYPE_ADR;
+       }
+
+       /* XXX hack to fix up the ranges of the cloned single-block handlers */
 
-                       bptr++;
-               } /* while blocks */
-       } while (repeat && !deadcode);
+       ex = cd->exceptiontable;
+       for (; ex != NULL; ex = ex->down) {
+               if (ex->start == ex->end) {
+                       assert(ex->end->next);
+                       ex->end = ex->end->next;
+               }
+       }
+
+       /* gather statistics *****************************************************/
 
 #if defined(ENABLE_STATISTICS)
        if (opt_stat) {
-               if (m->basicblockcount > count_max_basic_blocks)
-                       count_max_basic_blocks = m->basicblockcount;
-               count_basic_blocks += m->basicblockcount;
-               if (m->instructioncount > count_max_javainstr)                  count_max_javainstr = m->instructioncount;
-               count_javainstr += m->instructioncount;
-               if (m->stackcount > count_upper_bound_new_stack)
-                       count_upper_bound_new_stack = m->stackcount;
-               if ((new - m->stack) > count_max_new_stack)
-                       count_max_new_stack = (new - m->stack);
-
-               b_count = m->basicblockcount;
-               bptr = m->basicblocks;
-               while (--b_count >= 0) {
-                       if (bptr->flags > BBREACHED) {
-                               if (bptr->indepth >= 10)
+               if (jd->basicblockcount > count_max_basic_blocks)
+                       count_max_basic_blocks = jd->basicblockcount;
+               count_basic_blocks += jd->basicblockcount;
+               if (jd->instructioncount > count_max_javainstr)
+                       count_max_javainstr = jd->instructioncount;
+               count_javainstr += jd->instructioncount;
+               if (jd->stackcount > count_upper_bound_new_stack)
+                       count_upper_bound_new_stack = jd->stackcount;
+               if ((sd.new - jd->stack) > count_max_new_stack)
+                       count_max_new_stack = (sd.new - jd->stack);
+
+               sd.bptr = jd->basicblocks;
+               for (; sd.bptr; sd.bptr = sd.bptr->next) {
+                       if (sd.bptr->flags > BBREACHED) {
+                               if (sd.bptr->indepth >= 10)
                                        count_block_stack[10]++;
                                else
-                                       count_block_stack[bptr->indepth]++;
-                               len = bptr->icount;
-                               if (len < 10) 
+                                       count_block_stack[sd.bptr->indepth]++;
+                               len = sd.bptr->icount;
+                               if (len < 10)
                                        count_block_size_distribution[len]++;
                                else if (len <= 12)
                                        count_block_size_distribution[10]++;
@@ -5282,58 +4406,54 @@ bool stack_analyse(jitdata *jd)
                                else
                                        count_block_size_distribution[17]++;
                        }
-                       bptr++;
                }
 
-               if (loops == 1)
+               if (iteration_count == 1)
                        count_analyse_iterations[0]++;
-               else if (loops == 2)
+               else if (iteration_count == 2)
                        count_analyse_iterations[1]++;
-               else if (loops == 3)
+               else if (iteration_count == 3)
                        count_analyse_iterations[2]++;
-               else if (loops == 4)
+               else if (iteration_count == 4)
                        count_analyse_iterations[3]++;
                else
                        count_analyse_iterations[4]++;
 
-               if (m->basicblockcount <= 5)
+               if (jd->basicblockcount <= 5)
                        count_method_bb_distribution[0]++;
-               else if (m->basicblockcount <= 10)
+               else if (jd->basicblockcount <= 10)
                        count_method_bb_distribution[1]++;
-               else if (m->basicblockcount <= 15)
+               else if (jd->basicblockcount <= 15)
                        count_method_bb_distribution[2]++;
-               else if (m->basicblockcount <= 20)
+               else if (jd->basicblockcount <= 20)
                        count_method_bb_distribution[3]++;
-               else if (m->basicblockcount <= 30)
+               else if (jd->basicblockcount <= 30)
                        count_method_bb_distribution[4]++;
-               else if (m->basicblockcount <= 40)
+               else if (jd->basicblockcount <= 40)
                        count_method_bb_distribution[5]++;
-               else if (m->basicblockcount <= 50)
+               else if (jd->basicblockcount <= 50)
                        count_method_bb_distribution[6]++;
-               else if (m->basicblockcount <= 75)
+               else if (jd->basicblockcount <= 75)
                        count_method_bb_distribution[7]++;
                else
                        count_method_bb_distribution[8]++;
        }
 #endif /* defined(ENABLE_STATISTICS) */
 
-       /* everything's ok */
+       /* everything's ok *******************************************************/
 
        return true;
 
+       /* goto labels for throwing verifier exceptions **************************/
+
 #if defined(ENABLE_VERIFIER)
 
 throw_stack_underflow:
-       *exceptionptr =
-               new_verifyerror(m, "Unable to pop operand off an empty stack");
+       exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
        return false;
 
 throw_stack_overflow:
-       *exceptionptr = new_verifyerror(m, "Stack size too large");
-       return false;
-
-throw_stack_depth_error:
-       *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
+       exceptions_throw_verifyerror(m, "Stack size too large");
        return false;
 
 throw_stack_type_error:
@@ -5341,14 +4461,109 @@ throw_stack_type_error:
        return false;
 
 throw_stack_category_error:
-       *exceptionptr =
-               new_verifyerror(m, "Attempt to split long or double on the stack");
+       exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
        return false;
 
 #endif
 }
 
 
+/* functions for verbose stack analysis output ********************************/
+
+#if defined(STACK_VERBOSE)
+static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
+{
+       printf("%c", show_jit_type_letters[v->type]);
+       if (v->type == TYPE_RET)
+               printf("{L%03d}", v->vv.retaddr->nr);
+}
+
+
+static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
+{
+       assert(index >= 0 && index < sd->vartop);
+       stack_verbose_show_varinfo(sd, sd->var + index);
+}
+
+
+static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
+{
+       s4 i;
+
+       printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
+       if (bptr->invars) {
+               for (i=0; i<bptr->indepth; ++i) {
+                       if (i)
+                               putchar(' ');
+                       stack_verbose_show_variable(sd, bptr->invars[i]);
+               }
+       }
+       else
+               putchar('-');
+       printf("] inlocals [");
+       if (bptr->inlocals) {
+               for (i=0; i<sd->localcount; ++i) {
+                       if (i)
+                               putchar(' ');
+                       stack_verbose_show_varinfo(sd, bptr->inlocals + i);
+               }
+       }
+       else
+               putchar('-');
+       printf("] out:%d [", bptr->outdepth);
+       if (bptr->outvars) {
+               for (i=0; i<bptr->outdepth; ++i) {
+                       if (i)
+                               putchar(' ');
+                       stack_verbose_show_variable(sd, bptr->outvars[i]);
+               }
+       }
+       else
+               putchar('-');
+       printf("]");
+
+       if (bptr->original)
+               printf(" (clone of L%03d)", bptr->original->nr);
+       else {
+               basicblock *b = bptr->copied_to;
+               if (b) {
+                       printf(" (copied to ");
+                       for (; b; b = b->copied_to)
+                               printf("L%03d ", b->nr);
+                       printf(")");
+               }
+       }
+}
+
+
+static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
+{
+       int i;
+
+       printf("======================================== STACK %sANALYSE BLOCK ", 
+                       (reanalyse) ? "RE-" : "");
+       stack_verbose_show_block(sd, sd->bptr);
+       printf("\n");
+
+       if (sd->handlers[0]) {
+               printf("HANDLERS: ");
+               for (i=0; sd->handlers[i]; ++i) {
+                       printf("L%03d ", sd->handlers[i]->handler->nr);
+               }
+               printf("\n");
+       }
+       printf("\n");
+}
+
+
+static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
+{
+       printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
+       stack_verbose_show_block(sd, sd->bptr);
+       printf("\n");
+}
+#endif
+
 
 /*
  * These are local overrides for various environment variables in Emacs.