Unified variables changes for common/i386.
authorchristian <none@none>
Thu, 7 Sep 2006 13:29:05 +0000 (13:29 +0000)
committerchristian <none@none>
Thu, 7 Sep 2006 13:29:05 +0000 (13:29 +0000)
--HG--
branch : unified_variables

22 files changed:
.hgtags
src/vm/jit/allocator/simplereg.c
src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/emit.h
src/vm/jit/i386/codegen.c
src/vm/jit/i386/codegen.h
src/vm/jit/i386/emit.c
src/vm/jit/jit.c
src/vm/jit/jit.h
src/vm/jit/parse.c
src/vm/jit/parse.h
src/vm/jit/reg.c
src/vm/jit/reg.h
src/vm/jit/replace.c
src/vm/jit/show.c
src/vm/jit/stack.c
src/vm/jit/stack.h
src/vm/jit/verify/typecheck.c
tests/regression/Makefile.am
tests/regression/codepatching/Makefile.am
tests/regression/native/Makefile.am

diff --git a/.hgtags b/.hgtags
index cbc17eaed9d54ef15b54831730716df73a8da2d8..734924606376b67f0099ad84b9a2490d6166e1ff 100644 (file)
--- a/.hgtags
+++ b/.hgtags
@@ -11,3 +11,4 @@ a7d9b1655845c526636a510594214c32d3a120ea cacao-0_93-release
 f0bbc765d01fd58f0c42e25de02f059c2f9a9598 cacao-0.95
 31f9c3186dded73dab4ed3f519c1cc28940c98dd cacao-0.96
 ae597ed07b16e08575c39f88b93004049f663b2b new_instruction_format_branch_point
+d19da1d8ff91d76df914b1d2455d6faaec4fbcdf unified_variables_branch_point
index 042082fe6c69b3a7f7bb16e9ac023db6b90ecd52..499204dd4c36a5566b4f031b5a160e77c7057252 100644 (file)
@@ -32,7 +32,7 @@
             Michael Starzinger
             Edwin Steiner
 
-   $Id: simplereg.c 5343 2006-09-05 21:20:33Z twisti $
+   $Id: simplereg.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -80,16 +80,21 @@ bool new_regalloc(jitdata *jd)
           allocate_scratch_registers and setting it back to the original
           value before calling local_regalloc.  */
 
+       printf("------- rd->memuse bef %d\n",jd->rd->memuse);
+
        interface_regalloc(jd);
+       printf("------- rd->memuse int %d\n",jd->rd->memuse);
        new_allocate_scratch_registers(jd);
+       printf("------- rd->memuse scr %d\n",jd->rd->memuse);
        local_regalloc(jd);
+       printf("------- rd->memuse loc %d\n",jd->rd->memuse);
 
        /* everthing's ok */
 
        return true;
 }
 
-
+#if defined(NEW_VAR)
 /* interface_regalloc **********************************************************
 
    Allocates registers for all interface variables.
@@ -104,7 +109,7 @@ 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 */
+                       /* in case more vars are packed into this interface slot */
        varinfo *v;
        int             intregsneeded = 0;
        int             memneeded = 0;
@@ -145,16 +150,21 @@ static void interface_regalloc(jitdata *jd)
 
        for (s = 0; s < cd->maxstack; 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;
+
+               saved = 0;
+
+               for (tt = 0; tt <=4; tt++) {
+                       if ((t = jd->interface_map[s * 5 + TYPE_INT]) != UNUSED) {
+                               saved |= (jd->var[t].flags & SAVEDVAR);
+                       }
+               }
+
                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] == UNUSED)
+                               continue;
+
+                       v = &(jd->var[jd->interface_map[s * 5 + t]]);
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
@@ -181,9 +191,8 @@ static void interface_regalloc(jitdata *jd)
                                                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;
+                                                               v->flags |= jd->var[fltalloc].flags & INMEMORY;
+                                                               v->regoff = jd->var[fltalloc].regoff;
                                                        } else if (rd->argfltreguse < FLT_ARG_CNT) {
                                                                v->regoff = rd->argfltregs[rd->argfltreguse++];
                                                        } else if (rd->tmpfltreguse > 0) {
@@ -200,7 +209,7 @@ static void interface_regalloc(jitdata *jd)
                                                                v->regoff = rd->memuse;
                                                                rd->memuse += memneeded + 1;
                                                        }
-                                                       fltalloc = t;
+                                                       fltalloc = jd->interface_map[s * 5 + t];
                                                } else { /* !IS_FLT_DBL_TYPE(t) */
 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                        /*
@@ -219,18 +228,17 @@ static void interface_regalloc(jitdata *jd)
 #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;
+                                                                       v->flags |= jd->var[intalloc].flags 
+                                                                                       & INMEMORY;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                                        if (!(v->flags & INMEMORY) 
-                                                                               && IS_2_WORD_TYPE(intalloc))
+                                                                         && IS_2_WORD_TYPE(jd->var[intalloc].type))
                                                                                v->regoff = GET_LOW_REG(
-                                                                                       rd->interfaces[s][intalloc].regoff);
+                                                                                       jd->var[intalloc].regoff);
                                                                        else
 #endif
                                                                                v->regoff = 
-                                                                                   rd->interfaces[s][intalloc].regoff;
+                                                                                   jd->var[intalloc].regoff;
                                                                } else 
                                                                        if (rd->argintreguse + intregsneeded 
                                                                                < INT_ARG_CNT) {
@@ -282,7 +290,7 @@ static void interface_regalloc(jitdata *jd)
                                                                                rd->memuse += memneeded + 1;
                                                                        }
 
-                                                       intalloc = t;
+                                                       intalloc = jd->interface_map[s * 5 + t];
                                                } /* if (IS_FLT_DBL_TYPE(t)) */
                                        } 
                                } else { /* (saved) */
@@ -301,12 +309,12 @@ static void interface_regalloc(jitdata *jd)
                                        {
                                                if (IS_FLT_DBL_TYPE(t)) {
                                                        if (fltalloc >= 0) {
-                                                               v->flags |= rd->interfaces[s][fltalloc].flags
-                                                                       & INMEMORY;
-                                                               v->regoff = rd->interfaces[s][fltalloc].regoff;
+                                                               v->flags |= jd->var[fltalloc].flags & INMEMORY;
+                                                               v->regoff = jd->var[fltalloc].regoff;
                                                        } else
                                                                if (rd->savfltreguse > 0) {
-                                                                       v->regoff = rd->savfltregs[--rd->savfltreguse];
+                                                                       v->regoff = 
+                                                                               rd->savfltregs[--rd->savfltreguse];
                                                                }
                                                                else {
                                                                        v->flags |= INMEMORY;
@@ -318,7 +326,7 @@ static void interface_regalloc(jitdata *jd)
                                                                        v->regoff = rd->memuse;
                                                                        rd->memuse += memneeded + 1;
                                                                }
-                                                       fltalloc = t;
+                                                       fltalloc = jd->interface_map[s * 5 + t];
                                                }
                                                else { /* IS_INT_LNG */
 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
@@ -338,18 +346,18 @@ static void interface_regalloc(jitdata *jd)
 #endif
                                                        {
                                                                if (intalloc >= 0) {
-                                                                       v->flags |= 
-                                                                  rd->interfaces[s][intalloc].flags & INMEMORY;
+                                                                       v->flags |= jd->var[intalloc].flags 
+                                                                                       & INMEMORY;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                                        if (!(v->flags & INMEMORY)
-                                                                               && IS_2_WORD_TYPE(intalloc))
+                                                                         && IS_2_WORD_TYPE(jd->var[intalloc].type))
                                                                                v->regoff =
                                                                                        GET_LOW_REG(
-                                                                                       rd->interfaces[s][intalloc].regoff);
+                                                                                       jd->var[intalloc].regoff);
                                                                        else
 #endif
                                                                                v->regoff =
-                                                                                       rd->interfaces[s][intalloc].regoff;
+                                                                                   jd->var[intalloc].regoff;
                                                                } else {
                                                                        if (rd->savintreguse > intregsneeded) {
                                                                                rd->savintreguse -= intregsneeded + 1;
@@ -378,34 +386,32 @@ static void interface_regalloc(jitdata *jd)
                                                } /* if (IS_FLT_DBL_TYPE(t) else */
                                        } /* if (IS_ADR_TYPE(t)) else */
                                } /* if (saved) else */
-                       /* if (type >= 0) */
+                       /* if (type >= 0) */
                } /* for t */
        } /* for s */
 }
+#else
+/* interface_regalloc **********************************************************
 
-
-/* local_regalloc **************************************************************
-
-   Allocates registers for all local variables.
+   Allocates registers for all interface variables.
        
 *******************************************************************************/
        
-static void local_regalloc(jitdata *jd)
+static void interface_regalloc(jitdata *jd)
 {
        methodinfo   *m;
        codegendata  *cd;
        registerdata *rd;
 
-       int     p, s, t, tt;
-       int     intalloc, fltalloc;
+       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;
-       int     memneeded = 0;
+       int             intregsneeded = 0;
+       int             memneeded = 0;
+    /* 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     fargcnt, iargcnt;
-#ifdef HAS_ADDRESS_REGISTER_FILE
-       int     aargcnt;
-#endif
 
        /* get required compiler data */
 
@@ -413,774 +419,2267 @@ static void local_regalloc(jitdata *jd)
        cd = jd->cd;
        rd = jd->rd;
 
-       if (jd->isleafmethod) {
-               methoddesc *md = m->parseddesc;
+       /* rd->memuse was already set in stack.c to allocate stack space
+          for passing arguments to called methods. */
 
-               iargcnt = rd->argintreguse;
-               fargcnt = rd->argfltreguse;
+#if defined(__I386__)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+               /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
+               if (rd->memuse < 1)
+                       rd->memuse = 1;
+       }
+#endif
+
+       if (jd->isleafmethod) {
+               /* Reserve argument register, which will be used for Locals acting */
+               /* as Parameters */
+               if (rd->argintreguse < m->parseddesc->argintreguse)
+                       rd->argintreguse = m->parseddesc->argintreguse;
+               if (rd->argfltreguse < m->parseddesc->argfltreguse)
+                       rd->argfltreguse = m->parseddesc->argfltreguse;
 #ifdef HAS_ADDRESS_REGISTER_FILE
-               aargcnt = rd->argadrreguse;
+               if (rd->argadrreguse < m->parseddesc->argadrreguse)
+                       rd->argadrreguse = m->parseddesc->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];
 
-                               if (v->type < 0)
-                                       continue;
+       }
 
+       for (s = 0; s < cd->maxstack; 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;
+               for (tt = 0; tt <= 4; tt++) {
+                       t = typeloop[tt];
+                       v = &rd->interfaces[s][t];
+                       if (v->type >= 0) {
 #if defined(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
-
-                               /*
-                                *  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) {
-                                               v->flags = 0;
-                                               v->regoff = rd->argadrregs[md->params[p].regoff];
-                                       }
-                                       else if (rd->tmpadrreguse > 0) {
-                                               v->flags = 0;
-                                               v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
-                                       }
-                                       /* use unused argument registers as local registers */
-                                       else if ((p >= md->paramcount) &&
-                                                        (aargcnt < ADR_ARG_CNT)) {
-                                               v->flags = 0;
-                                               v->regoff = rd->argadrregs[aargcnt++];
-                                       }
-                                       else if (rd->savadrreguse > 0) {
-                                               v->flags = 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->locals[s][fltalloc].flags;
-                                                       v->regoff = rd->locals[s][fltalloc].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->argfltregs[md->params[p].regoff];
-                                               }
-#endif
-                                               else if (rd->tmpfltreguse > 0) {
-                                                       v->flags = 0;
-                                                       v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
-                                               }
-                                               /* use unused argument registers as local registers */
-                                               else if ((p >= md->paramcount) &&
-                                                                (fargcnt < FLT_ARG_CNT)) {
-                                                       v->flags = 0;
-                                                       v->regoff = rd->argfltregs[fargcnt];
-                                                       fargcnt++;
-                                               }
-                                               else if (rd->savfltreguse > 0) {
-                                                       v->flags = 0;
-                                                       v->regoff = rd->savfltregs[--rd->savfltreguse];
-                                               }
-                                               else {
-                                                       v->flags = INMEMORY;
+                               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 */
+#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++;
+                                                               /* Align doubles in Memory */
+                                                               if ( (memneeded) && (rd->memuse & 1))
+                                                                       rd->memuse++;
 #endif
-                                                       v->regoff = rd->memuse;
-                                                       rd->memuse += memneeded + 1;
-                                               }
-                                               fltalloc = t;
-
-                                       } else {
+                                                               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;
+                                                       /*
+                                                        * 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 
+                                                               /* Align longs in Memory */
+                                                               if (rd->memuse & 1)
+                                                                       rd->memuse++;
 #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;
+                                                               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 (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)]);
+                                                                       if (!(v->flags & INMEMORY) 
+                                                                               && IS_2_WORD_TYPE(intalloc))
+                                                                               v->regoff = GET_LOW_REG(
+                                                                                       rd->interfaces[s][intalloc].regoff);
                                                                        else
 #endif
-                                                                               v->regoff =
-                                                                              rd->argintregs[md->params[p].regoff];
-                                                       }
-                                                       else if (rd->tmpintreguse > intregsneeded) {
-                                                               rd->tmpintreguse -= intregsneeded + 1;
-                                                               v->flags = 0;
+                                                                               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->tmpintregs[rd->tmpintreguse],
-                                                                               rd->tmpintregs[rd->tmpintreguse + 1]);
-                                                               else
+                                                                               if (intregsneeded) 
+                                                                                       v->regoff=PACK_REGS( 
+                                                                                 rd->argintregs[rd->argintreguse],
+                                                                                 rd->argintregs[rd->argintreguse + 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;
+                                                                                       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->argintregs[iargcnt],
-                                                                                                  rd->argintregs[iargcnt + 1]);
-                                                               else
+                                                                               if (intregsneeded) 
+                                                                                       v->regoff=PACK_REGS( 
+                                                                                 rd->tmpintregs[rd->tmpintreguse],
+                                                                                 rd->tmpintregs[rd->tmpintreguse + 1]);
+                                                                               else
 #endif
-                                                                       v->regoff = rd->argintregs[iargcnt];
-                                                               iargcnt += intregsneeded + 1;
-                                                       }
-                                                       else if (rd->savintreguse > intregsneeded) {
-                                                               rd->savintreguse -= intregsneeded + 1;
-                                                               v->flags = 0;
+                                                                                       v->regoff = 
+                                                                                          rd->tmpintregs[rd->tmpintreguse];
+                                                                       }
+                                                                       else if (rd->savintreguse > intregsneeded) {
+                                                                               rd->savintreguse -= intregsneeded + 1;
+                                                                               v->regoff = 
+                                                                                       rd->savintregs[rd->savintreguse];
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (intregsneeded) 
-                                                                       v->regoff = PACK_REGS(
-                                                                           rd->savintregs[rd->savintreguse],
-                                                                               rd->savintregs[rd->savintreguse + 1]);
-                                                               else
+                                                                               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;
+                                                                                       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;
-                                                       }
-                                               }
-                                               intalloc = t;
-                                       }
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                               }
+                                                                               /* Align longs in Memory */
+                                                                               if ( (memneeded) && (rd->memuse & 1))
+                                                                                       rd->memuse++;
 #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++;
-               }
-               return;
-       }
-
-       for (s = 0; s < cd->maxlocals; s++) {
-               intalloc = -1; fltalloc = -1;
-               for (tt=0; tt<=4; tt++) {
-                       t = typeloop[tt];
-                       v = &rd->locals[s][t];
+                                                                               v->regoff = rd->memuse;
+                                                                               rd->memuse += memneeded + 1;
+                                                                       }
 
-                       if (v->type >= 0) {
-#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
+                                                       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->flags = 0;
-                                               v->regoff = rd->savadrregs[--rd->savadrreguse];
-                                       }
-                                       else {
-                                               v->flags = INMEMORY;
-                                               v->regoff = rd->memuse++;
-                                       }
-                               } else {
+                                       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->locals[s][fltalloc].flags;
-                                               v->regoff = rd->locals[s][fltalloc].regoff;
-                                       }
-                                       else if (rd->savfltreguse > 0) {
-                                               v->flags = 0;
-                                               v->regoff = rd->savfltregs[--rd->savfltreguse];
-                                       }
-                                       else {
-                                               v->flags = INMEMORY;
+                                       {
+                                               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 {
+                                                                       v->flags |= INMEMORY;
 #if defined(ALIGN_DOUBLES_IN_MEMORY)
-                                               /* Align doubles in Memory */
-                                               if ( (memneeded) && (rd->memuse & 1))
-                                                       rd->memuse++;
+                                                                       /* Align doubles in Memory */
+                                                                       if ( (memneeded) && (rd->memuse & 1))
+                                                                               rd->memuse++;
 #endif
-                                               v->regoff = rd->memuse;
-                                               rd->memuse += memneeded + 1;
-                                       }
-                                       fltalloc = t;
-                               }
-                               else {
+                                                                       v->regoff = rd->memuse;
+                                                                       rd->memuse += memneeded + 1;
+                                                               }
+                                                       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;
+                                                       /*
+                                                        * 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++;
+                                                               /* Align longs in Memory */
+                                                               if (rd->memuse & 1)
+                                                                       rd->memuse++;
 #endif
-                                               v->regoff = rd->memuse;
-                                               rd->memuse += memneeded + 1;
-                                       } else {
+                                                               v->regoff = rd->memuse;
+                                                               rd->memuse += memneeded + 1;
+                                                       } else
 #endif
-                                               if (intalloc >= 0) {
-                                                       v->flags = rd->locals[s][intalloc].flags;
+                                                       {
+                                                               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->locals[s][intalloc].regoff);
-                                                       else
+                                                                       if (!(v->flags & INMEMORY)
+                                                                               && IS_2_WORD_TYPE(intalloc))
+                                                                               v->regoff =
+                                                                                       GET_LOW_REG(
+                                                                                       rd->interfaces[s][intalloc].regoff);
+                                                                       else
 #endif
-                                                               v->regoff = rd->locals[s][intalloc].regoff;
-                                               }
-                                               else if (rd->savintreguse > intregsneeded) {
-                                                       rd->savintreguse -= intregsneeded+1;
-                                                       v->flags = 0;
+                                                                               v->regoff =
+                                                                                       rd->interfaces[s][intalloc].regoff;
+                                                               } else {
+                                                                       if (rd->savintreguse > intregsneeded) {
+                                                                               rd->savintreguse -= intregsneeded + 1;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                               if (intregsneeded) 
-                                                                       v->regoff = PACK_REGS(
-                                                                               rd->savintregs[rd->savintreguse],
-                                                                           rd->savintregs[rd->savintreguse + 1]);
-                                                               else
+                                                                               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;
+                                                                                       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;
-                                               }
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                       }
-#endif
-                                       intalloc = t;
-                               }
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                               }
+                                                                       /* Align longs in Memory */
+                                                                       if ( (memneeded) && (rd->memuse & 1))
+                                                                               rd->memuse++;
 #endif
-
-                       }
-               }
-       }
+                                                                               v->regoff = rd->memuse;
+                                                                               rd->memuse += memneeded + 1;
+                                                                       }
+                                                               }
+                                                               intalloc = t;
+                                                       }
+                                               } /* if (IS_FLT_DBL_TYPE(t) else */
+                                       } /* if (IS_ADR_TYPE(t)) else */
+                               } /* if (saved) else */
+                       } /* if (type >= 0) */
+               } /* for t */
+       } /* for s */
 }
+#endif /* defined(NEW_VAR) */
 
-static void reg_init_temp(methodinfo *m, registerdata *rd)
+
+#if defined(NEW_VAR)
+/* local_regalloc **************************************************************
+
+   Allocates registers for all local variables.
+       
+*******************************************************************************/
+       
+static void local_regalloc(jitdata *jd)
 {
-       rd->freememtop = 0;
-#if defined(HAS_4BYTE_STACKSLOT)
-       rd->freememtop_2 = 0;
-#endif
+       methodinfo   *m;
+       codegendata  *cd;
+       registerdata *rd;
 
-       rd->freetmpinttop = 0;
-       rd->freesavinttop = 0;
-       rd->freetmpflttop = 0;
-       rd->freesavflttop = 0;
+       int     p, s, t, tt,lm;
+       int     intalloc, fltalloc;
+       varinfo *v;
+       int     intregsneeded = 0;
+       int     memneeded = 0;
+       int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
+       int     fargcnt, iargcnt;
 #ifdef HAS_ADDRESS_REGISTER_FILE
-       rd->freetmpadrtop = 0;
-       rd->freesavadrtop = 0;
+       int     aargcnt;
 #endif
 
-       rd->freearginttop = 0;
-       rd->freeargflttop = 0;
-#ifdef HAS_ADDRESS_REGISTER_FILE
-       rd->freeargadrtop = 0;
-#endif
-}
+       /* get required compiler data */
 
+       m  = jd->m;
+       cd = jd->cd;
+       rd = jd->rd;
 
-#define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
+       if (jd->isleafmethod) {
+               methoddesc *md = m->parseddesc;
 
-static void reg_new_temp_func(registerdata *rd, stackptr s)
-{
-       s4 intregsneeded;
-       s4 memneeded;
-       s4 tryagain;
+               iargcnt = rd->argintreguse;
+               fargcnt = rd->argfltreguse;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+               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];
+                               lm = jd->local_map[s * 5 + t];
+                               if (lm == UNUSED)
+                                       continue;
 
-       /* 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;
+                               v = &(jd->var[lm]);
 
-#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
-       intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       intregsneeded = 0;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                               intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
 #if defined(HAS_4BYTE_STACKSLOT)
-       memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       memneeded = 0;
+                               memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
 
-       for(; tryagain; --tryagain) {
-               if (tryagain == 1) {
-                       if (!(s->flags & SAVEDVAR))
-                               s->flags |= SAVEDTMP;
+                               /*
+                                *  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(s->type)) {
-                               if (rd->freesavadrtop > 0) {
-                                       s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
-                                       return;
-                               } else if (rd->savadrreguse > 0) {
-                                       s->regoff = rd->savadrregs[--rd->savadrreguse];
-                                       return;
-                               }
-                       } else
-#endif
-                       {
-                               if (IS_FLT_DBL_TYPE(s->type)) {
-                                       if (rd->freesavflttop > 0) {
-                                               s->regoff = rd->freesavfltregs[--rd->freesavflttop];
-                                               return;
-                                       } else if (rd->savfltreguse > 0) {
-                                               s->regoff = rd->savfltregs[--rd->savfltreguse];
-                                               return;
+                               if (IS_ADR_TYPE(t)) {
+                                       if ((p < md->paramcount) && !md->params[p].inmemory) {
+                                               v->flags = 0;
+                                               v->regoff = rd->argadrregs[md->params[p].regoff];
+                                       }
+                                       else if (rd->tmpadrreguse > 0) {
+                                               v->flags = 0;
+                                               v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+                                       }
+                                       /* use unused argument registers as local registers */
+                                       else if ((p >= md->paramcount) &&
+                                                        (aargcnt < ADR_ARG_CNT)) {
+                                               v->flags = 0;
+                                               v->regoff = rd->argadrregs[aargcnt++];
+                                       }
+                                       else if (rd->savadrreguse > 0) {
+                                               v->flags = 0;
+                                               v->regoff = rd->savadrregs[--rd->savadrreguse];
                                        }
+                                       else {
+                                               v->flags |= INMEMORY;
+                                               v->regoff = rd->memuse++;
+                                       }                                               
                                } else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                       /*
-                                        * for i386 put all longs in memory
-                                        */
-                                       if (!IS_2_WORD_TYPE(s->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
+                                       if (IS_FLT_DBL_TYPE(t)) {
+                                               if (fltalloc >= 0) {
+                                                       v->flags = jd->var[fltalloc].flags;
+                                                       v->regoff = jd->var[fltalloc].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->argfltregs[md->params[p].regoff];
+                                               }
 #endif
-                                                               s->regoff =
-                                                                       rd->freesavintregs[rd->freesavinttop];
-                                                       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
+                                               else if (rd->tmpfltreguse > 0) {
+                                                       v->flags = 0;
+                                                       v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+                                               }
+                                               /* use unused argument registers as local registers */
+                                               else if ((p >= md->paramcount) &&
+                                                                (fargcnt < FLT_ARG_CNT)) {
+                                                       v->flags = 0;
+                                                       v->regoff = rd->argfltregs[fargcnt];
+                                                       fargcnt++;
+                                               }
+                                               else if (rd->savfltreguse > 0) {
+                                                       v->flags = 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
-                                                               s->regoff = rd->savintregs[rd->savintreguse];
-                                                       return;
+                                                       v->regoff = rd->memuse;
+                                                       rd->memuse += memneeded + 1;
                                                }
-                                       }
-                               }
-                       }
-               } else { /* tryagain == 2 */
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                       if (IS_ADR_TYPE(s->type)) {
-                               if (rd->freetmpadrtop > 0) {
-                                       s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
-                                       return;
-                               } else if (rd->tmpadrreguse > 0) {
-                                       s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
-                                       return;
-                               }
-                       } else
-#endif
-                       {
-                               if (IS_FLT_DBL_TYPE(s->type)) {
-                                       if (rd->freeargflttop > 0) {
-                                               s->regoff = rd->freeargfltregs[--rd->freeargflttop];
-                                               s->flags |= TMPARG;
-                                               return;
-                                       } else if (rd->argfltreguse < FLT_ARG_CNT) {
-                                               s->regoff = rd->argfltregs[rd->argfltreguse++];
-                                               s->flags |= TMPARG;
-                                               return;
-                                       } else if (rd->freetmpflttop > 0) {
-                                               s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
-                                               return;
-                                       } else if (rd->tmpfltreguse > 0) {
-                                               s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
-                                               return;
-                                       }
+                                               fltalloc = jd->local_map[s * 5 + t];
 
-                               } else {
+                                       } else {
 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                       /*
-                                        * for i386 put all longs in memory
-                                        */
-                                       if (!IS_2_WORD_TYPE(s->type))
+                                               /*
+                                                * 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
-                                       {
-                                               if (rd->freearginttop > intregsneeded) {
-                                                       rd->freearginttop -= intregsneeded + 1;
-                                                       s->flags |= TMPARG;
+                                                       v->regoff = rd->memuse;
+                                                       rd->memuse += memneeded + 1;
+                                               } else 
+#endif
+                                               {
+                                                       if (intalloc >= 0) {
+                                                               v->flags = jd->var[intalloc].flags;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->freeargintregs[rd->freearginttop],
-                                                               rd->freeargintregs[rd->freearginttop + 1]);
-                                                       else
+                                                               if (!(v->flags & INMEMORY)
+                                                                       && IS_2_WORD_TYPE(jd->var[intalloc].type))
+                                                                       v->regoff = GET_LOW_REG(
+                                                                                                       jd->var[intalloc].regoff);
+                                                               else
 #endif
-                                                               s->regoff =
-                                                                       rd->freeargintregs[rd->freearginttop];
-                                                       return;
-                                               } else if (rd->argintreguse 
-                                                                  < INT_ARG_CNT - intregsneeded) {
+                                                                       v->regoff = jd->var[intalloc].regoff;
+                                                       }
+                                                       else if ((p < md->paramcount) && 
+                                                                        !md->params[p].inmemory) {
+                                                               v->flags = 0;
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (intregsneeded) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->argintregs[rd->argintreguse],
-                                                                   rd->argintregs[rd->argintreguse + 1]);
-                                                       else
+                                                               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
-                                                               s->regoff = rd->argintregs[rd->argintreguse];
-                                                       s->flags |= TMPARG;
-                                                       rd->argintreguse += intregsneeded + 1;
-                                                       return;
-                                               } else if (rd->freetmpinttop > intregsneeded) {
-                                                       rd->freetmpinttop -= intregsneeded + 1;
+                                                                               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) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->freetmpintregs[rd->freetmpinttop],
-                                                                   rd->freetmpintregs[rd->freetmpinttop + 1]);
-                                                       else
+                                                               if (intregsneeded) 
+                                                                       v->regoff = PACK_REGS(
+                                                                           rd->tmpintregs[rd->tmpintreguse],
+                                                                               rd->tmpintregs[rd->tmpintreguse + 1]);
+                                                               else
 #endif
-                                                               s->regoff = rd->freetmpintregs[rd->freetmpinttop];
-                                                       return;
-                                               } else if (rd->tmpintreguse > intregsneeded) {
-                                                       rd->tmpintreguse -= intregsneeded + 1;
+                                                                       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) 
-                                                               s->regoff = PACK_REGS(
-                                                                       rd->tmpintregs[rd->tmpintreguse],
-                                                                   rd->tmpintregs[rd->tmpintreguse + 1]);
-                                                       else
+                                                               if (intregsneeded) 
+                                                                       v->regoff=PACK_REGS( 
+                                                                                                  rd->argintregs[iargcnt],
+                                                                                                  rd->argintregs[iargcnt + 1]);
+                                                               else
 #endif
-                                                               s->regoff = rd->tmpintregs[rd->tmpintreguse];
-                                                       return;
+                                                               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;
+                                                       }
                                                }
-                                       } /* if (!IS_2_WORD_TYPE(s->type)) */
-                               } /* if (IS_FLT_DBL_TYPE(s->type)) */
-                       } /* if (IS_ADR_TYPE(s->type)) */
-               } /* if (tryagain == 1) else */
-       } /* for(; tryagain; --tryagain) */
+                                               intalloc = jd->local_map[s * 5 + t];
+                                       }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               }
+#endif
+                       } /* for (tt=0;...) */
 
-#if defined(HAS_4BYTE_STACKSLOT)
-       if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
-               rd->freememtop_2--;
-               s->regoff = rd->freemem_2[rd->freememtop_2];
-       } 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 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++;
+               }
+               return;
+       }
 
-#define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
+       for (s = 0; s < cd->maxlocals; s++) {
+               intalloc = -1; fltalloc = -1;
+               for (tt=0; tt<=4; tt++) {
+                       t = typeloop[tt];
 
-/* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
-/* alive using this reg/memory location */
+                       lm = jd->local_map[s * 5 + t];
+                       if (lm == UNUSED)
+                               continue;
 
-static void reg_free_temp_func(registerdata *rd, stackptr s)
-{
-       s4 intregsneeded;
-       s4 memneeded;
+                       v = &(jd->var[lm]);
 
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-       intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       intregsneeded = 0;
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
+                               intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
-
 #if defined(HAS_4BYTE_STACKSLOT)
-       memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
-#else
-       memneeded = 0;
+                               memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               if ( IS_ADR_TYPE(t) ) {
+                                       if (rd->savadrreguse > 0) {
+                                               v->flags = 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 = jd->var[fltalloc].flags;
+                                               v->regoff = jd->var[fltalloc].regoff;
+                                       }
+                                       else if (rd->savfltreguse > 0) {
+                                               v->flags = 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 = jd->local_map[s * 5 + 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 = jd->var[intalloc].flags;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                                       if (!(v->flags & INMEMORY)
+                                                               && IS_2_WORD_TYPE(jd->var[intalloc].type))
+                                                               v->regoff = GET_LOW_REG(
+                                                                                           jd->var[intalloc].regoff);
+                                                       else
+#endif
+                                                               v->regoff = jd->var[intalloc].regoff;
+                                               }
+                                               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;
+                                               }
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       }
+#endif
+                                       intalloc = jd->local_map[s * 5 + t];
+                               }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               }
+#endif
+
+               }
+       }
+}
+#else
+/* local_regalloc **************************************************************
+
+   Allocates registers for all local variables.
+       
+*******************************************************************************/
+       
+static void local_regalloc(jitdata *jd)
+{
+       methodinfo   *m;
+       codegendata  *cd;
+       registerdata *rd;
+
+       int     p, s, t, tt;
+       int     intalloc, fltalloc;
+       varinfo *v;
+       int     intregsneeded = 0;
+       int     memneeded = 0;
+       int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
+       int     fargcnt, iargcnt;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       int     aargcnt;
+#endif
+
+       /* get required compiler data */
+
+       m  = jd->m;
+       cd = jd->cd;
+       rd = jd->rd;
+
+       if (jd->isleafmethod) {
+               methoddesc *md = m->parseddesc;
+
+               iargcnt = rd->argintreguse;
+               fargcnt = rd->argfltreguse;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+               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];
+
+                               if (v->type < 0)
+                                       continue;
+
+#if defined(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
+
+                               /*
+                                *  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) {
+                                               v->flags = 0;
+                                               v->regoff = rd->argadrregs[md->params[p].regoff];
+                                       }
+                                       else if (rd->tmpadrreguse > 0) {
+                                               v->flags = 0;
+                                               v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+                                       }
+                                       /* use unused argument registers as local registers */
+                                       else if ((p >= md->paramcount) &&
+                                                        (aargcnt < ADR_ARG_CNT)) {
+                                               v->flags = 0;
+                                               v->regoff = rd->argadrregs[aargcnt++];
+                                       }
+                                       else if (rd->savadrreguse > 0) {
+                                               v->flags = 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->locals[s][fltalloc].flags;
+                                                       v->regoff = rd->locals[s][fltalloc].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->argfltregs[md->params[p].regoff];
+                                               }
+#endif
+                                               else if (rd->tmpfltreguse > 0) {
+                                                       v->flags = 0;
+                                                       v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+                                               }
+                                               /* use unused argument registers as local registers */
+                                               else if ((p >= md->paramcount) &&
+                                                                (fargcnt < FLT_ARG_CNT)) {
+                                                       v->flags = 0;
+                                                       v->regoff = rd->argfltregs[fargcnt];
+                                                       fargcnt++;
+                                               }
+                                               else if (rd->savfltreguse > 0) {
+                                                       v->flags = 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 {
+#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;
+                                                       }
+                                               }
+                                               intalloc = 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++;
+               }
+               return;
+       }
+
+       for (s = 0; s < cd->maxlocals; s++) {
+               intalloc = -1; fltalloc = -1;
+               for (tt=0; tt<=4; tt++) {
+                       t = typeloop[tt];
+                       v = &rd->locals[s][t];
+
+                       if (v->type >= 0) {
+#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) {
+                                               v->flags = 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->locals[s][fltalloc].flags;
+                                               v->regoff = rd->locals[s][fltalloc].regoff;
+                                       }
+                                       else if (rd->savfltreguse > 0) {
+                                               v->flags = 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 {
+#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 (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;
+                                               }
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       }
+#endif
+                                       intalloc = t;
+                               }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               }
+#endif
+
+                       }
+               }
+       }
+}
+#endif /* defined(NEW_VAR) */
+
+static void reg_init_temp(methodinfo *m, registerdata *rd)
+{
+       rd->freememtop = 0;
+#if defined(HAS_4BYTE_STACKSLOT)
+       rd->freememtop_2 = 0;
+#endif
+
+       rd->freetmpinttop = 0;
+       rd->freesavinttop = 0;
+       rd->freetmpflttop = 0;
+       rd->freesavflttop = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->freetmpadrtop = 0;
+       rd->freesavadrtop = 0;
+#endif
+
+       rd->freearginttop = 0;
+       rd->freeargflttop = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->freeargadrtop = 0;
+#endif
+}
+
+#if defined(NEW_VAR)
+
+#define reg_new_temp(jd,index) \
+       if ( (index >= jd->localcount) \
+                && (!(jd->var[index].flags & OUTVAR))   \
+                && (!(jd->var[index].flags & PREALLOC)) )      \
+               reg_new_temp_func(jd, index)
+
+static void reg_new_temp_func(jitdata *jd, s4 index)
+{
+       s4 intregsneeded;
+       s4 memneeded;
+       s4 tryagain;
+       registerdata *rd;
+       varinfo      *v;
+
+       rd = jd->rd;
+       v = &(jd->var[index]);
+
+       /* Try to allocate a saved register if there is no temporary one          */
+       /* available. This is what happens during the second run.                 */
+       tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
+
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
+       intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
+#else
+       intregsneeded = 0;
+#endif
+#if defined(HAS_4BYTE_STACKSLOT)
+       memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
+#else
+       memneeded = 0;
+#endif
+
+       for(; tryagain; --tryagain) {
+               if (tryagain == 1) {
+                       if (!(v->flags & SAVEDVAR))
+                               v->flags |= SAVEDTMP;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       if (IS_ADR_TYPE(v->type)) {
+                               if (rd->freesavadrtop > 0) {
+                                       v->regoff = rd->freesavadrregs[--rd->freesavadrtop];
+                                       return;
+                               } else if (rd->savadrreguse > 0) {
+                                       v->regoff = rd->savadrregs[--rd->savadrreguse];
+                                       return;
+                               }
+                       } else
+#endif
+                       {
+                               if (IS_FLT_DBL_TYPE(v->type)) {
+                                       if (rd->freesavflttop > 0) {
+                                               v->regoff = rd->freesavfltregs[--rd->freesavflttop];
+                                               return;
+                                       } else if (rd->savfltreguse > 0) {
+                                               v->regoff = rd->savfltregs[--rd->savfltreguse];
+                                               return;
+                                       }
+                               } else {
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       /*
+                                        * for i386 put all longs in memory
+                                        */
+                                       if (!IS_2_WORD_TYPE(v->type))
+#endif
+                                       {
+                                               if (rd->freesavinttop > intregsneeded) {
+                                                       rd->freesavinttop -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                                       if (intregsneeded)
+                                                               v->regoff = PACK_REGS(
+                                                               rd->freesavintregs[rd->freesavinttop],
+                                                                       rd->freesavintregs[rd->freesavinttop + 1]);
+                                               else
+#endif
+                                                               v->regoff =
+                                                                       rd->freesavintregs[rd->freesavinttop];
+                                                       return;
+                                               } else if (rd->savintreguse > intregsneeded) {
+                                                       rd->savintreguse -= intregsneeded + 1;
+#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];
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+               } else { /* tryagain == 2 */
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       if (IS_ADR_TYPE(v->type)) {
+                               if (rd->freetmpadrtop > 0) {
+                                       v->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
+                                       return;
+                               } else if (rd->tmpadrreguse > 0) {
+                                       v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+                                       return;
+                               }
+                       } else
+#endif
+                       {
+                               if (IS_FLT_DBL_TYPE(v->type)) {
+                                       if (rd->freeargflttop > 0) {
+                                               v->regoff = rd->freeargfltregs[--rd->freeargflttop];
+                                               v->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->argfltreguse < FLT_ARG_CNT) {
+                                               v->regoff = rd->argfltregs[rd->argfltreguse++];
+                                               v->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->freetmpflttop > 0) {
+                                               v->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
+                                               return;
+                                       } else if (rd->tmpfltreguse > 0) {
+                                               v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+                                               return;
+                                       }
+
+                               } else {
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       /*
+                                        * for i386 put all longs in memory
+                                        */
+                                       if (!IS_2_WORD_TYPE(v->type))
+#endif
+                                       {
+                                               if (rd->freearginttop > intregsneeded) {
+                                                       rd->freearginttop -= intregsneeded + 1;
+                                                       v->flags |= TMPARG;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                                       if (intregsneeded) 
+                                                               v->regoff = PACK_REGS(
+                                                                       rd->freeargintregs[rd->freearginttop],
+                                                               rd->freeargintregs[rd->freearginttop + 1]);
+                                                       else
+#endif
+                                                               v->regoff =
+                                                                       rd->freeargintregs[rd->freearginttop];
+                                                       return;
+                                               } else if (rd->argintreguse 
+                                                                  < INT_ARG_CNT - intregsneeded) {
+#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];
+                                                       v->flags |= TMPARG;
+                                                       rd->argintreguse += intregsneeded + 1;
+                                                       return;
+                                               } else if (rd->freetmpinttop > intregsneeded) {
+                                                       rd->freetmpinttop -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                                       if (intregsneeded) 
+                                                               v->regoff = PACK_REGS(
+                                                                       rd->freetmpintregs[rd->freetmpinttop],
+                                                                   rd->freetmpintregs[rd->freetmpinttop + 1]);
+                                                       else
+#endif
+                                                               v->regoff = rd->freetmpintregs[rd->freetmpinttop];
+                                                       return;
+                                               } 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
+#endif
+                                                               v->regoff = rd->tmpintregs[rd->tmpintreguse];
+                                                       return;
+                                               }
+                                       } /* if (!IS_2_WORD_TYPE(s->type)) */
+                               } /* if (IS_FLT_DBL_TYPE(s->type)) */
+                       } /* if (IS_ADR_TYPE(s->type)) */
+               } /* if (tryagain == 1) else */
+       } /* for(; tryagain; --tryagain) */
+
+#if defined(HAS_4BYTE_STACKSLOT)
+       if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
+               rd->freememtop_2--;
+               v->regoff = rd->freemem_2[rd->freememtop_2];
+       } else
+#endif /*defined(HAS_4BYTE_STACKSLOT) */
+               if ((memneeded == 0) && (rd->freememtop > 0)) {
+                       rd->freememtop--;;
+                       v->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) */
+                       v->regoff = rd->memuse;
+                       rd->memuse += memneeded + 1;
+               }
+       v->flags |= INMEMORY;
+}
+#else
+#define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
+
+static void reg_new_temp_func(registerdata *rd, stackptr s)
+{
+       s4 intregsneeded;
+       s4 memneeded;
+       s4 tryagain;
+
+       /* 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;
+
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
+       intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+       intregsneeded = 0;
+#endif
+#if defined(HAS_4BYTE_STACKSLOT)
+       memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+       memneeded = 0;
+#endif
+
+       for(; tryagain; --tryagain) {
+               if (tryagain == 1) {
+                       if (!(s->flags & SAVEDVAR))
+                               s->flags |= SAVEDTMP;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       if (IS_ADR_TYPE(s->type)) {
+                               if (rd->freesavadrtop > 0) {
+                                       s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
+                                       return;
+                               } else if (rd->savadrreguse > 0) {
+                                       s->regoff = rd->savadrregs[--rd->savadrreguse];
+                                       return;
+                               }
+                       } else
+#endif
+                       {
+                               if (IS_FLT_DBL_TYPE(s->type)) {
+                                       if (rd->freesavflttop > 0) {
+                                               s->regoff = rd->freesavfltregs[--rd->freesavflttop];
+                                               return;
+                                       } else if (rd->savfltreguse > 0) {
+                                               s->regoff = rd->savfltregs[--rd->savfltreguse];
+                                               return;
+                                       }
+                               } else {
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       /*
+                                        * for i386 put all longs in memory
+                                        */
+                                       if (!IS_2_WORD_TYPE(s->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];
+                                                       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];
+                                                       return;
+                                               }
+                                       }
+                               }
+                       }
+               } else { /* tryagain == 2 */
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       if (IS_ADR_TYPE(s->type)) {
+                               if (rd->freetmpadrtop > 0) {
+                                       s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
+                                       return;
+                               } else if (rd->tmpadrreguse > 0) {
+                                       s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+                                       return;
+                               }
+                       } else
+#endif
+                       {
+                               if (IS_FLT_DBL_TYPE(s->type)) {
+                                       if (rd->freeargflttop > 0) {
+                                               s->regoff = rd->freeargfltregs[--rd->freeargflttop];
+                                               s->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->argfltreguse < FLT_ARG_CNT) {
+                                               s->regoff = rd->argfltregs[rd->argfltreguse++];
+                                               s->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->freetmpflttop > 0) {
+                                               s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
+                                               return;
+                                       } else if (rd->tmpfltreguse > 0) {
+                                               s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+                                               return;
+                                       }
+
+                               } else {
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                                       /*
+                                        * for i386 put all longs in memory
+                                        */
+                                       if (!IS_2_WORD_TYPE(s->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];
+                                                       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;
+                                                       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];
+                                                       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];
+                                                       return;
+                                               }
+                                       } /* if (!IS_2_WORD_TYPE(s->type)) */
+                               } /* if (IS_FLT_DBL_TYPE(s->type)) */
+                       } /* if (IS_ADR_TYPE(s->type)) */
+               } /* if (tryagain == 1) else */
+       } /* for(; tryagain; --tryagain) */
+
+#if defined(HAS_4BYTE_STACKSLOT)
+       if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
+               rd->freememtop_2--;
+               s->regoff = rd->freemem_2[rd->freememtop_2];
+       } 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;
+}
+#endif
+
+#if defined(NEW_VAR)
+#define reg_free_temp(jd,index) \
+       if ((index > jd->localcount) \
+               && (!(jd->var[index].flags & OUTVAR))   \
+               && (!(jd->var[index].flags & STCOPY))    \
+               && (!(jd->var[index].flags & PREALLOC)) ) \
+               reg_free_temp_func(jd, index)
+
+/* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
+/* alive using this reg/memory location */
+
+static void reg_free_temp_func(jitdata *jd, s4 index)
+{
+       s4 intregsneeded;
+       s4 memneeded;
+       registerdata *rd;
+       varinfo *v;
+
+       rd = jd->rd;
+       v = &(jd->var[index]);
+
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+       intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
+#else
+       intregsneeded = 0;
+#endif
+
+#if defined(HAS_4BYTE_STACKSLOT)
+       memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
+#else
+       memneeded = 0;
+#endif
+
+       if (v->flags & INMEMORY) {
+#if defined(HAS_4BYTE_STACKSLOT)
+               if (memneeded > 0) {
+                       rd->freemem_2[rd->freememtop_2] = v->regoff;
+                       rd->freememtop_2++;
+               } else 
+#endif
+               {
+                       rd->freemem[rd->freememtop] = v->regoff;
+                       rd->freememtop++;
+               }
+
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       } else if (IS_ADR_TYPE(v->type)) {
+               if (v->flags & (SAVEDVAR | SAVEDTMP)) {
+/*                     v->flags &= ~SAVEDTMP; */
+                       rd->freesavadrregs[rd->freesavadrtop++] = v->regoff;
+               } else
+                       rd->freetmpadrregs[rd->freetmpadrtop++] = v->regoff;
+#endif
+       } else if (IS_FLT_DBL_TYPE(v->type)) {
+               if (v->flags & (SAVEDVAR | SAVEDTMP)) {
+/*                     v->flags &= ~SAVEDTMP; */
+                       rd->freesavfltregs[rd->freesavflttop++] = v->regoff;
+               } else if (v->flags & TMPARG) {
+/*                     v->flags &= ~TMPARG; */
+                       rd->freeargfltregs[rd->freeargflttop++] = v->regoff;
+               } else
+                       rd->freetmpfltregs[rd->freetmpflttop++] = v->regoff;
+       } else { /* IS_INT_LNG_TYPE */
+               if (v->flags & (SAVEDVAR | SAVEDTMP)) {
+/*                     v->flags &= ~SAVEDTMP; */
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                       if (intregsneeded) {
+                               rd->freesavintregs[rd->freesavinttop] =
+                                       GET_LOW_REG(v->regoff);
+                               rd->freesavintregs[rd->freesavinttop + 1] =
+                                       GET_HIGH_REG(v->regoff);
+                       } else
+#endif
+                       rd->freesavintregs[rd->freesavinttop] = v->regoff;
+                       rd->freesavinttop += intregsneeded + 1;
+
+               } else if (v->flags & TMPARG) {
+/*                     s->flags &= ~TMPARG; */
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                       if (intregsneeded) {
+                               rd->freeargintregs[rd->freearginttop] =
+                                       GET_LOW_REG(v->regoff);
+                               rd->freeargintregs[rd->freearginttop + 1] =
+                                       GET_HIGH_REG(v->regoff);
+                       } else 
+#endif
+                       rd->freeargintregs[rd->freearginttop] = v->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] = v->regoff;
+                       rd->freetmpinttop += intregsneeded + 1;
+               }
+       }
+}
+
+#else
+#define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
+
+/* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
+/* alive using this reg/memory location */
+
+static void reg_free_temp_func(registerdata *rd, stackptr s)
+{
+       s4 intregsneeded;
+       s4 memneeded;
+
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+       intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+       intregsneeded = 0;
+#endif
+
+#if defined(HAS_4BYTE_STACKSLOT)
+       memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+       memneeded = 0;
+#endif
+
+       if (s->flags & INMEMORY) {
+#if defined(HAS_4BYTE_STACKSLOT)
+               if (memneeded > 0) {
+                       rd->freemem_2[rd->freememtop_2] = s->regoff;
+                       rd->freememtop_2++;
+               } else 
+#endif
+               {
+                       rd->freemem[rd->freememtop] = s->regoff;
+                       rd->freememtop++;
+               }
+
+#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 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
+#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;
+               }
+       }
+}
+
+#endif
+
+#if !defined(NEW_VAR)
+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;
+}
+
+
+/* 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)
+{
+       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;
+       registerdata *rd;
+
+       rd = jd->rd;
+
+       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;
+                       }
+               }
+       }
+
+       /* 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;
+               }
+       }
+
+       /* 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;
+                       }
+               }
+       }
+
+       /* 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);
+                               }
+                       }
+               }
+       }
+}
+#endif
+
+#if defined(NEW_VAR)
+/* allocate_scratch_registers **************************************************
+
+   Allocate temporary (non-interface, non-local) registers.
+
+*******************************************************************************/
+
+static void new_allocate_scratch_registers(jitdata *jd)
+{
+       methodinfo         *m;
+       registerdata       *rd;
+       s4                  i;
+       s4                  len;
+       instruction        *iptr;
+       basicblock         *bptr;
+       builtintable_entry *bte;
+       methoddesc         *md;
+       s4                 *argp;
+
+       /* get required compiler data */
+
+       m  = jd->m;
+       rd = jd->rd;
+
+       /* initialize temp registers */
+
+       reg_init_temp(m, rd);
+
+       bptr = jd->new_basicblocks;
+
+       while (bptr != NULL) {
+               if (bptr->flags >= BBREACHED) {
+                       iptr = bptr->iinstr;
+                       len = bptr->icount;
+
+                       while (--len >= 0)  {
+                               switch (iptr->opc) {
+
+                                       /* pop 0 push 0 */
+
+                               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:
+                                       break;
+
+                                       /* pop 0 push 1 const */
+                                       
+                               case ICMD_ICONST:
+                               case ICMD_LCONST:
+                               case ICMD_FCONST:
+                               case ICMD_DCONST:
+                               case ICMD_ACONST:
+
+                                       /* pop 0 push 1 load */
+                                       
+                               case ICMD_ILOAD:
+                               case ICMD_LLOAD:
+                               case ICMD_FLOAD:
+                               case ICMD_DLOAD:
+                               case ICMD_ALOAD:
+                                       reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
+
+                                       /* pop 2 push 1 */
+
+                               case ICMD_IALOAD:
+                               case ICMD_LALOAD:
+                               case ICMD_FALOAD:
+                               case ICMD_DALOAD:
+                               case ICMD_AALOAD:
+
+                               case ICMD_BALOAD:
+                               case ICMD_CALOAD:
+                               case ICMD_SALOAD:
+                                       reg_free_temp(jd, iptr->sx.s23.s2.varindex);
+                                       reg_free_temp(jd, iptr->s1.varindex);
+                                       reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
+
+                                       /* pop 3 push 0 */
+
+                               case ICMD_IASTORE:
+                               case ICMD_LASTORE:
+                               case ICMD_FASTORE:
+                               case ICMD_DASTORE:
+                               case ICMD_AASTORE:
+
+                               case ICMD_BASTORE:
+                               case ICMD_CASTORE:
+                               case ICMD_SASTORE:
+                                       reg_free_temp(jd, iptr->sx.s23.s3.varindex);
+                                       reg_free_temp(jd, iptr->sx.s23.s2.varindex);
+                                       reg_free_temp(jd, iptr->s1.varindex);
+                                       break;
+
+                                       /* pop 1 push 0 store */
+
+                               case ICMD_ISTORE:
+                               case ICMD_LSTORE:
+                               case ICMD_FSTORE:
+                               case ICMD_DSTORE:
+                               case ICMD_ASTORE:
+
+                                       /* pop 1 push 0 */
+
+                               case ICMD_POP:
+
+                               case ICMD_IRETURN:
+                               case ICMD_LRETURN:
+                               case ICMD_FRETURN:
+                               case ICMD_DRETURN:
+                               case ICMD_ARETURN:
+
+                               case ICMD_ATHROW:
+
+                               case ICMD_PUTSTATIC:
+                               case ICMD_PUTFIELDCONST:
+
+                                       /* pop 1 push 0 branch */
+
+                               case ICMD_IFNULL:
+                               case ICMD_IFNONNULL:
+
+                               case ICMD_IFEQ:
+                               case ICMD_IFNE:
+                               case ICMD_IFLT:
+                               case ICMD_IFGE:
+                               case ICMD_IFGT:
+                               case ICMD_IFLE:
+
+                               case ICMD_IF_LEQ:
+                               case ICMD_IF_LNE:
+                               case ICMD_IF_LLT:
+                               case ICMD_IF_LGE:
+                               case ICMD_IF_LGT:
+                               case ICMD_IF_LLE:
+
+                                       /* pop 1 push 0 table branch */
+
+                               case ICMD_TABLESWITCH:
+                               case ICMD_LOOKUPSWITCH:
+
+                               case ICMD_MONITORENTER:
+                               case ICMD_MONITOREXIT:
+                                       reg_free_temp(jd, iptr->s1.varindex);
+                                       break;
+
+                                       /* pop 2 push 0 branch */
+
+                               case ICMD_IF_ICMPEQ:
+                               case ICMD_IF_ICMPNE:
+                               case ICMD_IF_ICMPLT:
+                               case ICMD_IF_ICMPGE:
+                               case ICMD_IF_ICMPGT:
+                               case ICMD_IF_ICMPLE:
+
+                               case ICMD_IF_LCMPEQ:
+                               case ICMD_IF_LCMPNE:
+                               case ICMD_IF_LCMPLT:
+                               case ICMD_IF_LCMPGE:
+                               case ICMD_IF_LCMPGT:
+                               case ICMD_IF_LCMPLE:
+
+                               case ICMD_IF_FCMPEQ:
+                               case ICMD_IF_FCMPNE:
+
+                               case ICMD_IF_FCMPL_LT:
+                               case ICMD_IF_FCMPL_GE:
+                               case ICMD_IF_FCMPL_GT:
+                               case ICMD_IF_FCMPL_LE:
+
+                               case ICMD_IF_FCMPG_LT:
+                               case ICMD_IF_FCMPG_GE:
+                               case ICMD_IF_FCMPG_GT:
+                               case ICMD_IF_FCMPG_LE:
+
+                               case ICMD_IF_DCMPEQ:
+                               case ICMD_IF_DCMPNE:
+
+                               case ICMD_IF_DCMPL_LT:
+                               case ICMD_IF_DCMPL_GE:
+                               case ICMD_IF_DCMPL_GT:
+                               case ICMD_IF_DCMPL_LE:
+
+                               case ICMD_IF_DCMPG_LT:
+                               case ICMD_IF_DCMPG_GE:
+                               case ICMD_IF_DCMPG_GT:
+                               case ICMD_IF_DCMPG_LE:
+
+                               case ICMD_IF_ACMPEQ:
+                               case ICMD_IF_ACMPNE:
+
+                                       /* pop 2 push 0 */
+
+                               case ICMD_POP2:
+
+                               case ICMD_PUTFIELD:
+
+                               case ICMD_IASTORECONST:
+                               case ICMD_LASTORECONST:
+                               case ICMD_AASTORECONST:
+                               case ICMD_BASTORECONST:
+                               case ICMD_CASTORECONST:
+                               case ICMD_SASTORECONST:
+                                       reg_free_temp(jd, iptr->sx.s23.s2.varindex);
+                                       reg_free_temp(jd, iptr->s1.varindex);
+                                       break;
+
+                                       /* pop 0 push 1 dup */
+                                       
+                               case ICMD_DUP:
+                                       /* src === dst->prev (identical Stackslot Element)     */
+                                       /* src --> dst       (copied value, take same reg/mem) */
+
+/*                                     if (!reg_alloc_dup(iptr->s1.varindex, iptr->dst.varindex)) { */
+                                               reg_new_temp(jd, iptr->dst.varindex);
+/*                                     } else { */
+/*                                             iptr->dst.varindex->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(jd, iptr->dst.dupslots[2+0]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1])) */
+                                               reg_new_temp(jd, 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(jd, iptr->dst.dupslots[2+0]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[2+2]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[2+1]);
+/*                                     new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0); */
+                                       break;
+
+                                       /* 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(jd, iptr->dst.dupslots[3+0]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+3]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+2]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+1]);
+/*                                     new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0); */
+                                       break;
+
+                                       /* 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(jd, iptr->dst.dupslots[3+1]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+4]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+0]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+3]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[3+2]);
+/*                                     new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0); */
+                                       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(jd, iptr->dst.dupslots[4+1]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[4+5]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[4+0]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[4+4]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[4+3]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[4+2]);
+/*                                     new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0); */
+                                       break;
+
+                                       /* 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(jd, iptr->dst.dupslots[2+0]);
+/*                                     if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1])) */
+                                               reg_new_temp(jd, iptr->dst.dupslots[2+1]);
+/*                                     new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0); */
+                                       break;
+
+                                       /* pop 2 push 1 */
+                                       
+                               case ICMD_IADD:
+                               case ICMD_ISUB:
+                               case ICMD_IMUL:
+                               case ICMD_IDIV:
+                               case ICMD_IREM:
+
+                               case ICMD_ISHL:
+                               case ICMD_ISHR:
+                               case ICMD_IUSHR:
+                               case ICMD_IAND:
+                               case ICMD_IOR:
+                               case ICMD_IXOR:
+
+                               case ICMD_LADD:
+                               case ICMD_LSUB:
+                               case ICMD_LMUL:
+                               case ICMD_LDIV:
+                               case ICMD_LREM:
+
+                               case ICMD_LOR:
+                               case ICMD_LAND:
+                               case ICMD_LXOR:
+
+                               case ICMD_LSHL:
+                               case ICMD_LSHR:
+                               case ICMD_LUSHR:
+
+                               case ICMD_FADD:
+                               case ICMD_FSUB:
+                               case ICMD_FMUL:
+                               case ICMD_FDIV:
+                               case ICMD_FREM:
+
+                               case ICMD_DADD:
+                               case ICMD_DSUB:
+                               case ICMD_DMUL:
+                               case ICMD_DDIV:
+                               case ICMD_DREM:
+
+                               case ICMD_LCMP:
+                               case ICMD_FCMPL:
+                               case ICMD_FCMPG:
+                               case ICMD_DCMPL:
+                               case ICMD_DCMPG:
+                                       reg_free_temp(jd, iptr->sx.s23.s2.varindex);
+                                       reg_free_temp(jd, iptr->s1.varindex);
+                                       reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
+
+                                       /* pop 1 push 1 */
+                                       
+                               case ICMD_IADDCONST:
+                               case ICMD_ISUBCONST:
+                               case ICMD_IMULCONST:
+                               case ICMD_IMULPOW2:
+                               case ICMD_IDIVPOW2:
+                               case ICMD_IREMPOW2:
+                               case ICMD_IANDCONST:
+                               case ICMD_IORCONST:
+                               case ICMD_IXORCONST:
+                               case ICMD_ISHLCONST:
+                               case ICMD_ISHRCONST:
+                               case ICMD_IUSHRCONST:
+
+                               case ICMD_LADDCONST:
+                               case ICMD_LSUBCONST:
+                               case ICMD_LMULCONST:
+                               case ICMD_LMULPOW2:
+                               case ICMD_LDIVPOW2:
+                               case ICMD_LREMPOW2:
+                               case ICMD_LANDCONST:
+                               case ICMD_LORCONST:
+                               case ICMD_LXORCONST:
+                               case ICMD_LSHLCONST:
+                               case ICMD_LSHRCONST:
+                               case ICMD_LUSHRCONST:
+
+                               case ICMD_INEG:
+                               case ICMD_INT2BYTE:
+                               case ICMD_INT2CHAR:
+                               case ICMD_INT2SHORT:
+                               case ICMD_LNEG:
+                               case ICMD_FNEG:
+                               case ICMD_DNEG:
 
-       if (s->flags & INMEMORY) {
-#if defined(HAS_4BYTE_STACKSLOT)
-               if (memneeded > 0) {
-                       rd->freemem_2[rd->freememtop_2] = s->regoff;
-                       rd->freememtop_2++;
-               } else 
-#endif
-               {
-                       rd->freemem[rd->freememtop] = s->regoff;
-                       rd->freememtop++;
-               }
+                               case ICMD_I2L:
+                               case ICMD_I2F:
+                               case ICMD_I2D:
+                               case ICMD_L2I:
+                               case ICMD_L2F:
+                               case ICMD_L2D:
+                               case ICMD_F2I:
+                               case ICMD_F2L:
+                               case ICMD_F2D:
+                               case ICMD_D2I:
+                               case ICMD_D2L:
+                               case ICMD_D2F:
 
-#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 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
-#endif
-                               rd->freesavintregs[rd->freesavinttop] = s->regoff;
-                       rd->freesavinttop += intregsneeded + 1;
+                               case ICMD_CHECKCAST:
 
-               } 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;
-               }
-       }
-}
+                               case ICMD_ARRAYLENGTH:
+                               case ICMD_INSTANCEOF:
 
-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;
-}
+                               case ICMD_NEWARRAY:
+                               case ICMD_ANEWARRAY:
 
-/* 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)
-{
-       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;
+                               case ICMD_GETFIELD:
+                                       reg_free_temp(jd, iptr->s1.varindex);
+                                       reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
 
-       assert(nin <= 4 && (nout + nthrough) <= 6);
+                                       /* pop 0 push 1 */
+                                       
+                               case ICMD_GETSTATIC:
 
-       /* 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;
-                       }
-               }
-       }
+                               case ICMD_NEW:
+                                       reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
 
-       /* 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;
-               }
-       }
+                                       /* pop many push any */
+                                       
+                               case ICMD_INVOKESTATIC:
+                               case ICMD_INVOKESPECIAL:
+                               case ICMD_INVOKEVIRTUAL:
+                               case ICMD_INVOKEINTERFACE:
+                                       INSTRUCTION_GET_METHODDESC(iptr,md);
+                                       i = md->paramcount;
+                                       argp = iptr->sx.s23.s2.args;
+                                       while (--i >= 0) {
+                                               reg_free_temp(jd, *argp);
+                                               argp++;
+                                       }
+                                       if (md->returntype.type != TYPE_VOID)
+                                               reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
 
-       /* 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;
-                       }
-               }
-       }
+                               case ICMD_BUILTIN:
+                                       bte = iptr->sx.s23.s3.bte;
+                                       md = bte->md;
+                                       i = md->paramcount;
+                                       argp = iptr->sx.s23.s2.args;
+                                       while (--i >= 0) {
+                                               reg_free_temp(jd, *argp);
+                                               argp++;
+                                       }
+                                       if (md->returntype.type != TYPE_VOID)
+                                               reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
 
-       /* 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);
-                               }
-                       }
-               }
-       }
-}
+                               case ICMD_MULTIANEWARRAY:
+                                       i = iptr->s1.argcount;
+                                       argp = iptr->sx.s23.s2.args;
+                                       while (--i >= 0) {
+                                               reg_free_temp(jd, *argp);
+                                               argp++;
+                                       }
+                                       reg_new_temp(jd, iptr->dst.varindex);
+                                       break;
 
+                               default:
+                                       *exceptionptr =
+                                               new_internalerror("Unknown ICMD %d during register allocation",
+                                                                                 iptr->opc);
+                                       return;
+                               } /* switch */
+                               iptr++;
+                       } /* while instructions */
+               } /* if */
+               bptr = bptr->next;
+       } /* while blocks */
+}
 
+#else
 /* allocate_scratch_registers **************************************************
 
    Allocate temporary (non-interface, non-local) registers.
@@ -1692,7 +3191,7 @@ static void new_allocate_scratch_registers(jitdata *jd)
                bptr = bptr->next;
        } /* while blocks */
 }
-
+#endif
 
 #if defined(ENABLE_STATISTICS)
 void reg_make_statistics(jitdata *jd)
index f756f8cf82e44a8b50fa4c9b10d6f096586f893b..e21f4a2c503b04e10af975367c20f90ab30c4114 100644 (file)
@@ -48,7 +48,7 @@
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen-common.c 5332 2006-09-05 19:38:28Z twisti $
+   $Id: codegen-common.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -1090,7 +1090,42 @@ void removenativestub(u1 *stub)
 
 *******************************************************************************/
 
-s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum)
+#if defined(NEW_VAR)
+s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum)
+{
+
+#if 0
+       /* Do we have to generate a conditional move?  Yes, then always
+          return the temporary register.  The real register is identified
+          during the store. */
+
+       if (opcode & ICMD_CONDITION_MASK)
+               return tempregnum;
+#endif
+
+       if (!(v->flags & INMEMORY)) {
+#if defined(__ARM__) && defined(__ARMEL__)
+               if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->regoff) == REG_SPLIT))
+                       return(PACK_REGS(GET_LOW_REG(var->regoff),
+                                                        GET_HIGH_REG(tempregnum)));
+#endif
+#if defined(__ARM__) && defined(__ARMEB__)
+               if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->regoff) == REG_SPLIT))
+                       return(PACK_REGS(GET_LOW_REG(tempregnum),
+                                                        GET_HIGH_REG(var->regoff)));
+#endif
+               return(v->regoff);
+       }
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_spills_read++;
+#endif
+
+       return tempregnum;
+}
+#else
+s4 codegen_reg_of_var(u2 opcode, stackptr v, s4 tempregnum)
 {
        varinfo *var;
 
@@ -1156,6 +1191,8 @@ s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum)
 
        return tempregnum;
 }
+#endif
+
 
 /* codegen_reg_of_dst **********************************************************
 
@@ -1175,52 +1212,21 @@ s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum)
 
 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
 {
-       varinfo *var;
-       stackptr v = iptr->dst.var;
-       registerdata *rd = jd->rd;
-
-       switch (v->varkind) {
-       case TEMPVAR:
-               if (!(v->flags & INMEMORY))
-                       return(v->regoff);
-               break;
+       varinfo *v = &jd->var[iptr->dst.varindex];
 
-       case STACKVAR:
-               var = &(rd->interfaces[v->varnum][v->type]);
-               v->regoff = var->regoff;
-               if (!(var->flags & INMEMORY))
-                       return(var->regoff);
-               break;
-
-       case LOCALVAR:
-               var = &(rd->locals[v->varnum][v->type]);
-               v->regoff = var->regoff;
-               if (!(var->flags & INMEMORY)) {
-#if defined(__ARM__) && defined(__ARMEL__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(var->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(var->regoff), GET_HIGH_REG(tempregnum)));
-#endif
-#if defined(__ARM__) && defined(__ARMEB__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(var->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(tempregnum), GET_HIGH_REG(var->regoff)));
-#endif
-                       return(var->regoff);
-               }
-               break;
-
-       case ARGVAR:
-               if (!(v->flags & INMEMORY)) {
+       if (!(v->flags & INMEMORY)) {
+               
 #if defined(__ARM__) && defined(__ARMEL__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(v->regoff), GET_HIGH_REG(tempregnum)));
+               if (IS_2_WORD_TYPE(v->type) && (GET_HIGH_REG(v->regoff) == REG_SPLIT))
+                       return(PACK_REGS(GET_LOW_REG(v->regoff),
+                                                        GET_HIGH_REG(tempregnum)));
 #endif
 #if defined(__ARM__) && defined(__ARMEB__)
-                       if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->regoff) == REG_SPLIT))
-                               return(PACK_REGS(GET_LOW_REG(tempregnum), GET_HIGH_REG(v->regoff)));
+               if (IS_2_WORD_TYPE(v->type) && (GET_LOW_REG(v->regoff) == REG_SPLIT))
+                       return(PACK_REGS(GET_LOW_REG(tempregnum),
+                                                        GET_HIGH_REG(v->regoff)));
 #endif
-                       return(v->regoff);
-               }
-               break;
+               return (v->regoff);
        }
 
 #if defined(ENABLE_STATISTICS)
@@ -1228,6 +1234,8 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
                count_spills_read++;
 #endif
 
+       /* Not necessary anymore - either v is inmemory or not. Setting again */
+       /* won't change anything */
        v->flags |= INMEMORY;
 
        return tempregnum;
index e5c1ca498559c711ef9afd8d0ada3b32d239acb9..81fb1d4477a3f989ccc36a1db65d0abcf973325d 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen-common.h 5332 2006-09-05 19:38:28Z twisti $
+   $Id: codegen-common.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -198,7 +198,11 @@ u1 *intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *md);
 void removecompilerstub(u1 *stub);
 void removenativestub(u1 *stub);
 
+#if defined(NEW_VAR)
+s4 codegen_reg_of_var(u2 opcode, varinfo *v, s4 tempregnum);
+#else
 s4 codegen_reg_of_var(registerdata *rd, u2 opcode, stackptr v, s4 tempregnum);
+#endif
 s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum);
 
 #if defined(ENABLE_THREADS)
index 0670257c18298daed2983fac42b0a99afde1ec81..1a880917c74bbc1c6e70bef448ab2045c5427a6a 100644 (file)
@@ -61,7 +61,7 @@
 
 /* code generation functions **************************************************/
 
-s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg);
+s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg);
 s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg);
 s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg);
 s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg);
@@ -76,15 +76,15 @@ s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg);
 s4 emit_load_s3_high(jitdata *jd, instruction *iptr, s4 tempreg);
 #endif
 
-void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d);
+void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
 void emit_store_dst(jitdata *jd, instruction *iptr, s4 d);
 
 #if SIZEOF_VOID_P == 4
-void emit_store_low(jitdata *jd, instruction *iptr, stackptr dst, s4 d);
-void emit_store_high(jitdata *jd, instruction *iptr, stackptr dst, s4 d);
+void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
+void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d);
 #endif
 
-void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst);
+void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst);
 
 void emit_iconst(codegendata *cd, s4 d, s4 value);
 void emit_lconst(codegendata *cd, s4 d, s8 value);
index 4a6eecc0246279d4dcfc9628a4515b3d8a319239..ca2c8dd541108a81c6d11e4ff2bca7932f16d381 100644 (file)
@@ -31,7 +31,7 @@
             Christian Ullrich
                        Edwin Steiner
 
-   $Id: codegen.c 5401 2006-09-07 12:52:31Z twisti $
+   $Id: codegen.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -96,6 +96,4027 @@ void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls,
                                                          basicblock *bptr);
 #endif
 
+#if defined(NEW_VAR)
+bool codegen(jitdata *jd)
+{
+       methodinfo         *m;
+       codeinfo           *code;
+       codegendata        *cd;
+       registerdata       *rd;
+       s4                  len, s1, s2, s3, d, disp;
+       varinfo            *var, *var1;
+       basicblock         *bptr;
+       instruction        *iptr;
+       exceptiontable     *ex;
+       u2                  currentline;
+       methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
+       builtintable_entry *bte;
+       methoddesc         *md;
+       rplpoint           *replacementpoint;
+       s4                 fieldtype;
+       s4                 varindex;
+#if defined(ENABLE_SSA)
+       lsradata *ls;
+       bool last_cmd_was_goto;
+
+       last_cmd_was_goto = false;
+       ls = jd->ls;
+#endif
+
+       /* get required compiler data */
+
+       m    = jd->m;
+       code = jd->code;
+       cd   = jd->cd;
+       rd   = jd->rd;
+
+       /* prevent compiler warnings */
+
+       d = 0;
+       currentline = 0;
+       lm = NULL;
+       bte = NULL;
+       s2 = 0;
+
+       {
+       s4 i, p, t, l;
+       s4 savedregs_num = 0;
+       s4 stack_off = 0;
+
+       /* space to save used callee saved registers */
+
+       savedregs_num += (INT_SAV_CNT - rd->savintreguse);
+
+       /* float register are saved on 2 4-byte stackslots */
+       savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
+
+       cd->stackframesize = rd->memuse + savedregs_num;
+
+          
+#if defined(ENABLE_THREADS)
+       /* space to save argument of monitor_enter */
+
+       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+               /* reserve 2 slots for long/double return values for monitorexit */
+
+               if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
+                       cd->stackframesize += 2;
+               else
+                       cd->stackframesize++;
+       }
+#endif
+
+       /* create method header */
+
+    /* Keep stack of non-leaf functions 16-byte aligned. */
+
+       if (!jd->isleafmethod)
+               cd->stackframesize |= 0x3;
+
+       (void) dseg_addaddress(cd, code);                      /* CodeinfoPointer */
+       (void) dseg_adds4(cd, cd->stackframesize * 4);         /* FrameSize       */
+
+#if defined(ENABLE_THREADS)
+       /* IsSync contains the offset relative to the stack pointer for the
+          argument of monitor_exit used in the exception handler. Since the
+          offset could be zero and give a wrong meaning of the flag it is
+          offset by one.
+       */
+
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               (void) dseg_adds4(cd, (rd->memuse + 1) * 4);       /* IsSync          */
+       else
+#endif
+               (void) dseg_adds4(cd, 0);                          /* IsSync          */
+                                              
+       (void) dseg_adds4(cd, jd->isleafmethod);               /* IsLeaf          */
+       (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave         */
+       (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave         */
+
+       /* adds a reference for the length of the line number counter. We don't
+          know the size yet, since we evaluate the information during code
+          generation, to save one additional iteration over the whole
+          instructions. During code optimization the position could have changed
+          to the information gotten from the class file */
+       (void) dseg_addlinenumbertablesize(cd);
+
+       (void) dseg_adds4(cd, cd->exceptiontablelength);       /* ExTableSize     */
+       
+       /* create exception table */
+
+       for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
+               dseg_addtarget(cd, ex->start);
+               dseg_addtarget(cd, ex->end);
+               dseg_addtarget(cd, ex->handler);
+               (void) dseg_addaddress(cd, ex->catchtype.cls);
+       }
+       
+       /* generate method profiling code */
+
+       if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
+               /* count frequency */
+
+               M_MOV_IMM(code, REG_ITMP3);
+               M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
+       }
+
+       /* create stack frame (if necessary) */
+
+       if (cd->stackframesize)
+               M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
+
+       /* save return address and used callee saved registers */
+
+       p = cd->stackframesize;
+       for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
+               p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
+       }
+       for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
+               p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
+       }
+
+       /* take arguments out of register or stack frame */
+
+       md = m->parseddesc;
+
+       stack_off = 0;
+       for (p = 0, l = 0; p < md->paramcount; p++) {
+               t = md->paramtypes[p].type;
+#if defined(ENABLE_SSA)
+               if ( ls != NULL ) {
+                       l = ls->local_0[p];
+               }
+#endif
+               var = &(jd->var[jd->local_map[l * 5 + t]]);
+               l++;
+               if (IS_2_WORD_TYPE(t))    /* increment local counter for 2 word types */
+                       l++;
+               if (var->type < 0)
+                       continue;
+               s1 = md->params[p].regoff;
+
+               if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
+                       if (!md->params[p].inmemory) {           /* register arguments    */
+                               log_text("integer register argument");
+                               assert(0);
+                               if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
+                                       /* rd->argintregs[md->params[p].regoff -> var->regoff     */
+                               } 
+                               else {                               /* reg arg -> spilled    */
+                                       /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
+                               }
+                       } 
+                       else {                                   /* stack arguments       */
+                               if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
+                                       emit_mov_membase_reg(           /* + 4 for return address */
+                                          cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->regoff);
+                                                                       /* + 4 for return address */
+                               } 
+                               else {                               /* stack arg -> spilled  */
+                                       if (!IS_2_WORD_TYPE(t)) {
+#if defined(ENABLE_SSA)
+                                               /* no copy avoiding by now possible with SSA */
+                                               if (ls != NULL) {
+                                                       emit_mov_membase_reg(   /* + 4 for return address */
+                                                                cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
+                                                                REG_ITMP1);    
+                                                       emit_mov_reg_membase(
+                                                                cd, REG_ITMP1, REG_SP, var->regoff * 4);
+                                               }
+                                               else 
+#endif /*defined(ENABLE_SSA)*/
+                                                                 /* reuse Stackslotand avoid copying */
+                                                       var->regoff = cd->stackframesize + s1 + 1;
+
+                                       } 
+                                       else {
+#if defined(ENABLE_SSA)
+                                               /* no copy avoiding by now possible with SSA */
+                                               if (ls != NULL) {
+                                                       emit_mov_membase_reg(  /* + 4 for return address */
+                                                                cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
+                                                                REG_ITMP1);
+                                                       emit_mov_reg_membase(
+                                                                cd, REG_ITMP1, REG_SP, var->regoff * 4);
+                                                       emit_mov_membase_reg(   /* + 4 for return address */
+                                                                 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
+                                                                 REG_ITMP1);             
+                                                       emit_mov_reg_membase(
+                                                                cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
+                                               }
+                                               else
+#endif /*defined(ENABLE_SSA)*/
+                                                                 /* reuse Stackslotand avoid copying */
+                                                       var->regoff = cd->stackframesize + s1 + 1;
+                                       }
+                               }
+                       }
+               }
+               else {                                       /* floating args         */
+                       if (!md->params[p].inmemory) {           /* register arguments    */
+                               log_text("There are no float argument registers!");
+                               assert(0);
+                               if (!(var->flags & INMEMORY)) {  /* reg arg -> register   */
+                                       /* rd->argfltregs[md->params[p].regoff -> var->regoff     */
+                               } else {                                     /* reg arg -> spilled    */
+                                       /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
+                               }
+
+                       } 
+                       else {                                   /* stack arguments       */
+                               if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
+                                       if (t == TYPE_FLT) {
+                                               emit_flds_membase(
+                            cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
+                                               assert(0);
+/*                                             emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
+
+                                       } 
+                                       else {
+                                               emit_fldl_membase(
+                            cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
+                                               assert(0);
+/*                                             emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
+                                       }
+
+                               } else {                             /* stack-arg -> spilled  */
+#if defined(ENABLE_SSA)
+                                       /* no copy avoiding by now possible with SSA */
+                                       if (ls != NULL) {
+                                               emit_mov_membase_reg(
+                                                cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
+                                               emit_mov_reg_membase(
+                                                                        cd, REG_ITMP1, REG_SP, var->regoff * 4);
+                                               if (t == TYPE_FLT) {
+                                                       emit_flds_membase(
+                                                                 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
+                                                       emit_fstps_membase(cd, REG_SP, var->regoff * 4);
+                                               } 
+                                               else {
+                                                       emit_fldl_membase(
+                                                                 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
+                                                       emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
+                                               }
+                                       }
+                                       else
+#endif /*defined(ENABLE_SSA)*/
+                                                                 /* reuse Stackslotand avoid copying */
+                                               var->regoff = cd->stackframesize + s1 + 1;
+                               }
+                       }
+               }
+       }  /* end for */
+
+       /* call monitorenter function */
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+               s1 = rd->memuse;
+
+               if (m->flags & ACC_STATIC) {
+                       M_MOV_IMM(&m->class->object.header, REG_ITMP1);
+               }
+               else {
+                       M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
+                       M_TEST(REG_ITMP1);
+                       M_BEQ(0);
+                       codegen_add_nullpointerexception_ref(cd);
+               }
+
+               M_AST(REG_ITMP1, REG_SP, s1 * 4);
+               M_AST(REG_ITMP1, REG_SP, 0 * 4);
+               M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
+               M_CALL(REG_ITMP3);
+       }                       
+#endif
+
+#if !defined(NDEBUG)
+       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+               emit_verbosecall_enter(jd);
+#endif
+
+       } 
+
+#if defined(ENABLE_SSA)
+       /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
+       if ( ls != NULL)
+                       codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
+#endif
+
+       /* end of header generation */
+
+       replacementpoint = jd->code->rplpoints;
+
+       /* walk through all basic blocks */
+       for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
+
+               bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
+
+               if (bptr->flags >= BBREACHED) {
+
+               /* branch resolving */
+
+               branchref *brefs;
+               for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
+                       gen_resolvebranch(cd->mcodebase + brefs->branchpos, 
+                                         brefs->branchpos,
+                                                         bptr->mpc);
+               }
+
+#if 0
+               /* handle replacement points */
+
+               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
+                       replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
+                       
+                       replacementpoint++;
+
+                       assert(cd->lastmcodeptr <= cd->mcodeptr);
+                       cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
+               }
+#endif
+
+               /* copy interface registers to their destination */
+
+               len = bptr->indepth;
+               MCODECHECK(512);
+
+#if 0
+               /* generate basic block profiling code */
+
+               if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
+                       /* count frequency */
+
+                       M_MOV_IMM(code->bbfrequency, REG_ITMP3);
+                       M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
+               }
+#endif
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+# if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
+               if (opt_lsra) {
+# endif
+# if defined(ENABLE_SSA)
+               if (ls != NULL) {
+                       last_cmd_was_goto = false;
+# endif
+                       if (len > 0) {
+                               len--;
+                               src = bptr->invars[len];
+                               if (bptr->type != BBTYPE_STD) {
+                                       if (!IS_2_WORD_TYPE(src->type)) {
+                                               if (bptr->type == BBTYPE_SBR) {
+                                                       if (!(src->flags & INMEMORY))
+                                                               d = src->regoff;
+                                                       else
+                                                               d = REG_ITMP1;
+                                                       emit_pop_reg(cd, d);
+                                                       emit_store(jd, NULL, src, d);
+                                               } else if (bptr->type == BBTYPE_EXH) {
+                                                       if (!(src->flags & INMEMORY))
+                                                               d = src->regoff;
+                                                       else
+                                                               d = REG_ITMP1;
+                                                       M_INTMOVE(REG_ITMP1, d);
+                                                       emit_store(jd, NULL, src, d);
+                                               }
+
+                                       } else {
+                                               log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
+                                               assert(0);
+                                       }
+                               }
+                       }
+
+               } else
+#endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
+               {
+               while (len) {
+                       len--;
+                       varindex = bptr->invars[len];
+                       var = &(jd->var[varindex]);
+                       if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
+                               if (!IS_2_WORD_TYPE(var->type)) {
+                                       if (bptr->type == BBTYPE_SBR) {
+                                               d = codegen_reg_of_var(0, var, REG_ITMP1);
+                                               emit_pop_reg(cd, d);
+                                               emit_store(jd, NULL, var, d);
+
+                                       } else if (bptr->type == BBTYPE_EXH) {
+                                               d = codegen_reg_of_var(0, var, REG_ITMP1);
+                                               M_INTMOVE(REG_ITMP1, d);
+                                               emit_store(jd, NULL, var, d);
+                                       }
+                               } else {
+                                       log_text("copy interface registers: longs have to be in \
+                               memory (begin 1)");
+                                       assert(0);
+                               }
+
+                       } else {
+                               printf("block %i var %i\n",bptr->nr, varindex);
+                               assert((var->flags & OUTVAR));
+                               /* will be done directly in simplereg lateron          */ 
+                               /* for now codegen_reg_of_var has to be called here to */
+                               /* set the regoff and flags for all bptr->invars[]     */
+                               d = codegen_reg_of_var(0, var, REG_ITMP1);
+
+                       }
+               }
+               }
+
+               /* walk through all instructions */
+               
+               len = bptr->icount;
+               currentline = 0;
+
+               for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
+                       if (iptr->line != currentline) {
+                               dseg_addlinenumber(cd, iptr->line);
+                               currentline = iptr->line;
+                       }
+
+                       MCODECHECK(1024);                         /* 1kB should be enough */
+
+               switch (iptr->opc) {
+               case ICMD_INLINE_START:
+#if 0
+                       {
+                               insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
+#if defined(ENABLE_THREADS)
+                               if (insinfo->synchronize) {
+                                       /* add monitor enter code */
+                                       if (insinfo->method->flags & ACC_STATIC) {
+                                               M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
+                                               M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                                       } 
+                                       else {
+                                               /* nullpointer check must have been performed before */
+                                               /* (XXX not done, yet) */
+                                               var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
+                                               if (var->flags & INMEMORY) {
+                                                       emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
+                                                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                                               } 
+                                               else {
+                                                       M_AST(var->regoff, REG_SP, 0 * 4);
+                                               }
+                                       }
+
+                                       M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
+                                       M_CALL(REG_ITMP3);
+                               }
+#endif
+                               dseg_addlinenumber_inline_start(cd, iptr);
+                       }
+#endif
+                       break;
+
+               case ICMD_INLINE_END:
+#if 0
+                       {
+                               insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
+
+                               dseg_addlinenumber_inline_end(cd, iptr);
+                               dseg_addlinenumber(cd, iptr->line);
+
+#if defined(ENABLE_THREADS)
+                               if (insinfo->synchronize) {
+                                       /* add monitor exit code */
+                                       if (insinfo->method->flags & ACC_STATIC) {
+                                               M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
+                                               M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                                       } 
+                                       else {
+                                               var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
+                                               if (var->flags & INMEMORY) {
+                                                       M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
+                                                       M_AST(REG_ITMP1, REG_SP, 0 * 4);
+                                               } 
+                                               else {
+                                                       M_AST(var->regoff, REG_SP, 0 * 4);
+                                               }
+                                       }
+
+                                       M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
+                                       M_CALL(REG_ITMP3);
+                               }
+#endif
+                       }
+#endif
+                       break;
+
+               case ICMD_NOP:        /* ...  ==> ...                                 */
+                       break;
+
+               case ICMD_CHECKNULL:  /* ..., objectref  ==> ..., objectref           */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_TEST(s1);
+                       M_BEQ(0);
+                       codegen_add_nullpointerexception_ref(cd);
+                       break;
+
+               /* constant operations ************************************************/
+
+               case ICMD_ICONST:     /* ...  ==> ..., constant                       */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       ICONST(d, iptr->sx.val.i);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LCONST:     /* ...  ==> ..., constant                       */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       LCONST(d, iptr->sx.val.l);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FCONST:     /* ...  ==> ..., constant                       */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                       if (iptr->sx.val.f == 0.0) {
+                               emit_fldz(cd);
+
+                               /* -0.0 */
+                               if (iptr->sx.val.i == 0x80000000) {
+                                       emit_fchs(cd);
+                               }
+
+                       } else if (iptr->sx.val.f == 1.0) {
+                               emit_fld1(cd);
+
+                       } else if (iptr->sx.val.f == 2.0) {
+                               emit_fld1(cd);
+                               emit_fld1(cd);
+                               emit_faddp(cd);
+
+                       } else {
+                               disp = dseg_addfloat(cd, iptr->sx.val.f);
+                               emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                               dseg_adddata(cd);
+                               emit_flds_membase(cd, REG_ITMP1, disp);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+               
+               case ICMD_DCONST:     /* ...  ==> ..., constant                       */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                       if (iptr->sx.val.d == 0.0) {
+                               emit_fldz(cd);
+
+                               /* -0.0 */
+                               if (iptr->sx.val.l == 0x8000000000000000LL) {
+                                       emit_fchs(cd);
+                               }
+
+                       } else if (iptr->sx.val.d == 1.0) {
+                               emit_fld1(cd);
+
+                       } else if (iptr->sx.val.d == 2.0) {
+                               emit_fld1(cd);
+                               emit_fld1(cd);
+                               emit_faddp(cd);
+
+                       } else {
+                               disp = dseg_adddouble(cd, iptr->sx.val.d);
+                               emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                               dseg_adddata(cd);
+                               emit_fldl_membase(cd, REG_ITMP1, disp);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_ACONST:     /* ...  ==> ..., constant                       */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               codegen_addpatchref(cd, PATCHER_aconst,
+                                                                       iptr->sx.val.c.ref, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               M_MOV_IMM(NULL, d);
+
+                       } else {
+                               if (iptr->sx.val.anyptr == NULL)
+                                       M_CLR(d);
+                               else
+                                       M_MOV_IMM(iptr->sx.val.anyptr, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+
+               /* load/store operations **********************************************/
+
+               case ICMD_ILOAD:      /* ...  ==> ..., content of local variable      */
+               case ICMD_ALOAD:      /* op1 = local variable                         */
+
+                       if ( iptr->dst.varindex == iptr->s1.varindex)
+                               break;
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+
+                       s1 = emit_load_s1(jd, iptr, d);
+                       M_INTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+               case ICMD_LLOAD:      /* ...  ==> ..., content of local variable      */
+                                     /* s1.localindex = local variable                         */
+  
+                       if ( iptr->dst.varindex == iptr->s1.varindex)
+                               break;
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       M_INTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+               case ICMD_FLOAD:      
+               case ICMD_DLOAD:      /* ...  ==> ..., content of local variable      */
+                                     /* s1.localindex = local variable               */
+
+                       if ( iptr->dst.varindex == iptr->s1.varindex)
+                               break;
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       M_FLTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+
+               case ICMD_ISTORE:     /* ..., value  ==> ...                          */
+               case ICMD_ASTORE:     /* op1 = local variable                         */
+
+                       if ( iptr->s1.varindex == iptr->dst.varindex)
+                               break;
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+
+                       M_INTMOVE(s1,d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+               case ICMD_LSTORE:     /* ..., value  ==> ...                          */
+                                     /* dst.localindex = local variable              */
+
+                       if ( iptr->dst.varindex == iptr->dst.varindex)
+                               break;
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       M_INTMOVE(s1,d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+               case ICMD_FSTORE:     /* ..., value  ==> ...                          */
+                                     /* dst.localindex = local variable              */
+
+                       if ( iptr->dst.varindex == iptr->s1.varindex)
+                               break;
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       M_FLTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+               case ICMD_DSTORE:     /* ..., value  ==> ...                          */
+                                     /* dst.localindex = local variable              */
+
+                       if ( iptr->dst.varindex == iptr->s1.varindex)
+                               break;
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       M_FLTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+
+               /* pop/dup/swap operations ********************************************/
+
+               /* attention: double and longs are only one entry in CACAO ICMDs      */
+
+               case ICMD_POP:        /* ..., value  ==> ...                          */
+               case ICMD_POP2:       /* ..., value, value  ==> ...                   */
+                       break;
+
+               case ICMD_DUP:        /* ..., a ==> ..., a, a                         */
+
+                       M_COPY(iptr->s1.varindex, iptr->dst.varindex);
+                       break;
+
+               case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
+
+                       M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+2]);
+                       M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
+                       M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
+                       break;
+
+               case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
+
+                       M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+3]);
+                       M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+2]);
+                       M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+1]);
+                       M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
+                       break;
+
+               case ICMD_DUP2:       /* ..., a, b ==> ..., a, b, a, b                */
+
+                       M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+1]);
+                       M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+0]);
+                       break;
+
+               case ICMD_DUP2_X1:    /* ..., a, b, c ==> ..., b, c, a, b, c          */
+
+                       M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[3+4]);
+                       M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[3+3]);
+                       M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[3+2]);
+                       M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
+                       M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
+                       break;
+
+               case ICMD_DUP2_X2:    /* ..., a, b, c, d ==> ..., c, d, a, b, c, d    */
+
+                       M_COPY(iptr->dst.dupslots[  3], iptr->dst.dupslots[4+5]);
+                       M_COPY(iptr->dst.dupslots[  2], iptr->dst.dupslots[4+4]);
+                       M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[4+3]);
+                       M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[4+2]);
+                       M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
+                       M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
+                       break;
+
+               case ICMD_SWAP:       /* ..., a, b ==> ..., b, a                      */
+
+                       M_COPY(iptr->dst.dupslots[  1], iptr->dst.dupslots[2+0]);
+                       M_COPY(iptr->dst.dupslots[  0], iptr->dst.dupslots[2+1]);
+                       break;
+
+
+#if 0
+               case ICMD_DUP_X1:     /* ..., a, b ==> ..., b, a, b                   */
+
+                       M_COPY(src,       iptr->dst);
+                       M_COPY(src->prev, iptr->dst->prev);
+#if defined(ENABLE_SSA)
+                       if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
+                               (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
+#endif
+                               M_COPY(iptr->dst, iptr->dst->prev->prev);
+#if defined(ENABLE_SSA)
+                       } else {
+                               M_COPY(src, iptr->dst->prev->prev);
+                       }
+#endif
+                       break;
+
+               case ICMD_DUP_X2:     /* ..., a, b, c ==> ..., c, a, b, c             */
+
+                       M_COPY(src,             iptr->dst);
+                       M_COPY(src->prev,       iptr->dst->prev);
+                       M_COPY(src->prev->prev, iptr->dst->prev->prev);
+#if defined(ENABLE_SSA)
+                       if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
+                               (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
+#endif
+                               M_COPY(iptr->dst,       iptr->dst->prev->prev->prev);
+#if defined(ENABLE_SSA)
+                       } else {
+                               M_COPY(src, iptr->dst->prev->prev->prev);
+                       }
+#endif
+                       break;
+#endif
+
+               /* integer operations *************************************************/
+
+               case ICMD_INEG:       /* ..., value  ==> ..., - value                 */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1); 
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_NEG(d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_NEG(GET_LOW_REG(d));
+                       M_IADDC_IMM(0, GET_HIGH_REG(d));
+                       M_NEG(GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_I2L:        /* ..., value  ==> ..., value                   */
+
+                       s1 = emit_load_s1(jd, iptr, EAX);
+                       d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
+                       M_INTMOVE(s1, EAX);
+                       M_CLTD;
+                       M_LNGMOVE(EAX_EDX_PACKED, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_L2I:        /* ..., value  ==> ..., value                   */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_INTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_INT2BYTE:   /* ..., value  ==> ..., value                   */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_SLL_IMM(24, d);
+                       M_SRA_IMM(24, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_INT2CHAR:   /* ..., value  ==> ..., value                   */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_CZEXT(s1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_INT2SHORT:  /* ..., value  ==> ..., value                   */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_SSEXT(s1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+
+               case ICMD_IADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s2 == d)
+                               M_IADD(s1, d);
+                       else {
+                               M_INTMOVE(s1, d);
+                               M_IADD(s2, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IADDCONST:  /* ..., value  ==> ..., value + constant        */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_IADD_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_INTMOVE(s1, GET_LOW_REG(d));
+                       M_IADD(s2, GET_LOW_REG(d));
+                       /* don't use REG_ITMP1 */
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       M_INTMOVE(s1, GET_HIGH_REG(d));
+                       M_IADDC(s2, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
+                       M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_ISUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       if (s2 == d) {
+                               M_INTMOVE(s1, REG_ITMP1);
+                               M_ISUB(s2, REG_ITMP1);
+                               M_INTMOVE(REG_ITMP1, d);
+                       }
+                       else {
+                               M_INTMOVE(s1, d);
+                               M_ISUB(s2, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_ISUBCONST:  /* ..., value  ==> ..., value + constant        */
+                                     /* sx.val.i = constant                             */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_ISUB_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if (s2 == GET_LOW_REG(d)) {
+                               M_INTMOVE(s1, REG_ITMP1);
+                               M_ISUB(s2, REG_ITMP1);
+                               M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
+                       }
+                       else {
+                               M_INTMOVE(s1, GET_LOW_REG(d));
+                               M_ISUB(s2, GET_LOW_REG(d));
+                       }
+                       /* don't use REG_ITMP1 */
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       if (s2 == GET_HIGH_REG(d)) {
+                               M_INTMOVE(s1, REG_ITMP2);
+                               M_ISUBB(s2, REG_ITMP2);
+                               M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
+                       }
+                       else {
+                               M_INTMOVE(s1, GET_HIGH_REG(d));
+                               M_ISUBB(s2, GET_HIGH_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
+                       M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s2 == d)
+                               M_IMUL(s1, d);
+                       else {
+                               M_INTMOVE(s1, d);
+                               M_IMUL(s2, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IMULCONST:  /* ..., value  ==> ..., value * constant        */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_IMUL_IMM(s1, iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_low(jd, iptr, EDX);
+                       d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
+
+                       M_INTMOVE(s1, REG_ITMP2);
+                       M_IMUL(s2, REG_ITMP2);
+
+                       s1 = emit_load_s1_low(jd, iptr, EAX);
+                       s2 = emit_load_s2_high(jd, iptr, EDX);
+                       M_INTMOVE(s2, EDX);
+                       M_IMUL(s1, EDX);
+                       M_IADD(EDX, REG_ITMP2);
+
+                       s1 = emit_load_s1_low(jd, iptr, EAX);
+                       s2 = emit_load_s2_low(jd, iptr, EDX);
+                       M_INTMOVE(s1, EAX);
+                       M_MUL(s2);
+                       M_INTMOVE(EAX, GET_LOW_REG(d));
+                       M_IADD(REG_ITMP2, GET_HIGH_REG(d));
+
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LMULCONST:  /* ..., value  ==> ..., value * constant        */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
+                       ICONST(EAX, iptr->sx.val.l);
+                       M_MUL(s1);
+                       M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
+                       M_IADD(REG_ITMP2, EDX);
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
+                       M_IADD(REG_ITMP2, EDX);
+                       M_LNGMOVE(EAX_EDX_PACKED, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+
+                       s1 = emit_load_s1(jd, iptr, EAX);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, EAX);
+
+                       if (checknull) {
+                               M_TEST(s2);
+                               M_BEQ(0);
+                               codegen_add_arithmeticexception_ref(cd);
+                       }
+
+                       M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
+
+                       /* check as described in jvm spec */
+
+                       M_CMP_IMM(0x80000000, EAX);
+                       M_BNE(3 + 6);
+                       M_CMP_IMM(-1, s2);
+                       M_BEQ(1 + 2);
+                       M_CLTD;
+                       M_IDIV(s2);
+
+                       M_INTMOVE(EAX, d);           /* if INMEMORY then d is already EAX */
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+
+                       s1 = emit_load_s1(jd, iptr, EAX);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, EDX);
+
+                       if (checknull) {
+                               M_TEST(s2);
+                               M_BEQ(0);
+                               codegen_add_arithmeticexception_ref(cd);
+                       }
+
+                       M_INTMOVE(s1, EAX);           /* we need the first operand in EAX */
+
+                       /* check as described in jvm spec */
+
+                       M_CMP_IMM(0x80000000, EAX);
+                       M_BNE(2 + 3 + 6);
+                       M_CLR(EDX);
+                       M_CMP_IMM(-1, s2);
+                       M_BEQ(1 + 2);
+                       M_CLTD;
+                       M_IDIV(s2);
+
+                       M_INTMOVE(EDX, d);           /* if INMEMORY then d is already EDX */
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
+                                     /* sx.val.i = constant                          */
+
+                       /* TODO: optimize for `/ 2' */
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_TEST(d);
+                       M_BNS(6);
+                       M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
+                       M_SRA_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s1 == d) {
+                               M_MOV(s1, REG_ITMP1);
+                               s1 = REG_ITMP1;
+                       } 
+                       M_INTMOVE(s1, d);
+                       M_AND_IMM(iptr->sx.val.i, d);
+                       M_TEST(s1);
+                       M_BGE(2 + 2 + 6 + 2);
+                       M_MOV(s1, d);  /* don't use M_INTMOVE, so we know the jump offset */
+                       M_NEG(d);
+                       M_AND_IMM32(iptr->sx.val.i, d);     /* use 32-bit for jump offset */
+                       M_NEG(d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+               case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+
+                       M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
+                       M_OR(GET_HIGH_REG(s2), REG_ITMP3);
+                       M_BEQ(0);
+                       codegen_add_arithmeticexception_ref(cd);
+
+                       bte = iptr->sx.s23.s3.bte;
+                       md = bte->md;
+
+                       M_LST(s2, REG_SP, 2 * 4);
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       M_LST(s1, REG_SP, 0 * 4);
+
+                       M_MOV_IMM(bte->fp, REG_ITMP3);
+                       M_CALL(REG_ITMP3);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value >> constant       */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_TEST(GET_HIGH_REG(d));
+                       M_BNS(6 + 3);
+                       M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
+                       M_IADDC_IMM(0, GET_HIGH_REG(d));
+                       M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
+                       M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+#if 0
+               case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
+                                     /* sx.val.l = constant                          */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
+                       if (iptr->dst.var->flags & INMEMORY) {
+                               if (iptr->s1.var->flags & INMEMORY) {
+                                       /* Alpha algorithm */
+                                       disp = 3;
+                                       CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
+                                       disp += 3;
+                                       CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4 + 4);
+
+                                       disp += 2;
+                                       disp += 3;
+                                       disp += 2;
+
+                                       /* TODO: hmm, don't know if this is always correct */
+                                       disp += 2;
+                                       CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
+                                       disp += 2;
+                                       CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
+
+                                       disp += 2;
+                                       disp += 3;
+                                       disp += 2;
+
+                                       emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
+                                       emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
+                                       
+                                       emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
+                                       emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
+                                       emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->regoff * 4 + 4);
+                                       emit_jcc(cd, CC_GE, disp);
+
+                                       emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
+                                       emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
+                                       
+                                       emit_neg_reg(cd, REG_ITMP1);
+                                       emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
+                                       emit_neg_reg(cd, REG_ITMP2);
+                                       
+                                       emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
+                                       emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
+                                       
+                                       emit_neg_reg(cd, REG_ITMP1);
+                                       emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
+                                       emit_neg_reg(cd, REG_ITMP2);
+
+                                       emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->regoff * 4);
+                                       emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->regoff * 4 + 4);
+                               }
+                       }
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));      
+                       M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
+                       M_TEST(GET_LOW_REG(s1));
+                       M_BGE(0);
+                       M_LNGMOVE(s1, d);
+               break;
+#endif
+
+               case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
+                       M_INTMOVE(s1, d);
+                       M_SLL(d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_ISHLCONST:  /* ..., value  ==> ..., value << constant       */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_SLL_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_ISHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
+                       M_INTMOVE(s1, d);
+                       M_SRA(d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_ISHRCONST:  /* ..., value  ==> ..., value >> constant       */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_SRA_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s2, ECX);                       /* s2 may be equal to d */
+                       M_INTMOVE(s1, d);
+                       M_SRL(d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_SRL_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
+                       s2 = emit_load_s2(jd, iptr, ECX);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_INTMOVE(s2, ECX);
+                       M_TEST_IMM(32, ECX);
+                       M_BEQ(2 + 2);
+                       M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
+                       M_CLR(GET_LOW_REG(d));
+                       M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
+                       M_SLL(GET_LOW_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+        case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
+                                         /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       if (iptr->sx.val.i & 0x20) {
+                               M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
+                               M_CLR(GET_LOW_REG(d));
+                               M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), 
+                                                  GET_HIGH_REG(d));
+                       }
+                       else {
+                               M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
+                                                  GET_HIGH_REG(d));
+                               M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LSHR:       /* ..., val1, val2  ==> ..., val1 >> val2       */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
+                       s2 = emit_load_s2(jd, iptr, ECX);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_INTMOVE(s2, ECX);
+                       M_TEST_IMM(32, ECX);
+                       M_BEQ(2 + 3);
+                       M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
+                       M_SRA_IMM(31, GET_HIGH_REG(d));
+                       M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
+                       M_SRA(GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LSHRCONST:  /* ..., value  ==> ..., value >> constant       */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       if (iptr->sx.val.i & 0x20) {
+                               M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
+                               M_SRA_IMM(31, GET_HIGH_REG(d));
+                               M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
+                                                  GET_LOW_REG(d));
+                       }
+                       else {
+                               M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
+                                                  GET_LOW_REG(d));
+                               M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LUSHR:      /* ..., val1, val2  ==> ..., val1 >>> val2      */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
+                       s2 = emit_load_s2(jd, iptr, ECX);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_INTMOVE(s2, ECX);
+                       M_TEST_IMM(32, ECX);
+                       M_BEQ(2 + 2);
+                       M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
+                       M_CLR(GET_HIGH_REG(d));
+                       M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
+                       M_SRL(GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LUSHRCONST: /* ..., value  ==> ..., value >>> constant      */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       if (iptr->sx.val.i & 0x20) {
+                               M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
+                               M_CLR(GET_HIGH_REG(d));
+                               M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
+                                                  GET_LOW_REG(d));
+                       }
+                       else {
+                               M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d), 
+                                                  GET_LOW_REG(d));
+                               M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s2 == d)
+                               M_AND(s1, d);
+                       else {
+                               M_INTMOVE(s1, d);
+                               M_AND(s2, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IANDCONST:  /* ..., value  ==> ..., value & constant        */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_AND_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if (s2 == GET_LOW_REG(d))
+                               M_AND(s1, GET_LOW_REG(d));
+                       else {
+                               M_INTMOVE(s1, GET_LOW_REG(d));
+                               M_AND(s2, GET_LOW_REG(d));
+                       }
+                       /* REG_ITMP1 probably contains low 32-bit of destination */
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       if (s2 == GET_HIGH_REG(d))
+                               M_AND(s1, GET_HIGH_REG(d));
+                       else {
+                               M_INTMOVE(s1, GET_HIGH_REG(d));
+                               M_AND(s2, GET_HIGH_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
+                       M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s2 == d)
+                               M_OR(s1, d);
+                       else {
+                               M_INTMOVE(s1, d);
+                               M_OR(s2, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IORCONST:   /* ..., value  ==> ..., value | constant        */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_OR_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if (s2 == GET_LOW_REG(d))
+                               M_OR(s1, GET_LOW_REG(d));
+                       else {
+                               M_INTMOVE(s1, GET_LOW_REG(d));
+                               M_OR(s2, GET_LOW_REG(d));
+                       }
+                       /* REG_ITMP1 probably contains low 32-bit of destination */
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       if (s2 == GET_HIGH_REG(d))
+                               M_OR(s1, GET_HIGH_REG(d));
+                       else {
+                               M_INTMOVE(s1, GET_HIGH_REG(d));
+                               M_OR(s2, GET_HIGH_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
+                       M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s2 == d)
+                               M_XOR(s1, d);
+                       else {
+                               M_INTMOVE(s1, d);
+                               M_XOR(s2, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IXORCONST:  /* ..., value  ==> ..., value ^ constant        */
+                                     /* sx.val.i = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, d);
+                       M_XOR_IMM(iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if (s2 == GET_LOW_REG(d))
+                               M_XOR(s1, GET_LOW_REG(d));
+                       else {
+                               M_INTMOVE(s1, GET_LOW_REG(d));
+                               M_XOR(s2, GET_LOW_REG(d));
+                       }
+                       /* REG_ITMP1 probably contains low 32-bit of destination */
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       if (s2 == GET_HIGH_REG(d))
+                               M_XOR(s1, GET_HIGH_REG(d));
+                       else {
+                               M_INTMOVE(s1, GET_HIGH_REG(d));
+                               M_XOR(s2, GET_HIGH_REG(d));
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
+                                     /* sx.val.l = constant                          */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_LNGMOVE(s1, d);
+                       M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
+                       M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IINC:       /* ..., value  ==> ..., value + constant        */
+                                     /* s1.localindex = variable, sx.val.i = constant*/
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                               
+                       /* `inc reg' is slower on p4's (regarding to ia32
+                          optimization reference manual and benchmarks) and as
+                          fast on athlon's. */
+
+                       M_INTMOVE(s1, d);
+                       M_IADD_IMM(iptr->sx.val.i, d);
+
+                       emit_store_dst(jd, iptr, d);
+
+                       break;
+
+
+               /* floating operations ************************************************/
+
+               case ICMD_FNEG:       /* ..., value  ==> ..., - value                 */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       emit_fchs(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_DNEG:       /* ..., value  ==> ..., - value                 */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       emit_fchs(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_faddp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_DADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_faddp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_fsubp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_DSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_fsubp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_fmulp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_DMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_fmulp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_fdivp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_DDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       emit_fdivp(cd);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+
+                       /* exchanged to skip fxch */
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+/*                     emit_fxch(cd); */
+                       emit_fprem(cd);
+                       emit_wait(cd);
+                       emit_fnstsw(cd);
+                       emit_sahf(cd);
+                       emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
+                       emit_store_dst(jd, iptr, d);
+                       emit_ffree_reg(cd, 0);
+                       emit_fincstp(cd);
+                       break;
+
+               case ICMD_DREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+
+                       /* exchanged to skip fxch */
+                       s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+/*                     emit_fxch(cd); */
+                       emit_fprem(cd);
+                       emit_wait(cd);
+                       emit_fnstsw(cd);
+                       emit_sahf(cd);
+                       emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
+                       emit_store_dst(jd, iptr, d);
+                       emit_ffree_reg(cd, 0);
+                       emit_fincstp(cd);
+                       break;
+
+               case ICMD_I2F:       /* ..., value  ==> ..., (float) value            */
+               case ICMD_I2D:       /* ..., value  ==> ..., (double) value           */
+
+                       var = &(jd->var[iptr->s1.varindex]);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+
+                       if (var->flags & INMEMORY) {
+                               emit_fildl_membase(cd, REG_SP, var->regoff * 4);
+                       } else {
+                               disp = dseg_adds4(cd, 0);
+                               emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                               dseg_adddata(cd);
+                               emit_mov_reg_membase(cd, var->regoff, REG_ITMP1, disp);
+                               emit_fildl_membase(cd, REG_ITMP1, disp);
+                       }
+
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_L2F:       /* ..., value  ==> ..., (float) value            */
+               case ICMD_L2D:       /* ..., value  ==> ..., (double) value           */
+
+                       var = &(jd->var[iptr->s1.varindex]);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                       if (var->flags & INMEMORY) {
+                               emit_fildll_membase(cd, REG_SP, var->regoff * 4);
+
+                       } else {
+                               log_text("L2F: longs have to be in memory");
+                               assert(0);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+                       
+               case ICMD_F2I:       /* ..., value  ==> ..., (int) value              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
+
+                       emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                       dseg_adddata(cd);
+
+                       /* Round to zero, 53-bit mode, exception masked */
+                       disp = dseg_adds4(cd, 0x0e7f);
+                       emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                       var = &(jd->var[iptr->dst.varindex]);
+                       var1 = &(jd->var[iptr->s1.varindex]);
+
+                       if (var->flags & INMEMORY) {
+                               emit_fistpl_membase(cd, REG_SP, var->regoff * 4);
+
+                               /* Round to nearest, 53-bit mode, exceptions masked */
+                               disp = dseg_adds4(cd, 0x027f);
+                               emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                               emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
+                                                                        REG_SP, var->regoff * 4);
+
+                               disp = 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2 + 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+
+                       } else {
+                               disp = dseg_adds4(cd, 0);
+                               emit_fistpl_membase(cd, REG_ITMP1, disp);
+                               emit_mov_membase_reg(cd, REG_ITMP1, disp, var->regoff);
+
+                               /* Round to nearest, 53-bit mode, exceptions masked */
+                               disp = dseg_adds4(cd, 0x027f);
+                               emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                               emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->regoff);
+
+                               disp = 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2 + ((REG_RESULT == var->regoff) ? 0 : 2);
+                       }
+
+                       emit_jcc(cd, CC_NE, disp);
+
+                       /* XXX: change this when we use registers */
+                       emit_flds_membase(cd, REG_SP, var1->regoff * 4);
+                       emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
+                       emit_call_reg(cd, REG_ITMP1);
+
+                       if (var->flags & INMEMORY) {
+                               emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
+
+                       } else {
+                               M_INTMOVE(REG_RESULT, var->regoff);
+                       }
+                       break;
+
+               case ICMD_D2I:       /* ..., value  ==> ..., (int) value              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
+
+                       emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                       dseg_adddata(cd);
+
+                       /* Round to zero, 53-bit mode, exception masked */
+                       disp = dseg_adds4(cd, 0x0e7f);
+                       emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                       var  = &(jd->var[iptr->dst.varindex]);
+                       var1 = &(jd->var[iptr->s1.varindex]);
+
+                       if (var->flags & INMEMORY) {
+                               emit_fistpl_membase(cd, REG_SP, var->regoff * 4);
+
+                               /* Round to nearest, 53-bit mode, exceptions masked */
+                               disp = dseg_adds4(cd, 0x027f);
+                               emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                               emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
+                                                                        REG_SP, var->regoff * 4);
+
+                               disp = 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2 + 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+
+                       } else {
+                               disp = dseg_adds4(cd, 0);
+                               emit_fistpl_membase(cd, REG_ITMP1, disp);
+                               emit_mov_membase_reg(cd, REG_ITMP1, disp, var->regoff);
+
+                               /* Round to nearest, 53-bit mode, exceptions masked */
+                               disp = dseg_adds4(cd, 0x027f);
+                               emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                               emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->regoff);
+
+                               disp = 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2 + ((REG_RESULT == var->regoff) ? 0 : 2);
+                       }
+
+                       emit_jcc(cd, CC_NE, disp);
+
+                       /* XXX: change this when we use registers */
+                       emit_fldl_membase(cd, REG_SP, var1->regoff * 4);
+                       emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
+                       emit_call_reg(cd, REG_ITMP1);
+
+                       if (var->flags & INMEMORY) {
+                               emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
+                       } else {
+                               M_INTMOVE(REG_RESULT, var->regoff);
+                       }
+                       break;
+
+               case ICMD_F2L:       /* ..., value  ==> ..., (long) value             */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
+
+                       emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                       dseg_adddata(cd);
+
+                       /* Round to zero, 53-bit mode, exception masked */
+                       disp = dseg_adds4(cd, 0x0e7f);
+                       emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                       var  = &(jd->var[iptr->dst.varindex]);
+                       var1 = &(jd->var[iptr->s1.varindex]);
+
+                       if (var->flags & INMEMORY) {
+                               emit_fistpll_membase(cd, REG_SP, var->regoff * 4);
+
+                               /* Round to nearest, 53-bit mode, exceptions masked */
+                               disp = dseg_adds4(cd, 0x027f);
+                               emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                               emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
+                                                                        REG_SP, var->regoff * 4 + 4);
+
+                               disp = 6 + 4;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+                               disp += 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2;
+                               disp += 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+                               disp += 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4 + 4);
+
+                               emit_jcc(cd, CC_NE, disp);
+
+                               emit_alu_imm_membase(cd, ALU_CMP, 0, 
+                                                                        REG_SP, var->regoff * 4);
+
+                               disp = 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2 + 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+
+                               emit_jcc(cd, CC_NE, disp);
+
+                               /* XXX: change this when we use registers */
+                               emit_flds_membase(cd, REG_SP, var1->regoff * 4);
+                               emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
+                               emit_call_reg(cd, REG_ITMP1);
+                               emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
+                               emit_mov_reg_membase(cd, REG_RESULT2, 
+                                                                        REG_SP, var->regoff * 4 + 4);
+
+                       } else {
+                               log_text("F2L: longs have to be in memory");
+                               assert(0);
+                       }
+                       break;
+
+               case ICMD_D2L:       /* ..., value  ==> ..., (long) value             */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_NULL);
+
+                       emit_mov_imm_reg(cd, 0, REG_ITMP1);
+                       dseg_adddata(cd);
+
+                       /* Round to zero, 53-bit mode, exception masked */
+                       disp = dseg_adds4(cd, 0x0e7f);
+                       emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                       var  = &(jd->var[iptr->dst.varindex]);
+                       var1 = &(jd->var[iptr->s1.varindex]);
+
+                       if (var->flags & INMEMORY) {
+                               emit_fistpll_membase(cd, REG_SP, var->regoff * 4);
+
+                               /* Round to nearest, 53-bit mode, exceptions masked */
+                               disp = dseg_adds4(cd, 0x027f);
+                               emit_fldcw_membase(cd, REG_ITMP1, disp);
+
+                               emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, 
+                                                                        REG_SP, var->regoff * 4 + 4);
+
+                               disp = 6 + 4;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+                               disp += 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2;
+                               disp += 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+                               disp += 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4 + 4);
+
+                               emit_jcc(cd, CC_NE, disp);
+
+                               emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->regoff * 4);
+
+                               disp = 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
+                               disp += 5 + 2 + 3;
+                               CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
+
+                               emit_jcc(cd, CC_NE, disp);
+
+                               /* XXX: change this when we use registers */
+                               emit_fldl_membase(cd, REG_SP, var1->regoff * 4);
+                               emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
+                               emit_call_reg(cd, REG_ITMP1);
+                               emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
+                               emit_mov_reg_membase(cd, REG_RESULT2, 
+                                                                        REG_SP, var->regoff * 4 + 4);
+
+                       } else {
+                               log_text("D2L: longs have to be in memory");
+                               assert(0);
+                       }
+                       break;
+
+               case ICMD_F2D:       /* ..., value  ==> ..., (double) value           */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       /* nothing to do */
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_D2F:       /* ..., value  ==> ..., (float) value            */
+
+                       s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       /* nothing to do */
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FCMPL:      /* ..., val1, val2  ==> ..., val1 fcmpl val2    */
+               case ICMD_DCMPL:
+
+                       /* exchanged to skip fxch */
+                       s2 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s1 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+/*                     emit_fxch(cd); */
+                       emit_fucompp(cd);
+                       emit_fnstsw(cd);
+                       emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as GT */
+                       emit_jcc(cd, CC_E, 6);
+                       emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
+                       emit_sahf(cd);
+                       emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
+                       emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
+                       emit_jcc(cd, CC_B, 3 + 5);
+                       emit_alu_imm_reg(cd, ALU_SUB, 1, d);
+                       emit_jmp_imm(cd, 3);
+                       emit_alu_imm_reg(cd, ALU_ADD, 1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_FCMPG:      /* ..., val1, val2  ==> ..., val1 fcmpg val2    */
+               case ICMD_DCMPG:
+
+                       /* exchanged to skip fxch */
+                       s2 = emit_load_s1(jd, iptr, REG_FTMP1);
+                       s1 = emit_load_s2(jd, iptr, REG_FTMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+/*                     emit_fxch(cd); */
+                       emit_fucompp(cd);
+                       emit_fnstsw(cd);
+                       emit_test_imm_reg(cd, 0x400, EAX);    /* unordered treat as LT */
+                       emit_jcc(cd, CC_E, 3);
+                       emit_movb_imm_reg(cd, 1, REG_AH);
+                       emit_sahf(cd);
+                       emit_mov_imm_reg(cd, 0, d);    /* does not affect flags */
+                       emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
+                       emit_jcc(cd, CC_B, 3 + 5);
+                       emit_alu_imm_reg(cd, ALU_SUB, 1, d);
+                       emit_jmp_imm(cd, 3);
+                       emit_alu_imm_reg(cd, ALU_ADD, 1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+
+               /* memory operations **************************************************/
+
+               case ICMD_ARRAYLENGTH: /* ..., arrayref  ==> ..., length              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       gen_nullptr_check(s1);
+                       M_ILD(d, s1, OFFSET(java_arrayheader, size));
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_BALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), 
+                                                                        s1, s2, 0, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_CALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), 
+                                                                        s1, s2, 1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;                  
+
+               case ICMD_SALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), 
+                                                                        s1, s2, 1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_IALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), 
+                                                                 s1, s2, 2, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_LALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+
+                       var  = &(jd->var[iptr->dst.varindex]);
+
+                       assert(var->flags & INMEMORY);
+                       emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), 
+                                                                 s1, s2, 3, REG_ITMP3);
+                       emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->regoff * 4);
+                       emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, 
+                                                                 s1, s2, 3, REG_ITMP3);
+                       emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->regoff * 4 + 4);
+                       break;
+
+               case ICMD_FALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_DALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_AALOAD:     /* ..., arrayref, index  ==> ..., value         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
+                                                                 s1, s2, 2, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+
+               case ICMD_BASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       if (s3 >= EBP) { 
+                               /* because EBP, ESI, EDI have no xH and xL nibbles */
+                               M_INTMOVE(s3, REG_ITMP3);
+                               s3 = REG_ITMP3;
+                       }
+                       emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]),
+                                                                  s1, s2, 0);
+                       break;
+
+               case ICMD_CASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
+                                                                  s1, s2, 1);
+                       break;
+
+               case ICMD_SASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
+                                                                  s1, s2, 1);
+                       break;
+
+               case ICMD_IASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
+                                                                 s1, s2, 2);
+                       break;
+
+               case ICMD_LASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+
+                       var  = &(jd->var[iptr->sx.s23.s3.varindex]);
+
+                       assert(var->flags & INMEMORY);
+                       emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP3);
+                       emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0])
+                                                                 , s1, s2, 3);
+                       emit_mov_membase_reg(cd, REG_SP, var->regoff * 4 + 4, REG_ITMP3);
+                       emit_mov_reg_memindex(cd, REG_ITMP3,
+                                                           OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
+                       break;
+
+               case ICMD_FASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_FTMP1);
+                       emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
+                       break;
+
+               case ICMD_DASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_FTMP1);
+                       emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
+                                                               s1, s2, 3);
+                       break;
+
+               case ICMD_AASTORE:    /* ..., arrayref, index, value  ==> ...         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+
+                       M_AST(s1, REG_SP, 0 * 4);
+                       M_AST(s3, REG_SP, 1 * 4);
+                       M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
+                       M_CALL(REG_ITMP1);
+                       M_TEST(REG_RESULT);
+                       M_BEQ(0);
+                       codegen_add_arraystoreexception_ref(cd);
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+                       emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]),
+                                                                 s1, s2, 2);
+                       break;
+
+               case ICMD_BASTORECONST: /* ..., arrayref, index  ==> ...              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
+                                                                  OFFSET(java_bytearray, data[0]), s1, s2, 0);
+                       break;
+
+               case ICMD_CASTORECONST:   /* ..., arrayref, index  ==> ...            */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
+                                                                  OFFSET(java_chararray, data[0]), s1, s2, 1);
+                       break;
+
+               case ICMD_SASTORECONST:   /* ..., arrayref, index  ==> ...            */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
+                                                                  OFFSET(java_shortarray, data[0]), s1, s2, 1);
+                       break;
+
+               case ICMD_IASTORECONST: /* ..., arrayref, index  ==> ...              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
+                                                                 OFFSET(java_intarray, data[0]), s1, s2, 2);
+                       break;
+
+               case ICMD_LASTORECONST: /* ..., arrayref, index  ==> ...              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_mov_imm_memindex(cd, 
+                                                  (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
+                                                  OFFSET(java_longarray, data[0]), s1, s2, 3);
+                       emit_mov_imm_memindex(cd, 
+                                                       ((s4)iptr->sx.s23.s3.constval) >> 31, 
+                                                       OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
+                       break;
+
+               case ICMD_AASTORECONST: /* ..., arrayref, index  ==> ...              */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       if (INSTRUCTION_MUST_CHECK(iptr)) {
+                               gen_nullptr_check(s1);
+                               gen_bound_check;
+                       }
+                       emit_mov_imm_memindex(cd, 0, 
+                                                                 OFFSET(java_objectarray, data[0]), s1, s2, 2);
+                       break;
+
+
+               case ICMD_GETSTATIC:  /* ...  ==> ..., value                          */
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+
+                               codegen_addpatchref(cd, PATCHER_get_putstatic,
+                                                                       iptr->sx.s23.s3.uf, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+
+                               fieldtype = fi->type;
+
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+                               }
+
+                               disp = (ptrint) &(fi->value);
+                       }
+
+                       M_MOV_IMM(disp, REG_ITMP1);
+                       switch (fieldtype) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                               M_ILD(d, REG_ITMP1, 0);
+                               break;
+                       case TYPE_LNG:
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
+                               M_LLD(d, REG_ITMP1, 0);
+                               break;
+                       case TYPE_FLT:
+                               d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                               M_FLD(d, REG_ITMP1, 0);
+                               break;
+                       case TYPE_DBL:                          
+                               d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                               M_DLD(d, REG_ITMP1, 0);
+                               break;
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_PUTSTATIC:  /* ..., value  ==> ...                          */
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+
+                               codegen_addpatchref(cd, PATCHER_get_putstatic,
+                                                                       iptr->sx.s23.s3.uf, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+                               
+                               fieldtype = fi->type;
+
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+                               }
+
+                               disp = (ptrint) &(fi->value);
+                       }
+
+                       M_MOV_IMM(disp, REG_ITMP1);
+                       switch (fieldtype) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP2);
+                               M_IST(s1, REG_ITMP1, 0);
+                               break;
+                       case TYPE_LNG:
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
+                               M_LST(s1, REG_ITMP1, 0);
+                               break;
+                       case TYPE_FLT:
+                               s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                               emit_fstps_membase(cd, REG_ITMP1, 0);
+                               break;
+                       case TYPE_DBL:
+                               s1 = emit_load_s1(jd, iptr, REG_FTMP1);
+                               emit_fstpl_membase(cd, REG_ITMP1, 0);
+                               break;
+                       }
+                       break;
+
+               case ICMD_PUTSTATICCONST: /* ...  ==> ...                             */
+                                         /* val = value (in current instruction)     */
+                                         /* following NOP)                           */
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+
+                               codegen_addpatchref(cd, PATCHER_get_putstatic,
+                                                                       uf, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+
+                               fieldtype = fi->type;
+
+                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                                       codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+                               }
+
+                               disp = (ptrint) &(fi->value);
+                       }
+
+                       M_MOV_IMM(disp, REG_ITMP1);
+                       switch (fieldtype) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
+                               break;
+                       case TYPE_LNG:
+                               M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
+                               M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
+                               break;
+                       default:
+                               assert(0);
+                       }
+                       break;
+
+               case ICMD_GETFIELD:   /* .., objectref.  ==> ..., value               */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       gen_nullptr_check(s1);
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+
+                               codegen_addpatchref(cd, PATCHER_getfield,
+                                                                       iptr->sx.s23.s3.uf, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+                               
+                               fieldtype = fi->type;
+                               disp = fi->offset;
+                       }
+
+                       switch (fieldtype) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                               M_ILD32(d, s1, disp);
+                               break;
+                       case TYPE_LNG:
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
+                               M_LLD32(d, s1, disp);
+                               break;
+                       case TYPE_FLT:
+                               d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                               M_FLD32(d, s1, disp);
+                               break;
+                       case TYPE_DBL:                          
+                               d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+                               M_DLD32(d, s1, disp);
+                               break;
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_PUTFIELD:   /* ..., objectref, value  ==> ...               */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       gen_nullptr_check(s1);
+
+                       /* must be done here because of code patching */
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+                       }
+                       else {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+
+                               fieldtype = fi->type;
+                       }
+
+                       if (!IS_FLT_DBL_TYPE(fieldtype)) {
+                               if (IS_2_WORD_TYPE(fieldtype))
+                                       s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
+                               else
+                                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       }
+                       else
+                               s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+
+                               disp = fi->offset;
+                       }
+
+                       switch (fieldtype) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               M_IST32(s2, s1, disp);
+                               break;
+                       case TYPE_LNG:
+                               M_LST32(s2, s1, disp);
+                               break;
+                       case TYPE_FLT:
+                               emit_fstps_membase32(cd, s1, disp);
+                               break;
+                       case TYPE_DBL:
+                               emit_fstpl_membase32(cd, s1, disp);
+                               break;
+                       }
+                       break;
+
+               case ICMD_PUTFIELDCONST:  /* ..., objectref  ==> ...                  */
+                                         /* val = value (in current instruction)     */
+                                         /* following NOP)                           */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       gen_nullptr_check(s1);
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               unresolved_field *uf = iptr->sx.s23.s3.uf;
+
+                               fieldtype = uf->fieldref->parseddesc.fd->type;
+
+                               codegen_addpatchref(cd, PATCHER_putfieldconst,
+                                                                       uf, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else
+                       {
+                               fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
+
+                               fieldtype = fi->type;
+                               disp = fi->offset;
+                       }
+
+
+                       switch (fieldtype) {
+                       case TYPE_INT:
+                       case TYPE_ADR:
+                               M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
+                               break;
+                       case TYPE_LNG:
+                               M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
+                               M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
+                               break;
+                       default:
+                               assert(0);
+                       }
+                       break;
+
+
+               /* branch operations **************************************************/
+
+               case ICMD_ATHROW:       /* ..., objectref ==> ... (, objectref)       */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_INTMOVE(s1, REG_ITMP1_XPTR);
+
+#ifdef ENABLE_VERIFIER
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
+                                                                       iptr->sx.s23.s2.uc, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+                       }
+#endif /* ENABLE_VERIFIER */
+
+                       M_CALL_IMM(0);                            /* passing exception pc */
+                       M_POP(REG_ITMP2_XPC);
+
+                       M_MOV_IMM(asm_handle_exception, REG_ITMP3);
+                       M_JMP(REG_ITMP3);
+                       break;
+
+               case ICMD_INLINE_GOTO:
+#if 0
+                       M_COPY(src, iptr->dst.var);
+#endif
+                       /* FALLTHROUGH! */
+
+               case ICMD_GOTO:         /* ... ==> ...                                */
+
+#if defined(ENABLE_SSA)
+                       if ( ls != NULL ) {
+                               last_cmd_was_goto = true;
+                               /* In case of a Goto phimoves have to be inserted before the */
+                               /* jump */
+                               codegen_insert_phi_moves(cd, rd, ls, bptr);
+                       }
+#endif
+                       M_JMP_IMM(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       ALIGNCODENOP;
+                       break;
+
+               case ICMD_JSR:          /* ... ==> ...                                */
+
+                       M_CALL_IMM(0);
+                       codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
+                       break;
+                       
+               case ICMD_RET:          /* ... ==> ...                                */
+                                       /* s1.localindex = local variable                       */
+
+                       var = &(jd->var[iptr->s1.varindex]);
+                       if (var->flags & INMEMORY) {
+                               M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
+                               M_JMP(REG_ITMP1);
+                       }
+                       else
+                               M_JMP(var->regoff);
+                       break;
+
+               case ICMD_IFNULL:       /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_TEST(s1);
+                       M_BEQ(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFNONNULL:    /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_TEST(s1);
+                       M_BNE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFEQ:         /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_CMP_IMM(iptr->sx.val.i, s1);
+                       M_BEQ(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFLT:         /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_CMP_IMM(iptr->sx.val.i, s1);
+                       M_BLT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFLE:         /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_CMP_IMM(iptr->sx.val.i, s1);
+                       M_BLE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFNE:         /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_CMP_IMM(iptr->sx.val.i, s1);
+                       M_BNE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFGT:         /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_CMP_IMM(iptr->sx.val.i, s1);
+                       M_BGT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IFGE:         /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       M_CMP_IMM(iptr->sx.val.i, s1);
+                       M_BGE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       if (iptr->sx.val.l == 0) {
+                               M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
+                               M_OR(GET_HIGH_REG(s1), REG_ITMP1);
+                       }
+                       else {
+                               M_LNGMOVE(s1, REG_ITMP12_PACKED);
+                               M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
+                               M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
+                               M_OR(REG_ITMP2, REG_ITMP1);
+                       }
+                       M_BEQ(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LLT:       /* ..., value ==> ...                         */
+
+                       if (iptr->sx.val.l == 0) {
+                               /* If high 32-bit are less than zero, then the 64-bits
+                                  are too. */
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                               M_CMP_IMM(0, s1);
+                               M_BLT(0);
+                       }
+                       else {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
+                               M_BLT(0);
+                               codegen_addreference(cd, iptr->dst.block);
+                               M_BGT(6 + 6);
+                               M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
+                               M_BB(0);
+                       }                       
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LLE:       /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
+                       M_BLT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       M_BGT(6 + 6);
+                       M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
+                       M_BBE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LNE:       /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       if (iptr->sx.val.l == 0) {
+                               M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
+                               M_OR(GET_HIGH_REG(s1), REG_ITMP1);
+                       }
+                       else {
+                               M_LNGMOVE(s1, REG_ITMP12_PACKED);
+                               M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
+                               M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
+                               M_OR(REG_ITMP2, REG_ITMP1);
+                       }
+                       M_BNE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LGT:       /* ..., value ==> ...                         */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
+                       M_BGT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       M_BLT(6 + 6);
+                       M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
+                       M_BA(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LGE:       /* ..., value ==> ...                         */
+
+                       if (iptr->sx.val.l == 0) {
+                               /* If high 32-bit are greater equal zero, then the
+                                  64-bits are too. */
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                               M_CMP_IMM(0, s1);
+                               M_BGE(0);
+                       }
+                       else {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
+                               M_BGT(0);
+                               codegen_addreference(cd, iptr->dst.block);
+                               M_BLT(6 + 6);
+                               M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
+                               M_BAE(0);
+                       }
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BEQ(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_INTMOVE(s1, REG_ITMP1);
+                       M_XOR(s2, REG_ITMP1);
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       M_INTMOVE(s1, REG_ITMP2);
+                       M_XOR(s2, REG_ITMP2);
+                       M_OR(REG_ITMP1, REG_ITMP2);
+                       M_BEQ(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
+               case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BNE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_INTMOVE(s1, REG_ITMP1);
+                       M_XOR(s2, REG_ITMP1);
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       M_INTMOVE(s1, REG_ITMP2);
+                       M_XOR(s2, REG_ITMP2);
+                       M_OR(REG_ITMP1, REG_ITMP2);
+                       M_BNE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BLT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BLT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BGT(2 + 6);
+                       M_CMP(s2, s1);
+                       M_BB(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BGT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BGT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BLT(2 + 6);
+                       M_CMP(s2, s1);
+                       M_BA(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BLE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BLT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BGT(2 + 6);
+                       M_CMP(s2, s1);
+                       M_BBE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BGE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+               case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMP(s2, s1);
+                       M_BGT(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BLT(2 + 6);
+                       M_CMP(s2, s1);
+                       M_BAE(0);
+                       codegen_addreference(cd, iptr->dst.block);
+                       break;
+
+
+               case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
+
+                       s1 = emit_load_s1(jd, iptr, REG_RESULT);
+                       M_INTMOVE(s1, REG_RESULT);
+                       goto nowperformreturn;
+
+               case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
+
+                       s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
+                       M_LNGMOVE(s1, REG_RESULT_PACKED);
+                       goto nowperformreturn;
+
+               case ICMD_ARETURN:      /* ..., retvalue ==> ...                      */
+
+                       s1 = emit_load_s1(jd, iptr, REG_RESULT);
+                       M_INTMOVE(s1, REG_RESULT);
+
+#ifdef ENABLE_VERIFIER
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               codegen_addpatchref(cd, PATCHER_athrow_areturn,
+                                                                       iptr->sx.s23.s2.uc, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+                       }
+#endif /* ENABLE_VERIFIER */
+                       goto nowperformreturn;
+
+               case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
+               case ICMD_DRETURN:
+
+                       s1 = emit_load_s1(jd, iptr, REG_FRESULT);
+                       goto nowperformreturn;
+
+               case ICMD_RETURN:      /* ...  ==> ...                                */
+
+nowperformreturn:
+                       {
+                       s4 i, p;
+                       
+                       p = cd->stackframesize;
+                       
+#if !defined(NDEBUG)
+                       if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
+                               emit_verbosecall_exit(jd);
+#endif
+
+#if defined(ENABLE_THREADS)
+                       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+                               M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
+
+                               /* we need to save the proper return value */
+                               switch (iptr->opc) {
+                               case ICMD_IRETURN:
+                               case ICMD_ARETURN:
+                                       M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
+                                       break;
+
+                               case ICMD_LRETURN:
+                                       M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
+                                       break;
+
+                               case ICMD_FRETURN:
+                                       emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
+                                       break;
+
+                               case ICMD_DRETURN:
+                                       emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
+                                       break;
+                               }
+
+                               M_AST(REG_ITMP2, REG_SP, 0);
+                               M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
+                               M_CALL(REG_ITMP3);
+
+                               /* and now restore the proper return value */
+                               switch (iptr->opc) {
+                               case ICMD_IRETURN:
+                               case ICMD_ARETURN:
+                                       M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
+                                       break;
+
+                               case ICMD_LRETURN:
+                                       M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
+                                       break;
+
+                               case ICMD_FRETURN:
+                                       emit_flds_membase(cd, REG_SP, rd->memuse * 4);
+                                       break;
+
+                               case ICMD_DRETURN:
+                                       emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
+                                       break;
+                               }
+                       }
+#endif
+
+                       /* restore saved registers */
+
+                       for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
+                               p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
+                       }
+
+                       for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
+                               p--;
+                               emit_fldl_membase(cd, REG_SP, p * 4);
+                               if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
+                                       assert(0);
+/*                                     emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
+                               } else {
+                                       assert(0);
+/*                                     emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
+                               }
+                       }
+
+                       /* deallocate stack */
+
+                       if (cd->stackframesize)
+                               M_AADD_IMM(cd->stackframesize * 4, REG_SP);
+
+                       emit_ret(cd);
+                       }
+                       break;
+
+
+               case ICMD_TABLESWITCH:  /* ..., index ==> ...                         */
+                       {
+                               s4 i, l;
+                               branch_target_t *table;
+
+                               table = iptr->dst.table;
+
+                               l = iptr->sx.s23.s2.tablelow;
+                               i = iptr->sx.s23.s3.tablehigh;
+
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                               M_INTMOVE(s1, REG_ITMP1);
+
+                               if (l != 0)
+                                       M_ISUB_IMM(l, REG_ITMP1);
+
+                               i = i - l + 1;
+
+                /* range check */
+                               M_CMP_IMM(i - 1, REG_ITMP1);
+                               M_BA(0);
+
+                               codegen_addreference(cd, table[0].block); /* default target */
+
+                               /* build jump table top down and use address of lowest entry */
+
+                               table += i;
+
+                               while (--i >= 0) {
+                                       dseg_addtarget(cd, table->block); 
+                                       --table;
+                               }
+
+                               /* length of dataseg after last dseg_addtarget is used
+                                  by load */
+
+                               M_MOV_IMM(0, REG_ITMP2);
+                               dseg_adddata(cd);
+                               emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
+                               M_JMP(REG_ITMP1);
+                       }
+                       break;
+
+
+               case ICMD_LOOKUPSWITCH: /* ..., key ==> ...                           */
+                       {
+                               s4 i;
+                               lookup_target_t *lookup;
+
+                               lookup = iptr->dst.lookup;
+
+                               i = iptr->sx.s23.s2.lookupcount;
+                       
+                               MCODECHECK((i<<2)+8);
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+
+                               while (--i >= 0) {
+                                       M_CMP_IMM(lookup->value, s1);
+                                       M_BEQ(0);
+                                       codegen_addreference(cd, lookup->target.block);
+                                       lookup++;
+                               }
+
+                               M_JMP_IMM(0);
+                       
+                               codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
+                       }
+                       break;
+
+               case ICMD_BUILTIN:      /* ..., [arg1, [arg2 ...]] ==> ...            */
+
+                       bte = iptr->sx.s23.s3.bte;
+                       md = bte->md;
+                       goto gen_method;
+
+               case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ...            */
+
+               case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
+               case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer    */
+               case ICMD_INVOKEINTERFACE:
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
+                               lm = NULL;
+                       }
+                       else {
+                               lm = iptr->sx.s23.s3.fmiref->p.method;
+                               md = lm->parseddesc;
+                       }
+
+gen_method:
+                       s3 = md->paramcount;
+
+                       MCODECHECK((s3 << 1) + 64);
+
+                       /* copy arguments to registers or stack location                  */
+
+                       for (s3 = s3 - 1; s3 >= 0; s3--) {
+                               s1 = iptr->sx.s23.s2.args[s3];
+                               var1 = &(jd->var[s1]);
+         
+                               /* Already Preallocated (ARGVAR) ? */
+                               if (var1->flags & PREALLOC)
+                                       continue;
+                               if (IS_INT_LNG_TYPE(var1->type)) {
+                                       if (!md->params[s3].inmemory) {
+                                               log_text("No integer argument registers available!");
+                                               assert(0);
+
+                                       } else {
+                                               if (IS_2_WORD_TYPE(var1->type)) {
+                                                       d = emit_load(jd, iptr, var1, REG_ITMP12_PACKED);
+                                                       M_LST(d, REG_SP, md->params[s3].regoff * 4);
+                                               } else {
+                                                       d = emit_load(jd, iptr, var1, REG_ITMP1);
+                                                       M_IST(d, REG_SP, md->params[s3].regoff * 4);
+                                               }
+                                       }
+
+                               } else {
+                                       if (!md->params[s3].inmemory) {
+                                               s1 = rd->argfltregs[md->params[s3].regoff];
+                                               d = emit_load(jd, iptr, var1, s1);
+                                               M_FLTMOVE(d, s1);
+
+                                       } else {
+                                               d = emit_load(jd, iptr, var1, REG_FTMP1);
+                                               if (IS_2_WORD_TYPE(var1->type))
+                                                       M_DST(d, REG_SP, md->params[s3].regoff * 4);
+                                               else
+                                                       M_FST(d, REG_SP, md->params[s3].regoff * 4);
+                                       }
+                               }
+                       } /* end of for */
+
+                       switch (iptr->opc) {
+                       case ICMD_BUILTIN:
+                               disp = (ptrint) bte->fp;
+                               d = md->returntype.type;
+
+                               M_MOV_IMM(disp, REG_ITMP1);
+                               M_CALL(REG_ITMP1);
+
+
+                               if (INSTRUCTION_MUST_CHECK(iptr)) {
+                                       M_TEST(REG_RESULT);
+                                       M_BEQ(0);
+                                       codegen_add_fillinstacktrace_ref(cd);
+                               }
+                               break;
+
+                       case ICMD_INVOKESPECIAL:
+                               M_ALD(REG_ITMP1, REG_SP, 0);
+                               M_TEST(REG_ITMP1);
+                               M_BEQ(0);
+                               codegen_add_nullpointerexception_ref(cd);
+
+                               /* fall through */
+
+                       case ICMD_INVOKESTATIC:
+                               if (lm == NULL) {
+                                       unresolved_method *um = iptr->sx.s23.s3.um;
+
+                                       codegen_addpatchref(cd, PATCHER_invokestatic_special,
+                                                                               um, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+
+                                       disp = 0;
+                                       d = md->returntype.type;
+                               }
+                               else {
+                                       disp = (ptrint) lm->stubroutine;
+                                       d = lm->parseddesc->returntype.type;
+                               }
+
+                               M_MOV_IMM(disp, REG_ITMP2);
+                               M_CALL(REG_ITMP2);
+                               break;
+
+                       case ICMD_INVOKEVIRTUAL:
+                               M_ALD(REG_ITMP1, REG_SP, 0 * 4);
+                               gen_nullptr_check(REG_ITMP1);
+
+                               if (lm == NULL) {
+                                       unresolved_method *um = iptr->sx.s23.s3.um;
+
+                                       codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+
+                                       s1 = 0;
+                                       d = md->returntype.type;
+                               }
+                               else {
+                                       s1 = OFFSET(vftbl_t, table[0]) +
+                                               sizeof(methodptr) * lm->vftblindex;
+                                       d = md->returntype.type;
+                               }
+
+                               M_ALD(REG_METHODPTR, REG_ITMP1,
+                                         OFFSET(java_objectheader, vftbl));
+                               M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
+                               M_CALL(REG_ITMP3);
+                               break;
+
+                       case ICMD_INVOKEINTERFACE:
+                               M_ALD(REG_ITMP1, REG_SP, 0 * 4);
+                               gen_nullptr_check(REG_ITMP1);
+
+                               if (lm == NULL) {
+                                       unresolved_method *um = iptr->sx.s23.s3.um;
+
+                                       codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+
+                                       s1 = 0;
+                                       s2 = 0;
+                                       d = md->returntype.type;
+                               }
+                               else {
+                                       s1 = OFFSET(vftbl_t, interfacetable[0]) -
+                                               sizeof(methodptr) * lm->class->index;
+
+                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+
+                                       d = md->returntype.type;
+                               }
+
+                               M_ALD(REG_METHODPTR, REG_ITMP1,
+                                         OFFSET(java_objectheader, vftbl));
+                               M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
+                               M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
+                               M_CALL(REG_ITMP3);
+                               break;
+                       }
+
+                       /* d contains return type */
+
+                       if (d != TYPE_VOID) {
+#if defined(ENABLE_SSA)
+                               if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
+                                       (ls->lifetime[-iptr->dst->varnum-1].type != -1)) 
+                                       /* a "living" stackslot */
+#endif
+                               {
+                                       if (IS_INT_LNG_TYPE(d)) {
+                                               if (IS_2_WORD_TYPE(d)) {
+                                                       s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                                                       M_LNGMOVE(REG_RESULT_PACKED, s1);
+                                               }
+                                               else {
+                                                       s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+                                                       M_INTMOVE(REG_RESULT, s1);
+                                               }
+                                       }
+                                       else {
+                                               s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
+                                       }
+                                       emit_store_dst(jd, iptr, s1);
+                               }
+                       }
+                       break;
+
+
+               case ICMD_CHECKCAST:  /* ..., objectref ==> ..., objectref            */
+                                     /* val.a: (classinfo*) superclass               */
+
+                       /*  superclass is an interface:
+                        *
+                        *  OK if ((sub == NULL) ||
+                        *         (sub->vftbl->interfacetablelength > super->index) &&
+                        *         (sub->vftbl->interfacetable[-super->index] != NULL));
+                        *
+                        *  superclass is a class:
+                        *
+                        *  OK if ((sub == NULL) || (0
+                        *         <= (sub->vftbl->baseval - super->vftbl->baseval) <=
+                        *         super->vftbl->diffval));
+                        */
+
+                       if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
+                               /* object type cast-check */
+
+                               classinfo *super;
+                               vftbl_t   *supervftbl;
+                               s4         superindex;
+
+                               if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                       super = NULL;
+                                       superindex = 0;
+                                       supervftbl = NULL;
+                               }
+                               else {
+                                       super = iptr->sx.s23.s3.c.cls;
+                                       superindex = super->index;
+                                       supervftbl = super->vftbl;
+                               }
+                       
+#if defined(ENABLE_THREADS)
+                               codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
+#endif
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+
+                               /* calculate interface checkcast code size */
+
+                               s2 = 2; /* mov_membase_reg */
+                               CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
+
+                               s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
+                                          2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
+                                          2 /* test */ + 6 /* jcc */);
+
+                               if (!super)
+                                       s2 += (opt_showdisassemble ? 5 : 0);
+
+                               /* calculate class checkcast code size */
+
+                               s3 = 2; /* mov_membase_reg */
+                               CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
+
+                               s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
+
+#if 0
+                               if (s1 != REG_ITMP1) {
+                                       a += 2;
+                                       CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
+                               
+                                       a += 2;
+                                       CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
+                               
+                                       a += 2;
+                               
+                               } else
+#endif
+                                       {
+                                               s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
+                                                          5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
+                                               CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
+                                       }
+
+                               s3 += 2 /* cmp */ + 6 /* jcc */;
+
+                               if (super == NULL)
+                                       s3 += (opt_showdisassemble ? 5 : 0);
+
+                               /* if class is not resolved, check which code to call */
+
+                               if (super == NULL) {
+                                       M_TEST(s1);
+                                       M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
+
+                                       codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
+                                                                               iptr->sx.s23.s3.c.ref, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+
+                                       M_MOV_IMM(0, REG_ITMP2);                  /* super->flags */
+                                       M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
+                                       M_BEQ(s2 + 5);
+                               }
+
+                               /* interface checkcast code */
+
+                               if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
+                                       if (super != NULL) {
+                                               M_TEST(s1);
+                                               M_BEQ(s2);
+                                       }
+
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+
+                                       if (super == NULL) {
+                                               codegen_addpatchref(cd,
+                                                                                       PATCHER_checkcast_instanceof_interface,
+                                                                                       iptr->sx.s23.s3.c.ref,
+                                                                                       0);
+
+                                               if (opt_showdisassemble) {
+                                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                               }
+                                       }
+
+                                       M_ILD32(REG_ITMP3,
+                                                       REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
+                                       M_ISUB_IMM32(superindex, REG_ITMP3);
+                                       M_TEST(REG_ITMP3);
+                                       M_BLE(0);
+                                       codegen_add_classcastexception_ref(cd, s1);
+                                       M_ALD32(REG_ITMP3, REG_ITMP2,
+                                                       OFFSET(vftbl_t, interfacetable[0]) -
+                                                       superindex * sizeof(methodptr*));
+                                       M_TEST(REG_ITMP3);
+                                       M_BEQ(0);
+                                       codegen_add_classcastexception_ref(cd, s1);
+
+                                       if (super == NULL)
+                                               M_JMP_IMM(s3);
+                               }
+
+                               /* class checkcast code */
+
+                               if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
+                                       if (super != NULL) {
+                                               M_TEST(s1);
+                                               M_BEQ(s3);
+                                       }
+
+                                       M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
+
+                                       if (super == NULL) {
+                                               codegen_addpatchref(cd, PATCHER_checkcast_class,
+                                                                                       iptr->sx.s23.s3.c.ref,
+                                                                                       0);
+
+                                               if (opt_showdisassemble) {
+                                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                               }
+                                       }
+
+                                       M_MOV_IMM(supervftbl, REG_ITMP3);
+#if defined(ENABLE_THREADS)
+                                       codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
+#endif
+                                       M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
+
+                                       /*                              if (s1 != REG_ITMP1) { */
+                                       /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
+                                       /*                                      emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
+                                       /* #if defined(ENABLE_THREADS) */
+                                       /*                                      codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
+                                       /* #endif */
+                                       /*                                      emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
+
+                                       /*                              } else { */
+                                       M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
+                                       M_ISUB(REG_ITMP3, REG_ITMP2);
+                                       M_MOV_IMM(supervftbl, REG_ITMP3);
+                                       M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
+#if defined(ENABLE_THREADS)
+                                       codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
+#endif
+                                       /*                              } */
+
+                                       M_CMP(REG_ITMP3, REG_ITMP2);
+                                       M_BA(0);         /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
+                                       codegen_add_classcastexception_ref(cd, s1);
+                               }
+
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
+                       }
+                       else {
+                               /* array type cast-check */
+
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP2);
+                               M_AST(s1, REG_SP, 0 * 4);
+
+                               if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                                       codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
+                                                                               iptr->sx.s23.s3.c.ref, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+                               }
+
+                               M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
+                               M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
+                               M_CALL(REG_ITMP3);
+
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP2);
+                               M_TEST(REG_RESULT);
+                               M_BEQ(0);
+                               codegen_add_classcastexception_ref(cd, s1);
+
+                               d = codegen_reg_of_dst(jd, iptr, s1);
+                       }
+
+                       M_INTMOVE(s1, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+               case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult            */
+                                     /* val.a: (classinfo*) superclass               */
+
+                       /*  superclass is an interface:
+                        *
+                        *  return (sub != NULL) &&
+                        *         (sub->vftbl->interfacetablelength > super->index) &&
+                        *         (sub->vftbl->interfacetable[-super->index] != NULL);
+                        *
+                        *  superclass is a class:
+                        *
+                        *  return ((sub != NULL) && (0
+                        *          <= (sub->vftbl->baseval - super->vftbl->baseval) <=
+                        *          super->vftbl->diffvall));
+                        */
+
+                       {
+                       classinfo *super;
+                       vftbl_t   *supervftbl;
+                       s4         superindex;
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               super = NULL;
+                               superindex = 0;
+                               supervftbl = NULL;
+
+                       } else {
+                               super = iptr->sx.s23.s3.c.cls;
+                               superindex = super->index;
+                               supervftbl = super->vftbl;
+                       }
+                       
+#if defined(ENABLE_THREADS)
+                       codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
+#endif
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       if (s1 == d) {
+                               M_INTMOVE(s1, REG_ITMP1);
+                               s1 = REG_ITMP1;
+                       }
+
+                       /* calculate interface instanceof code size */
+
+                       s2 = 2; /* mov_membase_reg */
+                       CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
+
+                       s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
+                                  2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
+                                  2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
+
+                       if (!super)
+                               s2 += (opt_showdisassemble ? 5 : 0);
+
+                       /* calculate class instanceof code size */
+
+                       s3 = 2; /* mov_membase_reg */
+                       CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
+                       s3 += 5; /* mov_imm_reg */
+                       s3 += 2;
+                       CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
+                       s3 += 2;
+                       CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
+                       s3 += 2;
+                       CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
+
+                       s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
+                                  2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
+
+                       if (!super)
+                               s3 += (opt_showdisassemble ? 5 : 0);
+
+                       M_CLR(d);
+
+                       /* if class is not resolved, check which code to call */
+
+                       if (!super) {
+                               M_TEST(s1);
+                               M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
+
+                               codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
+                                                                       iptr->sx.s23.s3.c.ref, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               M_MOV_IMM(0, REG_ITMP3);                      /* super->flags */
+                               M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
+                               M_BEQ(s2 + 5);
+                       }
+
+                       /* interface instanceof code */
+
+                       if (!super || (super->flags & ACC_INTERFACE)) {
+                               if (super) {
+                                       M_TEST(s1);
+                                       M_BEQ(s2);
+                               }
+
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+
+                               if (!super) {
+                                       codegen_addpatchref(cd,
+                                                                               PATCHER_checkcast_instanceof_interface,
+                                                                               iptr->sx.s23.s3.c.ref, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+                               }
+
+                               M_ILD32(REG_ITMP3,
+                                               REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
+                               M_ISUB_IMM32(superindex, REG_ITMP3);
+                               M_TEST(REG_ITMP3);
+
+                               disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
+                                               6 /* jcc */ + 5 /* mov_imm_reg */);
+
+                               M_BLE(disp);
+                               M_ALD32(REG_ITMP1, REG_ITMP1,
+                                               OFFSET(vftbl_t, interfacetable[0]) -
+                                               superindex * sizeof(methodptr*));
+                               M_TEST(REG_ITMP1);
+/*                                     emit_setcc_reg(cd, CC_A, d); */
+/*                                     emit_jcc(cd, CC_BE, 5); */
+                               M_BEQ(5);
+                               M_MOV_IMM(1, d);
+
+                               if (!super)
+                                       M_JMP_IMM(s3);
+                       }
+
+                       /* class instanceof code */
+
+                       if (!super || !(super->flags & ACC_INTERFACE)) {
+                               if (super) {
+                                       M_TEST(s1);
+                                       M_BEQ(s3);
+                               }
+
+                               M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
+
+                               if (!super) {
+                                       codegen_addpatchref(cd, PATCHER_instanceof_class,
+                                                                               iptr->sx.s23.s3.c.ref, 0);
+
+                                       if (opt_showdisassemble) {
+                                               M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                                       }
+                               }
+
+                               M_MOV_IMM(supervftbl, REG_ITMP2);
+#if defined(ENABLE_THREADS)
+                               codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
+#endif
+                               M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
+                               M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
+                               M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
+#if defined(ENABLE_THREADS)
+                               codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
+#endif
+                               M_ISUB(REG_ITMP2, REG_ITMP1);
+                               M_CLR(d);                                 /* may be REG_ITMP2 */
+                               M_CMP(REG_ITMP3, REG_ITMP1);
+                               M_BA(5);
+                               M_MOV_IMM(1, d);
+                       }
+                       emit_store_dst(jd, iptr, d);
+                       }
+                       break;
+
+                       break;
+
+               case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref  */
+
+                       /* check for negative sizes and copy sizes to stack if necessary  */
+
+                       MCODECHECK((iptr->s1.argcount << 1) + 64);
+
+                       for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
+                               /* copy SAVEDVAR sizes to stack */
+                               s3 = iptr->sx.s23.s2.args[s1];
+                               var1 = &(jd->var[s3]);
+
+                               /* Already Preallocated (ARGVAR) ? */
+                               if (!(var1->flags & PREALLOC)) {
+                                       if (var1->flags & INMEMORY) {
+                                               M_ILD(REG_ITMP1, REG_SP, var1->regoff * 4);
+                                               M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
+                                       }
+                                       else
+                                               M_IST(var1->regoff, REG_SP, (s1 + 3) * 4);
+                               }
+                       }
+
+                       /* is a patcher function set? */
+
+                       if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                               codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
+                                                                       iptr->sx.s23.s3.c.ref, 0);
+
+                               if (opt_showdisassemble) {
+                                       M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
+                               }
+
+                               disp = 0;
+
+                       }
+                       else
+                               disp = (ptrint) iptr->sx.s23.s3.c.cls;
+
+                       /* a0 = dimension count */
+
+                       M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
+
+                       /* a1 = arraydescriptor */
+
+                       M_IST_IMM(disp, REG_SP, 1 * 4);
+
+                       /* a2 = pointer to dimensions = stack pointer */
+
+                       M_MOV(REG_SP, REG_ITMP1);
+                       M_AADD_IMM(3 * 4, REG_ITMP1);
+                       M_AST(REG_ITMP1, REG_SP, 2 * 4);
+
+                       M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
+                       M_CALL(REG_ITMP1);
+
+                       /* check for exception before result assignment */
+
+                       M_TEST(REG_RESULT);
+                       M_BEQ(0);
+                       codegen_add_fillinstacktrace_ref(cd);
+
+                       s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+                       M_INTMOVE(REG_RESULT, s1);
+                       emit_store_dst(jd, iptr, s1);
+                       break;
+
+               default:
+                       *exceptionptr =
+                               new_internalerror("Unknown ICMD %d", iptr->opc);
+                       return false;
+       } /* switch */
+               
+       } /* for instruction */
+               
+       /* copy values to interface registers */
+
+       len = bptr->outdepth;
+       MCODECHECK(64+len);
+#if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
+       if (!opt_lsra)
+#endif
+#if defined(ENABLE_SSA)
+       if ( ls != NULL ) {
+               /* by edge splitting, in Blocks with phi moves there can only */
+               /* be a goto as last command, no other Jump/Branch Command    */
+               if (!last_cmd_was_goto)
+                       codegen_insert_phi_moves(cd, rd, ls, bptr);
+       }
+
+#endif
+
+       /* At the end of a basic block we may have to append some nops,
+          because the patcher stub calling code might be longer than the
+          actual instruction. So codepatching does not change the
+          following block unintentionally. */
+
+       if (cd->mcodeptr < cd->lastmcodeptr) {
+               while (cd->mcodeptr < cd->lastmcodeptr) {
+                       M_NOP;
+               }
+       }
+
+       } /* if (bptr -> flags >= BBREACHED) */
+       } /* for basic block */
+
+       dseg_createlinenumbertable(cd);
+
+
+       /* generate exception and patcher stubs */
+
+       emit_exception_stubs(jd);
+       emit_patcher_stubs(jd);
+#if 0
+       emit_replacement_stubs(jd);
+#endif
+
+       codegen_finish(jd);
+
+       /* everything's ok */
+
+       return true;
+}
+#else
 bool codegen(jitdata *jd)
 {
        methodinfo         *m;
@@ -4191,6 +8212,7 @@ gen_method:
 
        return true;
 }
+#endif /* defined(NEW_VAR) */
 
 #if defined(ENABLE_SSA)
 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls, basicblock *bptr) {
index 6515cc9a16f77eb2cbe9dcae47316819b1793923..434e4264eecf977bd1a4f80d3307e0ec43df8ba0 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes:
 
-   $Id: codegen.h 5352 2006-09-05 22:51:48Z christian $
+   $Id: codegen.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
 #define M_COPY(from,to) _M_COPY((from),(to));
 #endif
 
-#define _M_COPY(s,d)                     emit_copy(jd, iptr, (s), (d))
+#define _M_COPY(s,d)    emit_copy(jd, iptr, &(jd->var[(s)]), &(jd->var[(d)]))
 
 #define ICONST(d,c) \
     do { \
index 46feebf6c89eb79c45339cb901023bb077d330e8..fbc38dcb7de51c62cb7410e05a5080293560eb85 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: emit.c 5401 2006-09-07 12:52:31Z twisti $
+   $Id: emit.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -62,7 +62,7 @@
 
 *******************************************************************************/
 
-inline s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+inline s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 {
        codegendata  *cd;
        s4            disp;
@@ -105,7 +105,7 @@ inline s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
 
 *******************************************************************************/
 
-inline s4 emit_load_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+inline s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src,s4 tempreg)
 {
        codegendata  *cd;
        s4            disp;
@@ -140,7 +140,7 @@ inline s4 emit_load_low(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg
 
 *******************************************************************************/
 
-inline s4 emit_load_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+inline s4 emit_load_high(jitdata *jd, instruction *iptr,varinfo *src,s4 tempreg)
 {
        codegendata  *cd;
        s4            disp;
@@ -176,12 +176,12 @@ inline s4 emit_load_high(jitdata *jd, instruction *iptr, stackptr src, s4 tempre
 
 s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
        /* get required compiler data */
 
-       src = iptr->s1.var;
+       src = &(jd->var[iptr->s1.varindex]);
 
        reg = emit_load(jd, iptr, src, tempreg);
    
@@ -197,12 +197,12 @@ s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
 
 s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
        /* get required compiler data */
 
-       src = iptr->sx.s23.s2.var;
+       src = &(jd->var[iptr->sx.s23.s2.varindex]);
 
        reg = emit_load(jd, iptr, src, tempreg);
        
@@ -218,12 +218,12 @@ s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
 
 s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
        /* get required compiler data */
 
-       src = iptr->sx.s23.s3.var;
+       src = &(jd->var[iptr->sx.s23.s3.varindex]);
 
        reg = emit_load(jd, iptr, src, tempreg);
 
@@ -240,13 +240,13 @@ s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
 
 s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
 
        /* get required compiler data */
 
-       src = iptr->s1.var;
+       src = &(jd->var[iptr->s1.varindex]);
 
        reg = emit_load_low(jd, iptr, src, tempreg);
 
@@ -265,12 +265,12 @@ s4 emit_load_s1_low(jitdata *jd, instruction *iptr, s4 tempreg)
 
 s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
        /* get required compiler data */
 
-       src = iptr->sx.s23.s2.var;
+       src = &(jd->var[iptr->sx.s23.s2.varindex]);
 
        reg = emit_load_low(jd, iptr, src, tempreg);
 
@@ -287,12 +287,12 @@ s4 emit_load_s2_low(jitdata *jd, instruction *iptr, s4 tempreg)
 
 s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
        /* get required compiler data */
 
-       src = iptr->s1.var;
+       src = &(jd->var[iptr->s1.varindex]);
 
        reg = emit_load_high(jd, iptr, src, tempreg);
 
@@ -309,12 +309,12 @@ s4 emit_load_s1_high(jitdata *jd, instruction *iptr, s4 tempreg)
 
 s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
 {
-       stackptr      src;
+       varinfo       *src;
        s4            reg;
 
        /* get required compiler data */
 
-       src = iptr->sx.s23.s2.var;
+       src = &(jd->var[iptr->sx.s23.s2.varindex]);
 
        reg = emit_load_high(jd, iptr, src, tempreg);
 
@@ -328,7 +328,7 @@ s4 emit_load_s2_high(jitdata *jd, instruction *iptr, s4 tempreg)
 
 *******************************************************************************/
 
-inline void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -362,7 +362,7 @@ inline void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
 *******************************************************************************/
 
-inline void emit_store_low(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store_low(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -386,7 +386,7 @@ inline void emit_store_low(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
 *******************************************************************************/
 
-inline void emit_store_high(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+inline void emit_store_high(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
 {
        codegendata  *cd;
 
@@ -413,9 +413,9 @@ inline void emit_store_high(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
 
 void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
 {
-       stackptr dst;
+       varinfo *dst;
        
-       dst = iptr->dst.var;
+       dst = &(jd->var[iptr->dst.varindex]);
 
        emit_store(jd, iptr, dst, d);
 }
@@ -427,16 +427,14 @@ void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
 
 *******************************************************************************/
 
-void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
+void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
 {
        codegendata  *cd;
-       registerdata *rd;
        s4            s1, d;
 
        /* get required compiler data */
 
        cd = jd->cd;
-       rd = jd->rd;
 
        if ((src->regoff != dst->regoff) ||
                ((src->flags ^ dst->flags) & INMEMORY)) {
@@ -447,9 +445,9 @@ void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
 
                if (IS_INMEMORY(src->flags)) {
                        if (IS_LNG_TYPE(src->type))
-                               d = codegen_reg_of_var(rd, iptr->opc, dst, REG_ITMP12_PACKED);
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
                        else
-                               d = codegen_reg_of_var(rd, iptr->opc, dst, REG_ITMP1);
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP1);
 
                        s1 = emit_load(jd, iptr, src, d);
                }
@@ -459,7 +457,7 @@ void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
                        else
                                s1 = emit_load(jd, iptr, src, REG_ITMP1);
 
-                       d = codegen_reg_of_var(rd, iptr->opc, dst, s1);
+                       d = codegen_reg_of_var(iptr->opc, dst, s1);
                }
 
                if (s1 != d) {
index 8e07065268f0ba931ae784af757df2a1434e5696..8b4235c39907b828269e194c3994818145c64104 100644 (file)
@@ -31,7 +31,7 @@
             Christian Thalinger
             Christian Ullrich
 
-   $Id: jit.c 5343 2006-09-05 21:20:33Z twisti $
+   $Id: jit.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -1327,8 +1327,10 @@ u1 *jit_compile(methodinfo *m)
 
        jd->flags = JITDATA_FLAG_PARSE;
 
+#if defined(ENABLE_VERIFY)
        if (opt_verify)
                jd->flags |= JITDATA_FLAG_VERIFY;
+#endif
 
        if (opt_prof)
                jd->flags |= JITDATA_FLAG_INSTRUMENT;
@@ -1613,6 +1615,7 @@ static u1 *jit_compile_intern(jitdata *jd)
                DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
 
                /* call typecheck pass */
+#if !defined(NEW_VAR)
                if (!typecheck(jd)) {
                        DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
 
@@ -1620,6 +1623,7 @@ static u1 *jit_compile_intern(jitdata *jd)
                }
 
                DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
+#endif
        }
 #endif
        RT_TIMING_GET_TIME(time_typecheck);
index a8d0277b622a84b96b9f617e45681417e1037076..9418bbca53f94cfc4daf78d95845fd3ef6a27ee1 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Thalinger
                        Edwin Steiner
 
-   $Id: jit.h 5392 2006-09-07 09:40:25Z twisti $
+   $Id: jit.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -38,6 +38,8 @@
 #ifndef _JIT_H
 #define _JIT_H
 
+#define NEW_VAR
+
 /* forward typedefs ***********************************************************/
 
 typedef struct jitdata jitdata;
@@ -117,18 +119,19 @@ struct jitdata {
 
 #if defined(NEW_VAR)
        varinfo *var;
-       int     vartop;
+       s4      vartop;
     
-       int     varcount;
-       int     localcount;
-    int     *local_map; /* internal structure to rename(de-coallesc) locals  */
-                            /* and keep the coalescing info for simplereg.       */
-                            /* local_map[local_index * 5 + local_type] = new_index in */
-                         /* rd->var or LOCAL_UNUSED    */
+       s4      varcount;
+       s4      localcount;
+    s4      *local_map; /* internal structure to rename(de-coallesc) locals  */
+                           /* and keep the coalescing info for simplereg.       */
+                           /* local_map[local_index * 5 + local_type] =         */
+                           /* new_index in rd->var or LOCAL_UNUSED              */
+       s4      *interface_map; /* like local_map for interfaces */
 #endif
 };
 
-#define LOCAL_UNUSED                     -1
+#define UNUSED                     -1
 
 #define JITDATA_FLAG_PARSE               0x00000001
 #define JITDATA_FLAG_VERIFY              0x00000002
@@ -180,6 +183,9 @@ struct jitdata {
                                 /* using the same register/memory location    */
 #define STKEEP    32            /* to prevent reg_mark_copy to free this      */
                                 /* stackslot */
+#define PREALLOC  64            /* preallocated var like for ARGVARS. Used    */
+                                /* with the new var system */
+#define OUTVAR   128            /* STACKVR flag for new var system */
 
 #define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
 #define IS_INMEMORY(x)    ((x) & INMEMORY)
@@ -287,7 +293,7 @@ typedef union {
 /*** dst operand ***/
 
 typedef union {
-#if defined(VAR_NEW)
+#if defined(NEW_VAR)
        s4                         varindex;
 #else
     stackptr                   var;
@@ -297,7 +303,11 @@ typedef union {
     branch_target_t           *table;       /* for TABLESWITCH                */
     lookup_target_t           *lookup;      /* for LOOKUPSWITCH               */
     s4                         insindex;    /* used between parse and stack   */
+#if defined(NEW_VAR)
+       s4                        *dupslots;    /* for SWAP, DUP* except DUP      */
+#else
        stackptr                  *dupslots;    /* for SWAP, DUP* except DUP      */
+#endif
 } dst_operand_t;
 
 /*** flags (32 bits) ***/
@@ -438,9 +448,14 @@ struct basicblock {
        s4            icount;       /* number of intermediate code instructions   */
        s4            mpc;          /* machine code pc at start of block          */
        stackptr      instack;      /* stack at begin of basic block              */
-       stackptr     *invars;       /* array of in-variables at begin of block    */
        stackptr      outstack;     /* stack at end of basic block                */
+#if defined(NEW_VAR)
+       s4           *invars;       /* array of in-variables at begin of block    */
+       s4           *outvars;      /* array of out-variables at end of block     */
+#else
+       stackptr     *invars;       /* array of in-variables at begin of block    */
        stackptr     *outvars;      /* array of out-variables at end of block     */
+#endif
        s4            indepth;      /* stack depth at begin of basic block        */
        s4            outdepth;     /* stack depth end of basic block             */
 
index cf6e800f71e8d56c76373666bb88faa47a82ddb4..d855e2e9c230ba6d40262bb4761d667a2d739f64 100644 (file)
@@ -31,7 +31,7 @@
             Joseph Wenninger
             Christian Thalinger
 
-   $Id: parse.c 5375 2006-09-06 16:01:23Z edwin $
+   $Id: parse.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -389,7 +389,6 @@ fetch_opcode:
                INSTRUCTIONS_CHECK(1);
 
                /* translate this bytecode instruction */
-
                switch (opcode) {
 
                case JAVA_NOP:
@@ -1506,11 +1505,11 @@ invoke_method:
                /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
                /* index,type pairs (localmap[index*5+type]==1) to an unique value */
                /* -> == new local var index */
-               for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
+               for(i = 0; i < (cd->maxlocals * 5); i++, mapptr++) {
                        if (*mapptr)
                                *mapptr = nlocals++;
                        else
-                               *mapptr = LOCAL_UNUSED;
+                               *mapptr = UNUSED;
                }
 
                jd->localcount = nlocals;
@@ -1520,8 +1519,15 @@ invoke_method:
                jd->varcount   = nlocals + s_count + 
                        jd->new_basicblockcount * m->maxstack;        /* out-stacks */
                
-               jd->var_top = nlocals;
+               jd->vartop = nlocals;
                jd->var = DMNEW(varinfo, jd->varcount);
+               m->maxlocals = nlocals;
+               cd->maxlocals = nlocals;
+
+               /* set types of all Locals in jd->var */
+               for(mapptr = local_map, i = 0; i < (cd->maxlocals * 5); i++, mapptr++)
+                       if (*mapptr != UNUSED)
+                               jd->var[*mapptr].type = i%5;
        }
 #endif
 
index 2a461cba42ce5b47e0a5949588f4129824038998..6f247a5a06578b3d70f74f39e5771f005cf91f24 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: parse.h 5375 2006-09-06 16:01:23Z edwin $
+   $Id: parse.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
 
 # define LOCALTYPE_USED(index,type)                                                                       \
        do {                                                                                                                       \
-               local_map[index * 5 +type] = 1;                                                            \
+               local_map[(index) * 5 + (type)] = 1;                                               \
        } while (0)
 #else 
 # define OP_LOCALINDEX(o,index)                                        \
     iptr->s1.localindex      = (index);                                \
     iptr->sx.val.i           = (v);                                    \
     PINC
-
+#error 333
 # define LOCALTYPE_USED(index,type)
 #endif /* defined(NEW_VAR) */
 
index 53898c09189c73f859af8c3536f0e392027c40e6..cb6407d9a80037b4ff3e98c2f33db0f437db4426 100644 (file)
@@ -32,7 +32,7 @@
             Michael Starzinger
             Edwin Steiner
 
-   $Id: reg.c 5231 2006-08-11 10:13:28Z twisti $
+   $Id: reg.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -62,7 +62,9 @@ void reg_setup(jitdata *jd)
        methodinfo   *m;
        registerdata *rd;
        s4            i;
+#if !defined(NEW_VAR)
        varinfo5     *v;
+#endif
 
        /* get required compiler data */
 
@@ -198,6 +200,7 @@ void reg_setup(jitdata *jd)
 #if defined(HAS_4BYTE_STACKSLOT)
        rd->freemem_2  = DMNEW(s4, m->maxstack);
 #endif
+#if !defined(NEW_VAR)
        rd->locals     = DMNEW(varinfo5, m->maxlocals);
        rd->interfaces = DMNEW(varinfo5, m->maxstack);
        for (v = rd->locals, i = m->maxlocals; i > 0; v++, i--) {
@@ -232,6 +235,7 @@ void reg_setup(jitdata *jd)
                v[0][TYPE_DBL].regoff = 0;
                v[0][TYPE_ADR].regoff = 0;
        }
+#endif
 
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
index c0f36cc1eb309340fa2b7783943ccb85ef32a046..4042789f9c646f98cf20ecdfb2dacefd572cba59 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Christian Ullrich
             Edwin Steiner
 
-   $Id: reg.h 4710 2006-03-30 10:23:11Z twisti $
+   $Id: reg.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -63,10 +63,10 @@ typedef struct varinfo varinfo5[5];
 
 
 struct registerdata {
+#if !defined(NEW_VAR)
        varinfo5 *locals;
        varinfo5 *interfaces;
-
-
+#endif
        int intreg_ret;                 /* register to return integer values      */
        int fltreg_ret;                 /* register for return float values       */
 
index de1a99891ba94c98a99633036f03715a2584b02b..060203db71d5ee67c3870b24cefaa52b7ab30105 100644 (file)
@@ -82,6 +82,7 @@
 
 bool replace_create_replacement_points(jitdata *jd)
 {
+#if 0
        codeinfo     *code;
        registerdata *rd;
        basicblock *bptr;
@@ -242,6 +243,7 @@ bool replace_create_replacement_points(jitdata *jd)
        /* everything alright */
 
        return true;
+#endif
 }
 
 /* replace_free_replacement_points *********************************************
index b1549e4e3a65ed6bc19348245de4f1d2451efa39..937bf46132fd47d4f0324ea43fe1d880ff7521a4 100644 (file)
@@ -68,7 +68,7 @@ static java_objectheader *show_global_lock;
 /* forward declarations *******************************************************/
 
 #if !defined(NDEBUG)
-static void new_show_variable_array(jitdata *jd, stackptr *vars, int n, int stage);
+static void new_show_variable_array(jitdata *jd, s4 *vars, int n, int stage);
 #endif
 
 
@@ -185,37 +185,38 @@ void new_show_method(jitdata *jd, int stage)
                printf("   %3d: ", i);
 
 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
-               for (j = TYPE_INT; j <= TYPE_ADR; j++) {
+/*             for (j = TYPE_INT; j <= TYPE_ADR; j++) { */
 # if defined(ENABLE_INTRP)
                        if (!opt_intrp) {
 # endif
-                               if (rd->locals[i][j].type >= 0) {
-                                       printf("   (%s) ", jit_type[j]);
+/*                             if (rd->locals[i][j].type >= 0) { */
+                                       printf("   (%s) ", jit_type[jd->var[i].type]);
                                        if (stage >= SHOW_REGS) {
-                                               if (rd->locals[i][j].flags & INMEMORY)
-                                                       printf("m%2d", rd->locals[i][j].regoff);
+                                               if (jd->var[i].flags & INMEMORY)
+                                                       printf("m%2d", jd->var[i].regoff);
 # ifdef HAS_ADDRESS_REGISTER_FILE
-                                               else if (j == TYPE_ADR)
-                                                       printf("r%02d", rd->locals[i][j].regoff);
+                                               else if (jd->var[i].type == TYPE_ADR)
+                                                       printf("r%02d", jd->var[i].regoff);
 # endif
-                                               else if ((j == TYPE_FLT) || (j == TYPE_DBL))
-                                                       printf("f%02d", rd->locals[i][j].regoff);
+                                               else if ((jd->var[i].type == TYPE_FLT) ||
+                                                                (jd->var[i].type == TYPE_DBL))
+                                                       printf("f%02d", jd->var[i].regoff);
                                                else {
 # if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                        if (IS_2_WORD_TYPE(j))
                                                                printf(" %3s/%3s",
-                                                                          regs[GET_LOW_REG(rd->locals[i][j].regoff)],
-                                                                          regs[GET_HIGH_REG(rd->locals[i][j].regoff)]);
+                                                                          regs[GET_LOW_REG(jd->var[i].regoff)],
+                                                                          regs[GET_HIGH_REG(jd->var[i].regoff)]);
                                                        else
 # endif
-                                                               printf("%3s", regs[rd->locals[i][j].regoff]);
+                                                               printf("%3s", regs[jd->var[i].regoff]);
                                                }
                                        }
-                               }
+/*                             } */
 # if defined(ENABLE_INTRP)
                        }
 # endif
-               }
+/*             } */
 #endif /* defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER) */
 
                printf("\n");
@@ -223,90 +224,36 @@ void new_show_method(jitdata *jd, int stage)
        printf("\n");
        }
 
-       if (stage >= SHOW_STACK && rd) {
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-       if (!opt_lsra) {
-#endif
-#if defined(ENABLE_INTRP)
-               if (!opt_intrp) {
-#endif
-       printf("Interface Table:\n");
-       for (i = 0; i < cd->maxstack; i++) {
-               if ((rd->interfaces[i][0].type >= 0) ||
-                       (rd->interfaces[i][1].type >= 0) ||
-                   (rd->interfaces[i][2].type >= 0) ||
-                       (rd->interfaces[i][3].type >= 0) ||
-                   (rd->interfaces[i][4].type >= 0)) {
-                       printf("   %3d: ", i);
-
-#if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
-# if defined(ENABLE_INTRP)
-                       if (!opt_intrp) {
-# endif
-                               for (j = TYPE_INT; j <= TYPE_ADR; j++) {
-                                       if (rd->interfaces[i][j].type >= 0) {
-                                               printf("   (%s) ", jit_type[j]);
-                                               if (stage >= SHOW_REGS) {
-                                                       if (rd->interfaces[i][j].flags & SAVEDVAR) {
-                                                               if (rd->interfaces[i][j].flags & INMEMORY)
-                                                                       printf("M%2d", rd->interfaces[i][j].regoff);
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                                                               else if (j == TYPE_ADR)
-                                                                       printf("R%02d", rd->interfaces[i][j].regoff);
-#endif
-                                                               else if ((j == TYPE_FLT) || (j == TYPE_DBL))
-                                                                       printf("F%02d", rd->interfaces[i][j].regoff);
-                                                               else {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                       if (IS_2_WORD_TYPE(j))
-                                                                               printf(" %3s/%3s",
-                                                                                          regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
-                                                                                          regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
-                                                                       else
-#endif
-                                                                               printf("%3s",regs[rd->interfaces[i][j].regoff]);
-                                                               }
-                                                       }
-                                                       else {
-                                                               if (rd->interfaces[i][j].flags & INMEMORY)
-                                                                       printf("m%2d", rd->interfaces[i][j].regoff);
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                                                               else if (j == TYPE_ADR)
-                                                                       printf("r%02d", rd->interfaces[i][j].regoff);
-#endif
-                                                               else if ((j == TYPE_FLT) || (j == TYPE_DBL))
-                                                                       printf("f%02d", rd->interfaces[i][j].regoff);
-                                                               else {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                                       if (IS_2_WORD_TYPE(j))
-                                                                               printf(" %3s/%3s",
-                                                                                          regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
-                                                                                          regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
-                                                                       else
-#endif
-                                                                               printf("%3s",regs[rd->interfaces[i][j].regoff]);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                               printf("\n");
-# if defined(ENABLE_INTRP)
-                       }
-# endif
-#endif /* defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER) */
-
+       if (cd->maxlocals > 0) {
+               for (i = 0; i < 5; i++) {
+                       printf("%5s ",jit_type[i]);
+                       for (j = 0; j < cd->maxlocals; j++)
+                               printf("%3i ",jd->local_map[j*5+i]);
+                       printf("\n");
                }
+               printf("\n");
        }
-       printf("\n");
 
-#if defined(ENABLE_INTRP)
+       printf("Interface Table:(In/Outvars)\n");
+       if (cd->maxstack > 0) {
+               bool exist = false;
+               s4 *mapptr = jd->interface_map;
+               
+               /* look if there exist IN/OUTVARS */
+               if (mapptr != NULL) {
+                       for (i = 0; (i < (5 * cd->maxstack)) && !exist; i++, mapptr++)
+                               exist = (*mapptr != UNUSED);
+               
+                       if (exist)
+                               for (i = 0; i < 5; i++) {
+                                       printf("%5s ",jit_type[i]);
+                                       for (j = 0; j < cd->maxstack; j++)
+                                               printf("%3i ",jd->interface_map[j*5+i]);
+                                       printf("\n");
+                               }
+                       printf("\n");
                }
-#endif
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
-       }
-#endif
-       } /* if >= SHOW_STACK */
+       }
 
        if (code->rplpoints) {
                printf("Replacement Points:\n");
@@ -552,196 +499,125 @@ void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
         }
 
 #define SHOW_STACKVAR(sp)                                            \
-        new_show_stackvar(jd, (sp), stage)
+       new_show_stackvar(jd, (sp), stage)
 
 #define SHOW_S1(iptr)                                                \
         if (stage >= SHOW_STACK) {                                   \
-            SHOW_STACKVAR(iptr->s1.var);                             \
+            SHOW_STACKVAR(iptr->s1.varindex);                   \
         }
 
 #define SHOW_S2(iptr)                                                \
         if (stage >= SHOW_STACK) {                                   \
-            SHOW_STACKVAR(iptr->sx.s23.s2.var);                      \
+            SHOW_STACKVAR(iptr->sx.s23.s2.varindex);                    \
         }
 
 #define SHOW_S3(iptr)                                                \
-        if (stage >= SHOW_STACK) {                                   \
-            SHOW_STACKVAR(iptr->sx.s23.s3.var);                      \
-        }
+       if (stage >= SHOW_STACK) {                                                                               \
+               SHOW_STACKVAR(iptr->sx.s23.s3.varindex);                                         \
+       }
 
 #define SHOW_DST(iptr)                                               \
-        if (stage >= SHOW_STACK) {                                   \
-            printf("=> ");                                           \
-            SHOW_STACKVAR(iptr->dst.var);                            \
-        }
+       if (stage >= SHOW_STACK) {                                                                               \
+               printf("=> ");                                                                                           \
+               SHOW_STACKVAR(iptr->dst.varindex);                                                       \
+       }
 
 #define SHOW_S1_LOCAL(iptr)                                          \
-        if (stage >= SHOW_STACK) {                                   \
-            printf("L%d ", iptr->s1.localindex);                     \
-        }
+       if (stage >= SHOW_STACK) {                                                                               \
+               printf("L%d ", iptr->s1.varindex);                                                       \
+       }
 
 #define SHOW_DST_LOCAL(iptr)                                         \
-        if (stage >= SHOW_STACK) {                                   \
-            printf("=> L%d ", iptr->dst.localindex);                 \
-        }
+       if (stage >= SHOW_STACK) {                                                                               \
+               printf("=> L%d ", iptr->dst.varindex);                                           \
+       }
 
-static void new_show_stackvar(jitdata *jd, stackptr sp, int stage)
+static void new_show_stackvar(jitdata *jd, s4 index, int stage)
 {
        char type;
+       varinfo *sp;
+
+       sp = &(jd->var[index]);
 
        switch (sp->type) {
-               case TYPE_INT: type = 'i'; break;
-               case TYPE_LNG: type = 'l'; break;
-               case TYPE_FLT: type = 'f'; break;
-               case TYPE_DBL: type = 'd'; break;
-               case TYPE_ADR: type = 'a'; break;
-               default:       type = '?';
+       case TYPE_INT: type = 'i'; break;
+       case TYPE_LNG: type = 'l'; break;
+       case TYPE_FLT: type = 'f'; break;
+       case TYPE_DBL: type = 'd'; break;
+       case TYPE_ADR: type = 'a'; break;
+       default:       type = '?';
        }
-
+#if 0
        switch (sp->varkind) {
-               case TEMPVAR: printf("T%c%d", type, (int) (sp - jd->new_stack)); break;
-               case LOCALVAR: printf("L%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
-               case STACKVAR: printf("I%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
-               case ARGVAR: printf("A%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
-               default: printf("?%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
+       case TEMPVAR: printf("T%c%d", type, (int) (sp - jd->new_stack)); break;
+       case LOCALVAR: printf("L%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
+       case STACKVAR: printf("I%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
+       case ARGVAR: printf("A%c%d(T%d)", type, sp->varnum, (int) (sp - jd->new_stack)); break;
+       default: printf("?%c%d", type, index); break;
        }
+#endif
+
+       if (sp->flags & PREALLOC)
+               printf("A");
+       else if (sp->flags & OUTVAR)
+               printf("I");
+       else if (index < jd->localcount)
+               printf("L");
+       else printf("T");
+       printf("%c%d", type, index);
 
        if (stage >= SHOW_REGS) {
                putchar('(');
 
-               if (sp->flags & SAVEDVAR) {
-                       switch (sp->varkind) {
-                       case TEMPVAR:
-                               if (sp->flags & INMEMORY)
-                                       printf("M%02d", sp->regoff);
+               if (sp->flags & INMEMORY)
+                       printf("M%02d", sp->regoff);
 #ifdef HAS_ADDRESS_REGISTER_FILE
-                               else if (sp->type == TYPE_ADR)
-                                       printf("R%02d", sp->regoff);
+               else if (sp->type == TYPE_ADR)
+                       printf("R%02d", sp->regoff);
 #endif
-                               else if (IS_FLT_DBL_TYPE(sp->type))
-                                       printf("F%02d", sp->regoff);
-                               else {
+               else if (IS_FLT_DBL_TYPE(sp->type))
+                       printf("F%02d", sp->regoff);
+               else {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                       if (IS_2_WORD_TYPE(sp->type)) {
+                       if (IS_2_WORD_TYPE(sp->type)) {
 # if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
 #  if defined(ENABLE_INTRP)
-                                               if (opt_intrp)
-                                                       printf("%3d/%3d", GET_LOW_REG(sp->regoff),
-                                                                  GET_HIGH_REG(sp->regoff));
-                                               else
+                               if (opt_intrp)
+                                       printf("%3d/%3d", GET_LOW_REG(sp->regoff),
+                                                  GET_HIGH_REG(sp->regoff));
+                               else
 #  endif
-                                                       printf("%3s/%3s", regs[GET_LOW_REG(sp->regoff)],
-                                                                  regs[GET_HIGH_REG(sp->regoff)]);
+                                       printf("%3s/%3s", regs[GET_LOW_REG(sp->regoff)],
+                                                  regs[GET_HIGH_REG(sp->regoff)]);
 # else
-                                               printf("%3d/%3d", GET_LOW_REG(sp->regoff),
-                                                          GET_HIGH_REG(sp->regoff));
+                               printf("%3d/%3d", GET_LOW_REG(sp->regoff),
+                                          GET_HIGH_REG(sp->regoff));
 # endif
-                                       
-                                       else 
+                       } 
+                       else 
 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
-                                               {
+                               {
 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
 # if defined(ENABLE_INTRP)
-                                                       if (opt_intrp)
-                                                               printf("%3d", sp->regoff);
-                                                       else
-# endif
-                                                               printf("%3s", regs[sp->regoff]);
-#else
-                                                       printf("%3d", sp->regoff);
-#endif
-                                               }
-                               }
-                               break;
-                       case STACKVAR:
-                               printf("I%02d", sp->varnum);
-                               break;
-                       case LOCALVAR:
-                               printf("L%02d", sp->varnum);
-                               break;
-                       case ARGVAR:
-                               if (sp->varnum == -1) {
-                                       /* Return Value                                  */
-                                       /* varkind ARGVAR "misused for this special case */
-                                       printf(" V0");
-                               } 
-                               else /* "normal" Argvar */
-                                       printf("A%02d", sp->varnum);
-                               break;
-                       default:
-                               printf("!xx {kind=%d, num=%d}", sp->varkind, sp->varnum);
-                       }
-               }
-               else { /* not SAVEDVAR */
-                       switch (sp->varkind) {
-                       case TEMPVAR:
-                               if (sp->flags & INMEMORY)
-                                       printf("m%02d", sp->regoff);
-#ifdef HAS_ADDRESS_REGISTER_FILE
-                               else if (sp->type == TYPE_ADR)
-                                       printf("r%02d", sp->regoff);
-#endif
-                               else if (IS_FLT_DBL_TYPE(sp->type))
-                                       printf("f%02d", sp->regoff);
-                               else {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                       if (IS_2_WORD_TYPE(sp->type)) {
-# if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
-#  if defined(ENABLE_INTRP)
-                                               if (opt_intrp)
-                                                       printf("%3d/%3d", GET_LOW_REG(sp->regoff),
-                                                                  GET_HIGH_REG(sp->regoff));
-                                               else
-#  endif
-                                                       printf("%3s/%3s", regs[GET_LOW_REG(sp->regoff)],
-                                                                  regs[GET_HIGH_REG(sp->regoff)]);
-# else
-                                               printf("%3d/%3d", GET_LOW_REG(sp->regoff),
-                                                          GET_HIGH_REG(sp->regoff));
-# endif
-                                       } 
+                                       if (opt_intrp)
+                                               printf("%3d", sp->regoff);
                                        else
-#endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
-                                               {
-#if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
-# if defined(ENABLE_INTRP)
-                                                       if (opt_intrp)
-                                                               printf("%3d", sp->regoff);
-                                                       else
 # endif
-                                                               printf("%3s", regs[sp->regoff]);
+                                               printf("%3s", regs[sp->regoff]);
 #else
-                                                       printf("%3d", sp->regoff);
+                                       printf("%3d", sp->regoff);
 #endif
-                                               }
                                }
-                               break;
-                       case STACKVAR:
-                               printf("i%02d", sp->varnum);
-                               break;
-                       case LOCALVAR:
-                               printf("l%02d", sp->varnum);
-                               break;
-                       case ARGVAR:
-                               if (sp->varnum == -1) {
-                                       /* Return Value                                  */
-                                       /* varkind ARGVAR "misused for this special case */
-                                       printf(" v0");
-                               } 
-                               else /* "normal" Argvar */
-                               printf("a%02d", sp->varnum);
-                               break;
-                       default:
-                               printf("?xx {kind=%d, num=%d}", sp->varkind, sp->varnum);
-                       }
                }
 
+
                putchar(')');
        }
        putchar(' ');
+       fflush(stdout);
 }
 
-static void new_show_variable_array(jitdata *jd, stackptr *vars, int n, int stage)
+static void new_show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
 {
        int i;
 
@@ -760,7 +636,7 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        branch_target_t   *table;
        lookup_target_t   *lookup;
        constant_FMIref   *fmiref;
-       stackptr          *argp;
+       s4          *argp;
        s4                 i;
 
        /* get the opcode and the condition */
@@ -1245,8 +1121,8 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
                break;
 
        case ICMD_DUP:
-       case ICMD_COPY:
-       case ICMD_MOVE:
+/*     case ICMD_COPY: */
+/*     case ICMD_MOVE: */
                SHOW_S1(iptr);
                SHOW_DST(iptr);
                break;
@@ -1326,6 +1202,7 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
                break;
 
        }
+       fflush(stdout);
 }
 #endif /* !defined(NDEBUG) */
 
index 4959c114c21864928ce3d980c43ea9c292c0945e..6fc4d1e4d710910996cd91227447bc77d8aa42d8 100644 (file)
@@ -30,7 +30,7 @@
             Christian Thalinger
             Christian Ullrich
 
-   $Id: stack.c 5385 2006-09-06 21:40:50Z twisti $
+   $Id: stack.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -144,15 +144,65 @@ bool stack_init(void)
 
 *******************************************************************************/
 #if defined(NEW_VAR)
-#define GET_NEW_INDEX(new_varindex)                            \
+#define GET_NEW_INDEX(new_varindex)                                                                     \
        do {                                                                                                                     \
                assert(jd->vartop < jd->varcount);                                                       \
                (new_varindex) = (jd->vartop)++;                                                         \
-       } while(0)
+       } while (0)
 
-/* not implemented now, can be used to reuse varindices */
+/* not implemented now, can be used to reuse varindices          */
+/* pay attention to not release a localvar once implementing it! */
 #define RELEASE_INDEX(varindex)
 
+/* with the new vars setting an OUTVAR is not as trivial as changing */
+/* the varkind before. If varindex was a localvar, a new TEMPVAR has */
+/* to be created for the slot and the OUTVAR flag set */
+#define SET_OUTVAR(sp)                                                 \
+       do {                                                                            \
+               if (IS_LOCALVAR((sp))) {                                \
+                       GET_NEW_INDEX(new_index);                       \
+                       sp->varnum = new_index;                         \
+                       sp->flags = 0;                                          \
+               }                                                                               \
+               SET_OUTVAR_BY_INDEX((sp)->varnum);              \
+       } while(0)
+
+#define SET_OUTVAR_BY_INDEX(index) \
+       do {                                                                                                            \
+               assert(index >= jd->localcount);                                                \
+               jd->var[(index)].flags |=OUTVAR;                                                \
+       } while (0);
+
+
+#define SET_TEMPVAR(sp) \
+       do {                                                                                                            \
+               if ( IS_LOCALVAR( (sp) ) ) {                                                    \
+                       GET_NEW_INDEX(new_index);                                                       \
+                       (sp)->varnum = new_index;                                                       \
+                       jd->var[(sp)->varnum].flags = copy->flags;                      \
+               }                                                                                                               \
+               jd->var[(sp)->varnum].flags &= ~(OUTVAR | PREALLOC);    \
+       } while (0);
+
+#define SET_PREALLOC(sp) \
+       do { \
+               assert(!IS_LOCALVAR((sp))); \
+               jd->var[(sp)->varnum].flags |= PREALLOC; \
+       } while (0);
+
+#define IS_OUTVAR(sp) \
+       (jd->var[(sp)->varnum].flags & OUTVAR)
+
+#define IS_PREALLOC(sp) \
+       (jd->var[(sp)->varnum].flags & PREALLOC)
+
+#define IS_TEMPVAR(sp) \
+       ( (jd->var[(sp)->varnum].flags & (OUTVAR | PREALLOC)    \
+          && (((sp)->varnum < jd->localcount)) == 0) )
+
+#define IS_LOCALVAR(sp)                                                        \
+                ((sp)->varnum < jd->localcount)
+
 #define CLR_S1                                                       \
     (iptr->s1.varindex = -1)
 
@@ -201,10 +251,10 @@ bool stack_init(void)
 #define CLR_DST                                                      \
     (iptr->dst.varindex = -1)
 
-#define DST(typed, varindex)                                         \
+#define DST(typed, index)                                                                                       \
     do {                                                             \
-        NEWSTACKn((varindex));                                                                          \
-        iptr->dst.varindex = (varindex);                                                        \
+        NEWSTACKn((typed),(index));                                                                     \
+        iptr->dst.varindex = (index);                                                           \
     } while (0)
 
 #define DST_LOCALVAR(typed, index)                                   \
@@ -238,7 +288,7 @@ bool stack_init(void)
     do {                                                             \
         POP_S1(type1);                                               \
                GET_NEW_INDEX(new_index);                                                                        \
-        DST(typed, new_index                                                                          \
+        DST(typed, new_index);                                                                          \
     } while (0)
 
 #define OP2_1(type1, type2, typed)                                   \
@@ -545,6 +595,12 @@ bool new_stack_analyse(jitdata *jd)
 #endif
 
 #if defined(NEW_VAR)
+       /* init jd->interface_map */
+
+       jd->interface_map = DMNEW(s4, m->maxstack * 5);
+       for (i = 0; i < m->maxstack * 5; i++)
+               jd->interface_map[i] = UNUSED;
+
        last_store_boundary = DMNEW(stackptr, jd->localcount);
 #else
        last_store_boundary = DMNEW(stackptr , cd->maxlocals);
@@ -572,7 +628,10 @@ bool new_stack_analyse(jitdata *jd)
                GET_NEW_INDEX(new_index);
                bptr->invars = DMNEW(s4, 1);
                bptr->invars[0] = new_index;
-               NEWSTACK(TYPE_ADR, STACKVAR,new_index);
+               NEWSTACK(TYPE_ADR, STACKVAR, new_index);
+
+               jd->interface_map[0 * 5 + TYPE_ADR] = new_index;
+               SET_OUTVAR_BY_INDEX(new_index);
 #else
                bptr->invars = DMNEW(stackptr, 1);
                bptr->invars[0] = new;
@@ -600,7 +659,11 @@ bool new_stack_analyse(jitdata *jd)
 
                while (--b_count >= 0) {
 #if defined(STACK_VERBOSE)
-                       printf("ANALYZING BLOCK L%03d\n", bptr->nr);
+                       printf("----\nANALYZING BLOCK L%03d ", bptr->nr);
+                       if (bptr->type == BBTYPE_EXH) printf("EXH\n");
+                       else if (bptr->type == BBTYPE_SBR) printf("SBR\n");
+                       else printf("STD\n");
+                          
 #endif
 
                        if (bptr->flags == BBDELETED) {
@@ -661,14 +724,31 @@ bool new_stack_analyse(jitdata *jd)
                                /* XXX store the start of the block's stack representation */
 
                                bptr->stack = new;
+#if defined(STACK_VERBOSE)
+                               printf("INVARS\n");
+                                       for( copy = bptr->instack; copy; copy = copy->prev ) {
+                                               printf("%2d(%d", copy->varnum, copy->type);
+                                               if (IS_OUTVAR(copy))
+                                                       printf("S");
+                                               if (IS_PREALLOC(copy))
+                                                       printf("A");
+                                               printf(") ");
+                                       }
+                                       printf("\n");
 
+#endif
                                /* iterate over ICMDs ****************************************/
 
                                while (--len >= 0)  {
 #if defined(STACK_VERBOSE)
                                        new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
                                        for( copy = curstack; copy; copy = copy->prev ) {
-                                               printf("%d ", copy->type);
+                                               printf("%2d(%d", copy->varnum, copy->type);
+                                               if (IS_OUTVAR(copy))
+                                                       printf("S");
+                                               if (IS_PREALLOC(copy))
+                                                       printf("A");
+                                               printf(") ");
                                        }
                                        printf("\n");
 #endif
@@ -1569,12 +1649,12 @@ normal_ACONST:
                                                i = stackdepth - 1;
                                                while (copy) {
                                                        if ((copy->varkind == LOCALVAR) &&
-                                                               (copy->varnum == iptr->s1.localindex))
+                                                               (copy->varnum == iptr->s1.varindex))
                                                        {
                                                                copy->varkind = TEMPVAR;
 #if defined(NEW_VAR)
-                                                               GET_NEW_INDEX(new_index);
-                                                               copy->varnum = new_index;
+                                                               assert(IS_LOCALVAR(copy));
+                                                               SET_TEMPVAR(copy);
 #else
                                                                copy->varnum = i;
 #endif
@@ -1602,7 +1682,7 @@ normal_ACONST:
                                                i = opcode - ICMD_ISTORE; /* type */
 #if defined(NEW_VAR)
                                                j = iptr->dst.varindex = 
-                                                       jd->local_map[iptr->dst.varindex * 5 + 1]:
+                                                       jd->local_map[iptr->dst.varindex * 5 + i];
 
 #else
                                                j = iptr->dst.localindex; /* index */
@@ -1635,8 +1715,8 @@ normal_ACONST:
                                                        {
                                                                copy->varkind = TEMPVAR;
 #if defined(NEW_VAR)
-                                                               GET_NEW_INDEX(new_index);
-                                                               copy->varnum = new_index;
+                                                               assert(IS_LOCALVAR(copy));
+                                                               SET_TEMPVAR(copy);
 #else
                                                                copy->varnum = i;
 #endif
@@ -1647,7 +1727,7 @@ normal_ACONST:
 
                                                /* if the variable is already coalesced, don't bother */
 
-                                               if (curstack->varkind == STACKVAR
+                                               if (IS_OUTVAR(curstack)
                                                        || (curstack->varkind == LOCALVAR 
                                                                && curstack->varnum != j))
                                                        goto store_tail;
@@ -1662,7 +1742,7 @@ normal_ACONST:
                                                if (curstack < last_pei_boundary)
                                                        goto assume_conflict;
 
-                                               /* there is no non-consuming USE while curstack is live */
+                                               /*there is no non-consuming USE while curstack is live*/
 
                                                if (curstack < last_dup_boundary)
                                                        goto assume_conflict;
@@ -1677,8 +1757,12 @@ normal_ACONST:
 
                                                /* coalesce the temporary variable with Lj */
 #if defined(NEW_VAR)
-                                               assert(currstack->varkind == TEMPVAR);
-                                               RELEASE_INDEX(curstack->varnum);
+                                               assert( (CURKIND == TEMPVAR) || (CURKIND == UNDEFVAR));
+                                               assert(!IS_LOCALVAR(curstack));
+                                               assert(!IS_OUTVAR(curstack));
+                                               assert(!IS_PREALLOC(curstack));
+
+                                               RELEASE_INDEX(curstack);
 #endif
                                                curstack->varkind = LOCALVAR;
                                                curstack->varnum = j;
@@ -1691,8 +1775,8 @@ assume_conflict:
                                                {
                                                        curstack->varkind = TEMPVAR;
 #if defined(NEW_VAR)
-                                                       GET_NEW_INDEX(new_index);
-                                                       curstack->varnum = new_index;
+                                                       assert(IS_LOCALVAR(curstack));
+                                                       SET_TEMPVAR(curstack);
 #else
                                                        curstack->varnum = stackdepth-1;
 #endif
@@ -1727,6 +1811,13 @@ store_tail:
 
                                                copy = curstack;
                                                while (copy) {
+#if defined(NEW_VAR)
+                                                       jd->var[copy->varnum].flags |= SAVEDVAR;
+                                                       /* in case copy->varnum is/will be a LOCALVAR */
+                                                       /* once and set back to a non LOCALVAR        */
+                                                       /* the correct SAVEDVAR flag has to be        */
+                                                       /* remembered in copy->flags, too             */
+#endif
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
@@ -1968,6 +2059,19 @@ icmd_DUP:
                                                                        goto throw_stack_category_error;
                                                        }
 #endif
+#if defined(NEW_VAR)
+                                                       iptr->dst.dupslots = DMNEW(s4, 2 + 2);
+                                                                                /* XXX live through */
+                                                       iptr->dst.dupslots[0] = curstack->prev->varnum;
+                                                                          /* XXX live through */
+                                                       iptr->dst.dupslots[1] = curstack->varnum;
+                                                       copy = curstack;
+
+                                                       DUP_SLOT(copy->prev);
+                                                       iptr->dst.dupslots[2+0] = curstack->varnum;
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[2+1] = curstack->varnum;
+#else
                                                        iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
                                                        iptr->dst.dupslots[0] = curstack->prev; /* XXX live through */
                                                        iptr->dst.dupslots[1] = curstack;       /* XXX live through */
@@ -1976,6 +2080,7 @@ icmd_DUP:
                                                        iptr->dst.dupslots[2+0] = curstack;
                                                        DUP_SLOT(iptr->dst.dupslots[1]);
                                                        iptr->dst.dupslots[2+1] = curstack;
+#endif
                                                        last_dup_boundary = new;
                                                        stackdepth += 2;
                                                }
@@ -1994,6 +2099,20 @@ icmd_DUP:
 #endif
 
 icmd_DUP_X1:
+#if defined(NEW_VAR)
+                                               iptr->dst.dupslots = DMNEW(int, 2 + 3);
+                                               iptr->dst.dupslots[0] = curstack->prev->varnum;
+                                               iptr->dst.dupslots[1] = curstack->varnum;
+                                               copy = curstack;
+                                               POPANY; POPANY;
+
+                                               DUP_SLOT(copy);
+                                               iptr->dst.dupslots[2+0] = curstack->varnum;
+                                               DUP_SLOT(copy->prev);
+                                               iptr->dst.dupslots[2+1] = curstack->varnum;
+                                               DUP_SLOT(copy);
+                                               iptr->dst.dupslots[2+2] = curstack->varnum;
+#else
                                                iptr->dst.dupslots = DMNEW(stackptr, 2 + 3);
                                                iptr->dst.dupslots[0] = curstack->prev;
                                                iptr->dst.dupslots[1] = curstack;
@@ -2005,6 +2124,7 @@ icmd_DUP_X1:
                                                iptr->dst.dupslots[2+1] = curstack;
                                                DUP_SLOT(iptr->dst.dupslots[1]);
                                                iptr->dst.dupslots[2+2] = curstack;
+#endif
                                                last_dup_boundary = new;
                                                stackdepth++;
                                                break;
@@ -2034,6 +2154,25 @@ icmd_DUP_X1:
 #endif
 
 icmd_DUP2_X1:
+#if defined(NEW_VAR)
+                                                       iptr->dst.dupslots = DMNEW(s4, 3 + 5);
+                                                       iptr->dst.dupslots[0] =curstack->prev->prev->varnum;
+                                                       iptr->dst.dupslots[1] = curstack->prev->varnum;
+                                                       iptr->dst.dupslots[2] = curstack->varnum;
+                                                       copy = curstack;
+                                                       POPANY; POPANY; POPANY;
+
+                                                       DUP_SLOT(copy->prev);
+                                                       iptr->dst.dupslots[3+0] = curstack->varnum;
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[3+1] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev->prev);
+                                                       iptr->dst.dupslots[3+2] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev);
+                                                       iptr->dst.dupslots[3+3] = curstack->varnum;
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[3+4] = curstack->varnum;
+#else
                                                        iptr->dst.dupslots = DMNEW(stackptr, 3 + 5);
                                                        iptr->dst.dupslots[0] = curstack->prev->prev;
                                                        iptr->dst.dupslots[1] = curstack->prev;
@@ -2050,6 +2189,7 @@ icmd_DUP2_X1:
                                                        iptr->dst.dupslots[3+3] = curstack;
                                                        DUP_SLOT(iptr->dst.dupslots[2]);
                                                        iptr->dst.dupslots[3+4] = curstack;
+#endif
                                                        last_dup_boundary = new;
                                                        stackdepth += 2;
                                                }
@@ -2081,6 +2221,23 @@ icmd_DUP2_X1:
                                                        }
 #endif
 icmd_DUP_X2:
+#if defined(NEW_VAR)
+                                                       iptr->dst.dupslots = DMNEW(s4, 3 + 4);
+                                                       iptr->dst.dupslots[0] =curstack->prev->prev->varnum;
+                                                       iptr->dst.dupslots[1] = curstack->prev->varnum;
+                                                       iptr->dst.dupslots[2] = curstack->varnum;
+                                                       copy = curstack;
+                                                       POPANY; POPANY; POPANY;
+
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[3+0] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev->prev);
+                                                       iptr->dst.dupslots[3+1] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev);
+                                                       iptr->dst.dupslots[3+2] = curstack->varnum;
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[3+3] = curstack->varnum;
+#else
                                                        iptr->dst.dupslots = DMNEW(stackptr, 3 + 4);
                                                        iptr->dst.dupslots[0] = curstack->prev->prev;
                                                        iptr->dst.dupslots[1] = curstack->prev;
@@ -2095,6 +2252,7 @@ icmd_DUP_X2:
                                                        iptr->dst.dupslots[3+2] = curstack;
                                                        DUP_SLOT(iptr->dst.dupslots[2]);
                                                        iptr->dst.dupslots[3+3] = curstack;
+#endif
                                                        last_dup_boundary = new;
                                                        stackdepth++;
                                                }
@@ -2147,6 +2305,31 @@ icmd_DUP_X2:
                                                                        goto throw_stack_category_error;
                                                        }
 #endif
+
+#if defined(NEW_VAR)
+                                                       iptr->dst.dupslots = DMNEW(s4, 4 + 6);
+                                                       iptr->dst.dupslots[0] = 
+                                                               curstack->prev->prev->prev->varnum;
+                                                       iptr->dst.dupslots[1] = 
+                                                               curstack->prev->prev->varnum;
+                                                       iptr->dst.dupslots[2] = curstack->prev->varnum;
+                                                       iptr->dst.dupslots[3] = curstack->varnum;
+                                                       copy = curstack;
+                                                       POPANY; POPANY; POPANY; POPANY;
+
+                                                       DUP_SLOT(copy->prev);
+                                                       iptr->dst.dupslots[4+0] = curstack->varnum;
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[4+1] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev->prev->prev);
+                                                       iptr->dst.dupslots[4+2] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev->prev);
+                                                       iptr->dst.dupslots[4+3] = curstack->varnum;
+                                                       DUP_SLOT(copy->prev);
+                                                       iptr->dst.dupslots[4+4] = curstack->varnum;
+                                                       DUP_SLOT(copy);
+                                                       iptr->dst.dupslots[4+5] = curstack->varnum;
+#else
                                                        iptr->dst.dupslots = DMNEW(stackptr, 4 + 6);
                                                        iptr->dst.dupslots[0] = curstack->prev->prev->prev;
                                                        iptr->dst.dupslots[1] = curstack->prev->prev;
@@ -2166,6 +2349,7 @@ icmd_DUP_X2:
                                                        iptr->dst.dupslots[4+4] = curstack;
                                                        DUP_SLOT(iptr->dst.dupslots[3]);
                                                        iptr->dst.dupslots[4+5] = curstack;
+#endif
                                                        last_dup_boundary = new;
                                                        stackdepth += 2;
                                                }
@@ -2182,6 +2366,19 @@ icmd_DUP_X2:
                                                                goto throw_stack_category_error;
                                                }
 #endif
+
+#if defined(NEW_VAR)
+                                               iptr->dst.dupslots = DMNEW(s4, 2 + 2);
+                                               iptr->dst.dupslots[0] = curstack->prev->varnum;
+                                               iptr->dst.dupslots[1] = curstack->varnum;
+                                               copy = curstack;
+                                               POPANY; POPANY;
+
+                                               DUP_SLOT(copy);
+                                               iptr->dst.dupslots[2+0] = curstack->varnum;
+                                               DUP_SLOT(copy->prev);
+                                               iptr->dst.dupslots[2+1] = curstack->varnum;
+#else
                                                iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
                                                iptr->dst.dupslots[0] = curstack->prev;
                                                iptr->dst.dupslots[1] = curstack;
@@ -2191,6 +2388,7 @@ icmd_DUP_X2:
                                                iptr->dst.dupslots[2+0] = curstack;
                                                DUP_SLOT(iptr->dst.dupslots[0]);
                                                iptr->dst.dupslots[2+1] = curstack;
+#endif
                                                last_dup_boundary = new;
                                                break;
 
@@ -2212,6 +2410,9 @@ icmd_DUP_X2:
 
                                                copy = curstack;
                                                while (copy) {
+#if defined(NEW_VAR)
+                                                       jd->var[copy->varnum].flags |= SAVEDVAR;
+#endif
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
@@ -2249,6 +2450,9 @@ icmd_DUP_X2:
 
                                                copy = curstack;
                                                while (copy) {
+#if defined(NEW_VAR)
+                                                       jd->var[copy->varnum].flags |= SAVEDVAR;
+#endif
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
@@ -2602,6 +2806,9 @@ normal_DCMPG:
 
                                                        copy = curstack;
                                                        while (copy) {
+#if defined(NEW_VAR)
+                                                               jd->var[copy->varnum].flags |= SAVEDVAR;
+#endif
                                                                copy->flags |= SAVEDVAR;
                                                                copy = copy->prev;
                                                        }
@@ -2702,57 +2909,111 @@ icmd_BUILTIN:
                                                /* XXX optimize for <= 2 args */
                                                /* XXX not for ICMD_BUILTIN */
                                                iptr->s1.argcount = stackdepth;
+#if defined(NEW_VAR)
+                                               iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
+#else                                    
                                                iptr->sx.s23.s2.args = DMNEW(stackptr, stackdepth);
+#endif
 
                                                copy = curstack;
                                                for (i-- ; i >= 0; i--) {
+#if defined(NEW_VAR)
+                                                       iptr->sx.s23.s2.args[i] = copy->varnum;
+#else
                                                        iptr->sx.s23.s2.args[i] = copy;
+#endif
 
-                                                       /* do not change STACKVARs to ARGVAR ->
-                                                          won't help anyway */
+                                                       /* do not change STACKVARs or LOCALVARS to ARGVAR*/
+                                                       /* ->  won't help anyway */
+#if defined(NEW_VAR)
+                                                       if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
+#else
                                                        if (copy->varkind != STACKVAR) {
+#endif
 
 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
-                                                       /* If we pass float arguments in integer argument registers, we
-                                                        * are not allowed to precolor them here. Floats have to be moved
-                                                        * to this regs explicitly in codegen().
-                                                        * Only arguments that are passed by stack anyway can be precolored
-                                                        * (michi 2005/07/24) */
+                       /* If we pass float arguments in integer argument registers, we
+                        * are not allowed to precolor them here. Floats have to be moved
+                        * to this regs explicitly in codegen().
+                        * Only arguments that are passed by stack anyway can be precolored
+                        * (michi 2005/07/24) */
+# if defined(NEW_VAR)
+                                                       if (!(jd->var[copy->varnum].flags & SAVEDVAR) &&
+                                                          (!IS_FLT_DBL_TYPE(copy->type) 
+                                                               || md->params[i].inmemory)) {
+# else /* defined(NEW_VAR) */
                                                        if (!(copy->flags & SAVEDVAR) &&
-                                                          (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
+                                                          (!IS_FLT_DBL_TYPE(copy->type) 
+                                                               || md->params[i].inmemory)) {
+# endif /* defined(NEW_VAR) */
+#else
+# if defined(NEW_VAR)
+                                                       if (!(jd->var[copy->varnum].flags & SAVEDVAR)) {
 #else
                                                        if (!(copy->flags & SAVEDVAR)) {
 #endif
+#endif
+
+#if defined(NEW_VAR)
+                                                               SET_PREALLOC(copy);
+#else
                                                                copy->varkind = ARGVAR;
                                                                copy->varnum = i;
+#endif
 
 #if defined(ENABLE_INTRP)
                                                                if (!opt_intrp) {
 #endif
                                                                        if (md->params[i].inmemory) {
+#if defined(NEW_VAR)
+                                                                               jd->var[copy->varnum].regoff =
+                                                                                       md->params[i].regoff;
+                                                                               jd->var[copy->varnum].flags |= 
+                                                                                       INMEMORY;
+#else   
                                                                                copy->flags = INMEMORY;
                                                                                copy->regoff = md->params[i].regoff;
+#endif
                                                                        }
                                                                        else {
+#if !defined(NEW_VAR)
                                                                                copy->flags = 0;
+#endif
                                                                                if (IS_FLT_DBL_TYPE(copy->type)) {
 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
                                                                                        assert(0); /* XXX is this assert ok? */
 #else
+#if defined(NEW_VAR)
+                                                                                       jd->var[copy->varnum].regoff = 
+                                                                               rd->argfltregs[md->params[i].regoff];
+#else                                                                                  
                                                                                        copy->regoff =
-                                                                                               rd->argfltregs[md->params[i].regoff];
+                                                                               rd->argfltregs[md->params[i].regoff];
+#endif
 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
                                                                                }
                                                                                else {
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
                                                                                        if (IS_2_WORD_TYPE(copy->type))
-                                                                                               copy->regoff = PACK_REGS(
-                                                                                                       rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
-                                                                                                       rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
+#if defined(NEW_VAR)
+                                                                                               jd->var[copy->varnum].regoff = 
+                               PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
+                                                  rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
+
+#else
+                                                                                           copy->regoff = PACK_REGS(
+                                                       rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
+                                                       rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
+#endif
                                                                                        else
 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
-                                                                                               copy->regoff =
-                                                                                                       rd->argintregs[md->params[i].regoff];
+#if defined(NEW_VAR)
+                                                                                               jd->var[copy->varnum].regoff = 
+                                                                               rd->argintregs[md->params[i].regoff];
+#else
+                                                                                                       copy->regoff =
+                                                                               rd->argintregs[md->params[i].regoff];
+#endif
                                                                                }
                                                                        }
 #if defined(ENABLE_INTRP)
@@ -2763,14 +3024,20 @@ icmd_BUILTIN:
                                                        copy = copy->prev;
                                                }
 
-                                               /* deal with live-through stack slots "under" the arguments */
+                                               /* deal with live-through stack slots "under" the */
+                                               /* arguments */
                                                /* XXX not for ICMD_BUILTIN */
 
                                                i = md->paramcount;
 
                                                while (copy) {
+#if defined(NEW_VAR)
+                                                       iptr->sx.s23.s2.args[i++] = copy->varnum;
+                                                       jd->var[copy->varnum].flags |= SAVEDVAR;
+#else
                                                        iptr->sx.s23.s2.args[i++] = copy;
                                                        copy->flags |= SAVEDVAR;
+#endif
                                                        copy = copy->prev;
                                                }
 
@@ -2786,7 +3053,12 @@ icmd_BUILTIN:
                                                /* push the return value */
 
                                                if (md->returntype.type != TYPE_VOID) {
+#if defined(NEW_VAR)
+                                                       GET_NEW_INDEX(new_index);
+                                                       DST(md->returntype.type, new_index);
+#else
                                                        DST(md->returntype.type, stackdepth);
+#endif
                                                        stackdepth++;
                                                }
                                                break;
@@ -2806,11 +3078,15 @@ icmd_BUILTIN:
 
                                                REQUIRE(i);
 
+#if defined(NEW_VAR)
+                                               iptr->sx.s23.s2.args = DMNEW(s4, i);
+#else
                                                iptr->sx.s23.s2.args = DMNEW(stackptr, i);
+#endif
 
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                               if (rd->memuse < (i + INT_ARG_CNT + LA_SIZE_IN_POINTERS))
+                                               if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
                                                        rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
                                                if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
@@ -2830,11 +3106,39 @@ icmd_BUILTIN:
 #endif
                                                copy = curstack;
                                                while (--i >= 0) {
-                                                       /* check INT type here? Currently typecheck does this. */
+                                       /* check INT type here? Currently typecheck does this. */
+#if defined(NEW_VAR)
+                                                       iptr->sx.s23.s2.args[i] = copy->varnum;
+                                                       if (!(jd->var[copy->varnum].flags & SAVEDVAR)
+                                                               && (!IS_OUTVAR(copy))
+                                                               && (!IS_LOCALVAR(copy)) ) {
+#else
                                                        iptr->sx.s23.s2.args[i] = copy;
                                                        if (!(copy->flags & SAVEDVAR) 
                                                                && (copy->varkind != STACKVAR)) {
+#endif
                                                                copy->varkind = ARGVAR;
+#if defined(NEW_VAR)
+                                                               jd->var[copy->varnum].flags |=
+                                                                       INMEMORY & PREALLOC;
+#if defined(SPECIALMEMUSE)
+# if defined(__DARWIN__)
+                                                               jd->var[copy->varnum].regoff = i + 
+                                                                       LA_SIZE_IN_POINTERS + INT_ARG_CNT;
+# else
+                                                               jd->var[copy->varnum].regoff = i + 
+                                                                       LA_SIZE_IN_POINTERS + 3;
+# endif
+#else
+# if defined(__I386__)
+                                                               jd->var[copy->varnum].regoff = i + 3;
+# elif defined(__MIPS__) && SIZEOF_VOID_P == 4
+                                                               jd->var[copy->varnum].regoff = i + 2;
+# else
+                                                               jd->var[copy->varnum].regoff = i;
+# endif /* defined(__I386__) */
+#endif /* defined(SPECIALMEMUSE) */
+#else /* defined(NEW_VAR) */
                                                                copy->varnum = i + INT_ARG_CNT;
                                                                copy->flags |= INMEMORY;
 #if defined(SPECIALMEMUSE)
@@ -2852,11 +3156,17 @@ icmd_BUILTIN:
                                                                copy->regoff = i;
 # endif /* defined(__I386__) */
 #endif /* defined(SPECIALMEMUSE) */
+
+#endif /* defined(NEW_VAR) */
                                                        }
                                                        copy = copy->prev;
                                                }
                                                while (copy) {
+#if defined(NEW_VAR)
+                                                       jd->var[copy->varnum].flags |= SAVEDVAR;
+#else
                                                        copy->flags |= SAVEDVAR;
+#endif
                                                        copy = copy->prev;
                                                }
 
@@ -2865,7 +3175,12 @@ icmd_BUILTIN:
                                                while (--i >= 0) {
                                                        POPANY;
                                                }
+#if defined(NEW_VAR)
+                                               GET_NEW_INDEX(new_index);
+                                               DST(TYPE_ADR, new_index);
+#else
                                                DST(TYPE_ADR, stackdepth);
+#endif
                                                stackdepth++;
                                                break;
 
@@ -2883,22 +3198,48 @@ icmd_BUILTIN:
 
                                bptr->outstack = curstack;
                                bptr->outdepth = stackdepth;
+#if defined(NEW_VAR)
+                               bptr->outvars = DMNEW(s4, stackdepth);
+                               for (i = stackdepth, copy = curstack; i--; copy = copy->prev)
+                                       bptr->outvars[i] = copy->varnum;
+#else
                                bptr->outvars = DMNEW(stackptr, stackdepth);
                                for (i = stackdepth, copy = curstack; i--; copy = copy->prev)
                                        bptr->outvars[i] = copy;
+#endif
 
                                /* stack slots at basic block end become interfaces */
 
                                i = stackdepth - 1;
                                for (copy = curstack; copy; i--, copy = copy->prev) {
-                                       if ((copy->varkind == STACKVAR) && (copy->varnum > i)) {
 #if defined(NEW_VAR)
-                                               /* with the new vars rd->interfaces will be removed */
-                                               /* and all in and outvars have to be STACKVARS!     */
-                                               /* in the moment i.e. SWAP with in and out vars     */
-                                               /* an unresolvable conflict */
-                                               assert(0);
-#endif
+                                       /* with the new vars rd->interfaces will be removed */
+                                       /* and all in and outvars have to be STACKVARS!     */
+                                       /* in the moment i.e. SWAP with in and out vars can */
+                                       /* create an unresolvable conflict */
+
+                                       j = jd->interface_map[i * 5 + copy->type];
+                                       if (j == UNUSED) {
+                                               /* no interface var until now for this depth and */
+                                               /* type */
+                                               
+                                               SET_OUTVAR(copy);
+                                               
+                                               if (! IS_LOCALVAR(copy) )
+                                                       jd->var[j].flags |= jd->var[copy->varnum].flags;
+                                               jd->interface_map[i*5 + copy->type] = copy->varnum;
+                                       }
+                                       else if (j != copy->varnum) {
+                                               /* release copy->varnum and take already existing */
+                                               /* interface var */
+                                               RELEASE_INDEX(copy);
+                                               
+                                               if (! IS_LOCALVAR(copy) )
+                                                       jd->var[j].flags |= jd->var[copy->varnum].flags;
+                                               copy->varnum = jd->interface_map[i*5 + copy->type];
+                                       } /* else <-> if (j == copy->varnum) --> nothing todo! */
+#else
+                                       if ((copy->varkind == STACKVAR) && (copy->varnum > i)) {
                                                copy->varkind = TEMPVAR;
                                        } else {
                                                copy->varkind = STACKVAR;
@@ -2908,10 +3249,11 @@ icmd_BUILTIN:
                                                        rd->interfaces[i][copy->type].type = copy->type;
                                                        rd->interfaces[i][copy->type].flags |= copy->flags;
                                        );
+#endif
                                }
 
                                /* check if interface slots at basic block begin must be saved */
-
+#if !defined(NEW_VAR)
                                IF_NO_INTRP(
                                        i = bptr->indepth - 1;
                                        for (copy = bptr->instack; copy; i--, copy = copy->prev) {
@@ -2922,8 +3264,21 @@ icmd_BUILTIN:
                                                }
                                        }
                                );
+#endif
 
-                       } /* if */
+#if defined(STACK_VERBOSE)
+                               printf("OUTVARS\n");
+                               for( copy = bptr->outstack; copy; copy = copy->prev ) {
+                                       printf("%2d(%d", copy->varnum, copy->type);
+                                       if (IS_OUTVAR(copy))
+                                               printf("S");
+                                       if (IS_PREALLOC(copy))
+                                               printf("A");
+                                       printf(") ");
+                               }
+                               printf("\n");
+#endif
+                   } /* if */
                        else
                                superblockend = true;
 
index b18d2b44e8b9ad0483dee60397adc7b0ddf1125b..abcbf59ffc8143de5960d0425194d5b0e1c94a57 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Ullrich
 
-   $Id: stack.h 5375 2006-09-06 16:01:23Z edwin $
+   $Id: stack.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
         new->varkind = (v); \
         new->varnum = (n); \
         curstack = new; \
+               jd->var[(n)].type = (s); \
+               jd->var[(n)].flags = 0;  \
         new++; \
     } while (0)
 
                        copy->flags=0;\
                        copy->varkind=STACKVAR;\
                        copy->varnum=s->varnum;\
-                       assert(s->varkind == STACKVAR); \
+                       SET_OUTVAR(s);             \
                        s=s->prev;\
                        }\
                copy->prev=NULL;\
             (b)->flags = BBREACHED; \
             (b)->instack = (c); \
             (b)->indepth = stackdepth; \
-                       (b)->invars = DMNEW(stackptr, stackdepth); \
-                       for (locali = stackdepth; locali--; (c) = (c)->prev) \
-                               (b)->invars[locali] = (c); \
+                       (b)->invars = DMNEW(s4, stackdepth); \
+                       for (locali = stackdepth; locali--; (c) = (c)->prev) {  \
+                               (b)->invars[locali] = (c)->varnum;                                      \
+                               SET_OUTVAR((c));                                                        \
+                       }                                                                                                               \
         } else { \
             stackptr s = curstack; \
             stackptr t = (b)->instack; \
index 0f88a5b02742d2cf35540d3cf943a81489cc5a4a..29772a19dc2c6d4704e1a83e580a1ac34aa6de9a 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: typecheck.c 5332 2006-09-05 19:38:28Z twisti $
+   $Id: typecheck.c 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -184,7 +184,7 @@ of the typeinfo of the stack slot.
 #include "vm/resolve.h"
 #include "vm/exceptions.h"
 
-
+#if !defined(NEW_VAR)
 /****************************************************************************/
 /* DEBUG HELPERS                                                            */
 /****************************************************************************/
@@ -2835,7 +2835,7 @@ bool typecheck(jitdata *jd)
     LOGimp("exiting typecheck");
        return true;
 }
-
+#endif /* !defined(NEW_VAR) */
 #endif /* ENABLE_VERIFIER */
 
 /*
index b45d6a1cd30c9162c09d9bec625246b204d1d8e1..e2bbd45db395556001b5ae9da1d483c9e79a2e37 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes:
 ##
-## $Id: Makefile.am 5015 2006-06-06 13:13:46Z twisti $
+## $Id: Makefile.am 5404 2006-09-07 13:29:05Z christian $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -88,7 +88,7 @@ build:
        @$(JAVAC) -d . $(SOURCE_FILES)
 
 $(SIMPLE_JAVA_TESTS):
-       @echo -n "$@: "
+       @echo -nowarn -n "$@: "
        @$(JAVA) $(JAVAFLAGS) $@
 
 
index 0714fcd0f153805e4ea713cd5cb78954d724c027..6513cbb6383be27db459c3ace9f474f2f3dad52f 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes:
 ##
-## $Id: Makefile.am 5015 2006-06-06 13:13:46Z twisti $
+## $Id: Makefile.am 5404 2006-09-07 13:29:05Z christian $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -135,7 +135,7 @@ check: build
        @$(JAVA) $(JAVAFLAGS) test
 
 build:
-       @$(JAVAC) -d . $(SOURCE_FILES)
+       @$(JAVAC) -nowarn -d . $(SOURCE_FILES)
 
 remove:
        $(RM) $(CLASSES)
index 08cafa05665b33ec79473b9301d0401939d37da5..53ed06c45ca863f5b3e665c32290dd1c761b417c 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## Changes:
 ##
-## $Id: Makefile.am 5015 2006-06-06 13:13:46Z twisti $
+## $Id: Makefile.am 5404 2006-09-07 13:29:05Z christian $
 
 ## Process this file with automake to produce Makefile.in
 
@@ -67,7 +67,7 @@ TESTNAMES = \
 check: $(TESTNAMES)
 
 $(TESTNAMES) $(NOTESTNAMES):
-       @$(JAVAC) -d . $(srcdir)/$@.java
+       @$(JAVAC) -nowarn -d . $(srcdir)/$@.java
        @$(JAVAH) $@
        @$(CC) -shared $(AM_CPPFLAGS) $(CFLAGS) $(srcdir)/$@.c -o lib$@.so -fPIC
        @$(SHELL) $(srcdir)/../Test.sh "$(JAVA) $(JAVAFLAGS)" $@ $(srcdir)