Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vm / jit / stack.c
index c8a6d4983ec03aa843ec21670161715403ef1363..b81dfd45e1a62f1a736c595dc7f225b9d6350908 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/stack.c - stack analysis
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-
-   Changes: Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-   $Id: stack.c 5244 2006-08-16 12:21:35Z christian $
+   $Id: stack.c 7908 2007-05-15 09:55:17Z christian $
 
 */
 
 #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/types.h"
+
+#include "vm/jit/abi.h"
 #include "vm/jit/cfg.h"
 #include "vm/jit/codegen-common.h"
-#include "vm/jit/abi.h"
+#include "vm/jit/parse.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 0
+#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
+#endif
 
-/*#define STACK_VERBOSE*/
+#include "vmcore/options.h"
+#include "vm/resolve.h"
 
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
 
-/* macro for saving #ifdefs ***************************************************/
+/*#define STACK_VERBOSE*/
 
-#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) */
+/* macro for saving #ifdefs ***************************************************/
 
 #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 ******************************************************************
 
-   Initialized the stack analysis subsystem (called by jit_init).
+#define MIN(a,b)  (((a) < (b)) ? (a) : (b))
 
-*******************************************************************************/
 
-bool stack_init(void)
-{
-       return true;
-}
+/* For returnAddresses we use a field of the typeinfo to store from which  */
+/* subroutine the returnAddress will return, if used.                      */
+/* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
+/* to need it initialised to NULL. This should be investigated.            */
 
+#if defined(ENABLE_VERIFIER)
+#define SBRSTART  typeinfo.elementclass.any
+#endif
 
-/* 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.
+/* stackdata_t *****************************************************************
+
+   This struct holds internal data during stack analysis.
 
 *******************************************************************************/
 
-#define BLOCK_OF(index)                                              \
-    (jd->new_basicblocks + jd->new_basicblockindex[index])
+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;                  /* maximum number of variables expected     */
+       s4 varsallocated;             /* total number of variables allocated      */
+       s4 maxlocals;                 /* max. number of Java locals               */
+    varinfo *var;                 /* variable array (same as jd->var)         */
+       s4 *javalocals;               /* map from Java locals to jd->var indices  */
+       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      */
+       exception_entry **handlers;   /* exception handlers for the current block */
+       exception_entry *extableend;  /* points to the last exception entry       */
+       stackelement exstack;         /* instack for exception handlers           */
+};
+
+
+/* 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)
+
+/* 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 CLR_S1                                                       \
-    (iptr->s1.var = NULL)
+#define GET_NEW_VAR(sd, newvarindex, newtype)                        \
+    do {                                                             \
+        GET_NEW_INDEX((sd), (newvarindex));                          \
+        (sd).var[newvarindex].type = (newtype);                      \
+    } while (0)
 
-#define USE_S1_LOCAL(type1)
+
+/* 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))) {                                     \
+            stack_change_to_tempvar(&sd, (sp), iptr);                \
+        }                                                            \
+        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);
+
+
+/* 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)                                                \
@@ -243,3014 +298,2345 @@ 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                                                    \
+
+/* macro for propagating constant values ****************************/
+
+#if defined(ENABLE_VERIFIER)
+#define COPY_VAL_AND_TYPE_VAR(sv, dv)                                \
     do {                                                             \
-        CLR_S1;                                                      \
-        CLR_DST;                                                     \
+        if (((dv)->type = (sv)->type) == TYPE_RET) {                 \
+            (dv)->vv  = (sv)->vv;                                    \
+            (dv)->SBRSTART = (sv)->SBRSTART;                         \
+        }                                                            \
     } while (0)
-
-#define NEW_OP0_BRANCH                                               \
+#else
+#define COPY_VAL_AND_TYPE_VAR(sv, dv)                                \
     do {                                                             \
-        CLR_S1;                                                      \
+        (dv)->type = (sv)->type;                                     \
+        if (((dv)->type = (sv)->type) == TYPE_RET) {                 \
+            (dv)->vv  = (sv)->vv;                                    \
+        }                                                            \
     } while (0)
+#endif
+
+#define COPY_VAL_AND_TYPE(sd, sindex, dindex)                        \
+       COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
+
 
-#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 {                                                             \
+        iptr->opc = ICMD_MOVE;                                       \
+        iptr->s1.varindex = (sp)->varnum;                            \
+        DUP_SLOT(sp);                                                \
+        curstack->creator = iptr;                                    \
+        iptr->dst.varindex = curstack->varnum;                       \
+        stackdepth++;                                                \
+    } while (0)
+
+/* does not check input stackdepth */
+#define COPY_UP(sp)                                                  \
     do {                                                             \
-        (bt).block = tempbptr = BLOCK_OF((bt).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 BRANCH(tempbptr, tempsp)                                     \
+#define COPY_DOWN(s, d)                                              \
     do {                                                             \
-        iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex);   \
-        MARKREACHED(tempbptr, tempsp);                               \
+        SET_TEMPVAR((s));                                            \
+        iptr->opc = ICMD_COPY;                                       \
+        iptr->s1.varindex = (s)->varnum;                             \
+        iptr->dst.varindex = (d)->varnum;                            \
+        (d)->creator = iptr;                                         \
     } while (0)
 
-#define DUP_SLOT(sp)                                                 \
+#define MOVE_TO_TEMP(sp)                                             \
     do {                                                             \
-        if ((sp)->varkind != TEMPVAR)                                \
-            NEWSTACK((sp)->type, TEMPVAR, stackdepth);               \
-        else                                                         \
-            NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum);       \
-    } while(0)
+        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)
 
-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
+/* macros for branching / reaching basic blocks *********************/
 
-#if defined(STACK_VERBOSE)
-       new_show_method(jd, SHOW_PARSE);
-#endif
+#define BRANCH_TARGET(bt, tempbptr)                                  \
+    do {                                                             \
+        tempbptr = (bt).block;                                       \
+        tempbptr = stack_mark_reached(&sd, tempbptr, curstack,       \
+                                      stackdepth);                   \
+        if (tempbptr == NULL)                                        \
+            return false;                                            \
+        (bt).block = tempbptr;                                       \
+    } while (0)
 
-       /* get required compiler data - initialization */
+#define BRANCH(tempbptr)                                             \
+    BRANCH_TARGET(iptr->dst, tempbptr)
 
-       m    = jd->m;
-       code = jd->code;
-       cd   = jd->cd;
-       rd   = jd->rd;
 
-#if defined(ENABLE_LSRA)
-       m->maxlifetimes = 0;
-#endif
+/* forward declarations *******************************************************/
 
-#if defined(ENABLE_STATISTICS)
-       iteration_count = 0;
+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);
+static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, 
+                                                                        stackptr curstack);
 #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->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
-               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.
+   The number is added to `varcount`, which is the maximum number of variables
+   we expect to need at this point. The actual number of variables
+   (`varsallocated`) may be larger than that, in order to avoid too many
+   reallocations.
 
-                       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].predecessorcount++;
-                                       /* FALLTHROUGH */
-
-                                       /* unconditional branch */
-                               case ICMD_GOTO:
-                                       BLOCK_OF(iptr->dst.insindex)->predecessorcount++;
-                                       break;
+static void stack_grow_variable_array(stackdata_t *sd, s4 num)
+{
+       s4 newsize;
 
-                                       /* switches */
-                               case ICMD_TABLESWITCH:
-                                       table = iptr->dst.table;
-                                       BLOCK_OF((table++)->insindex)->predecessorcount++;
-                                       i = iptr->sx.s23.s3.tablehigh
-                                               - iptr->sx.s23.s2.tablelow + 1;
-                                       while (--i >= 0) {
-                                               BLOCK_OF((table++)->insindex)->predecessorcount++;
-                                       }
-                                       break;
+       assert(num >= 0);
 
-                               case ICMD_LOOKUPSWITCH:
-                                       lookup = iptr->dst.lookup;
-                                       BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->predecessorcount++;
-                                       i = iptr->sx.s23.s2.lookupcount;
-                                       while (--i >= 0) {
-                                               BLOCK_OF((lookup++)->target.insindex)->predecessorcount++;
-                                       }
-                                       break;
+       if (sd->varcount + num > sd->varsallocated) {
+               newsize = 2*sd->varsallocated + num;
 
-                                       /* default - fall into next block */
-                               default:
-                                       bptr[1].predecessorcount++;
-                                       break;
-                       } /* end switch */
-               } /* end basic block loop */
+               sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
+               MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
+               sd->varsallocated = newsize;
+               sd->jd->var = sd->var;
        }
-#endif /* CONDITIONAL_LOADCONST */
 
-       /* stack analysis loop (until fixpoint reached) **************************/
+       sd->varcount += num;
+       sd->jd->varcount += num;
 
-       do {
-#if defined(ENABLE_STATISTICS)
-               iteration_count++;
-#endif
+       assert(sd->varcount <= sd->varsallocated);
+}
 
-               /* initialize loop over basic blocks */
 
-               b_count = jd->new_basicblockcount;
-               bptr = jd->new_basicblocks;
-               superblockend = true;
-               repeat = false;
-               STACKRESET;
-               deadcode = true;
+/* stack_append_block **********************************************************
 
-               /* iterate over basic blocks *****************************************/
+   Append the given block after the last real block of the method (before
+   the pseudo-block at the end).
 
-               while (--b_count >= 0) {
+   IN:
+      sd...........stack analysis data
+         b............the block to append
+
+*******************************************************************************/
+
+static void stack_append_block(stackdata_t *sd, basicblock *b)
+{
 #if defined(STACK_VERBOSE)
-                       printf("ANALYZING BLOCK L%03d\n", bptr->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;
+       b->nr = sd->jd->basicblockcount++;
+       b->next->nr = b->nr + 1;
+}
 
-                               /* 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->javalocals = NULL;
+       clone->invars = NULL;
+
+       clone->original = (b->original) ? b->original : b;
+       clone->copied_to = clone->original->copied_to;
+       clone->original->copied_to = clone;
+       clone->next = NULL;
+       clone->flags = BBREACHED;
+
+       stack_append_block(sd, clone);
+
+       /* reserve 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_locals *********************************************************
+   Create the local variables for the start of the given basic block.
 
-#if defined(USEBUILTINTABLE)
-                                       IF_NO_INTRP(
-                                               bte = builtintable_get_automatic(opcode);
+   IN:
+      sd...........stack analysis data
+         b............block to create the locals for
 
-                                               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) */
+*******************************************************************************/
 
-                                       /* main opcode switch *************************************/
+static void stack_create_locals(stackdata_t *sd, basicblock *b)
+{
+       s4       i;
+       s4      *jl;
+       varinfo *dv;
 
-                                       switch (opcode) {
+       /* copy the current state of the local variables */
+       /* (one extra local is needed by the verifier)   */
 
-                                               /* pop 0 push 0 */
+       dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
+       b->inlocals = dv;
+       for (i=0; i<sd->localcount; ++i)
+               *dv++ = sd->var[i];
 
-                                       case ICMD_NOP:
-icmd_NOP:
-                                               CLR_SX;
-                                               NEW_OP0_0;
-                                               break;
+       /* the current map from java locals to cacao variables */
 
-                                       case ICMD_CHECKNULL:
-                                               COUNT(count_check_null);
-                                               USE_S1(TYPE_ADR);
-                                               CLR_SX;
-                                               CLR_DST; /* XXX live through? */
-                                               break;
+       jl = DMNEW(s4, sd->maxlocals);
+       b->javalocals = jl;
+       MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
+}
 
-                                       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.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;
-                                                                               NEW_OP0_0;
-                                                                               break;
-                                                                       case ICMD_PUTFIELD:
-                                                                               iptr->opc = ICMD_PUTFIELDCONST;
-                                                                               NEW_OP1_0(TYPE_ADR);
-                                                                               break;
-                                                               }
+/* stack_merge_locals **********************************************************
+   Merge local variables at the beginning of the given basic block.
 
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               COUNT(count_pcmd_op);
-                                                               break;
-#endif /* SUPPORT_CONST_STORE */
+   IN:
+      sd...........stack analysis data
+         b............the block that is reached
 
-                                                       default:
-                                                               goto normal_ICONST;
-                                               }
+*******************************************************************************/
 
-                                               /* if we get here, the ICONST has been optimized */
-                                               break;
+static void stack_merge_locals(stackdata_t *sd, basicblock *b)
+{
+       s4 i;
+       varinfo *dv;
+       varinfo *sv;
+
+       /* If a javalocal is mapped to different cacao locals along the */
+       /* incoming control-flow edges, it becomes undefined.           */
+
+       for (i=0; i<sd->maxlocals; ++i) {
+               if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
+                       b->javalocals[i] = UNUSED;
+                       if (b->flags >= BBFINISHED)
+                               b->flags = BBTYPECHECK_REACHED;
+                       if (b->nr <= sd->bptr->nr)
+                               sd->repeat = true;
+               }
+       }
 
-normal_ICONST:
-                                               /* normal case of an unoptimized ICONST */
-                                               NEW_OP0_1(TYPE_INT);
-                                               break;
+#if defined(ENABLE_VERIFIER)
+       if (b->inlocals) {
+               for (i=0; i<sd->localcount; ++i) {
+                       dv = b->inlocals + i;
+                       sv = sd->var + i;
+                       if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
+                                       && (sv->SBRSTART != dv->SBRSTART))
+                       {
+#if defined(STACK_VERBOSE)
+                               printf("JSR MISMATCH: setting variable %d to VOID\n", i);
+#endif
+                               dv->type = TYPE_VOID;
+                               if (b->flags >= BBFINISHED)
+                                       b->flags = BBTYPECHECK_REACHED;
+                               sd->repeat = true; /* This is very rare, so just repeat */
+                       }
+               }
+       }
+#endif /* defined(ENABLE_VERIFIER) */
+}
 
-       /************************** LCONST OPTIMIZATIONS **************************/
 
-                                       case ICMD_LCONST:
-                                               COUNT(count_pcmd_load);
-                                               if (len == 0)
-                                                       goto normal_LCONST;
+/* stack_create_invars *********************************************************
 
-                                               /* switch depending on the following instruction */
+   Create the invars for the given basic block. Also make a copy of the locals.
 
-                                               switch (iptr[1].opc) {
-#if SUPPORT_LONG_ADD
-                                                       case ICMD_LADD:
-                                                               iptr->opc = ICMD_LADDCONST;
-                                                               /* FALLTHROUGH */
+   IN:
+      sd...........stack analysis data
+         b............block to create the invars for
+         curstack.....current stack top
+         stackdepth...current stack depth
 
-                                                       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;
+   This function creates STACKDEPTH invars and sets their types to the
+   types to the types of the corresponding slot in the current stack.
 
-                                                       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 */
+static void stack_create_invars(stackdata_t *sd, basicblock *b, 
+                                                               stackptr curstack, int stackdepth)
+{
+       stackptr sp;
+       int i;
+       int index;
+       varinfo *dv;
+       varinfo *sv;
+
+       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;
+               dv = sd->var + index;
+               sv = sd->var + sp->varnum;
+               dv->flags = INOUT;
+               COPY_VAL_AND_TYPE_VAR(sv, dv);
+       }
 
-#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 */
+       stack_create_locals(sd, b);
+}
 
-#if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
 
-                                                       case ICMD_LAND:
-                                                               iptr->opc = ICMD_LANDCONST;
-                                                               goto icmd_lconst_tail;
+/* stack_create_invars_from_outvars ********************************************
 
-                                                       case ICMD_LOR:
-                                                               iptr->opc = ICMD_LORCONST;
-                                                               goto icmd_lconst_tail;
+   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.
 
-                                                       case ICMD_LXOR:
-                                                               iptr->opc = ICMD_LXORCONST;
-                                                               goto icmd_lconst_tail;
-#endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
+   IN:
+      sd...........stack analysis data
+         b............block to create the invars for
 
-#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 */
+static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
+{
+       int i;
+       int n;
+       varinfo *sv, *dv;
 
-                                                               switch (iptr[2].opc) {
-                                                                       case ICMD_IFEQ:
-                                                                               iptr->opc = ICMD_IF_LEQ;
-                                                                               /* FALLTHROUGH */
+       n = sd->bptr->outdepth;
+       assert(sd->vartop + n <= sd->varcount);
 
-                                                                       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;
+       b->indepth = n;
+       b->invars = DMNEW(s4, n);
 
-                                                                               NEW_OP1_BRANCH(TYPE_LNG);
-                                                                               BRANCH(tbptr, copy);
-                                                                               COUNT(count_pcmd_bra);
-                                                                               COUNT(count_pcmd_op);
-                                                                               break;
+       if (n) {
+               dv = sd->var + sd->vartop;
 
-                                                                       case ICMD_IFNE:
-                                                                               iptr->opc = ICMD_IF_LNE;
-                                                                               goto icmd_lconst_lcmp_tail;
+               /* allocate the invars */
 
-                                                                       case ICMD_IFLT:
-                                                                               iptr->opc = ICMD_IF_LLT;
-                                                                               goto icmd_lconst_lcmp_tail;
+               for (i=0; i<n; ++i, ++dv) {
+                       sv = sd->var + sd->bptr->outvars[i];
+                       b->invars[i] = sd->vartop++;
+                       dv->flags = INOUT;
+                       COPY_VAL_AND_TYPE_VAR(sv, dv);
+               }
+       }
 
-                                                                       case ICMD_IFGT:
-                                                                               iptr->opc = ICMD_IF_LGT;
-                                                                               goto icmd_lconst_lcmp_tail;
+       stack_create_locals(sd, b);
+}
 
-                                                                       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;
+/* stack_check_invars **********************************************************
 
-                                                                       default:
-                                                                               goto normal_LCONST;
-                                                               } /* end switch on opcode after LCONST - LCMP */
-                                                               break;
-#endif /* SUPPORT_LONG_CMP_CONST */
+   Check the current stack against the invars of the given basic block.
+   Depth and types must match.
 
-#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;
+   IN:
+      sd...........stack analysis data
+         b............block which invars to check against
+         curstack.....current stack top
+         stackdepth...current stack depth
+
+   RETURN VALUE:
+      the destinaton block
+         NULL.........a VerifyError has been thrown
+
+*******************************************************************************/
+
+static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
+                                                                          stackptr curstack, int stackdepth)
+{
+       int i;
+       stackptr sp;
+       basicblock *orig;
+       bool separable;
+       varinfo *sv;
+       varinfo *dv;
+
+#if defined(STACK_VERBOSE)
+       printf("stack_check_invars(L%03d)\n", b->nr);
 #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);
+       /* find original of b */
+       if (b->original)
+               b = b->original;
+       orig = b;
 
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               COUNT(count_pcmd_op);
-                                                               break;
+#if defined(STACK_VERBOSE)
+       printf("original is L%03d\n", orig->nr);
+#endif
 
-                                                       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;
+       i = orig->indepth;
+
+#if defined(ENABLE_VERIFIER)
+       if (i != stackdepth) {
+               exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
+               return NULL;
+       }
 #endif
-                                                               /* XXX check field type? */
 
-                                                               /* copy the constant to s2 */
-                                                               /* XXX constval -> fieldconstval? */
-                                                               iptr->sx.s23.s2.constval = iptr->sx.val.l;
+       do {
+               separable = false;
 
-                                                               goto putconst_tail;
+#if defined(STACK_VERBOSE)
+               printf("checking against ");
+               stack_verbose_show_block(sd, b); printf("\n");
+#endif
 
-#endif /* SUPPORT_CONST_STORE */
+               sp = curstack;
+               for (i = orig->indepth; i--; sp = sp->prev) {
+                       dv = sd->var + b->invars[i];
+                       sv = sd->var + sp->varnum;
 
-                                                       default:
-                                                               goto normal_LCONST;
-                                               } /* end switch opcode after LCONST */
+#if defined(ENABLE_VERIFIER)
+                       if (dv->type != sp->type) {
+                               exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
+                               return NULL;
+                       }
+#endif
 
-                                               /* if we get here, the LCONST has been optimized */
-                                               break;
+                       if (sp->type == TYPE_RET) {
+#if defined(ENABLE_VERIFIER)
+                               if (dv->SBRSTART != sv->SBRSTART) {
+                                       exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
+                                       return NULL;
+                               }
+#endif
+                               if (dv->vv.retaddr != sv->vv.retaddr) {
+                                       separable = true;
+                                       /* don't break! have to check the remaining stackslots */
+                               }
+                       }
+               }
 
-normal_LCONST:
-                                               /* the normal case of an unoptimized LCONST */
-                                               NEW_OP0_1(TYPE_LNG);
+               if (b->inlocals) {
+                       for (i=0; i<sd->localcount; ++i) {
+                               dv = b->inlocals + i;
+                               sv = sd->var + i;
+                               if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
+                                       if (
+#if defined(ENABLE_VERIFIER)
+                                                       (sv->SBRSTART == dv->SBRSTART) &&
+#endif
+                                                       (sv->vv.retaddr != dv->vv.retaddr)) 
+                                       {
+                                               separable = true;
                                                break;
+                                       }
+                               }
+                       }
+               }
 
-       /************************ END OF LCONST OPTIMIZATIONS *********************/
+               if (!separable) {
+                       /* XXX cascading collapse? */
 
-                                       case ICMD_FCONST:
-                                               COUNT(count_pcmd_load);
-                                               NEW_OP0_1(TYPE_FLT);
-                                               break;
+                       stack_merge_locals(sd, b);
 
-                                       case ICMD_DCONST:
-                                               COUNT(count_pcmd_load);
-                                               NEW_OP0_1(TYPE_DBL);
-                                               break;
+#if defined(STACK_VERBOSE)
+                       printf("------> using L%03d\n", b->nr);
+#endif
+                       return b;
+               }
+       } while ((b = b->copied_to) != NULL);
 
-       /************************** ACONST OPTIMIZATIONS **************************/
+       b = stack_clone_block(sd, orig);
+       if (!b)
+               return NULL;
 
-                                       case ICMD_ACONST:
-                                               COUNT(count_pcmd_load);
-#if SUPPORT_CONST_STORE
-                                               IF_INTRP( goto normal_ACONST; )
+       stack_create_invars(sd, b, curstack, stackdepth);
+       return b;
+}
 
-                                               /* We can only optimize if the ACONST is resolved
-                                                * and there is an instruction after it. */
 
-                                               if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
-                                                       goto normal_ACONST;
+/* stack_check_invars_from_outvars *********************************************
 
-                                               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;
+   Check the outvars of the current block against the invars of the given block.
+   Depth and types must match.
 
-                                                               /* copy the constant (NULL) to s3 */
-                                                               iptr->sx.s23.s3.constval = 0;
-                                                               iptr->opc = ICMD_AASTORECONST;
-                                                               NEW_OP2_0(TYPE_ADR, TYPE_INT);
+   IN:
+      sd...........stack analysis data
+         b............block which invars to check against
 
-                                                               iptr[1].opc = ICMD_NOP;
-                                                               COUNT(count_pcmd_op);
-                                                               break;
+   RETURN VALUE:
+      the destinaton block
+         NULL.........a VerifyError has been thrown
 
-                                                       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;
+*******************************************************************************/
 
-                                                               goto putconst_tail;
+static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
+{
+       int i;
+       int n;
+       varinfo *sv, *dv;
+       basicblock *orig;
+       bool separable;
 
-                                                       default:
-                                                               goto normal_ACONST;
-                                               }
+#if defined(STACK_VERBOSE)
+       printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
+#endif
 
-                                               /* if we get here the ACONST has been optimized */
-                                               break;
+       /* find original of b */
+       if (b->original)
+               b = b->original;
+       orig = b;
 
-normal_ACONST:
-#endif /* SUPPORT_CONST_STORE */
-                                               NEW_OP0_1(TYPE_ADR);
-                                               break;
+#if defined(STACK_VERBOSE)
+       printf("original is L%03d\n", orig->nr);
+#endif
 
+       i = orig->indepth;
+       n = sd->bptr->outdepth;
 
-                                               /* pop 0 push 1 load */
+#if defined(ENABLE_VERIFIER)
+       if (i != n) {
+               exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
+               return NULL;
+       }
+#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;
+       do {
+               separable = false;
 
-                                               /* pop 2 push 1 */
+#if defined(STACK_VERBOSE)
+               printf("checking against ");
+               stack_verbose_show_block(sd, b); printf("\n");
+#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);
+               if (n) {
+                       dv = sd->var + b->invars[0];
+
+                       for (i=0; i<n; ++i, ++dv) {
+                               sv = sd->var + sd->bptr->outvars[i];
+
+#if defined(ENABLE_VERIFIER)
+                               if (sv->type != dv->type) {
+                                       exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
+                                       return NULL;
+                               }
+#endif
+
+                               if (dv->type == TYPE_RET) {
+#if defined(ENABLE_VERIFIER)
+                                       if (sv->SBRSTART != dv->SBRSTART) {
+                                               exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
+                                               return NULL;
+                                       }
+#endif
+                                       if (sv->vv.retaddr != dv->vv.retaddr) {
+                                               separable = true;
+                                               /* don't break! have to check the remaining stackslots */
+                                       }
+                               }
+                       }
+               }
+
+               if (b->inlocals) {
+                       for (i=0; i<sd->localcount; ++i) {
+                               dv = b->inlocals + i;
+                               sv = sd->var + i;
+                               if (
+#if defined(ENABLE_VERIFIER)
+                                               (sv->SBRSTART == dv->SBRSTART) &&
+#endif
+                                               (sv->type == TYPE_RET && dv->type == TYPE_RET))
+                               {
+                                       if (sv->vv.retaddr != dv->vv.retaddr) {
+                                               separable = true;
                                                break;
+                                       }
+                               }
+                       }
+               }
+
+               if (!separable) {
+                       /* XXX cascading collapse? */
+
+                       stack_merge_locals(sd, b);
+
+#if defined(STACK_VERBOSE)
+                       printf("------> using L%03d\n", b->nr);
+#endif
+                       return b;
+               }
+       } while ((b = b->copied_to) != NULL);
+
+       b = stack_clone_block(sd, orig);
+       if (!b)
+               return NULL;
+
+       stack_create_invars_from_outvars(sd, b);
+       return b;
+}
+
+
+/* stack_create_instack ********************************************************
+
+   Create the instack of the current basic block.
+
+   IN:
+      sd...........stack analysis data
+
+   RETURN VALUE:
+      the current stack top at the start of the basic block.
+
+*******************************************************************************/
+
+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;
+
+       /* return the top of the created stack */
+       return sd->new - 1;
+}
+
+
+/* stack_mark_reached **********************************************************
+
+   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.
+
+   IN:
+      sd...........stack analysis data
+         b............the block to reach
+         curstack.....the current stack top
+         stackdepth...the current stack depth
+
+   RETURN VALUE:
+      a pointer to (a specialized version of) the target
+         NULL.........a VerifyError has been thrown
+
+*******************************************************************************/
+
+static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth) 
+{
+       assert(b != NULL);
+
+#if defined(STACK_VERBOSE)
+       printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
+#endif
+
+       /* mark targets of backward branches */
+
+       if (b->nr <= sd->bptr->nr)
+               b->bitflags |= BBFLAG_REPLACEMENT;
+
+       if (b->flags < BBREACHED) {
+               /* b is reached for the first time. Create its invars. */
 
-                                       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 defined(STACK_VERBOSE)
+               printf("reached L%03d for the first time\n", b->nr);
+#endif
 
-                                               /* pop 0 push 0 iinc */
+               stack_create_invars(sd, b, curstack, stackdepth);
 
-                                       case ICMD_IINC:
-                                               STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
+               b->flags = BBREACHED;
 
-                                               last_store[5 * iptr->s1.localindex + TYPE_INT] = bptr->icount - len - 1;
+               return b;
+       } 
+       else {
+               /* b has been reached before. Check that its invars match. */
 
-                                               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;
-                                               }
+               return stack_check_invars(sd, b, curstack, stackdepth);
+       }
+}
 
-                                               iptr->dst.localindex = iptr->s1.localindex;
-                                               break;
 
-                                               /* pop 1 push 0 store */
+/* stack_mark_reached_from_outvars *********************************************
 
-                                       case ICMD_ISTORE:
-                                       case ICMD_LSTORE:
-                                       case ICMD_FSTORE:
-                                       case ICMD_DSTORE:
-                                       case ICMD_ASTORE:
-                                               REQUIRE_1;
+   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.
 
-                                               i = opcode - ICMD_ISTORE; /* type */
-                                               IF_NO_INTRP( rd->locals[iptr->dst.localindex][i].type = i; )
+   IN:
+      sd...........stack analysis data
+         b............the block to reach
 
-#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]++;
-                                               }
+   RETURN VALUE:
+      a pointer to (a specialized version of) the target
+         NULL.........a VerifyError has been thrown
+
+*******************************************************************************/
+
+static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
+{
+       assert(b != NULL);
+
+#if defined(STACK_VERBOSE)
+       printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->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;
-                                               }
+       /* mark targets of backward branches */
 
-                                               last_store[5 * iptr->dst.localindex + (opcode - ICMD_ISTORE)] = bptr->icount - len - 1;
+       if (b->nr <= sd->bptr->nr)
+               b->bitflags |= BBFLAG_REPLACEMENT;
 
-                                               NEW_STORE(opcode - ICMD_ISTORE, iptr->dst.localindex);
-                                               break;
+       if (b->flags < BBREACHED) {
+               /* b is reached for the first time. Create its invars. */
 
-                                       /* pop 3 push 0 */
+#if defined(STACK_VERBOSE)
+               printf("reached L%03d for the first time\n", b->nr);
+#endif
 
-                                       case ICMD_AASTORE:
-                                               COUNT(count_check_null);
-                                               COUNT(count_check_bound);
-                                               COUNT(count_pcmd_mem);
+               stack_create_invars_from_outvars(sd, b);
 
-                                               bte = builtintable_get_internal(BUILTIN_canstore);
-                                               md = bte->md;
+               b->flags = BBREACHED;
 
-                                               if (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
-                                               /* XXX non-leaf method? */
+               return b;
+       } 
+       else {
+               /* b has been reached before. Check that its invars match. */
 
-                                               /* make all stack variables saved */
+               return stack_check_invars_from_outvars(sd, b);
+       }
+}
 
-                                               copy = curstack;
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
 
-                                               NEW_OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
-                                               break;
+/* 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.
 
-                                       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;
+   IN:
+      sd...........stack analysis data
 
-                                       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;
+   RETURN VALUE:
+      a pointer to (a specialized version of) the following block
+         NULL.........a VerifyError has been thrown
 
-                                               /* pop 1 push 0 */
+*******************************************************************************/
 
-                                       case ICMD_POP:
-#ifdef ENABLE_VERIFIER
-                                               if (opt_verify) {
-                                                       REQUIRE_1;
-                                                       if (IS_2_WORD_TYPE(curstack->type))
-                                                               goto throw_stack_category_error;
-                                               }
-#endif
-                                               NEW_OP1_0_ANY;
-                                               break;
+static bool stack_reach_next_block(stackdata_t *sd)
+{
+       basicblock *tbptr;
+       instruction *iptr;
 
-                                       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;
+       tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
+       tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
 
-                                       case ICMD_ATHROW:
-                                               COUNT(count_check_null);
-                                               NEW_OP1_0(TYPE_ADR);
-                                               STACKRESET;
-                                               superblockend = true;
-                                               break;
+       if (tbptr == NULL)
+               return false;
 
-                                       case ICMD_PUTSTATIC:
-                                               COUNT(count_pcmd_mem);
-                                               NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
-                                               NEW_OP1_0(fmiref->parseddesc.fd->type);
-                                               break;
+       if (tbptr != sd->bptr->next) {
+#if defined(STACK_VERBOSE)
+               printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
+#endif
+               iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
+               assert(iptr->opc == ICMD_NOP);
+               iptr->opc = ICMD_GOTO;
+               iptr->dst.block = tbptr;
 
-                                               /* pop 1 push 0 branch */
+               if (tbptr->flags < BBFINISHED)
+                       sd->repeat = true; /* XXX check if we really need to repeat */
+       }
 
-                                       case ICMD_IFNULL:
-                                       case ICMD_IFNONNULL:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP1_BRANCH(TYPE_ADR);
-                                               BRANCH(tbptr, copy);
-                                               break;
+       return true;
+}
 
-                                       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. */
 
-                                               NEW_OP1_BRANCH(TYPE_INT);
-/*                                             iptr->sx.val.i = 0; */
-                                               BRANCH(tbptr, copy);
-                                               break;
+/* stack_reach_handlers ********************************************************
 
-                                               /* pop 0 push 0 branch */
+   Reach the exception handlers for the current block.
 
-                                       case ICMD_GOTO:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP0_BRANCH;
-                                               BRANCH(tbptr, copy);
-                                               superblockend = true;
-                                               break;
+   IN:
+      sd...........stack analysis data
 
-                                               /* pop 1 push 0 table branch */
+   RETURN VALUE:
+     true.........everything ok
+        false........a VerifyError has been thrown
 
-                                       case ICMD_TABLESWITCH:
-                                               COUNT(count_pcmd_table);
-                                               NEW_OP1_BRANCH(TYPE_INT);
+*******************************************************************************/
 
-                                               table = iptr->dst.table;
-                                               BRANCH_TARGET(*table, tbptr, copy);
-                                               table++;
+static bool stack_reach_handlers(stackdata_t *sd)
+{
+       s4 i;
+       basicblock *tbptr;
 
-                                               i = iptr->sx.s23.s3.tablehigh
-                                                 - iptr->sx.s23.s2.tablelow + 1;
+#if defined(STACK_VERBOSE)
+       printf("reaching exception handlers...\n");
+#endif
 
-                                               while (--i >= 0) {
-                                                       BRANCH_TARGET(*table, tbptr, copy);
-                                                       table++;
-                                               }
-                                               superblockend = true;
-                                               break;
+       for (i=0; sd->handlers[i]; ++i) {
+               tbptr = sd->handlers[i]->handler;
 
-                                               /* pop 1 push 0 table branch */
+               tbptr->type = BBTYPE_EXH;
+               tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
 
-                                       case ICMD_LOOKUPSWITCH:
-                                               COUNT(count_pcmd_table);
-                                               NEW_OP1_BRANCH(TYPE_INT);
+               /* reach (and specialize) the handler block */
 
-                                               BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
+               tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
 
-                                               lookup = iptr->dst.lookup;
+               if (tbptr == NULL)
+                       return false;
 
-                                               i = iptr->sx.s23.s2.lookupcount;
+               sd->handlers[i]->handler = tbptr;
+       }
 
-                                               while (--i >= 0) {
-                                                       BRANCH_TARGET(lookup->target, tbptr, copy);
-                                                       lookup++;
-                                               }
-                                               superblockend = true;
-                                               break;
+       return true;
+}
 
-                                       case ICMD_MONITORENTER:
-                                       case ICMD_MONITOREXIT:
-                                               COUNT(count_check_null);
-                                               NEW_OP1_0(TYPE_ADR);
-                                               break;
 
-                                               /* pop 2 push 0 branch */
+/* stack_reanalyse_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:
-                                               COUNT(count_pcmd_bra);
-                                               NEW_OP2_BRANCH(TYPE_INT, TYPE_INT);
-                                               BRANCH(tbptr, copy);
-                                               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_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
 
-                                               /* pop 2 push 0 */
+   RETURN VALUE:
+     true.........everything ok
+        false........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;
-                                                       }
-#endif
-                                                       NEW_OP2_0_ANY_ANY; /* pop two slots */
-                                               }
-                                               else {
-                                                       iptr->opc = ICMD_POP;
-                                                       NEW_OP1_0_ANY; /* pop one (two-word) slot */
-                                               }
-                                               break;
+#define RELOCATE(index)                                              \
+    do {                                                             \
+        if ((index) >= blockvarstart)                                \
+            (index) += blockvarshift;                                \
+        else if ((index) >= invarstart)                              \
+            (index) += invarshift;                                   \
+    } while (0)
 
-                                               /* pop 0 push 1 dup */
+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, varindex;
+       s4 *argp;
+       branch_target_t *table;
+       lookup_target_t *lookup;
+       bool superblockend;
+       bool cloneinstructions;
+       exception_entry *ex;
 
-                                       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)
+       stack_verbose_block_enter(sd, true);
 #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;
+       b = sd->bptr;
 
-                                       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;
+       if (!b->iinstr) {
+               orig = b->original;
+               assert(orig != NULL);
 
-                                               /* pop 2 push 3 dup */
+               /* clone the instruction list */
 
-                                       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;
+               cloneinstructions = true;
 
-icmd_DUP_X1:
-                                               iptr->dst.dupslots = DMNEW(stackptr, 2 + 3);
-                                               iptr->dst.dupslots[0] = curstack->prev;
-                                               iptr->dst.dupslots[1] = curstack;
-                                               POPANY; POPANY;
+               assert(orig->iinstr);
+               len = orig->icount;
+               iptr = DMNEW(instruction, len + 1);
 
-                                               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;
+               MCOPY(iptr, orig->iinstr, instruction, len);
+               iptr[len].opc = ICMD_NOP;
+               iptr[len].line = 0;
+               iptr[len].flags.bits = 0;
+               b->iinstr = iptr;
+               b->icount = ++len;
 
-                                       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
+               /* reserve space for the clone's block variables */
 
-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;
+               stack_grow_variable_array(sd, orig->varcount);
 
-                                                       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;
+               /* we already have the invars set */
 
-                                               /* pop 3 push 4 dup */
+               assert(b->indepth == orig->indepth);
 
-                                       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;
-                                                       }
-#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;
+               /* calculate relocation shifts for invars and block variables */
 
-                                                       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 (orig->indepth) {
+                       invarstart = orig->invars[0];
+                       invarshift = b->invars[0] - invarstart;
+               }
+               else {
+                       invarstart = INT_MAX;
+                       invarshift = 0;
+               }
+               blockvarstart = orig->varstart;
+               blockvarshift = sd->vartop - blockvarstart;
 
-                                       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;
-                                                               }
-#endif
-                                                               iptr->opc = ICMD_DUP_X2;
-                                                               goto icmd_DUP_X2;
-                                                       }
-                                               }
+               /* copy block variables */
 
-                                               REQUIRE_3;
-                                               /* ..., ????, ????, cat1 */
+               b->varstart = sd->vartop;
+               b->varcount = orig->varcount;
+               sd->vartop += b->varcount;
+               MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
 
-                                               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;
-                                                       }
-#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;
+               /* copy outvars */
 
-                                                       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;
+               b->outdepth = orig->outdepth;
+               b->outvars = DMNEW(s4, orig->outdepth);
+               MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
 
-                                               /* pop 2 push 2 swap */
+               /* clone exception handlers */
 
-                                       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;
+               for (i=0; sd->handlers[i]; ++i) {
+                       ex = DNEW(exception_entry);
+                       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;
 
-                                               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;
+                       assert(sd->extableend->down == NULL);
+                       sd->extableend->down = ex;
+                       sd->extableend = ex;
+                       sd->jd->exceptiontablelength++;
 
-                                               /* pop 2 push 1 */
+                       sd->handlers[i] = ex;
+               }
+       }
+       else {
+               cloneinstructions = false;
+               invarshift = 0;
+               blockvarshift = 0;
+               invarstart = sd->vartop;
+               blockvarstart = sd->vartop;
+               iptr = b->iinstr;
+       }
 
-                                       case ICMD_IDIV:
-                                       case ICMD_IREM:
-#if !SUPPORT_DIVISION
-                                               bte = iptr->sx.s23.s3.bte;
-                                               md = bte->md;
+       if (b->original) {
+               /* find exception handlers for the cloned block */
+               len = 0;
+               ex = sd->jd->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 (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
+#if defined(STACK_VERBOSE)
+       printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
+       printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
+#endif
 
-                                               /* make all stack variables saved */
+       /* mark block as finished */
 
-                                               copy = curstack;
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
-                                               /* FALLTHROUGH */
+       b->flags = BBFINISHED;
 
-#endif /* !SUPPORT_DIVISION */
+       /* initialize locals at the start of this block */
 
-                                       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;
+       if (b->inlocals)
+               MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
 
-                                       case ICMD_LDIV:
-                                       case ICMD_LREM:
-#if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
-                                               bte = iptr->sx.s23.s3.bte;
-                                               md = bte->md;
+       MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
 
-                                               if (md->memuse > rd->memuse)
-                                                       rd->memuse = md->memuse;
-                                               if (md->argintreguse > rd->argintreguse)
-                                                       rd->argintreguse = md->argintreguse;
-                                               /* XXX non-leaf method? */
+       /* reach exception handlers for this block */
 
-                                               /* make all stack variables saved */
+       if (!stack_reach_handlers(sd))
+               return false;
 
-                                               copy = curstack;
-                                               while (copy) {
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
-                                               /* FALLTHROUGH */
+       superblockend = false;
 
-#endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
+       for (len = b->icount; len--; iptr++) {
+#if defined(STACK_VERBOSE)
+               show_icmd(sd->jd, iptr, false, SHOW_STACK);
+               printf("\n");
+#endif
 
-                                       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;
+               switch (iptr->opc) {
+                       case ICMD_RET:
+                               varindex = iptr->s1.varindex;
 
-                                       case ICMD_LSHL:
-                                       case ICMD_LSHR:
-                                       case ICMD_LUSHR:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
-                                               break;
+#if defined(ENABLE_VERIFIER)
+                               if (sd->var[varindex].type != TYPE_RET) {
+                                       exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
+                                       return false;
+                               }
+#endif
 
-                                       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;
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[varindex].vv.retaddr);
+                               superblockend = true;
+                               break;
 
-                                       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;
+                       case ICMD_JSR:
+                               iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
+                               RELOCATE(iptr->dst.varindex);
+                               superblockend = true;
+                               break;
 
-                                       case ICMD_LCMP:
-                                               COUNT(count_pcmd_op);
-#if SUPPORT_LONG_CMP_CONST
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_LCMP;
+                       case ICMD_RETURN:
+                               superblockend = true;
+                               break;
 
-                                               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;
+                       case ICMD_CHECKNULL:
+                       case ICMD_PUTSTATICCONST:
+                               break;
 
-                                                       NEW_OP2_BRANCH(TYPE_LNG, TYPE_LNG);
-                                                       BRANCH(tbptr, copy);
+                       case ICMD_NOP:
+                       case ICMD_IINC:
+                               break;
 
-                                                       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;
+                       case ICMD_GOTO:
+                               iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
+                               superblockend = true;
+                               break;
+
+                               /* pop 0 push 1 const */
+
+                       case ICMD_ACONST:
+                       case ICMD_ICONST:
+                       case ICMD_LCONST:
+                       case ICMD_FCONST:
+                       case ICMD_DCONST:
+
+                               /* pop 0 push 1 load */
+
+                       case ICMD_ILOAD:
+                       case ICMD_LLOAD:
+                       case ICMD_FLOAD:
+                       case ICMD_DLOAD:
+                       case ICMD_ALOAD:
+                               RELOCATE(iptr->dst.varindex);
+                               break;
+
+                               /* 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);
+                               break;
+
+                               /* 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);
+                               break;
+
+                               /* pop 1 push 0 store */
+
+                       case ICMD_ISTORE:
+                       case ICMD_LSTORE:
+                       case ICMD_FSTORE:
+                       case ICMD_DSTORE:
+                       case ICMD_ASTORE:
+                               RELOCATE(iptr->s1.varindex);
+
+                               varindex = iptr->dst.varindex;
+                               COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, varindex);
+                               i = iptr->sx.s23.s3.javaindex;
+                               if (iptr->flags.bits & INS_FLAG_RETADDR) {
+                                       iptr->sx.s23.s2.retaddrnr =
+                                               JAVALOCAL_FROM_RETADDR(sd->var[varindex].vv.retaddr->nr);
+                                       sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
+                               }
+                               else
+                                       sd->javalocals[i] = varindex;
+                               if (iptr->flags.bits & INS_FLAG_KILL_PREV)
+                                       sd->javalocals[i-1] = UNUSED;
+                               if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
+                                       sd->javalocals[i+1] = UNUSED;
+                               break;
+
+                               /* pop 1 push 0 */
+
+                       case ICMD_ARETURN:
+                       case ICMD_ATHROW:
+                       case ICMD_IRETURN:
+                       case ICMD_LRETURN:
+                       case ICMD_FRETURN:
+                       case ICMD_DRETURN:
+                               RELOCATE(iptr->s1.varindex);
+                               superblockend = true;
+                               break;
+
+                       case ICMD_PUTSTATIC:
+                       case ICMD_PUTFIELDCONST:
+                       case ICMD_POP:
+                               RELOCATE(iptr->s1.varindex);
+                               break;
+
+                               /* pop 1 push 0 branch */
+
+                       case ICMD_IFNULL:
+                       case ICMD_IFNONNULL:
+
+                       case ICMD_IFEQ:
+                       case ICMD_IFNE:
+                       case ICMD_IFLT:
+                       case ICMD_IFGE:
+                       case ICMD_IFGT:
+                       case ICMD_IFLE:
+
+                       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;
+
+                               /* pop 1 push 0 table branch */
+
+                       case ICMD_TABLESWITCH:
+                               i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
+
+                               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;
+                               }
 
-                                               /* 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;
+                               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);
+                               break;
+
+                               /* pop 2 push 0 branch */
+
+                       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_LCMPEQ:
+                       case ICMD_IF_LCMPNE:
+                       case ICMD_IF_LCMPLT:
+                       case ICMD_IF_LCMPGE:
+                       case ICMD_IF_LCMPGT:
+                       case ICMD_IF_LCMPLE:
+
+                       case ICMD_IF_FCMPEQ:
+                       case ICMD_IF_FCMPNE:
+
+                       case ICMD_IF_FCMPL_LT:
+                       case ICMD_IF_FCMPL_GE:
+                       case ICMD_IF_FCMPL_GT:
+                       case ICMD_IF_FCMPL_LE:
+
+                       case ICMD_IF_FCMPG_LT:
+                       case ICMD_IF_FCMPG_GE:
+                       case ICMD_IF_FCMPG_GT:
+                       case ICMD_IF_FCMPG_LE:
+
+                       case ICMD_IF_DCMPEQ:
+                       case ICMD_IF_DCMPNE:
+
+                       case ICMD_IF_DCMPL_LT:
+                       case ICMD_IF_DCMPL_GE:
+                       case ICMD_IF_DCMPL_GT:
+                       case ICMD_IF_DCMPL_LE:
+
+                       case ICMD_IF_DCMPG_LT:
+                       case ICMD_IF_DCMPG_GE:
+                       case ICMD_IF_DCMPG_GT:
+                       case ICMD_IF_DCMPG_LE:
+
+                       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;
+
+                               /* 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:
+                       case ICMD_POP2:
+                               RELOCATE(iptr->sx.s23.s2.varindex);
+                               RELOCATE(iptr->s1.varindex);
+                               break;
+
+                               /* pop 0 push 1 copy */
+
+                       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;
+
+                               /* pop 2 push 1 */
+
+                       case ICMD_IDIV:
+                       case ICMD_IREM:
+                       case ICMD_LDIV:
+                       case ICMD_LREM:
+                       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;
+
+                               /* pop 1 push 1 */
+
+                       case ICMD_CHECKCAST:
+                       case ICMD_ARRAYLENGTH:
+                       case ICMD_INSTANCEOF:
+                       case ICMD_NEWARRAY:
+                       case ICMD_ANEWARRAY:
+                       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;
+
+                               /* pop 0 push 1 */
+
+                       case ICMD_GETSTATIC:
+                       case ICMD_NEW:
+                               RELOCATE(iptr->dst.varindex);
+                               break;
+
+                               /* 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;
+                               }
 
-                                               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;
+                               while (--i >= 0) {
+                                       RELOCATE(*argp);
+                                       argp++;
+                               }
+                               RELOCATE(iptr->dst.varindex);
+                               break;
 
-                                                       NEW_OP2_BRANCH(TYPE_FLT, TYPE_FLT);
-                                                       BRANCH(tbptr, copy);
+                       default:
+                               exceptions_throw_internalerror("Unknown ICMD %d during stack re-analysis",
+                                                                                          iptr->opc);
+                               return false;
+               } /* switch */
 
-                                                       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 defined(STACK_VERBOSE)
+               show_icmd(sd->jd, iptr, false, SHOW_STACK);
+               printf("\n");
+#endif
+       }
 
-normal_FCMPL:
-                                               OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
-                                               break;
+       /* relocate outvars */
 
-                                       case ICMD_FCMPG:
-                                               COUNT(count_pcmd_op);
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_FCMPG;
+       for (i=0; i<b->outdepth; ++i) {
+               RELOCATE(b->outvars[i]);
+       }
 
-                                               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;
+#if defined(STACK_VERBOSE)
+       stack_verbose_block_exit(sd, superblockend);
+#endif
 
-                                                       NEW_OP2_BRANCH(TYPE_FLT, TYPE_FLT);
-                                                       BRANCH(tbptr, copy);
+       /* propagate to the next block */
 
-                                                       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;
+       if (!superblockend)
+               if (!stack_reach_next_block(sd))
+                       return false;
 
-normal_FCMPG:
-                                               NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
-                                               break;
+       return true;
+}
 
-                                       case ICMD_DCMPL:
-                                               COUNT(count_pcmd_op);
-                                               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;
+/* stack_change_to_tempvar *****************************************************
 
-                                                       NEW_OP2_BRANCH(TYPE_DBL, TYPE_DBL);
-                                                       BRANCH(tbptr, copy);
+   Change the given stackslot to a TEMPVAR. This includes creating a new
+   temporary variable and changing the dst.varindex of the creator of the
+   stacklot to the new variable index. If this stackslot has been passed
+   through ICMDs between the point of its creation and the current point,
+   then the variable index is also changed in these ICMDs.
 
-                                                       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;
+   IN:
+      sd...........stack analysis data
+         sp...........stackslot to change
+         ilimit.......instruction up to which to look for ICMDs passing-through
+                      the stackslot (exclusive). This may point exactly after the 
+                                  last instruction, in which case the search is done to the
+                                  basic block end.
 
-normal_DCMPL:
-                                               OPTT2_1(TYPE_DBL, TYPE_INT);
-                                               break;
+*******************************************************************************/
 
-                                       case ICMD_DCMPG:
-                                               COUNT(count_pcmd_op);
-                                               if ((len == 0) || (iptr[1].sx.val.i != 0))
-                                                       goto normal_DCMPG;
+static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp, 
+                                                                       instruction *ilimit)
+{
+       s4 newindex;
+       s4 oldindex;
+       instruction *iptr;
+       s4 depth;
+       s4 i;
 
-                                               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;
+       oldindex = sp->varnum;
 
-                                                       NEW_OP2_BRANCH(TYPE_DBL, TYPE_DBL);
-                                                       BRANCH(tbptr, copy);
+       /* create a new temporary variable */
 
-                                                       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;
+       GET_NEW_VAR(*sd, newindex, sp->type);
 
-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->var[newindex].flags = sp->flags;
 
-                                       case ICMD_DCMPL:
-                                       case ICMD_DCMPG:
-                                               COUNT(count_pcmd_op);
-                                               NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
-                                               break;
-#endif
+       /* change the stackslot */
 
-                                               /* pop 1 push 1 */
+       sp->varnum = newindex;
+       sp->varkind = TEMPVAR;
 
-                                       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;
+       /* change the dst.varindex of the stackslot's creator */
 
-                                       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;
+       if (sp->creator)
+               sp->creator->dst.varindex = newindex;
 
-                                       case ICMD_CHECKCAST:
-                                               if (iptr->flags.bits & INS_FLAG_ARRAY) {
-                                                       /* array type cast-check */
+       /* handle ICMDs this stackslot passed through, if any */
 
-                                                       bte = builtintable_get_internal(BUILTIN_arraycheckcast);
-                                                       md = bte->md;
+       if (sp->flags & PASSTHROUGH) {
+               iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
 
-                                                       if (md->memuse > rd->memuse)
-                                                               rd->memuse = md->memuse;
-                                                       if (md->argintreguse > rd->argintreguse)
-                                                               rd->argintreguse = md->argintreguse;
+               /* assert that the limit points to an ICMD, or after the last one */
 
-                                                       /* make all stack variables saved */
+               assert(ilimit >= sd->bptr->iinstr);
+               assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
 
-                                                       copy = curstack;
-                                                       while (copy) {
-                                                               copy->flags |= SAVEDVAR;
-                                                               copy = copy->prev;
-                                                       }
-                                               }
-                                               NEW_OP1_1(TYPE_ADR, TYPE_ADR);
-                                               break;
+               /* find the stackdepth under sp plus one */
+               /* Note: This number is usually known when this function is called, */
+               /* but calculating it here is less error-prone and should not be    */
+               /* a performance problem.                                           */
 
-                                       case ICMD_INSTANCEOF:
-                                       case ICMD_ARRAYLENGTH:
-                                               NEW_OP1_1(TYPE_ADR, TYPE_INT);
-                                               break;
+               for (depth = 0; sp != NULL; sp = sp->prev)
+                       depth++;
 
-                                       case ICMD_NEWARRAY:
-                                       case ICMD_ANEWARRAY:
-                                               NEW_OP1_1(TYPE_INT, TYPE_ADR);
-                                               break;
+               /* iterate over all instructions in the range and replace */
 
-                                       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;
+               for (; iptr < ilimit; ++iptr) {
+                       switch (iptr->opc) {
+                               case ICMD_INVOKESTATIC:
+                               case ICMD_INVOKESPECIAL:
+                               case ICMD_INVOKEVIRTUAL:
+                               case ICMD_INVOKEINTERFACE:
+                               case ICMD_BUILTIN:
+                                       i = iptr->s1.argcount - depth;
+                                       if (iptr->sx.s23.s2.args[i] == oldindex) {
+                                               iptr->sx.s23.s2.args[i] = newindex;
+                                       }
+                                       break;
+                               /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
+                               /* stackslot, it must be added in this switch!           */
+                       }
+               }
+       }
+}
 
-                                               /* pop 0 push 1 */
 
-                                       case ICMD_GETSTATIC:
-                                               COUNT(count_pcmd_mem);
-                                               NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
-                                               NEW_OP0_1(fmiref->parseddesc.fd->type);
-                                               break;
+/* stack_init_javalocals *******************************************************
+   Initialize the mapping from Java locals to cacao variables at method entry.
+
+   IN:
+      sd...........stack analysis data
+
+*******************************************************************************/
 
-                                       case ICMD_NEW:
-                                               NEW_OP0_1(TYPE_ADR);
-                                               break;
+static void stack_init_javalocals(stackdata_t *sd)
+{
+       s4         *jl;
+       s4          type,i,j;
+       methoddesc *md;
+       jitdata    *jd;
+
+       jd = sd->jd;
+
+       jl = DMNEW(s4, sd->maxlocals);
+       jd->basicblocks[0].javalocals = jl;
+
+       for (i=0; i<sd->maxlocals; ++i)
+               jl[i] = UNUSED;
+
+       md = jd->m->parseddesc;
+       j = 0;
+       for (i=0; i<md->paramcount; ++i) {
+               type = md->paramtypes[i].type;
+               jl[j] = jd->local_map[5*j + type];
+               j++;
+               if (IS_2_WORD_TYPE(type))
+                       j++;
+       }
+}
 
-                                       case ICMD_JSR:
-                                               NEW_OP0_1(TYPE_ADR);
 
-                                               BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
+/* stack_analyse ***************************************************************
 
-                                               tbptr->type = BBTYPE_SBR;
+   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.
 
-                                               /* We need to check for overflow right here because
-                                                * the pushed value is poped afterwards */
-                                               NEW_CHECKOVERFLOW;
+*******************************************************************************/
 
-                                               /* calculate stack after return */
-                                               POPANY;
-                                               stackdepth--;
-                                               break;
+bool stack_analyse(jitdata *jd)
+{
+       methodinfo   *m;              /* method being analyzed                    */
+       registerdata *rd;
+       stackdata_t   sd;
+       int           stackdepth;
+       stackptr      curstack;       /* current stack top                        */
+       stackptr      copy;
+       int           opcode;         /* opcode of current instruction            */
+       int           i, varindex;
+       int           javaindex;
+       int           type;           /* operand type                             */
+       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;
+       basicblock   *original;
+       exception_entry *ex;
 
-                                       /* pop many push any */
+       stackptr     *last_store_boundary;
+       stackptr      coalescing_boundary;
 
-                                       case ICMD_BUILTIN:
-#if defined(USEBUILTINTABLE)
-icmd_BUILTIN:
-#endif
-                                               bte = iptr->sx.s23.s3.bte;
-                                               md = bte->md;
-                                               goto _callhandling;
+       stackptr      src1, src2, src3, src4, dst1, dst2;
 
-                                       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);} */
+       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
+       int           new_index; /* used to get a new var index with GET_NEW_INDEX*/
 
-                                       _callhandling:
+#if defined(STACK_VERBOSE)
+       show_method(jd, SHOW_PARSE);
+#endif
 
-                                               last_pei = bptr->icount - len - 1;
+       /* get required compiler data - initialization */
 
-                                               i = md->paramcount;
+       m    = jd->m;
+       rd   = jd->rd;
 
-                                               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;
+       /* initialize the stackdata_t struct */
 
-                                               REQUIRE(i);
+       sd.m = m;
+       sd.jd = jd;
+       sd.varcount = jd->varcount;
+       sd.vartop =  jd->vartop;
+       sd.localcount = jd->localcount;
+       sd.var = jd->var;
+       sd.varsallocated = sd.varcount;
+       sd.maxlocals = m->maxlocals;
+       sd.javalocals = DMNEW(s4, sd.maxlocals);
+       sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
 
-                                               /* XXX optimize for <= 2 args */
-                                               /* XXX not for ICMD_BUILTIN */
-                                               iptr->s1.argcount = stackdepth;
-                                               iptr->sx.s23.s2.args = DMNEW(stackptr, stackdepth);
+       /* prepare the variable for exception handler stacks               */
+       /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
 
-                                               copy = curstack;
-                                               for (i-- ; i >= 0; i--) {
-                                                       iptr->sx.s23.s2.args[i] = copy;
+       sd.exstack.type = TYPE_ADR;
+       sd.exstack.prev = NULL;
+       sd.exstack.varnum = sd.localcount;
+       sd.var[sd.exstack.varnum].type = TYPE_ADR;
 
-#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)) {
+#if defined(ENABLE_STATISTICS)
+       iteration_count = 0;
 #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)) {
-#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;
-                                               }
+       /* 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);
 
-                                               /* deal with live-through stack slots "under" the arguments */
-                                               /* XXX not for ICMD_BUILTIN */
+       /* find the last exception handler */
 
-                                               i = md->paramcount;
+       if (jd->exceptiontablelength)
+               sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
+       else
+               sd.extableend = NULL;
 
-                                               while (copy) {
-                                                       iptr->sx.s23.s2.args[i++] = copy;
-                                                       copy->flags |= SAVEDVAR;
-                                                       copy = copy->prev;
-                                               }
+       /* init jd->interface_map */
 
-                                               /* pop the arguments */
+       jd->maxinterfaces = m->maxstack;
+       jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
+       for (i = 0; i < m->maxstack * 5; i++)
+               jd->interface_map[i].flags = UNUSED;
 
-                                               i = md->paramcount;
+       last_store_boundary = DMNEW(stackptr, m->maxlocals);
 
-                                               stackdepth -= i;
-                                               while (--i >= 0) {
-                                                       POPANY;
-                                               }
+       /* initialize flags and invars (none) of first block */
 
-                                               /* push the return value */
+       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);
 
-                                               if (md->returntype.type != TYPE_VOID) {
-                                                       NEW_DST(md->returntype.type, stackdepth);
-                                                       stackdepth++;
-                                               }
-                                               break;
+       /* initialize java local mapping of first block */
 
-                                       case ICMD_INLINE_START:
-                                       case ICMD_INLINE_END:
-                                               CLR_S1;
-                                               CLR_DST;
-                                               break;
+       stack_init_javalocals(&sd);
 
-                                       case ICMD_MULTIANEWARRAY:
-                                               if (rd->argintreguse < 3)
-                                                       rd->argintreguse = 3;
+       /* stack analysis loop (until fixpoint reached) **************************/
 
-                                               i = iptr->s1.argcount;
+       do {
+#if defined(ENABLE_STATISTICS)
+               iteration_count++;
+#endif
 
-                                               REQUIRE(i);
+               /* initialize loop over basic blocks */
 
-                                               iptr->sx.s23.s2.args = DMNEW(stackptr, i);
+               sd.bptr       = jd->basicblocks;
+               superblockend = true;
+               sd.repeat     = false;
+               curstack      = NULL;
+               stackdepth    = 0;
+               deadcode      = true;
 
-#if defined(SPECIALMEMUSE)
-# if defined(__DARWIN__)
-                                               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_SIZE_IN_POINTERS + 3))
-                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + 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_SIZE_IN_POINTERS + INT_ARG_CNT;
-# else
-                                                               copy->regoff = i + LA_SIZE_IN_POINTERS + 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;
-                                               }
+               /* iterate over basic blocks *****************************************/
 
-                                               i = iptr->s1.argcount;
-                                               stackdepth -= i;
-                                               while (--i >= 0) {
-                                                       POPANY;
-                                               }
-                                               NEW_DST(TYPE_ADR, stackdepth);
-                                               stackdepth++;
-                                               break;
+               for (; sd.bptr; sd.bptr = sd.bptr->next) {
 
-                                       default:
-                                               *exceptionptr =
-                                                       new_internalerror("Unknown ICMD %d", opcode);
-                                               return false;
-                                       } /* switch */
+                       if (sd.bptr->flags == BBDELETED) {
+                               /* This block has been deleted - do nothing. */
 
-                                       NEW_CHECKOVERFLOW;
-                                       iptr++;
-                               } /* while instructions */
+                               continue;
+                       }
 
-                               /* set out-stack of block */
+                       if (sd.bptr->flags == BBTYPECHECK_REACHED) {
+                               /* re-analyse a block because its input changed */
 
-                               bptr->outstack = curstack;
-                               bptr->outdepth = stackdepth;
+                               deadcode = false;
 
-                               /* stack slots at basic block end become interfaces */
+                               if (!stack_reanalyse_block(&sd))
+                                       return false;
 
-                               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;
-                                       );
-                               }
+                               superblockend = true; /* XXX */
+                               continue;
+                       }
 
-                               /* check if interface slots at basic block begin must be saved */
+                       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. */
 
-                               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;
-                                               }
-                                       }
-                               );
+                               sd.repeat = true;
+                               continue;
+                       }
 
-                       } /* if */
-                       else
-                               superblockend = true;
+                       if (sd.bptr->flags > BBREACHED) {
+                               /* This block is already finished. */
 
-                       bptr++;
-               } /* while blocks */
-       } while (repeat && !deadcode);
+                               superblockend = true;
+                               continue;
+                       }
 
-       /* gather statistics *****************************************************/
+                       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. */
 
-#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]++;
+                               sd.repeat = true;
+                               /* XXX superblockend? */
+                               continue;
                        }
-                       bptr++;
-               }
 
-               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]++;
+                       /* This block has to be analysed now. */
 
-               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]++;
-       }
-#endif /* defined(ENABLE_STATISTICS) */
+                       deadcode = false;
 
-       /* everything's ok *******************************************************/
+                       /* XXX The rest of this block is still indented one level too */
+                       /* much in order to avoid a giant diff by changing that.      */
+
+                               /* We know that sd.bptr->flags == BBREACHED. */
+                               /* This block has been reached before.    */
+
+                               assert(sd.bptr->flags == BBREACHED);
+                               stackdepth = sd.bptr->indepth;
 
-       return true;
+                               /* find exception handlers for this block */
 
-       /* goto labels for throwing verifier exceptions **************************/
+                               /* determine the active exception handlers for this block */
+                               /* XXX could use a faster algorithm with sorted lists or  */
+                               /* something?                                             */
 
-#if defined(ENABLE_VERIFIER)
+                               original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
 
-throw_stack_underflow:
-       exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
-       return false;
+                               len = 0;
+                               ex = jd->exceptiontable;
+                               for (; ex != NULL; ex = ex->down) {
+                                       if ((ex->start <= original) && (ex->end > original)) {
+                                               sd.handlers[len++] = ex;
+                                       }
+                               }
+                               sd.handlers[len] = NULL;
 
-throw_stack_overflow:
-       exceptions_throw_verifyerror(m, "Stack size too large");
-       return false;
 
-throw_stack_depth_error:
-       exceptions_throw_verifyerror(m,"Stack depth mismatch");
-       return false;
+                               /* reanalyse cloned block */
 
-throw_stack_type_error:
-       exceptions_throw_verifyerror_for_stack(m, expectedtype);
-       return false;
+                               if (sd.bptr->original) {
+                                       if (!stack_reanalyse_block(&sd))
+                                               return false;
+                                       continue;
+                               }
 
-throw_stack_category_error:
-       exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
-       return false;
+                               /* reset the new pointer for allocating stackslots */
 
-#endif
-}
+                               sd.new = jd->stack;
 
-bool stack_analyse(jitdata *jd)
-{
-       methodinfo   *m;
-       codeinfo     *code;
-       codegendata  *cd;
-       registerdata *rd;
-       int           b_count;
-       int           b_index;
-       int           stackdepth;
-       stackptr      curstack;
-       stackptr      new;
-       stackptr      copy;
-       int           opcode, i, j, len, loops;
-       int           superblockend, repeat, deadcode;
-       instruction  *iptr;
-       basicblock   *bptr;
-       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;
-#if defined(ENABLE_VERIFIER)
-       int           expectedtype; /* used by CHECK_BASIC_TYPE */
-#endif
+                               /* create the instack of this block */
 
-       builtintable_entry *bte;
-       methoddesc         *md;
+                               curstack = stack_create_instack(&sd);
 
-       /* get required compiler data */
+                               /* initialize locals at the start of this block */
 
-       m    = jd->m;
-       code = jd->code;
-       cd   = jd->cd;
-       rd   = jd->rd;
+                               if (sd.bptr->inlocals)
+                                       MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
 
-       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->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
-               STACKRESET;
-               NEWXSTACK;
-       }
+                               MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
 
-       do {
-               loops++;
-               b_count = m->basicblockcount;
-               bptr = m->basicblocks;
-               superblockend = true;
-               repeat = false;
-               STACKRESET;
-               deadcode = true;
-
-               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);
-                               }
+                               /* set up local variables for analyzing this block */
 
-                               curstack = bptr->instack;
-                               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;
+
+                               /* mark the block as analysed */
+
+                               sd.bptr->flags = BBFINISHED;
+
+                               /* reset variables for dependency checking */
+
+                               coalescing_boundary = sd.new;
+                               for( i = 0; i < m->maxlocals; i++)
+                                       last_store_boundary[i] = sd.new;
+
+                               /* remember the start of this block's variables */
+  
+                               sd.bptr->varstart = sd.vartop;
 
-                               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;
+#if defined(STACK_VERBOSE)
+                               stack_verbose_block_enter(&sd, false);
+#endif
+  
+                               /* reach exception handlers for this block */
 
-                               bptr->stack = new;
+                               if (!stack_reach_handlers(&sd))
+                                       return false;
+
+                               /* iterate over ICMDs ****************************************/
 
                                while (--len >= 0)  {
+
+#if defined(STACK_VERBOSE)
+                                       stack_verbose_show_state(&sd, iptr, curstack);
+#endif
+
+                                       /* fetch the current opcode */
+
                                        opcode = iptr->opc;
 
-                                       /* check if ICMD opcode could throw an exception        */
-                                       /* and if so remember the instruction index in last_pei */
+                                       /* automatically replace some ICMDs with builtins */
 
-                                       if (op_data[opcode][PEI])
-                                               last_pei = bptr->icount - len - 1;
+                                       bte = builtintable_get_automatic(opcode);
 
-#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)
+                                       if ((bte != NULL) && (bte->opcode == opcode)) {
+                                               iptr->opc            = ICMD_BUILTIN;
+                                               iptr->flags.bits    &= INS_FLAG_ID_MASK;
+                                               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_NOP:
+icmd_NOP:
+                                               CLR_SX;
+                                               OP0_0;
+                                               break;
+
                                        case ICMD_CHECKNULL:
+                                               coalescing_boundary = sd.new;
                                                COUNT(count_check_null);
-                                       case ICMD_NOP:
-                                               SETDST;
+                                               USE_S1(TYPE_ADR);
+                                               CLR_SX;
+                                               iptr->dst.varindex = iptr->s1.varindex;
                                                break;
 
                                        case ICMD_RET:
-#if defined(ENABLE_INTRP)
-                                               if (!opt_intrp)
+                                               varindex = iptr->s1.varindex = 
+                                                       jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
+
+#if defined(ENABLE_VERIFIER)
+                                               if (sd.var[varindex].type != TYPE_RET) {
+                                                       exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
+                                                       return false;
+                                               }
 #endif
-                                                       rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
+               
+                                               CLR_SX;
+
+                                               iptr->dst.block = stack_mark_reached(&sd, sd.var[varindex].vv.retaddr, curstack, stackdepth);
+                                               superblockend = true;
+                                               break;
+
                                        case ICMD_RETURN:
                                                COUNT(count_pcmd_return);
-                                               SETDST;
+                                               CLR_SX;
+                                               OP0_0;
                                                superblockend = true;
+                                               sd.jd->returncount++;
+                                               sd.jd->returnblock = sd.bptr;
                                                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;
@@ -3260,569 +2646,584 @@ 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;
+                                                                       fmiref = iptr->sx.s23.s3.uf->fieldref;
+                                                               }
+                                                               else {
+                                                                       fmiref = iptr[1].sx.s23.s3.fmiref;
+                                                                       iptr->sx.s23.s3.fmiref = fmiref;
+                                                               }
+
+#if defined(ENABLE_VERIFIER)
+                                                               expectedtype = fmiref->parseddesc.fd->type;
+                                                               switch (iptr[0].opc) {
+                                                                       case ICMD_ICONST:
+                                                                               if (expectedtype != TYPE_INT)
+                                                                                       goto throw_stack_type_error;
+                                                                               break;
+                                                                       case ICMD_LCONST:
+                                                                               if (expectedtype != TYPE_LNG)
+                                                                                       goto throw_stack_type_error;
+                                                                               break;
+                                                                       case ICMD_ACONST:
+                                                                               if (expectedtype != TYPE_ADR)
+                                                                                       goto throw_stack_type_error;
+                                                                               break;
+                                                                       default:
+                                                                               assert(0);
+                                                               }
+#endif /* defined(ENABLE_VERIFIER) */
+                                                               
+                                                               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.block = iptr[2].dst.block;
                                                                                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)
+                                               type = opcode - ICMD_ILOAD;
+
+                                               varindex = iptr->s1.varindex = 
+                                                       jd->local_map[iptr->s1.varindex * 5 + type];
+
+#if defined(ENABLE_VERIFIER)
+                                               if (sd.var[varindex].type == TYPE_RET) {
+                                                       exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
+                                                       return false;
+                                               }
 #endif
-                                                       rd->locals[iptr->op1][i].type = i;
-                                               LOAD(i, LOCALVAR, iptr->op1);
+                                               LOAD(type, varindex);
                                                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:
-#if defined(ENABLE_STATISTICS)
-                                               if (opt_stat) {
-                                                       i = stackdepth;
-                                                       if (i >= 10)
-                                                               count_store_depth[10]++;
-                                                       else
-                                                               count_store_depth[i]++;
-                                               }
-#endif
-                                               last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1;
+                                               STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
+                                               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->op1)) {
-                                                               copy->varkind = TEMPVAR;
-                                                               copy->varnum = i;
+                                                               (copy->varnum == iptr->s1.varindex))
+                                                       {
+                                                               assert(IS_LOCALVAR(copy));
+                                                               SET_TEMPVAR(copy);
                                                        }
                                                        i--;
                                                        copy = copy->prev;
                                                }
-                                               
-                                               SETDST;
+
+                                               iptr->dst.varindex = iptr->s1.varindex;
                                                break;
 
                                                /* pop 1 push 0 store */
@@ -3832,152 +3233,140 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_FSTORE:
                                        case ICMD_DSTORE:
                                        case ICMD_ASTORE:
-                                               REQUIRE_1;
+                                               REQUIRE(1);
 
-                                       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]++;
+                                               type = opcode - ICMD_ISTORE;
+                                               javaindex = iptr->dst.varindex;
+                                               varindex = iptr->dst.varindex = 
+                                                       jd->local_map[javaindex * 5 + type];
+
+                                               COPY_VAL_AND_TYPE(sd, curstack->varnum, varindex);
+
+                                               iptr->sx.s23.s3.javaindex = javaindex;
+
+                                               if (curstack->type == TYPE_RET) {
+                                                       iptr->flags.bits |= INS_FLAG_RETADDR;
+                                                       iptr->sx.s23.s2.retaddrnr = 
+                                                               JAVALOCAL_FROM_RETADDR(sd.var[varindex].vv.retaddr->nr);
+                                                       sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
+                                               }
                                                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;
+                                                       sd.javalocals[javaindex] = varindex;
+
+                                               /* invalidate the following javalocal for 2-word types */
+
+                                               if (IS_2_WORD_TYPE(type)) {
+                                                       sd.javalocals[javaindex+1] = UNUSED;
+                                                       iptr->flags.bits |= INS_FLAG_KILL_NEXT;
                                                }
-                                               i--;
-                                               copy = copy->prev;
-                                       }
 
-                                       /* 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 */
+                                               /* invalidate 2-word types if second half was overwritten */
+
+                                               if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) >= 0) {
+                                                       if (IS_2_WORD_TYPE(sd.var[i].type)) {
+                                                               sd.javalocals[javaindex-1] = UNUSED;
+                                                               iptr->flags.bits |= INS_FLAG_KILL_PREV;
+                                                       }
+                                               }
+
+#if defined(ENABLE_STATISTICS)
+                                               if (opt_stat) {
+                                                       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
 
-                                                       /* TODO:.... */
-                                                       /* now look, if there is a LOCALVAR at anyone of */
-                                                       /* the src stacklots used by DUPX */
+                                               /* check for conflicts as described in Figure 5.2 */
 
-                                                       goto _possible_conflict;
+                                               copy = curstack->prev;
+                                               i = stackdepth - 2;
+                                               while (copy) {
+                                                       if ((copy->varkind == LOCALVAR) &&
+                                                               (copy->varnum == varindex))
+                                                       {
+                                                               copy->varkind = TEMPVAR;
+                                                               assert(IS_LOCALVAR(copy));
+                                                               SET_TEMPVAR(copy);
+                                                       }
+                                                       i--;
+                                                       copy = copy->prev;
                                                }
-                                       }
 
-                                       /* 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!!! */
+                                               /* if the variable is already coalesced, don't bother */
+
+                                               /* We do not need to check against INOUT, as invars */
+                                               /* are always before the coalescing boundary.        */
+
+                                               if (curstack->varkind == LOCALVAR)
+                                                       goto store_tail;
+
+                                               /* there is no STORE Lj while curstack is live */
+
+                                               if (curstack < last_store_boundary[javaindex])
+                                                       goto assume_conflict;
+
+                                               /* 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(varindex) 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 == varindex)
+                                                               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);
+                                               assert(!(curstack->flags & PASSTHROUGH));
+                                               RELEASE_INDEX(sd, curstack);
+                                               curstack->varkind = LOCALVAR;
+                                               curstack->varnum = varindex;
+                                               curstack->creator->dst.varindex = varindex;
+                                               goto store_tail;
+
+                                               /* revert the coalescing, if it has been done earlier */
+assume_conflict:
+                                               if ((curstack->varkind == LOCALVAR)
+                                                       && (curstack->varnum == varindex))
+                                               {
+                                                       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 (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
+                                                       STORE(TYPE_RET, varindex);
+                                               else
+                                                       STORE(opcode - ICMD_ISTORE, varindex);
+                                               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);
@@ -3989,35 +3378,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 */
@@ -4025,12 +3425,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:
@@ -4038,28 +3438,32 @@ 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;
+                                               sd.jd->returncount++;
+                                               sd.jd->returnblock = sd.bptr;
                                                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 */
@@ -4067,12 +3471,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:
@@ -4082,30 +3482,21 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_IFGT:
                                        case ICMD_IFLE:
                                                COUNT(count_pcmd_bra);
-
-                                               /* 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;
 
@@ -4113,63 +3504,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);
+
+                                               BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
 
-                                               tptr = DMNEW(void*, i+1);
-                                               iptr->target = (void *) tptr;
+                                               lookup = iptr->dst.lookup;
 
-                                               tptr[0] = (void *) tbptr;
-                                               tptr++;
+                                               i = iptr->sx.s23.s2.lookupcount;
 
                                                while (--i >= 0) {
-                                                       tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
-
-                                                       tptr[0] = (void *) tbptr;
-                                                       tptr++;
-                                                               
-                                                       MARKREACHED(tbptr, copy);
-                                                       s4ptr += 2;
+                                                       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;
 
@@ -4182,241 +3555,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;
@@ -4427,11 +3905,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:
@@ -4444,30 +3923,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:
@@ -4479,14 +3960,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:
@@ -4495,7 +3976,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:
@@ -4504,239 +3985,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.block = iptr[1].dst.block;
+                                                       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.block = iptr[1].dst.block;
+                                                       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;
+                                               }
+                                               break;
+
+normal_FCMPL:
+                                               OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
+                                               break;
+
+                                       case ICMD_FCMPG:
+                                               COUNT(count_pcmd_op);
+                                               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.block = iptr[1].dst.block;
+                                                       iptr[1].opc = ICMD_NOP;
+
+                                                       OP2_BRANCH(TYPE_FLT, TYPE_FLT);
+                                                       BRANCH(tbptr);
+
+                                                       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;
 
-                                       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;
-
-                                                               OP2_0(TYPE_FLT);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) 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);
-                                                       }
-                                               }
-                                               else
-                                                       OPTT2_1(TYPE_FLT, TYPE_INT);
+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.block = iptr[1].dst.block;
+                                                       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;
 
-                                                               OP2_0(TYPE_DBL);
-                                                               tbptr = m->basicblocks +
-                                                                       m->basicblockindex[iptr[0].op1];
-                       
-                                                               iptr[0].target = (void *) tbptr;
+                                               switch (iptr[1].opc) {
+                                               case ICMD_IFEQ:
+                                                       iptr->opc = ICMD_IF_DCMPEQ;
+                                               icmd_if_dcmpg_tail:
+                                                       iptr->dst.block = iptr[1].dst.block;
+                                                       iptr[1].opc = ICMD_NOP;
 
-                                                               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);
-                                                       }
+                                                       OP2_BRANCH(TYPE_DBL, TYPE_DBL);
+                                                       BRANCH(tbptr);
+
+                                                       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:
@@ -4807,7 +4281,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);
@@ -4822,6 +4297,7 @@ bool stack_analyse(jitdata *jd)
 
                                                        copy = curstack;
                                                        while (copy) {
+                                                               sd.var[copy->varnum].flags |= SAVEDVAR;
                                                                copy->flags |= SAVEDVAR;
                                                                copy = copy->prev;
                                                        }
@@ -4831,59 +4307,70 @@ 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];
+                                               OP0_1(TYPE_RET);
+
+                                               tbptr = iptr->sx.s23.s3.jsrtarget.block;
+                                               tbptr->type = BBTYPE_SBR;
 
-                                               iptr[0].target = (void *) tbptr;
+                                               assert(sd.bptr->next);  /* XXX exception */
+                                               sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
+#if defined(ENABLE_VERIFIER)
+                                               sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
+#endif
 
-                                               /* This is a dirty hack. The typechecker
-                                                * needs it because the OP1_0ANY below
-                                                * overwrites iptr->dst.
-                                                */
-                                               iptr->val.a = (void *) iptr->dst;
+                                               tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
+                                               if (tbptr == NULL)
+                                                       return false;
 
-                                               tbptr->type = BBTYPE_SBR;
+                                               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;
 
@@ -4892,13 +4379,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;
 
@@ -4911,83 +4406,109 @@ bool stack_analyse(jitdata *jd)
 
                                                REQUIRE(i);
 
+                                               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 = 
+                                                                                       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(GET_LOW_REG(md->params[i].regoff),
+                                         GET_HIGH_REG(md->params[i].regoff));
+
+                                                                               else
+#endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
+                                                                                       sd.var[copy->varnum].vv.regoff = 
+                                                                                               md->params[i].regoff;
                                                                        }
-#if defined(ENABLE_INTRP)
                                                                }
-#endif
+                                                       }
                                                        }
                                                        copy = copy->prev;
                                                }
 
+                                               /* deal with live-through stack slots "under" the */
+                                               /* arguments */
+
+                                               i = md->paramcount;
+
                                                while (copy) {
-                                                       copy->flags |= SAVEDVAR;
+                                                       iptr->sx.s23.s2.args[i++] = copy->varnum;
+                                                       sd.var[copy->varnum].flags |= SAVEDVAR;
+                                                       copy->flags |= SAVEDVAR | PASSTHROUGH;
                                                        copy = copy->prev;
                                                }
 
+                                               /* pop the arguments */
+
                                                i = md->paramcount;
-                                               POPMANY(i);
-                                               if (md->returntype.type != TYPE_VOID)
-                                                       OP0_1(md->returntype.type);
-                                               break;
 
-                                       case ICMD_INLINE_START:
-                                       case ICMD_INLINE_END:
-                                               SETDST;
+                                               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_MULTIANEWARRAY:
-                                               if (rd->argintreguse < 3)
-                                                       rd->argintreguse = 3;
+                                               coalescing_boundary = sd.new;
+                                               if (rd->argintreguse < MIN(3, INT_ARG_CNT))
+                                                       rd->argintreguse = MIN(3, INT_ARG_CNT);
 
-                                               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_SIZE_IN_POINTERS))
+                                               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_SIZE_IN_POINTERS + 3))
@@ -5007,41 +4528,53 @@ 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_SIZE_IN_POINTERS + INT_ARG_CNT;
+                                                               sd.var[copy->varnum].vv.regoff = i + 
+                                                                       LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                                               copy->regoff = i + LA_SIZE_IN_POINTERS + 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:
-                                               *exceptionptr =
-                                                       new_internalerror("Unknown ICMD %d", opcode);
+                                               exceptions_throw_internalerror("Unknown ICMD %d during stack analysis",
+                                                                                                          opcode);
                                                return false;
                                        } /* switch */
 
@@ -5049,70 +4582,149 @@ bool stack_analyse(jitdata *jd)
                                        iptr++;
                                } /* while instructions */
 
-                               /* set out-stack of block */
+                               /* show state after last instruction */
 
-                               bptr->outstack = curstack;
-                               bptr->outdepth = stackdepth;
+#if defined(STACK_VERBOSE)
+                               stack_verbose_show_state(&sd, NULL, curstack);
+#endif
 
                                /* 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;
-                                       else {
-                                               copy->varkind = STACKVAR;
-                                               copy->varnum = i;
+                                       varinfo *v;
+
+                                       /* 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);
+                                       type = copy->type;
+
+                                       v = sd.var + copy->varnum;
+                                       v->flags |= INOUT;
+
+                                       /* do not allocate variables for returnAddresses */
+
+                                       if (type != TYPE_RET) {
+                                               if (jd->interface_map[i*5 + type].flags == UNUSED) {
+                                                       /* no interface var until now for this depth and */
+                                                       /* type */
+                                                       jd->interface_map[i*5 + type].flags = v->flags;
+                                               }
+                                               else {
+                                                       jd->interface_map[i*5 + type].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];
+
+                                       type = v->type;
+
+                                       if (type != TYPE_RET) {
+                                               if (jd->interface_map[i*5 + type].flags == UNUSED) {
+                                                       /* no interface var until now for this depth and */
+                                                       /* type */
+                                                       jd->interface_map[i*5 + type].flags = v->flags;
+                                               }
+                                               else {
+                                                       jd->interface_map[i*5 + type].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;
 
-                       bptr++;
-               } /* while blocks */
-       } while (repeat && !deadcode);
+               } /* for blocks */
+
+       } while (sd.repeat && !deadcode);
+
+    /* reset locals of TYPE_RET|VOID to TYPE_ADR */
+
+    /* A local variable may be used as both a returnAddress and a reference */
+    /* type variable, as we do not split variables between these types when */
+    /* renaming locals. While returnAddresses have been eliminated now, we  */
+    /* must assume that the variable is still used as TYPE_ADR.             */
+    /* The only way that a local can be TYPE_VOID at this point, is that it */
+    /* was a TYPE_RET variable for which incompatible returnAddresses were  */
+    /* merged. Thus we must treat TYPE_VOID in the same way as TYPE_RET     */
+    /* here.                                                                */
+    /* XXX: It would be nice to remove otherwise unused returnAddress       */
+    /*      variables from the local variable array, so they are not        */
+    /*      allocated by simplereg. (For LSRA this is not needed).          */
+
+       for (i=0; i<sd.localcount; ++i) {
+               if (sd.var[i].type == TYPE_RET || sd.var[i].type == TYPE_VOID)
+                       sd.var[i].type = TYPE_ADR;
+       }
+
+       /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
+
+       for (i=sd.localcount; i<sd.vartop; ++i) {
+               if (sd.var[i].type == TYPE_RET)
+                       sd.var[i].flags |= PREALLOC;
+       }
+
+       /* XXX hack to fix up the ranges of the cloned single-block handlers */
+
+       ex = jd->exceptiontable;
+       for (; ex != NULL; ex = ex->down) {
+               if (ex->start == ex->end) {
+                       assert(ex->end->next);
+                       ex->end = ex->end->next;
+               }
+       }
+
+       /* store number of created variables */
+
+       jd->vartop = sd.vartop;
+
+       /* 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]++;
@@ -5131,45 +4743,46 @@ 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:
@@ -5180,10 +4793,6 @@ throw_stack_overflow:
        exceptions_throw_verifyerror(m, "Stack size too large");
        return false;
 
-throw_stack_depth_error:
-       exceptions_throw_verifyerror(m,"Stack depth mismatch");
-       return false;
-
 throw_stack_type_error:
        exceptions_throw_verifyerror_for_stack(m, expectedtype);
        return false;
@@ -5196,6 +4805,183 @@ throw_stack_category_error:
 }
 
 
+/* stack_javalocals_store ******************************************************
+   Model the effect of a ?STORE instruction upon the given javalocals array.
+  
+   IN:
+       iptr.............the ?STORE instruction
+          javalocals.......the javalocals array to modify
+  
+*******************************************************************************/
+
+void stack_javalocals_store(instruction *iptr, s4 *javalocals)
+{
+       s4 varindex;     /* index into the jd->var array */
+       s4 javaindex;    /* java local index             */
+
+       varindex = iptr->dst.varindex;
+       javaindex = iptr->sx.s23.s3.javaindex;
+
+       if (javaindex != UNUSED) {
+               assert(javaindex >= 0);
+               if (iptr->flags.bits & INS_FLAG_RETADDR)
+                       javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
+               else
+                       javalocals[javaindex] = varindex;
+
+               if (iptr->flags.bits & INS_FLAG_KILL_PREV)
+                       javalocals[javaindex-1] = UNUSED;
+
+               if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
+                       javalocals[javaindex+1] = UNUSED;
+       }
+}
+
+
+/* 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);
+#if defined(ENABLE_VERIFIER)
+               printf("{start=L%03d}", ((basicblock *)v->SBRSTART)->nr);
+#endif
+       }
+}
+
+
+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("] javalocals ");
+       show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
+       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) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "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");
+}
+
+static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
+{
+       stackptr sp;
+       s4       i;
+       s4       depth;
+       varinfo *v;
+       stackptr *stack;
+
+       printf("    javalocals ");
+       show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
+       printf(" stack [");
+
+       for(i = 0, sp = curstack; sp; sp = sp->prev)
+               i++;
+       depth = i;
+
+       stack = MNEW(stackptr, depth);
+       for(sp = curstack; sp; sp = sp->prev)
+               stack[--i] = sp;
+
+       for(i=0; i<depth; ++i) {
+               if (i)
+                       putchar(' ');
+               sp = stack[i];
+               v = &(sd->var[sp->varnum]);
+
+               if (v->flags & INOUT)
+                       putchar('I');
+               if (v->flags & PREALLOC)
+                       putchar('A');
+               printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
+               if (v->type == TYPE_RET) {
+                       printf("(L%03d)", v->vv.retaddr->nr);
+               }
+       }
+       printf("] ... ");
+       if (iptr)
+               show_icmd(sd->jd, iptr, false, SHOW_PARSE); 
+       printf("\n");
+}
+#endif
+
 
 /*
  * These are local overrides for various environment variables in Emacs.