* Removed all Id tags.
[cacao.git] / src / vm / jit / allocator / simplereg.c
index 15a12c80b00f06d2fedde44adb4231383da92ef1..a2a14bdc9088aa69e9cb5def082a1f37a3e6f161 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/allocator/simplereg.c - register allocator
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   Copyright (C) 1996-2005, 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., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Andreas Krall
-
-   Changes: Stefan Ring
-            Christian Thalinger
-            Christian Ullrich
-            Michael Starzinger
-            Edwin Steiner
-
-   $Id: simplereg.c 5317 2006-09-05 12:29:16Z edwin $
-
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
 
 #include "arch.h"
 #include "md-abi.h"
 
+#include "mm/memory.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
-#include "mm/memory.h"
-#include "vm/method.h"
-#include "vm/options.h"
 #include "vm/resolve.h"
 #include "vm/stringlocal.h"
+
+#include "vm/jit/abi.h"
 #include "vm/jit/reg.h"
+#include "vm/jit/show.h"
 #include "vm/jit/allocator/simplereg.h"
 
+#include "vmcore/method.h"
+#include "vmcore/options.h"
+
+
+#if 0
+#    define LOG(args) printf args
+#else
+#    define LOG(args)
+#endif
+
 
 /* function prototypes for this file ******************************************/
 
-static void interface_regalloc(jitdata *jd);
-static void local_regalloc(jitdata *jd);
-static void new_allocate_scratch_registers(jitdata *jd);
-static void allocate_scratch_registers(jitdata *jd);
+static void simplereg_allocate_interfaces(jitdata *jd);
+static void simplereg_allocate_locals(jitdata *jd);
+static void simplereg_allocate_temporaries(jitdata *jd);
+
+
+/* size of a stackslot used by the internal ABI */
+
+#if defined(HAS_4BYTE_STACKSLOT)
+# define SIZE_OF_STACKSLOT 4
+#else 
+# define SIZE_OF_STACKSLOT 8
+#endif
+
+
+/* total number of registers */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define TOTAL_REG_CNT  (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
+#else
+#define TOTAL_REG_CNT  (INT_REG_CNT + FLT_REG_CNT)
+#endif
+
+
+/* macros for handling register stacks ****************************************/
+
+#define AVAIL_FRONT(cnt, limit)   ((cnt) < (limit))
+#define AVAIL_BACK(cnt)           ((cnt) > 0)
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#define AVAIL_FRONT_INT(cnt, limit)   ((cnt) < (limit) - intregsneeded)
+#define AVAIL_BACK_INT(cnt)           ((cnt) > intregsneeded)
+#else
+#define AVAIL_FRONT_INT(cnt, limit)   AVAIL_FRONT(cnt, limit)
+#define AVAIL_BACK_INT(cnt)           AVAIL_BACK(cnt)
+#endif
+
+#define POP_FRONT(stk, cnt, reg)   do {  reg = stk[cnt++];    } while (0)
+#define POP_BACK(stk, cnt, reg)    do {  reg = stk[--cnt];    } while (0)
+#define PUSH_FRONT(stk, cnt, reg)  do {  stk[--cnt] = (reg);  } while (0)
+#define PUSH_BACK(stk, cnt, reg)   do {  stk[cnt++] = (reg);  } while (0)
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#define POP_FRONT_INT(stk, cnt, reg)                                 \
+    do {                                                             \
+        if (intregsneeded) {                                         \
+            reg = PACK_REGS(stk[cnt], stk[cnt+1]);                   \
+            cnt += 2;                                                \
+        }                                                            \
+        else                                                         \
+            POP_FRONT(stk, cnt, reg);                                \
+    } while (0)
+#else
+#define POP_FRONT_INT(stk, cnt, reg)  POP_FRONT(stk, cnt, reg)
+#endif
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#define POP_BACK_INT(stk, cnt, reg)                                  \
+    do {                                                             \
+        if (intregsneeded) {                                         \
+            cnt -= 2;                                                \
+            reg = PACK_REGS(stk[cnt], stk[cnt+1]);                   \
+        }                                                            \
+        else                                                         \
+            POP_BACK(stk, cnt, reg);                                 \
+    } while (0)
+#else
+#define POP_BACK_INT(stk, cnt, reg)  POP_BACK(stk, cnt, reg)
+#endif
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#define PUSH_BACK_INT(stk, cnt, reg)                                 \
+    do {                                                             \
+        if (intregsneeded) {                                         \
+            stk[cnt] = GET_LOW_REG(reg);                             \
+            stk[cnt + 1] = GET_HIGH_REG(reg);                        \
+            cnt += 2;                                                \
+        }                                                            \
+        else                                                         \
+            PUSH_BACK(stk, cnt, reg);                                \
+    } while (0)
+#else
+#define PUSH_BACK_INT(stk, cnt, reg)  PUSH_BACK(stk, cnt, reg)
+#endif
+
+#define AVAIL_ARG_FLT  AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
+#define AVAIL_TMP_FLT  AVAIL_BACK(rd->tmpfltreguse)
+#define AVAIL_SAV_FLT  AVAIL_BACK(rd->savfltreguse)
+
+#define AVAIL_ARG_ADR  AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
+#define AVAIL_TMP_ADR  AVAIL_BACK(rd->tmpadrreguse)
+#define AVAIL_SAV_ADR  AVAIL_BACK(rd->savadrreguse)
+
+#define AVAIL_ARG_INT  AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
+#define AVAIL_TMP_INT  AVAIL_BACK_INT(rd->tmpintreguse)
+#define AVAIL_SAV_INT  AVAIL_BACK_INT(rd->savintreguse)
+
+#define AVAIL_FREE_ARG_FLT  AVAIL_BACK(rd->freeargflttop)
+#define AVAIL_FREE_TMP_FLT  AVAIL_BACK(rd->freetmpflttop)
+#define AVAIL_FREE_SAV_FLT  AVAIL_BACK(rd->freesavflttop)
+
+#define AVAIL_FREE_ARG_ADR  AVAIL_BACK(rd->freeargadrtop)
+#define AVAIL_FREE_TMP_ADR  AVAIL_BACK(rd->freetmpadrtop)
+#define AVAIL_FREE_SAV_ADR  AVAIL_BACK(rd->freesavadrtop)
+
+#define AVAIL_FREE_ARG_INT  AVAIL_BACK_INT(rd->freearginttop)
+#define AVAIL_FREE_TMP_INT  AVAIL_BACK_INT(rd->freetmpinttop)
+#define AVAIL_FREE_SAV_INT  AVAIL_BACK_INT(rd->freesavinttop)
+
+#define TAKE_ARG_FLT(r)  POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
+#define TAKE_TMP_FLT(r)  POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
+#define TAKE_SAV_FLT(r)  POP_BACK(rd->savfltregs, rd->savfltreguse, r)
+
+#define TAKE_ARG_ADR(r)  POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
+#define TAKE_TMP_ADR(r)  POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
+#define TAKE_SAV_ADR(r)  POP_BACK(rd->savadrregs, rd->savadrreguse, r)
+
+#define TAKE_ARG_INT(r)  POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
+#define TAKE_TMP_INT(r)  POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
+#define TAKE_SAV_INT(r)  POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
+
+#define TAKE_FREE_ARG_FLT(r)  POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
+#define TAKE_FREE_TMP_FLT(r)  POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
+#define TAKE_FREE_SAV_FLT(r)  POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
+
+#define TAKE_FREE_ARG_ADR(r)  POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
+#define TAKE_FREE_TMP_ADR(r)  POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
+#define TAKE_FREE_SAV_ADR(r)  POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
+
+#define TAKE_FREE_ARG_INT(r)  POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
+#define TAKE_FREE_TMP_INT(r)  POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
+#define TAKE_FREE_SAV_INT(r)  POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
+
+#define PUSH_FREE_ARG_FLT(r)  PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
+#define PUSH_FREE_TMP_FLT(r)  PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
+#define PUSH_FREE_SAV_FLT(r)  PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
+
+#define PUSH_FREE_ARG_ADR(r)  PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
+#define PUSH_FREE_TMP_ADR(r)  PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
+#define PUSH_FREE_SAV_ADR(r)  PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
+
+#define PUSH_FREE_ARG_INT(r)  PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
+#define PUSH_FREE_TMP_INT(r)  PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
+#define PUSH_FREE_SAV_INT(r)  PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
+
+
+/* macros for allocating memory slots ****************************************/
+
+#define NEW_MEM_SLOT(r)                                              \
+    do {                                                             \
+        (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
+        rd->memuse += memneeded + 1;                                 \
+    } while (0)
+
+#define NEW_MEM_SLOT_ALIGNED(r)                                      \
+    do {                                                             \
+        if ( (memneeded) && (rd->memuse & 1))                        \
+            rd->memuse++;                                            \
+        (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
+        rd->memuse += memneeded + 1;                                 \
+    } while (0)
+
+#define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)                        \
+    do {                                                             \
+        if ( (memneeded) && (rd->memuse & 1)) {                      \
+                       PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse);      \
+            rd->memuse++;                                            \
+               }                                                            \
+        (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
+        rd->memuse += memneeded + 1;                                 \
+    } while (0)
+
+#if defined(ALIGN_LONGS_IN_MEMORY)
+#define NEW_MEM_SLOT_INT_LNG(r)  NEW_MEM_SLOT_ALIGNED(r)
+#else
+#define NEW_MEM_SLOT_INT_LNG(r)  NEW_MEM_SLOT(r)
+#endif
+
+#if defined(ALIGN_DOUBLES_IN_MEMORY)
+#define NEW_MEM_SLOT_FLT_DBL(r)  NEW_MEM_SLOT_ALIGNED(r)
+#else
+#define NEW_MEM_SLOT_FLT_DBL(r)  NEW_MEM_SLOT(r)
+#endif
+
+#if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
+#define NEW_MEM_SLOT_REUSE_PADDING(r)  NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
+#else
+#define NEW_MEM_SLOT_REUSE_PADDING(r)  NEW_MEM_SLOT(r)
+#endif
+
+
+/* macros for creating/freeing temporary variables ***************************/
+
+#define NEW_TEMP_REG(index)                                          \
+    if ( ((index) >= jd->localcount)                                 \
+         && (!(VAR(index)->flags & (INOUT | PREALLOC))) )            \
+        simplereg_new_temp(jd, (index))
+
+
+#define FREE_TEMP_REG(index)                                         \
+    if (((index) > jd->localcount)                                   \
+        && (!(VAR(index)->flags & (PREALLOC))))                      \
+        simplereg_free_temp(jd, (index))
+
+
+/* macro for getting a unique register index *********************************/
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#define REG_INDEX_NON_ADR(regoff, type)                              \
+    (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
+#else
+#define REG_INDEX_NON_ADR(regoff, type)                              \
+    (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
+#endif
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define REG_INDEX(regoff, type)                                      \
+    (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
+#else
+#define REG_INDEX(regoff, type)  REG_INDEX_NON_ADR(regoff, type)
+#endif
 
 
 /* regalloc ********************************************************************
@@ -70,19 +288,19 @@ static void allocate_scratch_registers(jitdata *jd);
        
 *******************************************************************************/
        
-bool new_regalloc(jitdata *jd)
+bool regalloc(jitdata *jd)
 {
        /* There is a problem with the use of unused float argument
           registers in leafmethods for stackslots on c7 (2 * Dual Core
           AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
           benchmark is heaviliy increased. This could be prevented by
           setting rd->argfltreguse to FLT_ARG_CNT before calling
-          allocate_scratch_registers and setting it back to the original
-          value before calling local_regalloc.  */
+          simplereg_allocate_temporaries and setting it back to the original
+          value before calling simplereg_allocate_locals.  */
 
-       interface_regalloc(jd);
-       new_allocate_scratch_registers(jd);
-       local_regalloc(jd);
+       simplereg_allocate_interfaces(jd);
+       simplereg_allocate_temporaries(jd);
+       simplereg_allocate_locals(jd);
 
        /* everthing's ok */
 
@@ -90,13 +308,13 @@ bool new_regalloc(jitdata *jd)
 }
 
 
-/* interface_regalloc **********************************************************
+/* simplereg_allocate_interfaces ***********************************************
 
    Allocates registers for all interface variables.
        
 *******************************************************************************/
        
-static void interface_regalloc(jitdata *jd)
+static void simplereg_allocate_interfaces(jitdata *jd)
 {
        methodinfo   *m;
        codegendata  *cd;
@@ -104,13 +322,15 @@ static void interface_regalloc(jitdata *jd)
 
        int     s, t, tt, saved;
        int     intalloc, fltalloc; /* Remember allocated Register/Memory offset */
-                     /* in case a more vars are packed into this interface slot */
-       varinfo *v;
-       int             intregsneeded = 0;
+                       /* in case more vars are packed into this interface slot */
        int             memneeded = 0;
-    /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
-       /* on HAS_4BYTE_STACKSLOT architectures */
+       /* Allocate LNG and DBL types first to ensure 2 memory slots or          */
+       /* registers on HAS_4BYTE_STACKSLOT architectures.                       */
        int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
+       int     flags, regoff;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+       int             intregsneeded;
+#endif
 
        /* get required compiler data */
 
@@ -129,7 +349,7 @@ static void interface_regalloc(jitdata *jd)
        }
 #endif
 
-       if (jd->isleafmethod) {
+       if (jd->isleafmethod) {
                /* Reserve argument register, which will be used for Locals acting */
                /* as Parameters */
                if (rd->argintreguse < m->parseddesc->argintreguse)
@@ -140,263 +360,219 @@ static void interface_regalloc(jitdata *jd)
                if (rd->argadrreguse < m->parseddesc->argadrreguse)
                        rd->argadrreguse = m->parseddesc->argadrreguse;
 #endif
+       }
 
-       }
-
-       for (s = 0; s < cd->maxstack; s++) {
+       for (s = 0; s < jd->maxinterfaces; s++) {
                intalloc = -1; fltalloc = -1;
-               saved = (rd->interfaces[s][TYPE_INT].flags |
-                                rd->interfaces[s][TYPE_LNG].flags |
-                        rd->interfaces[s][TYPE_FLT].flags |
-                                rd->interfaces[s][TYPE_DBL].flags |
-                        rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
+
+               /* check if the interface at this stack depth must be a SAVEDVAR */
+
+               saved = 0;
+
+               for (tt = 0; tt <=4; tt++) {
+                       if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
+                               saved |= t & SAVEDVAR;
+                       }
+               }
+
+               /* allocate reg/mem for each type the interface is used as */
+
                for (tt = 0; tt <= 4; tt++) {
                        t = typeloop[tt];
-                       v = &rd->interfaces[s][t];
-                       if (v->type >= 0) {
+                       if (jd->interface_map[s * 5 + t].flags == UNUSED)
+                               continue;
+
+                       flags = saved;
+                       regoff = -1; /* initialize to invalid value */
+
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                               intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+                       intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
+
 #if defined(HAS_4BYTE_STACKSLOT)
-                               memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+                       memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
-                               if (!saved) {
+
+                       if (!saved) {
 #if defined(HAS_ADDRESS_REGISTER_FILE)
-                                       if (IS_ADR_TYPE(t)) {
-                                               if (!jd->isleafmethod 
-                                                       &&(rd->argadrreguse < ADR_ARG_CNT)) {
-                                                       v->regoff = rd->argadrregs[rd->argadrreguse++];
-                                               } else if (rd->tmpadrreguse > 0) {
-                                                               v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
-                                               } else if (rd->savadrreguse > 0) {
-                                                               v->regoff = rd->savadrregs[--rd->savadrreguse];
-                                               } else {
-                                                       v->flags |= INMEMORY;
-                                                       v->regoff = rd->memuse++;
-                                               }                                               
-                                       } else /* !IS_ADR_TYPE */
+                               if (IS_ADR_TYPE(t)) {
+                                       if (!jd->isleafmethod && AVAIL_ARG_ADR) {
+                                               flags |= ARGREG;
+                                               TAKE_ARG_ADR(regoff);
+                                       } 
+                                       else if (AVAIL_TMP_ADR) {
+                                               TAKE_TMP_ADR(regoff);
+                                       } 
+                                       else if (AVAIL_SAV_ADR) {
+                                               flags |= SAVREG;
+                                               TAKE_SAV_ADR(regoff);
+                                       } 
+                                       else {
+                                               flags |= INMEMORY;
+                                               regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
+                                       }                                               
+                               } 
+                               else /* !IS_ADR_TYPE */
 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
-                                       {
-                                               if (IS_FLT_DBL_TYPE(t)) {
-                                                       if (fltalloc >= 0) {
-                      /* Reuse memory slot(s)/register(s) for shared interface slots */
-                                                               v->flags |= rd->interfaces[s][fltalloc].flags
-                                                                       & INMEMORY;
-                                                               v->regoff = rd->interfaces[s][fltalloc].regoff;
-                                                       } else if (rd->argfltreguse < FLT_ARG_CNT) {
-                                                               v->regoff = rd->argfltregs[rd->argfltreguse++];
-                                                       } else if (rd->tmpfltreguse > 0) {
-                                                               v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
-                                                       } else if (rd->savfltreguse > 0) {
-                                                               v->regoff = rd->savfltregs[--rd->savfltreguse];
-                                                       } else {
-                                                               v->flags |= INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
-                                                               /* Align doubles in Memory */
-                                                               if ( (memneeded) && (rd->memuse & 1))
-                                                                       rd->memuse++;
-#endif
-                                                               v->regoff = rd->memuse;
-                                                               rd->memuse += memneeded + 1;
-                                                       }
-                                                       fltalloc = t;
-                                               } else { /* !IS_FLT_DBL_TYPE(t) */
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       /*
-                                                        * for i386 put all longs in memory
-                                                        */
-                                                       if (IS_2_WORD_TYPE(t)) {
-                                                               v->flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                               /* Align longs in Memory */
-                                                               if (rd->memuse & 1)
-                                                                       rd->memuse++;
-#endif
-                                                               v->regoff = rd->memuse;
-                                                               rd->memuse += memneeded + 1;
-                                                       } else
-#endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
-                                                               if (intalloc >= 0) {
-                      /* Reuse memory slot(s)/register(s) for shared interface slots */
-                                                                       v->flags |= 
-                                                                               rd->interfaces[s][intalloc].flags 
-                                                                               & INMEMORY;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                       if (!(v->flags & INMEMORY) 
-                                                                               && IS_2_WORD_TYPE(intalloc))
-                                                                               v->regoff = GET_LOW_REG(
-                                                                                       rd->interfaces[s][intalloc].regoff);
-                                                                       else
-#endif
-                                                                               v->regoff = 
-                                                                                   rd->interfaces[s][intalloc].regoff;
-                                                               } else 
-                                                                       if (rd->argintreguse + intregsneeded 
-                                                                               < INT_ARG_CNT) {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                               if (intregsneeded) 
-                                                                                       v->regoff=PACK_REGS( 
-                                                                                 rd->argintregs[rd->argintreguse],
-                                                                                 rd->argintregs[rd->argintreguse + 1]);
-                                                                               else
-#endif
-                                                                                       v->regoff = 
-                                                                                          rd->argintregs[rd->argintreguse];
-                                                                               rd->argintreguse += intregsneeded + 1;
-                                                                       }
-                                                                       else if (rd->tmpintreguse > intregsneeded) {
-                                                                               rd->tmpintreguse -= intregsneeded + 1;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                               if (intregsneeded) 
-                                                                                       v->regoff=PACK_REGS( 
-                                                                                 rd->tmpintregs[rd->tmpintreguse],
-                                                                                 rd->tmpintregs[rd->tmpintreguse + 1]);
-                                                                               else
+                               {
+                                       if (IS_FLT_DBL_TYPE(t)) {
+                                               if (fltalloc >= 0) {
+                                                       /* Reuse memory slot(s)/register(s) for shared interface slots */
+                                                       flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
+                                                       regoff = jd->interface_map[fltalloc].regoff;
+                                               } 
+                                               else if (AVAIL_ARG_FLT) {
+                                                       flags |= ARGREG;
+                                                       TAKE_ARG_FLT(regoff);
+                                               } 
+                                               else if (AVAIL_TMP_FLT) {
+                                                       TAKE_TMP_FLT(regoff);
+                                               } 
+                                               else if (AVAIL_SAV_FLT) {
+                                                       flags |= SAVREG;
+                                                       TAKE_SAV_FLT(regoff);
+                                               } 
+                                               else {
+                                                       flags |= INMEMORY;
+                                                       NEW_MEM_SLOT_FLT_DBL(regoff);
+                                               }
+                                               fltalloc = s * 5 + t;
+                                       }
+                                       else { /* !IS_FLT_DBL_TYPE(t) */
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                               /*
+                                                * for i386 put all longs in memory
+                                                */
+                                               if (IS_2_WORD_TYPE(t)) {
+                                                       flags |= INMEMORY;
+                                                       NEW_MEM_SLOT_INT_LNG(regoff);
+                                               } 
+                                               else
 #endif
-                                                                                       v->regoff = 
-                                                                                          rd->tmpintregs[rd->tmpintreguse];
-                                                                       }
-                                                                       else if (rd->savintreguse > intregsneeded) {
-                                                                               rd->savintreguse -= intregsneeded + 1;
-                                                                               v->regoff = 
-                                                                                       rd->savintregs[rd->savintreguse];
+                                                       if (intalloc >= 0) {
+                                                               /* Reuse memory slot(s)/register(s) for shared interface slots */
+                                                               flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
+                                                               regoff = jd->interface_map[intalloc].regoff;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                               if (intregsneeded) 
-                                                                                       v->regoff=PACK_REGS( 
-                                                                                 rd->savintregs[rd->savintreguse],
-                                                                                 rd->savintregs[rd->savintreguse + 1]);
-                                                                               else
-#endif
-                                                                                       v->regoff = 
-                                                                                          rd->savintregs[rd->savintreguse];
-                                                                       }
-                                                                       else {
-                                                                               v->flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                                               /* Align longs in Memory */
-                                                                               if ( (memneeded) && (rd->memuse & 1))
-                                                                                       rd->memuse++;
+                                                               /* reuse lower half */
+                                                               if (!(flags & INMEMORY) 
+                                                                               && IS_2_WORD_TYPE(intalloc % 5))
+                                                                       regoff = GET_LOW_REG(regoff);
 #endif
-                                                                               v->regoff = rd->memuse;
-                                                                               rd->memuse += memneeded + 1;
-                                                                       }
-
-                                                       intalloc = t;
-                                               } /* if (IS_FLT_DBL_TYPE(t)) */
-                                       } 
-                               } else { /* (saved) */
-/* now the same like above, but without a chance to take a temporary register */
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                                       if (IS_ADR_TYPE(t)) {
-                                               if (rd->savadrreguse > 0) {
-                                                       v->regoff = rd->savadrregs[--rd->savadrreguse];
-                                               }
-                                               else {
-                                                       v->flags |= INMEMORY;
-                                                       v->regoff = rd->memuse++;
-                                               }                                               
-                                       } else
-#endif
-                                       {
-                                               if (IS_FLT_DBL_TYPE(t)) {
-                                                       if (fltalloc >= 0) {
-                                                               v->flags |= rd->interfaces[s][fltalloc].flags
-                                                                       & INMEMORY;
-                                                               v->regoff = rd->interfaces[s][fltalloc].regoff;
-                                                       } else
-                                                               if (rd->savfltreguse > 0) {
-                                                                       v->regoff = rd->savfltregs[--rd->savfltreguse];
+                                                       } 
+                                                       else {
+                                                               if (AVAIL_ARG_INT) {
+                                                                       flags |= ARGREG;
+                                                                       TAKE_ARG_INT(regoff);
+                                                               }
+                                                               else if (AVAIL_TMP_INT) {
+                                                                       TAKE_TMP_INT(regoff);
+                                                               }
+                                                               else if (AVAIL_SAV_INT) {
+                                                                       flags |= SAVREG;
+                                                                       TAKE_SAV_INT(regoff);
                                                                }
                                                                else {
-                                                                       v->flags |= INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
-                                                                       /* Align doubles in Memory */
-                                                                       if ( (memneeded) && (rd->memuse & 1))
-                                                                               rd->memuse++;
-#endif
-                                                                       v->regoff = rd->memuse;
-                                                                       rd->memuse += memneeded + 1;
+                                                                       flags |= INMEMORY;
+                                                                       NEW_MEM_SLOT_INT_LNG(regoff);
                                                                }
-                                                       fltalloc = t;
-                                               }
-                                               else { /* IS_INT_LNG */
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       /*
-                                                        * for i386 put all longs in memory
-                                                        */
-                                                       if (IS_2_WORD_TYPE(t)) {
-                                                               v->flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                               /* Align longs in Memory */
-                                                               if (rd->memuse & 1)
-                                                                       rd->memuse++;
-#endif
-                                                               v->regoff = rd->memuse;
-                                                               rd->memuse += memneeded + 1;
-                                                       } else
+                                                       }
+
+                                               intalloc = s * 5 + t;
+                                       } /* if (IS_FLT_DBL_TYPE(t)) */
+                               } 
+                       } 
+                       else { /* (saved) */
+                               /* now the same like above, but without a chance to take a temporary register */
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               if (IS_ADR_TYPE(t)) {
+                                       if (AVAIL_SAV_ADR) {
+                                               TAKE_SAV_ADR(regoff);
+                                       }
+                                       else {
+                                               flags |= INMEMORY;
+                                               regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
+                                       }                                               
+                               } 
+                               else
 #endif
-                                                       {
-                                                               if (intalloc >= 0) {
-                                                                       v->flags |= 
-                                                                  rd->interfaces[s][intalloc].flags & INMEMORY;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                       if (!(v->flags & INMEMORY)
-                                                                               && IS_2_WORD_TYPE(intalloc))
-                                                                               v->regoff =
-                                                                                       GET_LOW_REG(
-                                                                                       rd->interfaces[s][intalloc].regoff);
-                                                                       else
+                               {
+                                       if (IS_FLT_DBL_TYPE(t)) {
+                                               if (fltalloc >= 0) {
+                                                       flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
+                                                       regoff = jd->interface_map[fltalloc].regoff;
+                                               } 
+                                               else {
+                                                       if (AVAIL_SAV_FLT) {
+                                                               TAKE_SAV_FLT(regoff);
+                                                       }
+                                                       else {
+                                                               flags |= INMEMORY;
+                                                               NEW_MEM_SLOT_FLT_DBL(regoff);
+                                                       }
+                                               }
+                                               fltalloc = s * 5 + t;
+                                       }
+                                       else { /* IS_INT_LNG */
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                               /*
+                                                * for i386 put all longs in memory
+                                                */
+                                               if (IS_2_WORD_TYPE(t)) {
+                                                       flags |= INMEMORY;
+                                                       NEW_MEM_SLOT_INT_LNG(regoff);
+                                               } 
+                                               else
 #endif
-                                                                               v->regoff =
-                                                                                       rd->interfaces[s][intalloc].regoff;
-                                                               } else {
-                                                                       if (rd->savintreguse > intregsneeded) {
-                                                                               rd->savintreguse -= intregsneeded + 1;
+                                               {
+                                                       if (intalloc >= 0) {
+                                                               flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
+                                                               regoff = jd->interface_map[intalloc].regoff;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                               if (intregsneeded) 
-                                                                                       v->regoff = PACK_REGS( 
-                                                                                 rd->savintregs[rd->savintreguse],
-                                                                                 rd->savintregs[rd->savintreguse + 1]);
-                                                                               else
-#endif
-                                                                                       v->regoff =
-                                                                                          rd->savintregs[rd->savintreguse];
-                                                                       } else {
-                                                                               v->flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                                       /* Align longs in Memory */
-                                                                       if ( (memneeded) && (rd->memuse & 1))
-                                                                               rd->memuse++;
+                                                               /*  reuse lower half */
+                                                               if (!(flags & INMEMORY)
+                                                                               && IS_2_WORD_TYPE(intalloc % 5))
+                                                                       regoff = GET_LOW_REG(regoff);
 #endif
-                                                                               v->regoff = rd->memuse;
-                                                                               rd->memuse += memneeded + 1;
-                                                                       }
+                                                       } 
+                                                       else {
+                                                               if (AVAIL_SAV_INT) {
+                                                                       TAKE_SAV_INT(regoff);
+                                                               } 
+                                                               else {
+                                                                       flags |= INMEMORY;
+                                                                       NEW_MEM_SLOT_INT_LNG(regoff);
                                                                }
-                                                               intalloc = t;
                                                        }
-                                               } /* if (IS_FLT_DBL_TYPE(t) else */
-                                       } /* if (IS_ADR_TYPE(t)) else */
-                               } /* if (saved) else */
-                       } /* if (type >= 0) */
+                                                       intalloc = s*5 + t;
+                                               }
+                                       } /* if (IS_FLT_DBL_TYPE(t) else */
+                               } /* if (IS_ADR_TYPE(t)) else */
+                       } /* if (saved) else */
+                       /* if (type >= 0) */
+
+                       assert(regoff >= 0);
+                       jd->interface_map[5*s + t].flags = flags | INOUT;
+                       jd->interface_map[5*s + t].regoff = regoff;
                } /* for t */
        } /* for s */
 }
 
 
-/* local_regalloc **************************************************************
+/* simplereg_allocate_locals_leafmethod ****************************************
 
-   Allocates registers for all local variables.
+   Allocates registers for all local variables of a leafmethod.
        
 *******************************************************************************/
        
-static void local_regalloc(jitdata *jd)
+static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 {
        methodinfo   *m;
        codegendata  *cd;
        registerdata *rd;
+       methoddesc *md;
 
-       int     p, s, t, tt;
+       int     p, s, t, tt, varindex;
        int     intalloc, fltalloc;
        varinfo *v;
        int     intregsneeded = 0;
@@ -413,335 +589,308 @@ static void local_regalloc(jitdata *jd)
        cd = jd->cd;
        rd = jd->rd;
 
-       if (jd->isleafmethod) {
-               methoddesc *md = m->parseddesc;
+       md = m->parseddesc;
 
-               iargcnt = rd->argintreguse;
-               fargcnt = rd->argfltreguse;
+       iargcnt = rd->argintreguse;
+       fargcnt = rd->argfltreguse;
 #ifdef HAS_ADDRESS_REGISTER_FILE
-               aargcnt = rd->argadrreguse;
+       aargcnt = rd->argadrreguse;
 #endif
-               for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
-                       intalloc = -1; fltalloc = -1;
-                       for (tt = 0; tt <= 4; tt++) {
-                               t = typeloop[tt];
-                               v = &rd->locals[s][t];
+       for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
+               intalloc = -1; fltalloc = -1;
+               for (tt = 0; tt <= 4; tt++) {
+                       t = typeloop[tt];
+                       varindex = jd->local_map[s * 5 + t];
+                       if (varindex == UNUSED)
+                               continue;
 
-                               if (v->type < 0)
-                                       continue;
+                       v = VAR(varindex);
 
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                               intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+                       intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
 #if defined(HAS_4BYTE_STACKSLOT)
-                               memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
-#endif
-
-                               /*
-                                *  The order of
-                                *
-                                *  #ifdef HAS_ADDRESS_REGISTER_FILE
-                                *  if (IS_ADR_TYPE) { 
-                                *  ...
-                                *  } else 
-                                *  #endif
-                                *  if (IS_FLT_DBL) {
-                                *  ...
-                                *  } else { / int & lng
-                                *  ...
-                                *  }
-                                *
-                                *  must not to be changed!
-                                */
+                       memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+
+                       /*
+                        *  The order of
+                        *
+                        *  #ifdef HAS_ADDRESS_REGISTER_FILE
+                        *  if (IS_ADR_TYPE) { 
+                        *  ...
+                        *  } else 
+                        *  #endif
+                        *  if (IS_FLT_DBL) {
+                        *  ...
+                        *  } else { / int & lng
+                        *  ...
+                        *  }
+                        *
+                        *  must not to be changed!
+                        */
 
 #ifdef HAS_ADDRESS_REGISTER_FILE
-                               if (IS_ADR_TYPE(t)) {
-                                       if ((p < md->paramcount) && !md->params[p].inmemory) {
+                       if (IS_ADR_TYPE(t)) {
+                               if ((p < md->paramcount) && !md->params[p].inmemory) {
+                                       v->flags = 0;
+                                       v->vv.regoff = rd->argadrregs[md->params[p].regoff];
+                               }
+                               else if (AVAIL_TMP_ADR) {
+                                       v->flags = 0;
+                                       TAKE_TMP_ADR(v->vv.regoff);
+                               }
+                               /* use unused argument registers as local registers */
+                               else if ((p >= md->paramcount) &&
+                                                (aargcnt < ADR_ARG_CNT)) 
+                               {
+                                       v->flags = 0;
+                                       POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
+                               }
+                               else if (AVAIL_SAV_ADR) {
+                                       v->flags = 0;
+                                       TAKE_SAV_ADR(v->vv.regoff);
+                               }
+                               else {
+                                       v->flags |= INMEMORY;
+                                       v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
+                               }                                               
+                       } 
+                       else {
+#endif
+                               if (IS_FLT_DBL_TYPE(t)) {
+                                       if (fltalloc >= 0) {
+                                               v->flags = VAR(fltalloc)->flags;
+                                               v->vv.regoff = VAR(fltalloc)->vv.regoff;
+                                       }
+#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
+                                       /* We can only use float arguments as local variables,
+                                        * if we do not pass them in integer registers. */
+                                       else if ((p < md->paramcount) && !md->params[p].inmemory) {
                                                v->flags = 0;
-                                               v->regoff = rd->argadrregs[md->params[p].regoff];
+                                               v->vv.regoff = md->params[p].regoff;
                                        }
-                                       else if (rd->tmpadrreguse > 0) {
+#endif
+                                       else if (AVAIL_TMP_FLT) {
                                                v->flags = 0;
-                                               v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+                                               TAKE_TMP_FLT(v->vv.regoff);
                                        }
                                        /* use unused argument registers as local registers */
-                                       else if ((p >= md->paramcount) &&
-                                                        (aargcnt < ADR_ARG_CNT)) {
+                                       else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
                                                v->flags = 0;
-                                               v->regoff = rd->argadrregs[aargcnt++];
+                                               POP_FRONT(abi_registers_float_argument,
+                                                                 fargcnt, v->vv.regoff);
                                        }
-                                       else if (rd->savadrreguse > 0) {
+                                       else if (AVAIL_SAV_FLT) {
                                                v->flags = 0;
-                                               v->regoff = rd->savadrregs[--rd->savadrreguse];
+                                               TAKE_SAV_FLT(v->vv.regoff);
                                        }
                                        else {
-                                               v->flags |= INMEMORY;
-                                               v->regoff = rd->memuse++;
-                                       }                                               
-                               } else {
+                                               v->flags = INMEMORY;
+                                               NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
+                                       }
+                                       fltalloc = jd->local_map[s * 5 + t];
+
+                               } 
+                               else {
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       /*
+                                        * for i386 put all longs in memory
+                                        */
+                                       if (IS_2_WORD_TYPE(t)) {
+                                               v->flags = INMEMORY;
+                                               NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
+                                       } 
+                                       else 
 #endif
-                                       if (IS_FLT_DBL_TYPE(t)) {
-                                               if (fltalloc >= 0) {
-                                                       v->flags = rd->locals[s][fltalloc].flags;
-                                                       v->regoff = rd->locals[s][fltalloc].regoff;
+                                       {
+                                               if (intalloc >= 0) {
+                                                       v->flags = VAR(intalloc)->flags;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                                       if (!(v->flags & INMEMORY)
+                                                               && IS_2_WORD_TYPE(VAR(intalloc)->type))
+                                                               v->vv.regoff = GET_LOW_REG(
+                                                                                               VAR(intalloc)->vv.regoff);
+                                                       else
+#endif
+                                                               v->vv.regoff = VAR(intalloc)->vv.regoff;
                                                }
-#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
-                                               /* We can only use float arguments as local variables,
-                                                * if we do not pass them in integer registers. */
-                                               else if ((p < md->paramcount) &&
-                                                                !md->params[p].inmemory) {
+                                               else if ((p < md->paramcount) && 
+                                                                !md->params[p].inmemory) 
+                                               {
                                                        v->flags = 0;
-                                                       v->regoff = rd->argfltregs[md->params[p].regoff];
-                                               }
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                                       if (IS_2_WORD_TYPE(t))
+                                                               v->vv.regoff =
+                                                                       PACK_REGS(GET_LOW_REG(md->params[p].regoff),
+                                                                                         GET_HIGH_REG(md->params[p].regoff));
+                                                               else
 #endif
-                                               else if (rd->tmpfltreguse > 0) {
+                                                                       v->vv.regoff = md->params[p].regoff;
+                                               }
+                                               else if (AVAIL_TMP_INT) {
                                                        v->flags = 0;
-                                                       v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+                                                       TAKE_TMP_INT(v->vv.regoff);
                                                }
-                                               /* use unused argument registers as local registers */
-                                               else if ((p >= md->paramcount) &&
-                                                                (fargcnt < FLT_ARG_CNT)) {
+                                               /*
+                                                * use unused argument registers as local registers
+                                                */
+                                               else if ((p >= m->parseddesc->paramcount) &&
+                                                                (iargcnt + intregsneeded < INT_ARG_CNT)) 
+                                               {
                                                        v->flags = 0;
-                                                       v->regoff = rd->argfltregs[fargcnt];
-                                                       fargcnt++;
+                                                       POP_FRONT_INT(abi_registers_integer_argument,
+                                                                                 iargcnt, v->vv.regoff);
                                                }
-                                               else if (rd->savfltreguse > 0) {
+                                               else if (AVAIL_SAV_INT) {
                                                        v->flags = 0;
-                                                       v->regoff = rd->savfltregs[--rd->savfltreguse];
+                                                       TAKE_SAV_INT(v->vv.regoff);
                                                }
                                                else {
                                                        v->flags = INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
-                                                       /* Align doubles in Memory */
-                                                       if ( (memneeded) && (rd->memuse & 1))
-                                                               rd->memuse++;
-#endif
-                                                       v->regoff = rd->memuse;
-                                                       rd->memuse += memneeded + 1;
-                                               }
-                                               fltalloc = t;
-
-                                       } else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                               /*
-                                                * for i386 put all longs in memory
-                                                */
-                                               if (IS_2_WORD_TYPE(t)) {
-                                                       v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                       /* Align longs in Memory */
-                                                       if (rd->memuse & 1)
-                                                               rd->memuse++;
-#endif
-                                                       v->regoff = rd->memuse;
-                                                       rd->memuse += memneeded + 1;
-                                               } else 
-#endif
-                                               {
-                                                       if (intalloc >= 0) {
-                                                               v->flags = rd->locals[s][intalloc].flags;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (!(v->flags & INMEMORY)
-                                                                       && IS_2_WORD_TYPE(intalloc))
-                                                                       v->regoff = GET_LOW_REG(
-                                                                                   rd->locals[s][intalloc].regoff);
-                                                               else
-#endif
-                                                                       v->regoff = rd->locals[s][intalloc].regoff;
-                                                       }
-                                                       else if ((p < md->paramcount) && 
-                                                                        !md->params[p].inmemory) {
-                                                               v->flags = 0;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (IS_2_WORD_TYPE(t))
-                                                                       v->regoff = PACK_REGS(
-                                                       rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
-                                                       rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
-                                                                       else
-#endif
-                                                                               v->regoff =
-                                                                              rd->argintregs[md->params[p].regoff];
-                                                       }
-                                                       else if (rd->tmpintreguse > intregsneeded) {
-                                                               rd->tmpintreguse -= intregsneeded + 1;
-                                                               v->flags = 0;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (intregsneeded) 
-                                                                       v->regoff = PACK_REGS(
-                                                                           rd->tmpintregs[rd->tmpintreguse],
-                                                                               rd->tmpintregs[rd->tmpintreguse + 1]);
-                                                               else
-#endif
-                                                                       v->regoff = 
-                                                                               rd->tmpintregs[rd->tmpintreguse];
-                                                       }
-                                                       /*
-                                                        * use unused argument registers as local registers
-                                                        */
-                                                       else if ((p >= m->parseddesc->paramcount) &&
-                                                                        (iargcnt + intregsneeded < INT_ARG_CNT)) {
-                                                               v->flags = 0;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (intregsneeded) 
-                                                                       v->regoff=PACK_REGS( 
-                                                                                                  rd->argintregs[iargcnt],
-                                                                                                  rd->argintregs[iargcnt + 1]);
-                                                               else
-#endif
-                                                                       v->regoff = rd->argintregs[iargcnt];
-                                                               iargcnt += intregsneeded + 1;
-                                                       }
-                                                       else if (rd->savintreguse > intregsneeded) {
-                                                               rd->savintreguse -= intregsneeded + 1;
-                                                               v->flags = 0;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (intregsneeded) 
-                                                                       v->regoff = PACK_REGS(
-                                                                           rd->savintregs[rd->savintreguse],
-                                                                               rd->savintregs[rd->savintreguse + 1]);
-                                                               else
-#endif
-                                                                       v->regoff =rd->savintregs[rd->savintreguse];
-                                                       }
-                                                       else {
-                                                               v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                               /* Align longs in Memory */
-                                                               if ( (memneeded) && (rd->memuse & 1))
-                                                                       rd->memuse++;
-#endif
-                                                               v->regoff = rd->memuse;
-                                                               rd->memuse += memneeded + 1;
-                                                       }
+                                                       NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
                                                }
-                                               intalloc = t;
                                        }
-#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       intalloc = jd->local_map[s * 5 + t];
                                }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       }
+#endif
+               } /* for (tt=0;...) */
+
+               /* If the current parameter is a 2-word type, the next local slot */
+               /* is skipped.                                                    */
+
+               if (p < md->paramcount)
+                       if (IS_2_WORD_TYPE(md->paramtypes[p].type))
+                               s++;
+       }
+}
+
+/* simplereg_allocate_locals ***************************************************
+
+   Allocates registers for all local variables.
+       
+*******************************************************************************/
+       
+static void simplereg_allocate_locals(jitdata *jd)
+{
+       codegendata  *cd;
+       registerdata *rd;
+
+       int     s, t, tt, varindex;
+       int     intalloc, fltalloc;
+       varinfo *v;
+       int     memneeded = 0;
+       int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
+       s4 intregsneeded;
 #endif
-                       } /* for (tt=0;...) */
 
-                       /* If the current parameter is a 2-word type, the next local slot */
-                       /* is skipped.                                                    */
+       /* get required compiler data */
 
-                       if (p < md->paramcount)
-                               if (IS_2_WORD_TYPE(md->paramtypes[p].type))
-                                       s++;
-               }
+       cd = jd->cd;
+       rd = jd->rd;
+
+       if (jd->isleafmethod) {
+               simplereg_allocate_locals_leafmethod(jd);
                return;
        }
 
-       for (s = 0; s < cd->maxlocals; s++) {
+       for (s = 0; s < jd->maxlocals; s++) {
                intalloc = -1; fltalloc = -1;
                for (tt=0; tt<=4; tt++) {
                        t = typeloop[tt];
-                       v = &rd->locals[s][t];
 
-                       if (v->type >= 0) {
+                       varindex = jd->local_map[s * 5 + t];
+                       if (varindex == UNUSED)
+                               continue;
+
+                       v = VAR(varindex);
+
 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
                                intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
+
 #if defined(HAS_4BYTE_STACKSLOT)
                                memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
+
 #ifdef HAS_ADDRESS_REGISTER_FILE
-                               if ( IS_ADR_TYPE(t) ) {
-                                       if (rd->savadrreguse > 0) {
+                               if (IS_ADR_TYPE(t)) {
+                                       if (AVAIL_SAV_ADR) {
                                                v->flags = 0;
-                                               v->regoff = rd->savadrregs[--rd->savadrreguse];
+                                               TAKE_SAV_ADR(v->vv.regoff);
                                        }
                                        else {
                                                v->flags = INMEMORY;
-                                               v->regoff = rd->memuse++;
+                                               v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }
-                               } else {
+                               } 
+                               else {
 #endif
                                if (IS_FLT_DBL_TYPE(t)) {
                                        if (fltalloc >= 0) {
-                                               v->flags = rd->locals[s][fltalloc].flags;
-                                               v->regoff = rd->locals[s][fltalloc].regoff;
+                                               v->flags = VAR(fltalloc)->flags;
+                                               v->vv.regoff = VAR(fltalloc)->vv.regoff;
                                        }
-                                       else if (rd->savfltreguse > 0) {
+                                       else if (AVAIL_SAV_FLT) {
                                                v->flags = 0;
-                                               v->regoff = rd->savfltregs[--rd->savfltreguse];
+                                               TAKE_SAV_FLT(v->vv.regoff);
                                        }
                                        else {
                                                v->flags = INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
-                                               /* Align doubles in Memory */
-                                               if ( (memneeded) && (rd->memuse & 1))
-                                                       rd->memuse++;
-#endif
-                                               v->regoff = rd->memuse;
-                                               rd->memuse += memneeded + 1;
+                                               NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
                                        }
-                                       fltalloc = t;
+                                       fltalloc = jd->local_map[s * 5 + t];
                                }
                                else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
                                        if (IS_2_WORD_TYPE(t)) {
                                                v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                               /* Align longs in Memory */
-                                               if (rd->memuse & 1)
-                                                       rd->memuse++;
-#endif
-                                               v->regoff = rd->memuse;
-                                               rd->memuse += memneeded + 1;
-                                       } else {
+                                               NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
+                                       } 
+                                       else {
 #endif
                                                if (intalloc >= 0) {
-                                                       v->flags = rd->locals[s][intalloc].flags;
+                                                       v->flags = VAR(intalloc)->flags;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                        if (!(v->flags & INMEMORY)
-                                                               && IS_2_WORD_TYPE(intalloc))
-                                                               v->regoff = GET_LOW_REG(
-                                                                           rd->locals[s][intalloc].regoff);
+                                                               && IS_2_WORD_TYPE(VAR(intalloc)->type))
+                                                               v->vv.regoff = GET_LOW_REG(
+                                                                                           VAR(intalloc)->vv.regoff);
                                                        else
 #endif
-                                                               v->regoff = rd->locals[s][intalloc].regoff;
+                                                               v->vv.regoff = VAR(intalloc)->vv.regoff;
                                                }
-                                               else if (rd->savintreguse > intregsneeded) {
-                                                       rd->savintreguse -= intregsneeded+1;
+                                               else if (AVAIL_SAV_INT) {
                                                        v->flags = 0;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (intregsneeded) 
-                                                                       v->regoff = PACK_REGS(
-                                                                               rd->savintregs[rd->savintreguse],
-                                                                           rd->savintregs[rd->savintreguse + 1]);
-                                                               else
-#endif
-                                                                       v->regoff =rd->savintregs[rd->savintreguse];
+                                                       TAKE_SAV_INT(v->vv.regoff);
                                                }
                                                else {
                                                        v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
-                                                       /* Align longs in Memory */
-                                                       if ( (memneeded) && (rd->memuse & 1))
-                                                               rd->memuse++;
-#endif
-                                                       v->regoff = rd->memuse;
-                                                       rd->memuse += memneeded + 1;
+                                                       NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
                                                }
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        }
 #endif
-                                       intalloc = t;
+                                       intalloc = jd->local_map[s * 5 + t];
                                }
 #ifdef HAS_ADDRESS_REGISTER_FILE
                                }
 #endif
-
-                       }
                }
        }
 }
 
-static void reg_init_temp(methodinfo *m, registerdata *rd)
+
+static void simplereg_init(jitdata *jd, registerdata *rd)
 {
+       int i;
+
        rd->freememtop = 0;
 #if defined(HAS_4BYTE_STACKSLOT)
        rd->freememtop_2 = 0;
@@ -761,176 +910,239 @@ static void reg_init_temp(methodinfo *m, registerdata *rd)
 #ifdef HAS_ADDRESS_REGISTER_FILE
        rd->freeargadrtop = 0;
 #endif
+
+       rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
+       rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
+       MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
+
+       /* memcopycount is dynamically allocated when needed */
+
+       rd->memcopycount = NULL;
+       rd->memcopycountsize = 0;
+
+       rd->intusedinout = DMNEW(int, INT_REG_CNT);
+       MZERO(rd->intusedinout, int, INT_REG_CNT);
+       rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
+       MZERO(rd->fltusedinout, int, FLT_REG_CNT);
+
+       /* record the interface registers as used */
+
+       for (i=0; i<rd->argintreguse; ++i)
+               rd->intusedinout[abi_registers_integer_argument[i]] = 1;
+       for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
+               rd->intusedinout[rd->tmpintregs[i]] = 1;
+       for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
+               rd->intusedinout[rd->savintregs[i]] = 1;
+
+       for (i=0; i<rd->argfltreguse; ++i)
+               rd->fltusedinout[abi_registers_float_argument[i]] = 1;
+       for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
+               rd->fltusedinout[rd->tmpfltregs[i]] = 1;
+       for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
+               rd->fltusedinout[rd->savfltregs[i]] = 1;
+
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
+       MZERO(rd->adrusedinout, int, ADR_REG_CNT);
+
+       for (i=0; i<rd->argadrreguse; ++i)
+               rd->adrusedinout[rd->argadrregs[i]] = 1;
+       for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
+               rd->adrusedinout[rd->tmpadrregs[i]] = 1;
+       for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
+               rd->adrusedinout[rd->savadrregs[i]] = 1;
+#endif
 }
 
 
-#define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
+static void simplereg_init_block(registerdata *rd)
+{
+       int i;
+
+       /* remove all interface registers from the free lists */
+
+       for (i=0; i<rd->freearginttop; ++i)
+               if (rd->intusedinout[rd->freeargintregs[i]]) {
+                       rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
+               }
+       for (i=0; i<rd->freetmpinttop; ++i)
+               if (rd->intusedinout[rd->freetmpintregs[i]]) {
+                       rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
+               }
+       for (i=0; i<rd->freesavinttop; ++i)
+               if (rd->intusedinout[rd->freesavintregs[i]]) {
+                       rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
+               }
+
+       for (i=0; i<rd->freeargflttop; ++i)
+               if (rd->fltusedinout[rd->freeargfltregs[i]]) {
+                       rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
+               }
+       for (i=0; i<rd->freetmpflttop; ++i)
+               if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
+                       rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
+               }
+       for (i=0; i<rd->freesavflttop; ++i)
+               if (rd->fltusedinout[rd->freesavfltregs[i]]) {
+                       rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
+               }
+
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       for (i=0; i<rd->freeargadrtop; ++i)
+               if (rd->adrusedinout[rd->freeargadrregs[i]]) {
+                       rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
+               }
+       for (i=0; i<rd->freetmpadrtop; ++i)
+               if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
+                       rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
+               }
+       for (i=0; i<rd->freesavadrtop; ++i)
+               if (rd->adrusedinout[rd->freesavadrregs[i]]) {
+                       rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
+               }
+#endif
+}
+
 
-static void reg_new_temp_func(registerdata *rd, stackptr s)
+static void simplereg_new_temp(jitdata *jd, s4 index)
 {
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
        s4 intregsneeded;
+#endif
        s4 memneeded;
        s4 tryagain;
+       registerdata *rd;
+       varinfo      *v;
+
+       rd = jd->rd;
+       v = VAR(index);
+
+       /* assert that constants are not allocated */
+
+       assert(v->type != TYPE_RET);
 
        /* Try to allocate a saved register if there is no temporary one          */
        /* available. This is what happens during the second run.                 */
-       tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
+       tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
 
 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
-       intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       intregsneeded = 0;
+       intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
 #endif
+
 #if defined(HAS_4BYTE_STACKSLOT)
-       memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+       memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
 #else
        memneeded = 0;
 #endif
 
        for(; tryagain; --tryagain) {
                if (tryagain == 1) {
-                       if (!(s->flags & SAVEDVAR))
-                               s->flags |= SAVEDTMP;
+                       if (!(v->flags & SAVEDVAR))
+                               v->flags |= SAVREG;
 #ifdef HAS_ADDRESS_REGISTER_FILE
-                       if (IS_ADR_TYPE(s->type)) {
-                               if (rd->freesavadrtop > 0) {
-                                       s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
+                       if (IS_ADR_TYPE(v->type)) {
+                               if (AVAIL_FREE_SAV_ADR) {
+                                       TAKE_FREE_SAV_ADR(v->vv.regoff);
                                        return;
-                               } else if (rd->savadrreguse > 0) {
-                                       s->regoff = rd->savadrregs[--rd->savadrreguse];
+                               } 
+                               else if (AVAIL_SAV_ADR) {
+                                       TAKE_SAV_ADR(v->vv.regoff);
                                        return;
                                }
-                       } else
+                       } 
+                       else
 #endif
                        {
-                               if (IS_FLT_DBL_TYPE(s->type)) {
-                                       if (rd->freesavflttop > 0) {
-                                               s->regoff = rd->freesavfltregs[--rd->freesavflttop];
+                               if (IS_FLT_DBL_TYPE(v->type)) {
+                                       if (AVAIL_FREE_SAV_FLT) {
+                                               TAKE_FREE_SAV_FLT(v->vv.regoff);
                                                return;
-                                       } else if (rd->savfltreguse > 0) {
-                                               s->regoff = rd->savfltregs[--rd->savfltreguse];
+                                       } 
+                                       else if (AVAIL_SAV_FLT) {
+                                               TAKE_SAV_FLT(v->vv.regoff);
                                                return;
                                        }
-                               } else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                               } 
+                               else {
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
-                                       if (!IS_2_WORD_TYPE(s->type))
+                                       if (!IS_2_WORD_TYPE(v->type))
 #endif
                                        {
-                                               if (rd->freesavinttop > intregsneeded) {
-                                                       rd->freesavinttop -= intregsneeded + 1;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded)
-                                                               s->regoff = PACK_REGS(
-                                                               rd->freesavintregs[rd->freesavinttop],
-                                                                       rd->freesavintregs[rd->freesavinttop + 1]);
-                                               else
-#endif
-                                                               s->regoff =
-                                                                       rd->freesavintregs[rd->freesavinttop];
+                                               if (AVAIL_FREE_SAV_INT) {
+                                                       TAKE_FREE_SAV_INT(v->vv.regoff);
                                                        return;
-                                               } else if (rd->savintreguse > intregsneeded) {
-                                                       rd->savintreguse -= intregsneeded + 1;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded)
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->savintregs[rd->savintreguse],
-                                                               rd->savintregs[rd->savintreguse + 1]);
-                                                       else
-#endif
-                                                               s->regoff = rd->savintregs[rd->savintreguse];
+                                               } 
+                                               else if (AVAIL_SAV_INT) {
+                                                       TAKE_SAV_INT(v->vv.regoff);
                                                        return;
                                                }
                                        }
                                }
                        }
-               } else { /* tryagain == 2 */
+               } 
+               else { /* tryagain == 2 */
 #ifdef HAS_ADDRESS_REGISTER_FILE
-                       if (IS_ADR_TYPE(s->type)) {
-                               if (rd->freetmpadrtop > 0) {
-                                       s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
+                       if (IS_ADR_TYPE(v->type)) {
+                               if (AVAIL_FREE_TMP_ADR) {
+                                       TAKE_FREE_TMP_ADR(v->vv.regoff);
                                        return;
-                               } else if (rd->tmpadrreguse > 0) {
-                                       s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+                               } 
+                               else if (AVAIL_TMP_ADR) {
+                                       TAKE_TMP_ADR(v->vv.regoff);
                                        return;
                                }
-                       } else
+                       } 
+                       else
 #endif
                        {
-                               if (IS_FLT_DBL_TYPE(s->type)) {
-                                       if (rd->freeargflttop > 0) {
-                                               s->regoff = rd->freeargfltregs[--rd->freeargflttop];
-                                               s->flags |= TMPARG;
+                               if (IS_FLT_DBL_TYPE(v->type)) {
+                                       if (AVAIL_FREE_ARG_FLT) {
+                                               v->flags |= ARGREG;
+                                               TAKE_FREE_ARG_FLT(v->vv.regoff);
                                                return;
-                                       } else if (rd->argfltreguse < FLT_ARG_CNT) {
-                                               s->regoff = rd->argfltregs[rd->argfltreguse++];
-                                               s->flags |= TMPARG;
+                                       } 
+                                       else if (AVAIL_ARG_FLT) {
+                                               v->flags |= ARGREG;
+                                               TAKE_ARG_FLT(v->vv.regoff);
                                                return;
-                                       } else if (rd->freetmpflttop > 0) {
-                                               s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
+                                       } 
+                                       else if (AVAIL_FREE_TMP_FLT) {
+                                               TAKE_FREE_TMP_FLT(v->vv.regoff);
                                                return;
-                                       } else if (rd->tmpfltreguse > 0) {
-                                               s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+                                       } 
+                                       else if (AVAIL_TMP_FLT) {
+                                               TAKE_TMP_FLT(v->vv.regoff);
                                                return;
                                        }
 
-                               } else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                               } 
+                               else {
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                        /*
                                         * for i386 put all longs in memory
                                         */
-                                       if (!IS_2_WORD_TYPE(s->type))
+                                       if (!IS_2_WORD_TYPE(v->type))
 #endif
                                        {
-                                               if (rd->freearginttop > intregsneeded) {
-                                                       rd->freearginttop -= intregsneeded + 1;
-                                                       s->flags |= TMPARG;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->freeargintregs[rd->freearginttop],
-                                                               rd->freeargintregs[rd->freearginttop + 1]);
-                                                       else
-#endif
-                                                               s->regoff =
-                                                                       rd->freeargintregs[rd->freearginttop];
+                                               if (AVAIL_FREE_ARG_INT) {
+                                                       v->flags |= ARGREG;
+                                                       TAKE_FREE_ARG_INT(v->vv.regoff);
                                                        return;
-                                               } else if (rd->argintreguse 
-                                                                  < INT_ARG_CNT - intregsneeded) {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->argintregs[rd->argintreguse],
-                                                                   rd->argintregs[rd->argintreguse + 1]);
-                                                       else
-#endif
-                                                               s->regoff = rd->argintregs[rd->argintreguse];
-                                                       s->flags |= TMPARG;
-                                                       rd->argintreguse += intregsneeded + 1;
+                                               } 
+                                               else if (AVAIL_ARG_INT) {
+                                                       v->flags |= ARGREG;
+                                                       TAKE_ARG_INT(v->vv.regoff);
                                                        return;
-                                               } else if (rd->freetmpinttop > intregsneeded) {
-                                                       rd->freetmpinttop -= intregsneeded + 1;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->freetmpintregs[rd->freetmpinttop],
-                                                                   rd->freetmpintregs[rd->freetmpinttop + 1]);
-                                                       else
-#endif
-                                                               s->regoff = rd->freetmpintregs[rd->freetmpinttop];
+                                               } 
+                                               else if (AVAIL_FREE_TMP_INT) {
+                                                       TAKE_FREE_TMP_INT(v->vv.regoff);
                                                        return;
-                                               } else if (rd->tmpintreguse > intregsneeded) {
-                                                       rd->tmpintreguse -= intregsneeded + 1;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->tmpintregs[rd->tmpintreguse],
-                                                                   rd->tmpintregs[rd->tmpintreguse + 1]);
-                                                       else
-#endif
-                                                               s->regoff = rd->tmpintregs[rd->tmpintreguse];
+                                               } 
+                                               else if (AVAIL_TMP_INT) {
+                                                       TAKE_TMP_INT(v->vv.regoff);
                                                        return;
                                                }
                                        } /* if (!IS_2_WORD_TYPE(s->type)) */
@@ -939,265 +1151,180 @@ static void reg_new_temp_func(registerdata *rd, stackptr s)
                } /* if (tryagain == 1) else */
        } /* for(; tryagain; --tryagain) */
 
+       /* spill to memory */
+
+       v->flags |= INMEMORY;
+
 #if defined(HAS_4BYTE_STACKSLOT)
-       if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
-               rd->freememtop_2--;
-               s->regoff = rd->freemem_2[rd->freememtop_2];
-       } else
+       if ((memneeded == 1) && (rd->freememtop_2 > 0))
+               POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
+       else
 #endif /*defined(HAS_4BYTE_STACKSLOT) */
-               if ((memneeded == 0) && (rd->freememtop > 0)) {
-                       rd->freememtop--;;
-                       s->regoff = rd->freemem[rd->freememtop];
-               } else {
-#if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
-                       /* align 2 Word Types */
-                       if ((memneeded) && ((rd->memuse & 1) == 1)) { 
-                               /* Put patched memory slot on freemem */
-                               rd->freemem[rd->freememtop++] = rd->memuse;
-                               rd->memuse++;
-                       }
-#endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
-                       s->regoff = rd->memuse;
-                       rd->memuse += memneeded + 1;
-               }
-       s->flags |= INMEMORY;
+               if ((memneeded == 0) && (rd->freememtop > 0))
+                       POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
+               else
+                       NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
 }
 
 
-#define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
+static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
+{
+       /* assert that constants are not freed */
 
-/* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
-/* alive using this reg/memory location */
+       assert(type != TYPE_RET);
 
-static void reg_free_temp_func(registerdata *rd, stackptr s)
-{
-       s4 intregsneeded;
-       s4 memneeded;
+       /* if this is a copy of another variable, just decrement the copy counter */
 
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-       intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       intregsneeded = 0;
-#endif
+       if (flags & INMEMORY) {
+               int32_t memindex;
 
-#if defined(HAS_4BYTE_STACKSLOT)
-       memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       memneeded = 0;
-#endif
+               if (flags & INOUT)
+                       return;
+
+               memindex = regoff / SIZE_OF_STACKSLOT;
+
+               if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
+                       rd->memcopycount[memindex]--;
+                       return;
+               }
+       }
+       else {
+               s4 regindex;
+
+               regindex = REG_INDEX(regoff, type);
+
+               /* do not free interface registers that are needed as outvars */
+
+               if (flags & INOUT) {
+                       if (rd->regisoutvar[regindex]) {
+                               LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
+                               return;
+                       }
+
+                       LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
+               }
+
+               if (rd->regcopycount[regindex]) {
+                       rd->regcopycount[regindex]--;
+                       return;
+               }
+       }
 
-       if (s->flags & INMEMORY) {
+       if (flags & INMEMORY) {
 #if defined(HAS_4BYTE_STACKSLOT)
-               if (memneeded > 0) {
-                       rd->freemem_2[rd->freememtop_2] = s->regoff;
-                       rd->freememtop_2++;
-               } else 
+               if (IS_2_WORD_TYPE(type))
+                       PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
+               else 
 #endif
-               {
-                       rd->freemem[rd->freememtop] = s->regoff;
-                       rd->freememtop++;
-               }
+                       PUSH_BACK(rd->freemem, rd->freememtop, regoff);
+
+               return;
+       } 
+
+       /* freeing a register */
 
 #ifdef HAS_ADDRESS_REGISTER_FILE
-       } else if (IS_ADR_TYPE(s->type)) {
-               if (s->flags & (SAVEDVAR | SAVEDTMP)) {
-/*                     s->flags &= ~SAVEDTMP; */
-                       rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
-               } else
-                       rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
-#endif
-       } else if (IS_FLT_DBL_TYPE(s->type)) {
-               if (s->flags & (SAVEDVAR | SAVEDTMP)) {
-/*                     s->flags &= ~SAVEDTMP; */
-                       rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
-               } else if (s->flags & TMPARG) {
-/*                     s->flags &= ~TMPARG; */
-                       rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
-               } else
-                       rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
-       } else { /* IS_INT_LNG_TYPE */
-               if (s->flags & (SAVEDVAR | SAVEDTMP)) {
-/*                     s->flags &= ~SAVEDTMP; */
+       if (IS_ADR_TYPE(type)) {
+               if (flags & (SAVEDVAR | SAVREG))
+                       PUSH_FREE_SAV_ADR(regoff);
+               else
+                       PUSH_FREE_TMP_ADR(regoff);
+       } 
+#endif
+       else if (IS_FLT_DBL_TYPE(type)) {
+               if (flags & (SAVEDVAR | SAVREG))
+                       PUSH_FREE_SAV_FLT(regoff);
+               else if (flags & ARGREG)
+                       PUSH_FREE_ARG_FLT(regoff);
+               else
+                       PUSH_FREE_TMP_FLT(regoff);
+       } 
+       else { /* IS_INT_LNG_TYPE */
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                       if (intregsneeded) {
-                               rd->freesavintregs[rd->freesavinttop] =
-                                       GET_LOW_REG(s->regoff);
-                               rd->freesavintregs[rd->freesavinttop + 1] =
-                                       GET_HIGH_REG(s->regoff);
-                       } else
+               s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
 #endif
-                               rd->freesavintregs[rd->freesavinttop] = s->regoff;
-                       rd->freesavinttop += intregsneeded + 1;
 
-               } else if (s->flags & TMPARG) {
-/*                     s->flags &= ~TMPARG; */
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                       if (intregsneeded) {
-                               rd->freeargintregs[rd->freearginttop] =
-                                       GET_LOW_REG(s->regoff);
-                               rd->freeargintregs[rd->freearginttop + 1] =
-                                       GET_HIGH_REG(s->regoff);
-                       } else 
-#endif
-                               rd->freeargintregs[rd->freearginttop] = s->regoff;
-                       rd->freearginttop += intregsneeded + 1;
-               } else {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                       if (intregsneeded) {
-                               rd->freetmpintregs[rd->freetmpinttop] =
-                                       GET_LOW_REG(s->regoff);
-                               rd->freetmpintregs[rd->freetmpinttop + 1] =
-                                       GET_HIGH_REG(s->regoff);
-                       } else
-#endif
-                               rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
-                       rd->freetmpinttop += intregsneeded + 1;
-               }
+               if (flags & (SAVEDVAR | SAVREG))
+                       PUSH_FREE_SAV_INT(regoff);
+               else if (flags & ARGREG)
+                       PUSH_FREE_ARG_INT(regoff);
+               else
+                       PUSH_FREE_TMP_INT(regoff);
        }
 }
 
-static bool reg_alloc_dup(stackptr src, stackptr dst) {
-       /* only copy TEMPVARS, do not mess with STACKVAR,      */
-       /* LOCALVAR, or ARGVAR        */
-       if ((src->varkind == TEMPVAR) && (dst->varkind == TEMPVAR)) {
-               /* can not allocate a REG_TMP to a REG_SAV Slot */
-               if (src->flags & INMEMORY) {
-                       dst->regoff  = src->regoff;
-                       dst->flags |= INMEMORY;
-                       return true;
-               } else if ((src->flags & SAVEDVAR) == (dst->flags & SAVEDVAR)) {
-                       dst->regoff  = src->regoff;
-                       dst->flags |= src->flags & SAVEDTMP;
-                       dst->flags |= src->flags & TMPARG;
-                       return true;
-#if 0
-               } else if ((dst->flags & SAVEDVAR) == 0) {
-                       /* can only use a REG_SAV as REG_TMP! */
-                       dst->regoff = src->regoff;
-                       dst->flags |= src->flags & TMPARG;
-                       dst->flags |= SAVEDTMP;
-                       return true;
-#endif
-               } 
-       }
-       /* no copy possible - allocate a new reg/memory location*/
-       return false;
+
+static inline void simplereg_free_temp(jitdata *jd, s4 index)
+{
+       varinfo *v;
+
+       v = VAR(index);
+
+       simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
 }
 
-/* Mark the copies (STCOPY) at the dst stack right for DUPx and SWAP */
-static void new_reg_mark_copy(registerdata *rd, stackptr *dupslots, 
-                                                         int nin, int nout, int nthrough)
+
+static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
 {
-       s4 src_regoff[4];
-       s4 src_flags[4];
-       stackptr dst_stackslots[6];
-       int s_bottom, d_bottom, i, j, slots;
-       bool found;
-       stackptr sp;
-       stackptr *argp;
-
-       assert(nin <= 4 && (nout + nthrough) <= 6);
-
-       /* remember all different Registers/Memory Location of used TEMPVAR       */
-       /* instacks in src_varnum[] and src_flags[] _uniquely_. Take the STCOPY   */
-       /* flag of the last (deepest) occurence */
-       slots = nin;
-       argp = dupslots + slots;
-       for (s_bottom = 4; slots--; ) {
-               sp = *--argp;
-               if (sp->varkind == TEMPVAR) {
-                       found = false;
-                       for (i = 3; i >= s_bottom; i--) {
-                               if ((src_regoff[i] == sp->regoff) && 
-                                       ((src_flags[i] & INMEMORY) == (sp->flags & INMEMORY)) ) 
-                               {
-                                       src_flags[i] &= (~STCOPY | (sp->flags & STCOPY));
-                                       found = true;
-                               }
-                       }
-                       if (!found) {
-                               s_bottom--;
-                               src_regoff[s_bottom] = sp->regoff;
-                               src_flags[s_bottom] = sp->flags;
-                       }
-               }
-       }
+       varinfo *sv;
+       varinfo *dv;
 
-       /* Remember used TEMPVAR dst Stackslots in dst_stackslots[], since they   */
-       /* have to be from the "lowest" upwards, and the stackelements list is    */
-       /* linked from only top downwards */
-       
-       slots = nthrough + nout;
-       argp = dupslots + nin + nout;
-       for (d_bottom = 6; slots--; ) {
-               sp = *--argp;
-               if (sp->varkind == TEMPVAR) {
-                       d_bottom--;
-                       dst_stackslots[d_bottom] = sp;
-               }
-       }
+       /* do not coalesce local variables here */
 
-       /* Mark all reused reg/mem in dst stacklots with STCOPY, if the           */
-       /* corresponding src stackslot was marked STCOPY*/
-       /* if the correspondig STCOPY from the src stackslot was not set, do not  */
-       /* mark the lowest occurence at dst stackslots */
-       /* mark in src_flag reg/mem with STKEEP, if they where reused in the dst  */
-       /* stacklots, so they are not freed afterwards */
-       for (i = d_bottom; i < 6; i++) {
-               for (j = s_bottom; j < 4; j++) {
-                       if ( (src_regoff[j] == dst_stackslots[i]->regoff) &&
-                                ((src_flags[j] & INMEMORY) == (dst_stackslots[i]->flags & INMEMORY)) ) 
-                       {
-                               if (src_flags[j] & STCOPY) {
-                                       dst_stackslots[i]->flags |= STCOPY;
-                               }
-                               else {
-                                       src_flags[j] |= STCOPY;
-                                       dst_stackslots[i]->flags &= ~STCOPY;
-                               }
-                               /* do not free reg/mem of src Stackslot */
-                               src_flags[j] |= STKEEP;
-                       }
-               }
-       }
+       if (srcindex <= jd->localcount || dstindex <= jd->localcount)
+               return false;
 
-       /* free all reg/mem of src stack, which where not marked with STKEEP */
-       for (j=s_bottom; j < 4; j++) {
-               if ((src_flags[j] & STKEEP)==0) {
-                       /* free, if STCOPY of src stackslot is not set */
-                       /* STCOPY is already checked in reg_free_temp macro! */
-                       slots = nin;
-                       argp = dupslots + slots;
-                       while (--slots) {
-                               sp = *--argp;
-                               if ((src_regoff[j] == sp->regoff) && 
-                                       ((src_flags[j] & INMEMORY) == (sp->flags & INMEMORY)) ) 
-                               {
-                                       reg_free_temp(rd, sp);
-                               }
-                       }
-               }
+       sv = VAR(srcindex);
+       dv = VAR(dstindex);
+
+       /* do not coalesce in/out vars or preallocated variables here */
+
+       if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
+               return false;
+
+       /* if the source is in memory, we can coalesce in any case */
+
+       if (sv->flags & INMEMORY) {
+               dv->flags |= INMEMORY;
+               dv->vv.regoff = sv->vv.regoff;
+               return true;
        }
+
+       /* we do not allocate a REG_TMP to a REG_SAV variable */
+
+       if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
+               return false;
+
+       /* coalesce */
+       dv->vv.regoff = sv->vv.regoff;
+       dv->flags |= sv->flags & (SAVREG | ARGREG);
+
+       return true;
 }
 
 
-/* allocate_scratch_registers **************************************************
+/* simplereg_allocate_temporaries **********************************************
 
    Allocate temporary (non-interface, non-local) registers.
 
 *******************************************************************************/
 
-static void new_allocate_scratch_registers(jitdata *jd)
+static void simplereg_allocate_temporaries(jitdata *jd)
 {
        methodinfo         *m;
        registerdata       *rd;
        s4                  i;
        s4                  len;
-       new_instruction    *iptr;
+       instruction        *iptr;
        basicblock         *bptr;
        builtintable_entry *bte;
        methoddesc         *md;
-       stackptr           *argp;
+       s4                 *argp;
+       varinfo            *v;
+       s4                  flags;
+       s4                  regoff;
+       s4                  type;
+       s4                  regindex;
 
        /* get required compiler data */
 
@@ -1205,31 +1332,107 @@ static void new_allocate_scratch_registers(jitdata *jd)
        rd = jd->rd;
 
        /* initialize temp registers */
-       reg_init_temp(m, rd);
 
-       bptr = jd->new_basicblocks;
+       simplereg_init(jd, rd);
+
+       bptr = jd->basicblocks;
 
        while (bptr != NULL) {
                if (bptr->flags >= BBREACHED) {
-                       iptr = /* XXX */ (new_instruction *) bptr->iinstr;
+
+                       LOG(("\nallocating block L%03d\n", bptr->nr));
+
+                       simplereg_init_block(rd);
+
+                       /* assert that all copy counts are zero */
+
+#if !defined(NDEBUG)
+                       for (i=0; i < TOTAL_REG_CNT; ++i)
+                               assert(rd->regcopycount[i] == 0);
+#endif
+
+                       /* reset outvar flags */
+
+                       MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
+
+                       /* set allocation of invars */
+
+                       for (i=0; i<bptr->indepth; ++i) 
+                       {
+                               v = VAR(bptr->invars[i]);
+                               if (v->type == TYPE_RET)
+                                       continue;
+
+                               v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
+                               v->flags  = jd->interface_map[5*i + v->type].flags;
+
+                               if (!(v->flags & INMEMORY))
+                                       rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
+                       }
+
+                       /* set allocation of outvars */
+
+                       for (i=0; i<bptr->outdepth; ++i) 
+                       {
+                               v = VAR(bptr->outvars[i]);
+                               if (v->type == TYPE_RET)
+                                       continue;
+
+                               v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
+                               v->flags  = jd->interface_map[5*i + v->type].flags;
+
+                               if (!(v->flags & INMEMORY)) {
+                                       regindex = REG_INDEX(v->vv.regoff, v->type);
+                                       rd->regcopycount[regindex] = 1;
+                                       rd->regisoutvar[regindex] = 1;
+                               }
+                       }
+
+                       /* free interface registers not used in this block */
+
+                       for (i=0; i < 5 * jd->maxinterfaces; ++i) {
+                               type = i%5;
+                               regoff = jd->interface_map[i].regoff;
+                               flags = jd->interface_map[i].flags;
+
+                               if (!(flags & INMEMORY)) {
+                                       if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
+                                               LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n", 
+                                                                       flags, regoff, type));
+                                               simplereg_free(rd, flags, regoff, type);
+
+                                               /* mark it, so it is not freed again */
+                                               rd->regcopycount[REG_INDEX(regoff, type)] = -1;
+                                       }
+                               }
+                       }
+
+                       /* reset copy counts */
+
+                       MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
+
+                       /* iterate over ICMDS to allocate temporary variables */
+
+                       iptr = bptr->iinstr;
                        len = bptr->icount;
 
                        while (--len >= 0)  {
+
                                switch (iptr->opc) {
 
                                        /* pop 0 push 0 */
 
+                               case ICMD_JSR:
                                case ICMD_NOP:
                                case ICMD_CHECKNULL:
                                case ICMD_IINC:
-                               case ICMD_JSR:
                                case ICMD_RET:
                                case ICMD_RETURN:
                                case ICMD_GOTO:
                                case ICMD_PUTSTATICCONST:
                                case ICMD_INLINE_START:
                                case ICMD_INLINE_END:
-                               case ICMD_INLINE_GOTO:
+                               case ICMD_INLINE_BODY:
                                        break;
 
                                        /* pop 0 push 1 const */
@@ -1247,7 +1450,7 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_FLOAD:
                                case ICMD_DLOAD:
                                case ICMD_ALOAD:
-                                       reg_new_temp(rd, iptr->dst.var);
+                                       NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                        /* pop 2 push 1 */
@@ -1261,9 +1464,9 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_BALOAD:
                                case ICMD_CALOAD:
                                case ICMD_SALOAD:
-                                       reg_free_temp(rd, iptr->sx.s23.s2.var);
-                                       reg_free_temp(rd, iptr->s1.var);
-                                       reg_new_temp(rd, iptr->dst.var);
+                                       FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
+                                       FREE_TEMP_REG(iptr->s1.varindex);
+                                       NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                        /* pop 3 push 0 */
@@ -1277,9 +1480,9 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_BASTORE:
                                case ICMD_CASTORE:
                                case ICMD_SASTORE:
-                                       reg_free_temp(rd, iptr->sx.s23.s3.var);
-                                       reg_free_temp(rd, iptr->sx.s23.s2.var);
-                                       reg_free_temp(rd, iptr->s1.var);
+                                       FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
+                                       FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
+                                       FREE_TEMP_REG(iptr->s1.varindex);
                                        break;
 
                                        /* pop 1 push 0 store */
@@ -1331,7 +1534,7 @@ static void new_allocate_scratch_registers(jitdata *jd)
 
                                case ICMD_MONITORENTER:
                                case ICMD_MONITOREXIT:
-                                       reg_free_temp(rd, iptr->s1.var);
+                                       FREE_TEMP_REG(iptr->s1.varindex);
                                        break;
 
                                        /* pop 2 push 0 branch */
@@ -1391,131 +1594,50 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_BASTORECONST:
                                case ICMD_CASTORECONST:
                                case ICMD_SASTORECONST:
-                                       reg_free_temp(rd, iptr->sx.s23.s2.var);
-                                       reg_free_temp(rd, iptr->s1.var);
+                                       FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
+                                       FREE_TEMP_REG(iptr->s1.varindex);
                                        break;
 
-                                       /* pop 0 push 1 dup */
+                                       /* pop 0 push 1 copy */
                                        
-                               case ICMD_DUP:
+                               case ICMD_COPY:
                                        /* src === dst->prev (identical Stackslot Element)     */
                                        /* src --> dst       (copied value, take same reg/mem) */
 
-                                       if (!reg_alloc_dup(iptr->s1.var, iptr->dst.var)) {
-                                               reg_new_temp(rd, iptr->dst.var);
-                                       } else {
-                                               iptr->dst.var->flags |= STCOPY;
-                                       }
-                                       break;
-
-                                       /* pop 0 push 2 dup */
-                                       
-                               case ICMD_DUP2:
-                                       /* src->prev === dst->prev->prev->prev (identical Stackslot Element)     */
-                                       /* src       === dst->prev->prev       (identical Stackslot Element)     */
-                                       /* src->prev --> dst->prev             (copied value, take same reg/mem) */
-                                       /* src       --> dst                   (copied value, take same reg/mem) */
-                                                                                               
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+0]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+0]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+1]);
-                                       new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 2);
-                                       break;
-
-                                       /* pop 2 push 3 dup */
-                                       
-                               case ICMD_DUP_X1:
-                                       /* src->prev --> dst->prev       (copied value, take same reg/mem) */
-                                       /* src       --> dst             (copied value, take same reg/mem) */
-                                       /* src       --> dst->prev->prev (copied value, take same reg/mem) */
-                                                                                               
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+0]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+2]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+1]);
-                                       new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0);
-                                       break;
+                                       if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
+                                               NEW_TEMP_REG(iptr->dst.varindex);
+                                       } 
+                                       else {
+                                               v = VAROP(iptr->dst);
+
+                                               if (v->flags & INMEMORY) {
+                                                       int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
+                                                       if (memindex >= rd->memcopycountsize) {
+                                                               int newsize = (memindex + 1) * 2;
+                                                               i = rd->memcopycountsize;
+                                                               rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
+                                                               MZERO(rd->memcopycount + i, int, newsize - i);
+                                                               rd->memcopycountsize = newsize;
+                                                       }
+                                                       rd->memcopycount[memindex]++;
+                                               }
+                                               else {
+                                                       /* XXX split reg/mem variables on arm may need special handling here */
 
-                                       /* pop 3 push 4 dup */
-                                       
-                               case ICMD_DUP_X2:
-                                       /* src->prev->prev --> dst->prev->prev        */
-                                       /* src->prev       --> dst->prev              */
-                                       /* src             --> dst                    */
-                                       /* src             --> dst->prev->prev->prev  */
-                                       
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+0]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+0]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+3]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+2]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+1]);
-                                       new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0);
-                                       break;
+                                                       s4 regindex = REG_INDEX(v->vv.regoff, v->type);
 
-                                       /* pop 3 push 5 dup */
-                                       
-                               case ICMD_DUP2_X1:
-                                       /* src->prev->prev --> dst->prev->prev             */
-                                       /* src->prev       --> dst->prev                   */
-                                       /* src             --> dst                         */
-                                       /* src->prev       --> dst->prev->prev->prev->prev */
-                                       /* src             --> dst->prev->prev->prev       */
-                                                                                               
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+1]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+1]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+4]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+0]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+3]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[3+2]);
-                                       new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0);
+                                                       rd->regcopycount[regindex]++;
+                                               }
+                                       }
                                        break;
 
-                                       /* pop 4 push 6 dup */
-                                       
-                               case ICMD_DUP2_X2:
-                                       /* src->prev->prev->prev --> dst->prev->prev->prev             */
-                                       /* src->prev->prev       --> dst->prev->prev                   */
-                                       /* src->prev             --> dst->prev                         */
-                                       /* src                   --> dst                               */
-                                       /* src->prev             --> dst->prev->prev->prev->prev->prev */
-                                       /* src                   --> dst->prev->prev->prev->prev       */
-                                                                                               
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+1]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[4+1]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[4+5]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[4+0]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[4+4]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[4+3]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[4+2]);
-                                       new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0);
-                                       break;
+                                       /* pop 1 push 1 move */
 
-                                       /* pop 2 push 2 swap */
-                                       
-                               case ICMD_SWAP:
-                                       /* src       --> dst->prev   (copy) */
-                                       /* src->prev --> dst         (copy) */
-                                                                                               
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+0]);
-                                       if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
-                                               reg_new_temp(rd, iptr->dst.dupslots[2+1]);
-                                       new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0);
+                               case ICMD_MOVE:
+                                       if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
+                                               NEW_TEMP_REG(iptr->dst.varindex);
+                                               FREE_TEMP_REG(iptr->s1.varindex);
+                                       }
                                        break;
 
                                        /* pop 2 push 1 */
@@ -1564,9 +1686,9 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_FCMPG:
                                case ICMD_DCMPL:
                                case ICMD_DCMPG:
-                                       reg_free_temp(rd, iptr->sx.s23.s2.var);
-                                       reg_free_temp(rd, iptr->s1.var);
-                                       reg_new_temp(rd, iptr->dst.var);
+                                       FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
+                                       FREE_TEMP_REG(iptr->s1.varindex);
+                                       NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                        /* pop 1 push 1 */
@@ -1627,8 +1749,8 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_ANEWARRAY:
 
                                case ICMD_GETFIELD:
-                                       reg_free_temp(rd, iptr->s1.var);
-                                       reg_new_temp(rd, iptr->dst.var);
+                                       FREE_TEMP_REG(iptr->s1.varindex);
+                                       NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                        /* pop 0 push 1 */
@@ -1636,7 +1758,7 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                case ICMD_GETSTATIC:
 
                                case ICMD_NEW:
-                                       reg_new_temp(rd, iptr->dst.var);
+                                       NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                        /* pop many push any */
@@ -1649,11 +1771,11 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                        i = md->paramcount;
                                        argp = iptr->sx.s23.s2.args;
                                        while (--i >= 0) {
-                                               reg_free_temp(rd, *argp);
+                                               FREE_TEMP_REG(*argp);
                                                argp++;
                                        }
                                        if (md->returntype.type != TYPE_VOID)
-                                               reg_new_temp(rd, iptr->dst.var);
+                                               NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                case ICMD_BUILTIN:
@@ -1662,27 +1784,26 @@ static void new_allocate_scratch_registers(jitdata *jd)
                                        i = md->paramcount;
                                        argp = iptr->sx.s23.s2.args;
                                        while (--i >= 0) {
-                                               reg_free_temp(rd, *argp);
+                                               FREE_TEMP_REG(*argp);
                                                argp++;
                                        }
                                        if (md->returntype.type != TYPE_VOID)
-                                               reg_new_temp(rd, iptr->dst.var);
+                                               NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                case ICMD_MULTIANEWARRAY:
                                        i = iptr->s1.argcount;
                                        argp = iptr->sx.s23.s2.args;
                                        while (--i >= 0) {
-                                               reg_free_temp(rd, *argp);
+                                               FREE_TEMP_REG(*argp);
                                                argp++;
                                        }
-                                       reg_new_temp(rd, iptr->dst.var);
+                                       NEW_TEMP_REG(iptr->dst.varindex);
                                        break;
 
                                default:
-                                       *exceptionptr =
-                                               new_internalerror("Unknown ICMD %d during register allocation",
-                                                                                 iptr->opc);
+                                       exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
+                                                                                                  iptr->opc);
                                        return;
                                } /* switch */
                                iptr++;
@@ -1694,19 +1815,22 @@ static void new_allocate_scratch_registers(jitdata *jd)
 
 
 #if defined(ENABLE_STATISTICS)
-void reg_make_statistics(jitdata *jd)
+void simplereg_make_statistics(jitdata *jd)
 {
        methodinfo   *m;
        codegendata  *cd;
        registerdata *rd;
-       int i,type;
+       int i;
        s4 len;
+#if 0
        stackptr    src, src_old;
        stackptr    dst;
        instruction *iptr;
+#endif
        basicblock  *bptr;
        int size_interface; /* == maximum size of in/out stack at basic block boundaries */
        bool in_register;
+       varinfo *var;
 
        /* get required compiler data */
 
@@ -1719,19 +1843,20 @@ void reg_make_statistics(jitdata *jd)
        size_interface = 0;
 
                /* count how many local variables are held in memory or register */
-               for(i=0; i < cd->maxlocals; i++)
-                       for (type=0; type <=4; type++)
-                               if (rd->locals[i][type].type != -1) { /* valid local */
-                                       if (rd->locals[i][type].flags & INMEMORY) {
-                                               count_locals_spilled++;
-                                               in_register=false;
-                                       }
-                                       else
-                                               count_locals_register++;
-                               }
+               for(i=0; i < jd->localcount; i++) {
+                       if (VAR(i)->flags & INMEMORY) {
+                               count_locals_spilled++;
+                               in_register=false;
+                       }
+                       else {
+                               count_locals_register++;
+                       }
+               }
+
                /* count how many stack slots are held in memory or register */
 
-               bptr = m->basicblocks;
+               bptr = jd->basicblocks;
+
                while (bptr != NULL) {
                        if (bptr->flags >= BBREACHED) {
 
@@ -1739,56 +1864,33 @@ void reg_make_statistics(jitdata *jd)
                        if (!opt_lsra) {
 #endif 
                                /* check for memory moves from interface to BB instack */
-                               dst = bptr->instack;
                                len = bptr->indepth;
                                
                                if (len > size_interface) size_interface = len;
 
-                               while (dst != NULL) {
+                               while (len) {
                                        len--;
-                                       if (dst->varkind != STACKVAR) {
-                                               if ( (dst->flags & INMEMORY) ||
-                                                        (rd->interfaces[len][dst->type].flags & INMEMORY) || 
-                                                        ( (dst->flags & INMEMORY) && 
-                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) && 
-                                                          (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
-                                               {
-                                                       /* one in memory or both inmemory at different offsets */
-                                                       count_mem_move_bb++;
-                                                       in_register=false;
-                                               }
-                                       }
+                                       var = VAR(bptr->invars[len]);
 
-                                       dst = dst->prev;
+                                       /* invars statistics (currently none) */
                                }
 
                                /* check for memory moves from BB outstack to interface */
-                               dst = bptr->outstack;
                                len = bptr->outdepth;
                                if (len > size_interface) size_interface = len;
 
-                               while (dst) {
+                               while (len) {
                                        len--;
-                                       if (dst->varkind != STACKVAR) {
-                                               if ( (dst->flags & INMEMORY) || \
-                                                        (rd->interfaces[len][dst->type].flags & INMEMORY) || \
-                                                        ( (dst->flags & INMEMORY) && \
-                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) && \
-                                                          (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
-                                               {
-                                                       /* one in memory or both inmemory at different offsets */
-                                                       count_mem_move_bb++;
-                                                       in_register=false;
-                                               }
-                                       }
+                                       var = VAR(bptr->outvars[len]);
 
-                                       dst = dst->prev;
+                                       /* outvars statistics (currently none) */
                                }
 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
                        }
 #endif 
 
 
+#if 0
                                dst = bptr->instack;
                                iptr = bptr->iinstr;
                                len = bptr->icount;
@@ -1796,7 +1898,7 @@ void reg_make_statistics(jitdata *jd)
 
                                while (--len >= 0)  {
                                        src = dst;
-                                       dst = iptr->dst;
+                                       dst = iptr->dst.var;
 
                                        if ((src!= NULL) && (src != src_old)) { /* new stackslot */
                                                switch (src->varkind) {
@@ -1846,13 +1948,16 @@ void reg_make_statistics(jitdata *jd)
                                        
                                        iptr++;
                                } /* while instructions */
+#endif
                        } /* if */
+
                        bptr = bptr->next;
                } /* while blocks */
+
                count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
                if (in_register) count_method_in_register++;
                if (in_register) {
-                       printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
+/*                     printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
                }
 }
 #endif /* defined(ENABLE_STATISTICS) */