GNU header update.
[cacao.git] / src / vm / jit / reg.inc
index d236d349886ba17538c69acc1a88e399bf8e285b..70dc8052eb5d716e0f965751e9833af589bb46be 100644 (file)
@@ -1,10 +1,9 @@
-/* jit/reg.inc - register allocator
+/* vm/jit/reg.inc - register allocator
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
-   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
-   J. Wenninger
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
    Changes: Stefan Ring
             Christian Thalinger
 
-   $Id: reg.inc 1152 2004-06-07 10:09:20Z twisti $
+   $Id: reg.inc 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 
-#include "reg.h"
-#include "toolbox/memory.h"
+#include "mm/memory.h"
+#include "vm/jit/reg.h"
 
 
-varinfo5 *locals;
-varinfo5 *interfaces;
-
-static int intregsnum;              /* absolute number of integer registers   */
-static int floatregsnum;            /* absolute number of float registers     */
-
-static int intreg_ret;              /* register to return integer values      */
-int intreg_argnum;                  /* number of integer argument registers   */
-
-static int floatreg_ret;            /* register for return float values       */
-int fltreg_argnum;                  /* number of float argument registers     */
+/* function prototypes for this file */
 
+static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
+static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
+static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
 
-static int *argintregs;             /* scratch integer registers              */
-static int *tmpintregs;             /* scratch integer registers              */
-static int *savintregs;             /* saved integer registers                */
-static int *argfltregs;             /* scratch float registers                */
-static int *tmpfltregs;             /* scratch float registers                */
-static int *savfltregs;             /* saved float registers                  */
-static int *freeargintregs;         /* free argument integer registers        */
-static int *freetmpintregs;         /* free scratch integer registers         */
-static int *freesavintregs;         /* free saved integer registers           */
-static int *freeargfltregs;         /* free argument float registers          */
-static int *freetmpfltregs;         /* free scratch float registers           */
-static int *freesavfltregs;         /* free saved float registers             */
 
-#ifdef USETWOREGS
-static int *secondregs;             /* used for longs in 2 32 bit registers   */
-#endif
-
-static int *freemem;                /* free scratch memory                    */
-static int memuse;                  /* used memory count                      */
-static int ifmemuse;                /* interface used memory count            */
-static int maxmemuse;               /* maximal used memory count (spills)     */
-static int freememtop;              /* free memory count                      */
-
-static int tmpintregcnt;            /* scratch integer register count         */
-static int savintregcnt;            /* saved integer register count           */
-static int tmpfltregcnt;            /* scratch float register count           */
-static int savfltregcnt;            /* saved float register count             */
-
-static int iftmpintregcnt;          /* iface scratch integer register count   */
-static int ifsavintregcnt;          /* iface saved integer register count     */
-static int iftmpfltregcnt;          /* iface scratch float register count     */
-static int ifsavfltregcnt;          /* iface saved float register count       */
-
-static int argintreguse;            /* used argument integer register count   */
-static int tmpintreguse;            /* used scratch integer register count    */
-static int savintreguse;            /* used saved integer register count      */
-static int argfltreguse;            /* used argument float register count     */
-static int tmpfltreguse;            /* used scratch float register count      */
-static int savfltreguse;            /* used saved float register count        */
-
-static int maxargintreguse;         /* max used argument int register count   */
-static int maxtmpintreguse;         /* max used scratch int register count    */
-static int maxsavintreguse;         /* max used saved int register count      */
-static int maxargfltreguse;         /* max used argument float register count */
-static int maxtmpfltreguse;         /* max used scratch float register count  */
-static int maxsavfltreguse;         /* max used saved float register count    */
-
-static int freearginttop;           /* free argument integer register count   */
-static int freetmpinttop;           /* free scratch integer register count    */
-static int freesavinttop;           /* free saved integer register count      */
-static int freeargflttop;           /* free argument float register count     */
-static int freetmpflttop;           /* free scratch float register count      */
-static int freesavflttop;           /* free saved float register count        */
-
-static int savedregs_num;              /* total number of registers to be saved      */
-int arguments_num;              /* size of parameter field in the stackframe  */
+/* reg_init ********************************************************************
 
+   TODO
+       
+*******************************************************************************/
 
-/* function prototypes for this file */
+void reg_init()
+{
+       /* void */
+}
 
-static void interface_regalloc();
-static void local_regalloc();
-static void allocate_scratch_registers();
 
+/* reg_setup *******************************************************************
 
-/* function reg_init ***********************************************************
+   TODO
 
-       initialises the register-allocator
-       
 *******************************************************************************/
 
-void reg_init()
+void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
 {
-       int n;
-
-       if (TYPE_INT != 0 || TYPE_ADR != 4) 
-               panic("JAVA-Basictypes have been changed");
+       s4 i;
+       varinfo5 *v;
 
        /* setup the integer register table */
-       intreg_argnum = 0;
-       tmpintregcnt = 0;
-       savintregcnt = 0;
-
-       for (intregsnum = 0; nregdescint[intregsnum] != REG_END; intregsnum++) {
-               switch (nregdescint[intregsnum]) {
-               case REG_SAV: savintregcnt++;
+       rd->intreg_argnum = 0;
+       rd->tmpintregcnt = 0;
+       rd->savintregcnt = 0;
+
+       for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
+               switch (nregdescint[rd->intregsnum]) {
+               case REG_SAV:
+                       rd->savintregcnt++;
+                       break;
+               case REG_TMP:
+                       rd->tmpintregcnt++;
                        break;
-               case REG_TMP: tmpintregcnt++;
+               case REG_ARG:
+                       rd->intreg_argnum++;
                        break;
-               case REG_ARG: intreg_argnum++;
                }
        }
 
-       argintregs = MNEW(int, intreg_argnum);
-       tmpintregs = MNEW(int, tmpintregcnt);
-       savintregs = MNEW(int, savintregcnt);
-       freeargintregs = MNEW(int, intreg_argnum);
-       freetmpintregs = MNEW(int, tmpintregcnt);
-       freesavintregs = MNEW(int, savintregcnt);
+       rd->argintregs = DMNEW(s4, rd->intreg_argnum);
+       rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
+       rd->savintregs = DMNEW(s4, rd->savintregcnt);
+       rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
+       rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
+       rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
 #ifdef USETWOREGS
-       secondregs = MNEW(int, intregsnum);
+       rd->secondregs = DMNEW(s4, rd->intregsnum);
 #endif
 
-       intreg_argnum = 0;
-       argintreguse = 0;
-       tmpintreguse = 0;
-       savintreguse = 0;
+       rd->intreg_argnum = 0;
+       rd->argintreguse = 0;
+       rd->tmpintreguse = 0;
+       rd->savintreguse = 0;
 
-       for (n = 0; n < intregsnum; n++) {
-               switch (nregdescint[n]) {
-               case REG_RET: intreg_ret = n; 
+       for (i = 0; i < rd->intregsnum; i++) {
+               switch (nregdescint[i]) {
+               case REG_RET:
+                       rd->intreg_ret = i; 
                        break;
-               case REG_SAV: savintregs[savintreguse++] = n;
+               case REG_SAV:
+                       rd->savintregs[rd->savintreguse++] = i;
                        break;
-               case REG_TMP: tmpintregs[tmpintreguse++] = n;
+               case REG_TMP:
+                       rd->tmpintregs[rd->tmpintreguse++] = i;
                        break;
-               case REG_ARG: argintregs[intreg_argnum++] = n;
-                       argintreguse++;
+               case REG_ARG:
+                       rd->argintregs[rd->intreg_argnum++] = i;
+                       rd->argintreguse++;
                        break;
                }
        }
 
-#if defined(__I386__)
-       /* 
-          this assumes that we have 3 tmp regs (%ecx, %edx, %ebx) 
-          sort to [ %ebx, %edx, %ecx ]
-        */
-       n = tmpintregs[0];
-       tmpintregs[0] = tmpintregs[2];
-       tmpintregs[2] = n;
-#endif
-
 #if defined(__X86_64__)
        /* 
         * on x86_64 the argument registers are not in ascending order 
         * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
         */
-       n = argintregs[3];
-       argintregs[3] = argintregs[0];
-       argintregs[0] = n;
+       i = rd->argintregs[3];
+       rd->argintregs[3] = rd->argintregs[0];
+       rd->argintregs[0] = i;
 
-       n = argintregs[2];
-       argintregs[2] = argintregs[1];
-       argintregs[1] = n;
+       i = rd->argintregs[2];
+       rd->argintregs[2] = rd->argintregs[1];
+       rd->argintregs[1] = i;
 #endif
                
 #ifdef USETWOREGS
-       for (n = 1; n < intreg_argnum; n++)
-               secondregs[argintregs[n - 1]] = argintregs[n];
-       for (n = 1; n < tmpintregcnt; n++)
-               secondregs[tmpintregs[n - 1]] = tmpintregs[n];
-       for (n = 1; n < savintregcnt; n++)
-               secondregs[savintregs[n - 1]] = savintregs[n];
-
-       secondregs[REG_ITMP1] = REG_ITMP2;
-       secondregs[REG_ITMP3] = REG_ITMP2;
-       secondregs[REG_RESULT] = REG_RESULT + 1;
-       secondregs[argintregs[intreg_argnum - 1]] = REG_ITMP3;
+       for (i = 1; i < rd->intreg_argnum; i++)
+               rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
+       for (i = 1; i < rd->tmpintregcnt; i++)
+               rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
+       for (i = 1; i < rd->savintregcnt; i++)
+               rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
+
+       rd->secondregs[REG_ITMP1] = REG_ITMP2;
+       rd->secondregs[REG_ITMP3] = REG_ITMP2;
+       rd->secondregs[REG_RESULT] = REG_RESULT + 1;
+       rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
 #endif
 
        /* setup the float register table */
-       fltreg_argnum = 0;
-       tmpfltregcnt = 0;
-       savfltregcnt = 0;
-
-       for (floatregsnum = 0; nregdescfloat[floatregsnum] != REG_END; floatregsnum++) {
-               switch (nregdescfloat[floatregsnum]) {
-               case REG_SAV: savfltregcnt++;
+       rd->fltreg_argnum = 0;
+       rd->tmpfltregcnt = 0;
+       rd->savfltregcnt = 0;
+
+       for (rd->floatregsnum = 0; nregdescfloat[rd->floatregsnum] != REG_END; rd->floatregsnum++) {
+               switch (nregdescfloat[rd->floatregsnum]) {
+               case REG_SAV:
+                       rd->savfltregcnt++;
                        break;
-               case REG_TMP: tmpfltregcnt++;
+               case REG_TMP:
+                       rd->tmpfltregcnt++;
                        break;
-               case REG_ARG: fltreg_argnum++;
+               case REG_ARG:
+                       rd->fltreg_argnum++;
                        break;
                }
        }
 
-       argfltregs = MNEW(int, fltreg_argnum);
-       tmpfltregs = MNEW(int, tmpfltregcnt);
-       savfltregs = MNEW(int, savfltregcnt);
-       freeargfltregs = MNEW(int, fltreg_argnum);
-       freetmpfltregs = MNEW(int, tmpfltregcnt);
-       freesavfltregs = MNEW(int, savfltregcnt);
+       rd->argfltregs = DMNEW(s4, rd->fltreg_argnum);
+       rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
+       rd->savfltregs = DMNEW(s4, rd->savfltregcnt);
+       rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum);
+       rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
+       rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt);
 
-       fltreg_argnum = 0;
-       argfltreguse = 0;
-       tmpfltreguse = 0;
-       savfltreguse = 0;
+       rd->fltreg_argnum = 0;
+       rd->argfltreguse = 0;
+       rd->tmpfltreguse = 0;
+       rd->savfltreguse = 0;
 
-       for (n = 0; n < floatregsnum; n++) {
-               switch (nregdescfloat[n]) {
+       for (i = 0; i < rd->floatregsnum; i++) {
+               switch (nregdescfloat[i]) {
                case REG_RET:
-                       floatreg_ret = n
+                       rd->floatreg_ret = i
                        break;
-               case REG_SAV: savfltregs[savfltreguse++] = n;
+               case REG_SAV:
+                       rd->savfltregs[rd->savfltreguse++] = i;
                        break;
-               case REG_TMP: tmpfltregs[tmpfltreguse++] = n;
+               case REG_TMP:
+                       rd->tmpfltregs[rd->tmpfltreguse++] = i;
                        break;
-               case REG_ARG: argfltregs[fltreg_argnum++] = n;
-                       argfltreguse++;
+               case REG_ARG:
+                       rd->argfltregs[rd->fltreg_argnum++] = i;
+                       rd->argfltreguse++;
                        break;
                }
        }
-}
 
 
-void reg_setup()
-{
-       int i;
-       varinfo5 *v;
-
-       freemem    = DMNEW(int, maxstack);
-       locals     = DMNEW(varinfo5, maxlocals);
-       interfaces = DMNEW(varinfo5, maxstack);
+       rd->freemem    = DMNEW(s4, id->cummaxstack);
+       rd->locals     = DMNEW(varinfo5, id->cumlocals);
+       rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
 
-       for (v = locals, i = maxlocals; i > 0; v++, i--) {
+       for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) {
                v[0][TYPE_INT].type = -1;
                v[0][TYPE_LNG].type = -1;
                v[0][TYPE_FLT].type = -1;
@@ -274,7 +210,7 @@ void reg_setup()
                v[0][TYPE_ADR].type = -1;
        }
 
-       for (v = interfaces, i = maxstack; i > 0; v++, i--) {
+       for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
                v[0][TYPE_INT].type = -1;
                v[0][TYPE_INT].flags = 0;
                v[0][TYPE_LNG].type = -1;
@@ -289,32 +225,27 @@ void reg_setup()
 }
 
 
+/* function reg_free ***********************************************************
+
+   releases all allocated space for registers
+
+*******************************************************************************/
+
+void reg_free(methodinfo *m, registerdata *rd)
+{
+       /* void */
+}
+
 
-/* function reg_close **********************************************************
+/* reg_close *******************************************************************
 
-       releases all allocated space for registers
+   TODO
 
 *******************************************************************************/
 
 void reg_close()
 {
-       if (argintregs) MFREE(argintregs, int, intreg_argnum);
-       if (argfltregs) MFREE(argfltregs, int, fltreg_argnum);
-       if (tmpintregs) MFREE(tmpintregs, int, tmpintregcnt);
-       if (savintregs) MFREE(savintregs, int, savintregcnt);
-       if (tmpfltregs) MFREE(tmpfltregs, int, tmpfltregcnt);
-       if (savfltregs) MFREE(savfltregs, int, savfltregcnt);
-
-       if (freeargintregs) MFREE(freeargintregs, int, intreg_argnum);
-       if (freeargfltregs) MFREE(freeargfltregs, int, fltreg_argnum);
-       if (freetmpintregs) MFREE(freetmpintregs, int, tmpintregcnt);
-       if (freesavintregs) MFREE(freesavintregs, int, savintregcnt);
-       if (freetmpfltregs) MFREE(freetmpfltregs, int, tmpfltregcnt);
-       if (freesavfltregs) MFREE(freesavfltregs, int, savfltregcnt);
-
-#ifdef USETWOREGS
-       if (secondregs) MFREE(secondregs, int, intregsnum);
-#endif
+       /* void */
 }
 
 
@@ -324,22 +255,11 @@ void reg_close()
        
 *******************************************************************************/
        
-void regalloc()
+void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
 {
-#if defined(__I386__)
-       /* remove %ecx and/or %edx from tmpintregs */
-       int origtmpintregcnt = tmpintregcnt;
-       if (method_uses_ecx) tmpintregcnt--;
-       if (method_uses_edx) tmpintregcnt--;
-#endif
-
-       interface_regalloc();
-       allocate_scratch_registers();
-       local_regalloc();
-
-#if defined(__I386__)
-       tmpintregcnt = origtmpintregcnt;
-#endif
+       interface_regalloc(m, cd, rd);
+       allocate_scratch_registers(m, rd);
+       local_regalloc(m, cd, rd);
 }
 
 
@@ -349,13 +269,13 @@ void regalloc()
        
 *******************************************************************************/
        
-static void interface_regalloc()
+static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
 {
        int     s, t, saved;
        int     intalloc, fltalloc;
        varinfo *v;
        int             regsneeded = 0;
-       
+
        /* allocate stack space for passing arguments to called methods */
 
 #ifndef SPECIALMEMUSE
@@ -366,29 +286,31 @@ static void interface_regalloc()
         */
        /*      if (arguments_num > (intreg_argnum + fltreg_argnum)) */
        /*              ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
-       if (arguments_num > fltreg_argnum)
-               ifmemuse = arguments_num - fltreg_argnum;
+       if (rd->arguments_num > rd->fltreg_argnum)
+               rd->ifmemuse = rd->arguments_num - rd->fltreg_argnum;
 #else
-       if (arguments_num > intreg_argnum)
-               ifmemuse = arguments_num - intreg_argnum;
+       if (rd->arguments_num > rd->intreg_argnum)
+               rd->ifmemuse = rd->arguments_num - rd->intreg_argnum;
 #endif
        else
-               ifmemuse = 0;
+               rd->ifmemuse = 0;
 #endif
 
-       iftmpintregcnt = tmpintregcnt;
-       ifsavintregcnt = savintregcnt;
-       iftmpfltregcnt = tmpfltregcnt;
-       ifsavfltregcnt = savfltregcnt;
+       rd->iftmpintregcnt = rd->tmpintregcnt;
+       rd->ifsavintregcnt = rd->savintregcnt;
+       rd->iftmpfltregcnt = rd->tmpfltregcnt;
+       rd->ifsavfltregcnt = rd->savfltregcnt;
 
-       for (s = 0; s < maxstack; s++) {
+       for (s = 0; s < cd->maxstack; s++) {
                intalloc = -1; fltalloc = -1;
-               saved = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
-                        interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
-                        interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
+               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 (t = TYPE_INT; t <= TYPE_ADR; t++) {
-                       v = &interfaces[s][t];
+                       v = &rd->interfaces[s][t];
                        if (v->type >= 0) {
 #ifdef USETWOREGS
                                regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
@@ -396,21 +318,21 @@ static void interface_regalloc()
                                if (!saved) {
                                        if (IS_FLT_DBL_TYPE(t)) {
                                                if (fltalloc >= 0) {
-                                                       v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
-                                                       v->regoff = interfaces[s][fltalloc].regoff;
+                                                       v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
+                                                       v->regoff = rd->interfaces[s][fltalloc].regoff;
                                                }
-                                               else if (iftmpfltregcnt > 0) {
-                                                       iftmpfltregcnt--;
-                                                       v->regoff = tmpfltregs[iftmpfltregcnt];
+                                               else if (rd->iftmpfltregcnt > 0) {
+                                                       rd->iftmpfltregcnt--;
+                                                       v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
                                                }
-                                               else if (ifsavfltregcnt > 0) {
-                                                       ifsavfltregcnt--;
-                                                       v->regoff = savfltregs[ifsavfltregcnt];
+                                               else if (rd->ifsavfltregcnt > 0) {
+                                                       rd->ifsavfltregcnt--;
+                                                       v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
                                                }
                                                else {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = ifmemuse;
-                                                       ifmemuse += regsneeded + 1;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
                                                }
                                                fltalloc = t;
                                        }
@@ -421,25 +343,25 @@ static void interface_regalloc()
                                                 */
                                                if (IS_2_WORD_TYPE(t)) {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = ifmemuse++;
+                                                       v->regoff = rd->ifmemuse++;
                                                } else {
 #endif
                                                        if (intalloc >= 0) {
-                                                               v->flags |= interfaces[s][intalloc].flags & INMEMORY;
-                                                               v->regoff = interfaces[s][intalloc].regoff;
+                                                               v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
+                                                               v->regoff = rd->interfaces[s][intalloc].regoff;
                                                        }
-                                                       else if (iftmpintregcnt > regsneeded) {
-                                                               iftmpintregcnt -= regsneeded + 1;
-                                                               v->regoff = tmpintregs[iftmpintregcnt];
+                                                       else if (rd->iftmpintregcnt > regsneeded) {
+                                                               rd->iftmpintregcnt -= regsneeded + 1;
+                                                               v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
                                                        }
-                                                       else if (ifsavintregcnt > regsneeded) {
-                                                               ifsavintregcnt -= regsneeded + 1;
-                                                               v->regoff = savintregs[ifsavintregcnt];
+                                                       else if (rd->ifsavintregcnt > regsneeded) {
+                                                               rd->ifsavintregcnt -= regsneeded + 1;
+                                                               v->regoff = rd->savintregs[rd->ifsavintregcnt];
                                                        }
                                                        else {
                                                                v->flags |= INMEMORY;
-                                                               v->regoff = ifmemuse;
-                                                               ifmemuse += regsneeded + 1;
+                                                               v->regoff = rd->ifmemuse;
+                                                               rd->ifmemuse += regsneeded + 1;
                                                        }
 #if defined(__I386__)
                                                }
@@ -450,17 +372,17 @@ static void interface_regalloc()
                                else {
                                        if (IS_FLT_DBL_TYPE(t)) {
                                                if (fltalloc >= 0) {
-                                                       v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
-                                                       v->regoff = interfaces[s][fltalloc].regoff;
+                                                       v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
+                                                       v->regoff = rd->interfaces[s][fltalloc].regoff;
                                                }
-                                               else if (ifsavfltregcnt > 0) {
-                                                       ifsavfltregcnt--;
-                                                       v->regoff = savfltregs[ifsavfltregcnt];
+                                               else if (rd->ifsavfltregcnt > 0) {
+                                                       rd->ifsavfltregcnt--;
+                                                       v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
                                                }
                                                else {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = ifmemuse;
-                                                       ifmemuse += regsneeded + 1;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
                                                }
                                                fltalloc = t;
                                        }
@@ -471,21 +393,21 @@ static void interface_regalloc()
                                                 */
                                                if (IS_2_WORD_TYPE(t)) {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = ifmemuse++;
+                                                       v->regoff = rd->ifmemuse++;
                                                } else {
 #endif
                                                        if (intalloc >= 0) {
-                                                               v->flags |= interfaces[s][intalloc].flags & INMEMORY;
-                                                               v->regoff = interfaces[s][intalloc].regoff;
+                                                               v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
+                                                               v->regoff = rd->interfaces[s][intalloc].regoff;
                                                        }
-                                                       else if (ifsavintregcnt > regsneeded) {
-                                                               ifsavintregcnt -= regsneeded + 1;
-                                                               v->regoff = savintregs[ifsavintregcnt];
+                                                       else if (rd->ifsavintregcnt > regsneeded) {
+                                                               rd->ifsavintregcnt -= regsneeded + 1;
+                                                               v->regoff = rd->savintregs[rd->ifsavintregcnt];
                                                        }
                                                        else {
                                                                v->flags |= INMEMORY;
-                                                               v->regoff = ifmemuse;
-                                                               ifmemuse += regsneeded + 1;
+                                                               v->regoff = rd->ifmemuse;
+                                                               rd->ifmemuse += regsneeded + 1;
                                                        }
 #if defined(__I386__)
                                                }
@@ -497,13 +419,13 @@ static void interface_regalloc()
                } /* for t */
        } /* for s */
 
-       maxmemuse = ifmemuse;
-       maxargintreguse = -1;
-       maxtmpintreguse = iftmpintregcnt;
-       maxsavintreguse = ifsavintregcnt;
-       maxargfltreguse = -1;
-       maxtmpfltreguse = iftmpfltregcnt;
-       maxsavfltreguse = ifsavfltregcnt;
+       rd->maxmemuse = rd->ifmemuse;
+       rd->maxargintreguse = -1;
+       rd->maxtmpintreguse = rd->iftmpintregcnt;
+       rd->maxsavintreguse = rd->ifsavintregcnt;
+       rd->maxargfltreguse = -1;
+       rd->maxtmpfltreguse = rd->iftmpfltregcnt;
+       rd->maxsavfltreguse = rd->ifsavfltregcnt;
 }
 
 
@@ -514,24 +436,24 @@ static void interface_regalloc()
        
 *******************************************************************************/
        
-static void local_regalloc()
+static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
 {
        int      s, t, tt;
        int      intalloc, fltalloc;
        varinfo *v;
        int      regsneeded = 0;
        int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
-       
-       if (isleafmethod) {
+
+       if (m->isleafmethod) {
                int arg, doublewordarg, iargcnt, fargcnt;
 
                arg = 0, iargcnt = 0, fargcnt = 0;
                doublewordarg = 0;
-               for (s = 0; s < maxlocals; s++) {
+               for (s = 0; s < cd->maxlocals; s++) {
                        intalloc = -1; fltalloc = -1;
                        for (tt = 0; tt <= 4; tt++) {
                                t = typeloop[tt];
-                               v = &locals[s][t];
+                               v = &rd->locals[s][t];
 
                                if (v->type >= 0) {
 #ifdef USETWOREGS
@@ -542,28 +464,28 @@ static void local_regalloc()
                                                fargcnt = arg;
 #endif
                                                if (fltalloc >= 0) {
-                                                       v->flags = locals[s][fltalloc].flags;
-                                                       v->regoff = locals[s][fltalloc].regoff;
+                                                       v->flags = rd->locals[s][fltalloc].flags;
+                                                       v->regoff = rd->locals[s][fltalloc].regoff;
                                                }
-                                               else if (!doublewordarg && (arg < mparamcount)
-                                                                && (fargcnt < fltreg_argnum)) {
+                                               else if (!doublewordarg && (arg < m->paramcount) &&
+                                                                (fargcnt < rd->fltreg_argnum)) {
                                                        v->flags = 0;
-                                                       v->regoff = argfltregs[fargcnt];
+                                                       v->regoff = rd->argfltregs[fargcnt];
                                                }
-                                               else if (maxtmpfltreguse > 0) {
-                                                       maxtmpfltreguse--;
+                                               else if (rd->maxtmpfltreguse > 0) {
+                                                       rd->maxtmpfltreguse--;
                                                        v->flags = 0;
-                                                       v->regoff = tmpfltregs[maxtmpfltreguse];
+                                                       v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
                                                }
-                                               else if (maxsavfltreguse > 0) {
-                                                       maxsavfltreguse--;
+                                               else if (rd->maxsavfltreguse > 0) {
+                                                       rd->maxsavfltreguse--;
                                                        v->flags = 0;
-                                                       v->regoff = savfltregs[maxsavfltreguse];
+                                                       v->regoff = rd->savfltregs[rd->maxsavfltreguse];
                                                }
                                                else {
                                                        v->flags = INMEMORY;
-                                                       v->regoff = maxmemuse;
-                                                       maxmemuse += regsneeded + 1;
+                                                       v->regoff = rd->maxmemuse;
+                                                       rd->maxmemuse += regsneeded + 1;
                                                }
                                                fltalloc = t;
 
@@ -575,50 +497,50 @@ static void local_regalloc()
                                                 */
                                                if (IS_2_WORD_TYPE(t)) {
                                                        v->flags = INMEMORY;
-                                                       v->regoff = maxmemuse++;
+                                                       v->regoff = rd->maxmemuse++;
                                                } else {
 #endif
 #if !defined(CONSECUTIVE_INTARGS)
                                                        iargcnt = arg;
 #endif
                                                        if (intalloc >= 0) {
-                                                               v->flags = locals[s][intalloc].flags;
-                                                               v->regoff = locals[s][intalloc].regoff;
+                                                               v->flags = rd->locals[s][intalloc].flags;
+                                                               v->regoff = rd->locals[s][intalloc].regoff;
                                                        }
-                                                       else if (!doublewordarg && (arg < mparamcount)
+                                                       else if (!doublewordarg && (arg < m->paramcount)
 #ifndef USETWOREGS
-                                                                        && ((regtouse = iargcnt) < intreg_argnum)
+                                                                        && ((regtouse = iargcnt) < rd->intreg_argnum)
 #else
-                                                                        && ((regtouse = s) < intreg_argnum - regsneeded)
+                                                                        && ((regtouse = s) < rd->intreg_argnum - regsneeded)
 #endif
                                                                         ) {
                                                                v->flags = 0;
-                                                               v->regoff = argintregs[regtouse];
+                                                               v->regoff = rd->argintregs[regtouse];
                                                        }
-                                                       else if (maxtmpintreguse > regsneeded) {
-                                                               maxtmpintreguse -= regsneeded + 1;
+                                                       else if (rd->maxtmpintreguse > regsneeded) {
+                                                               rd->maxtmpintreguse -= regsneeded + 1;
                                                                v->flags = 0;
-                                                               v->regoff = tmpintregs[maxtmpintreguse];
+                                                               v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
                                                        }
-                                                       else if (maxsavintreguse > regsneeded) {
-                                                               maxsavintreguse -= regsneeded + 1;
+                                                       else if (rd->maxsavintreguse > regsneeded) {
+                                                               rd->maxsavintreguse -= regsneeded + 1;
                                                                v->flags = 0;
-                                                               v->regoff = savintregs[maxsavintreguse];
+                                                               v->regoff = rd->savintregs[rd->maxsavintreguse];
                                                        }
                                                        /*
                                                         * use unused argument registers as local registers
                                                         */
-                                                       else if (!doublewordarg && (arg >= mparamcount)
-                                                                        && (iargcnt < intreg_argnum)) {
+                                                       else if (!doublewordarg && (arg >= m->paramcount) &&
+                                                                        (iargcnt < rd->intreg_argnum)) {
                                                                v->flags = 0;
-                                                               v->regoff = argintregs[iargcnt];
+                                                               v->regoff = rd->argintregs[iargcnt];
                                                                iargcnt++;
                                                                arg++;
                                                        }
                                                        else {
                                                                v->flags = INMEMORY;
-                                                               v->regoff = maxmemuse;
-                                                               maxmemuse += regsneeded + 1;
+                                                               v->regoff = rd->maxmemuse;
+                                                               rd->maxmemuse += regsneeded + 1;
                                                        }
 #if defined(__I386__)
                                                }
@@ -627,11 +549,11 @@ static void local_regalloc()
                                        }
                                }
                        }
-                       if (arg < mparamcount) {
+                       if (arg < m->paramcount) {
                                if (doublewordarg) {
                                        doublewordarg = 0;
                                        /* what type was the double arg? */
-                                       if (IS_FLT_DBL_TYPE(mparamtypes[arg])) {
+                                       if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
                                                fargcnt++;
 
                                        } else {
@@ -639,11 +561,11 @@ static void local_regalloc()
                                        }
                                        arg++;
 
-                               } else if (IS_2_WORD_TYPE(mparamtypes[arg])) {
+                               } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
                                        doublewordarg = 1;
 
                                } else {
-                                       if (IS_FLT_DBL_TYPE(mparamtypes[arg])) {
+                                       if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
                                                fargcnt++;
 
                                        } else {
@@ -656,29 +578,29 @@ static void local_regalloc()
                return;
        }
 
-       for (s = 0; s < maxlocals; s++) {
+       for (s = 0; s < cd->maxlocals; s++) {
                intalloc = -1; fltalloc = -1;
                for (tt=0; tt<=4; tt++) {
                        t = typeloop[tt];
-                       v = &locals[s][t];
+                       v = &rd->locals[s][t];
                        if (v->type >= 0) {
 #ifdef USETWOREGS
                                regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
                                if (IS_FLT_DBL_TYPE(t)) {
                                        if (fltalloc >= 0) {
-                                               v->flags = locals[s][fltalloc].flags;
-                                               v->regoff = locals[s][fltalloc].regoff;
+                                               v->flags = rd->locals[s][fltalloc].flags;
+                                               v->regoff = rd->locals[s][fltalloc].regoff;
                                        }
-                                       else if (maxsavfltreguse > 0) {
-                                               maxsavfltreguse--;
+                                       else if (rd->maxsavfltreguse > 0) {
+                                               rd->maxsavfltreguse--;
                                                v->flags = 0;
-                                               v->regoff = savfltregs[maxsavfltreguse];
+                                               v->regoff = rd->savfltregs[rd->maxsavfltreguse];
                                        }
                                        else {
                                                v->flags = INMEMORY;
-                                               v->regoff = maxmemuse;
-                                               maxmemuse += regsneeded + 1;
+                                               v->regoff = rd->maxmemuse;
+                                               rd->maxmemuse += regsneeded + 1;
                                        }
                                        fltalloc = t;
                                }
@@ -689,22 +611,22 @@ static void local_regalloc()
                                         */
                                        if (IS_2_WORD_TYPE(t)) {
                                                v->flags = INMEMORY;
-                                               v->regoff = maxmemuse++;
+                                               v->regoff = rd->maxmemuse++;
                                        } else {
 #endif
                                                if (intalloc >= 0) {
-                                                       v->flags = locals[s][intalloc].flags;
-                                                       v->regoff = locals[s][intalloc].regoff;
+                                                       v->flags = rd->locals[s][intalloc].flags;
+                                                       v->regoff = rd->locals[s][intalloc].regoff;
                                                }
-                                               else if (maxsavintreguse > regsneeded) {
-                                                       maxsavintreguse -= regsneeded+1;
+                                               else if (rd->maxsavintreguse > regsneeded) {
+                                                       rd->maxsavintreguse -= regsneeded+1;
                                                        v->flags = 0;
-                                                       v->regoff = savintregs[maxsavintreguse];
+                                                       v->regoff = rd->savintregs[rd->maxsavintreguse];
                                                }
                                                else {
                                                        v->flags = INMEMORY;
-                                                       v->regoff = maxmemuse;
-                                                       maxmemuse += regsneeded + 1;
+                                                       v->regoff = rd->maxmemuse;
+                                                       rd->maxmemuse += regsneeded + 1;
                                                }
 #if defined(__I386__)
                                        }
@@ -718,42 +640,43 @@ static void local_regalloc()
 
 
 
-static void reg_init_temp()
+static void reg_init_temp(registerdata *rd)
 {
-       freememtop = 0;
-       memuse = ifmemuse;
+       rd->freememtop = 0;
+       rd->memuse = rd->ifmemuse;
 
-       freearginttop = 0;
-       freetmpinttop = 0;
-       freesavinttop = 0;
-       freeargflttop = 0;
-       freetmpflttop = 0;
-       freesavflttop = 0;
+       rd->freetmpinttop = 0;
+       rd->freesavinttop = 0;
+       rd->freetmpflttop = 0;
+       rd->freesavflttop = 0;
 
-       tmpintreguse = iftmpintregcnt;
-       savintreguse = ifsavintregcnt;
-       tmpfltreguse = iftmpfltregcnt;
-       savfltreguse = ifsavfltregcnt;
+       rd->tmpintreguse = rd->iftmpintregcnt;
+       rd->savintreguse = rd->ifsavintregcnt;
+       rd->tmpfltreguse = rd->iftmpfltregcnt;
+       rd->savfltreguse = rd->ifsavfltregcnt;
 
        /* all argument registers are available */
-       argintreguse = intreg_argnum;
-       argfltreguse = fltreg_argnum;
+       rd->argintreguse = rd->intreg_argnum;
+       rd->argfltreguse = rd->fltreg_argnum;
 }
 
 
+#define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
 
-#define reg_new_temp(s) if (s->varkind == TEMPVAR) reg_new_temp_func(s)
 
-static void reg_new_temp_func(stackptr s)
+static void reg_new_temp_func(registerdata *rd, stackptr s)
 {
-       int regsneeded = 0;
+       s4 regsneeded;
+       s4 tryagain;
 
        /* Try to allocate a saved register if there is no temporary one          */
-    /* available. This is what happens during the second run.                 */
-       int tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
+       /* available. This is what happens during the second run.                 */
+       tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
 
 #ifdef USETWOREGS
        regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+       regsneeded = 0;
 #endif
 
        for(; tryagain; --tryagain) {
@@ -761,75 +684,75 @@ static void reg_new_temp_func(stackptr s)
                        if (!(s->flags & SAVEDVAR))
                                s->flags |= SAVEDTMP;
                        if (IS_FLT_DBL_TYPE(s->type)) {
-                               if (freesavflttop > 0) {
-                                       freesavflttop--;
-                                       s->regoff = freesavfltregs[freesavflttop];
+                               if (rd->freesavflttop > 0) {
+                                       rd->freesavflttop--;
+                                       s->regoff = rd->freesavfltregs[rd->freesavflttop];
                                        return;
-                               }
-                               else if (savfltreguse > 0) {
-                                       savfltreguse--;
-                                       if (savfltreguse < maxsavfltreguse)
-                                               maxsavfltreguse = savfltreguse;
-                                       s->regoff = savfltregs[savfltreguse];
+
+                               } else if (rd->savfltreguse > 0) {
+                                       rd->savfltreguse--;
+                                       if (rd->savfltreguse < rd->maxsavfltreguse)
+                                               rd->maxsavfltreguse = rd->savfltreguse;
+                                       s->regoff = rd->savfltregs[rd->savfltreguse];
                                        return;
                                }
-                       }
-                       else {
+
+                       else {
 #if defined(__I386__)
                                /*
                                 * for i386 put all longs in memory
                                 */
                                if (!IS_2_WORD_TYPE(s->type)) {
 #endif
-                                       if (freesavinttop > regsneeded) {
-                                               freesavinttop -= regsneeded + 1;
-                                               s->regoff = freesavintregs[freesavinttop];
+                                       if (rd->freesavinttop > regsneeded) {
+                                               rd->freesavinttop -= regsneeded + 1;
+                                               s->regoff = rd->freesavintregs[rd->freesavinttop];
                                                return;
-                                       }
-                                       else if (savintreguse > regsneeded) {
-                                               savintreguse -= regsneeded + 1;
-                                               if (savintreguse < maxsavintreguse)
-                                                       maxsavintreguse = savintreguse;
-                                               s->regoff = savintregs[savintreguse];
+
+                                       } else if (rd->savintreguse > regsneeded) {
+                                               rd->savintreguse -= regsneeded + 1;
+                                               if (rd->savintreguse < rd->maxsavintreguse)
+                                                       rd->maxsavintreguse = rd->savintreguse;
+                                               s->regoff = rd->savintregs[rd->savintreguse];
                                                return;
                                        }
 #if defined(__I386__)
                                }
 #endif
                        }
-               }
-               else {
+
+               else {
                        if (IS_FLT_DBL_TYPE(s->type)) {
-                               if (freetmpflttop > 0) {
-                                       freetmpflttop--;
-                                       s->regoff = freetmpfltregs[freetmpflttop];
+                               if (rd->freetmpflttop > 0) {
+                                       rd->freetmpflttop--;
+                                       s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
                                        return;
-                               }
-                               else if (tmpfltreguse > 0) {
-                                       tmpfltreguse--;
-                                       if (tmpfltreguse < maxtmpfltreguse)
-                                               maxtmpfltreguse = tmpfltreguse;
-                                       s->regoff = tmpfltregs[tmpfltreguse];
+
+                               } else if (rd->tmpfltreguse > 0) {
+                                       rd->tmpfltreguse--;
+                                       if (rd->tmpfltreguse < rd->maxtmpfltreguse)
+                                               rd->maxtmpfltreguse = rd->tmpfltreguse;
+                                       s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
                                        return;
                                }
-                       }
-                       else {
+
+                       else {
 #if defined(__I386__)
                                /*
                                 * for i386 put all longs in memory
                                 */
                                if (!IS_2_WORD_TYPE(s->type)) {
 #endif
-                                       if (freetmpinttop > regsneeded) {
-                                               freetmpinttop -= regsneeded + 1;
-                                               s->regoff = freetmpintregs[freetmpinttop];
+                                       if (rd->freetmpinttop > regsneeded) {
+                                               rd->freetmpinttop -= regsneeded + 1;
+                                               s->regoff = rd->freetmpintregs[rd->freetmpinttop];
                                                return;
-                                       }
-                                       else if (tmpintreguse > regsneeded) {
-                                               tmpintreguse -= regsneeded + 1;
-                                               if (tmpintreguse < maxtmpintreguse)
-                                                       maxtmpintreguse = tmpintreguse;
-                                               s->regoff = tmpintregs[tmpintreguse];
+
+                                       } else if (rd->tmpintreguse > regsneeded) {
+                                               rd->tmpintreguse -= regsneeded + 1;
+                                               if (rd->tmpintreguse < rd->maxtmpintreguse)
+                                                       rd->maxtmpintreguse = rd->tmpintreguse;
+                                               s->regoff = rd->tmpintregs[rd->tmpintreguse];
                                                return;
                                        }
 #if defined(__I386__)
@@ -839,87 +762,92 @@ static void reg_new_temp_func(stackptr s)
                }
        }
 
-       if (freememtop > regsneeded) {
-               freememtop -= regsneeded + 1;
-               s->regoff = freemem[freememtop];
-       }
-       else {
-               s->regoff = memuse;
-               memuse += regsneeded + 1;
-               if (memuse > maxmemuse)
-                       maxmemuse = memuse;
+       if (rd->freememtop > regsneeded) {
+               rd->freememtop -= regsneeded + 1;
+               s->regoff = rd->freemem[rd->freememtop];
+
+       else {
+               s->regoff = rd->memuse;
+               rd->memuse += regsneeded + 1;
+               if (rd->memuse > rd->maxmemuse)
+                       rd->maxmemuse = rd->memuse;
        }
        s->flags |= INMEMORY;
 }
 
 
+#define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
 
-#define reg_free_temp(s) if (s->varkind == TEMPVAR) reg_free_temp_func(s)
 
-static void reg_free_temp_func(stackptr s)
+static void reg_free_temp_func(registerdata *rd, stackptr s)
 {
-       int regsneeded = 0;
+       s4 regsneeded;
 
 #ifdef USETWOREGS
        regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+       regsneeded = 0;
 #endif
 
        if (s->flags & INMEMORY) {
-               freemem[freememtop] = s->regoff;
+               rd->freemem[rd->freememtop] = s->regoff;
                if (regsneeded)
-                       freemem[freememtop + 1] = s->regoff + 1;
-               freememtop += regsneeded + 1;
-       }
-       else if (IS_FLT_DBL_TYPE(s->type)) {
+                       rd->freemem[rd->freememtop + 1] = s->regoff + 1;
+               rd->freememtop += regsneeded + 1;
+
+       else if (IS_FLT_DBL_TYPE(s->type)) {
                if (s->flags & (SAVEDVAR | SAVEDTMP)) {
                        s->flags &= ~SAVEDTMP;
-                       freesavfltregs[freesavflttop++] = s->regoff;
+                       rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
+
                } else
-                       freetmpfltregs[freetmpflttop++] = s->regoff;
-       }
-       else {
+                       rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
+
+       else {
                if (s->flags & (SAVEDVAR | SAVEDTMP)) {
                        s->flags &= ~SAVEDTMP;
-                       freesavintregs[freesavinttop] = s->regoff;
+                       rd->freesavintregs[rd->freesavinttop] = s->regoff;
 #ifdef USETWOREGS
                        if (regsneeded)
-                               freesavintregs[freesavinttop + 1] = secondregs[s->regoff];
+                               rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
 #endif
-                       freesavinttop += regsneeded + 1;
+                       rd->freesavinttop += regsneeded + 1;
+
                } else {
-                       freetmpintregs[freetmpinttop] = s->regoff;
+                       rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
 #ifdef USETWOREGS
                        if (regsneeded)
-                               freetmpintregs[freetmpinttop + 1] = secondregs[s->regoff];
+                               rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
 #endif
-                       freetmpinttop += regsneeded + 1;
+                       rd->freetmpinttop += regsneeded + 1;
                }
        }
 }
 
 
 
-static void allocate_scratch_registers()
+static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
 {
-       int opcode;
-       int i;
-       int len;
+       s4 opcode;
+       s4 i;
+       s4 len;
        stackptr    src;
        stackptr    dst;
        instruction *iptr;
        basicblock  *bptr;
 
-       /* b_count = block_count; */
+       bptr = m->basicblocks;
 
-       bptr = block;
        while (bptr != NULL) {
-
                if (bptr->flags >= BBREACHED) {
                        dst = bptr->instack;
-                       reg_init_temp();
+
+                       /* initialize temp registers */
+                       reg_init_temp(rd);
+
                        iptr = bptr->iinstr;
                        len = bptr->icount;
-  
+
                        while (--len >= 0)  {
                                src = dst;
                                dst = iptr->dst;
@@ -938,6 +866,8 @@ static void allocate_scratch_registers()
                                case ICMD_RET:
                                case ICMD_RETURN:
                                case ICMD_GOTO:
+                               case ICMD_INLINE_START:
+                               case ICMD_INLINE_END:
                                        break;
 
                                        /* pop 0 push 1 const */
@@ -955,7 +885,7 @@ static void allocate_scratch_registers()
                                case ICMD_FLOAD:
                                case ICMD_DLOAD:
                                case ICMD_ALOAD:
-                                       reg_new_temp(dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 2 push 1 */
@@ -969,10 +899,9 @@ static void allocate_scratch_registers()
                                case ICMD_BALOAD:
                                case ICMD_CALOAD:
                                case ICMD_SALOAD:
-
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
-                                       reg_new_temp(dst);
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 3 push 0 */
@@ -986,10 +915,9 @@ static void allocate_scratch_registers()
                                case ICMD_BASTORE:
                                case ICMD_CASTORE:
                                case ICMD_SASTORE:
-
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
-                                       reg_free_temp(src->prev->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_free_temp(rd, src->prev->prev);
                                        break;
 
                                        /* pop 1 push 0 store */
@@ -1041,7 +969,7 @@ static void allocate_scratch_registers()
                                case ICMD_NULLCHECKPOP:
                                case ICMD_MONITORENTER:
                                case ICMD_MONITOREXIT:
-                                       reg_free_temp(src);
+                                       reg_free_temp(rd, src);
                                        break;
 
                                        /* pop 2 push 0 branch */
@@ -1068,80 +996,87 @@ static void allocate_scratch_registers()
                                case ICMD_POP2:
 
                                case ICMD_PUTFIELD:
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
+
+                               case ICMD_IASTORECONST:
+                               case ICMD_LASTORECONST:
+                               case ICMD_AASTORECONST:
+                               case ICMD_BASTORECONST:
+                               case ICMD_CASTORECONST:
+                               case ICMD_SASTORECONST:
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
                                        break;
 
                                        /* pop 0 push 1 dup */
                                        
                                case ICMD_DUP:
-                                       reg_new_temp(dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 0 push 2 dup */
                                        
                                case ICMD_DUP2:
-                                       reg_new_temp(dst->prev);
-                                       reg_new_temp(dst);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 2 push 3 dup */
                                        
                                case ICMD_DUP_X1:
-                                       reg_new_temp(dst->prev->prev);
-                                       reg_new_temp(dst->prev);
-                                       reg_new_temp(dst);
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_new_temp(rd, dst->prev->prev);
                                        break;
 
                                        /* pop 3 push 4 dup */
                                        
                                case ICMD_DUP_X2:
-                                       reg_new_temp(dst->prev->prev->prev);
-                                       reg_new_temp(dst->prev->prev);
-                                       reg_new_temp(dst->prev);
-                                       reg_new_temp(dst);
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
-                                       reg_free_temp(src->prev->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_free_temp(rd, src->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev->prev);
                                        break;
 
                                        /* pop 3 push 5 dup */
                                        
                                case ICMD_DUP2_X1:
-                                       reg_new_temp(dst->prev->prev->prev->prev);
-                                       reg_new_temp(dst->prev->prev->prev);
-                                       reg_new_temp(dst->prev->prev);
-                                       reg_new_temp(dst->prev);
-                                       reg_new_temp(dst);
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
-                                       reg_free_temp(src->prev->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_free_temp(rd, src->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev->prev->prev);
                                        break;
 
                                        /* pop 4 push 6 dup */
                                        
                                case ICMD_DUP2_X2:
-                                       reg_new_temp(dst->prev->prev->prev->prev->prev);
-                                       reg_new_temp(dst->prev->prev->prev->prev);
-                                       reg_new_temp(dst->prev->prev->prev);
-                                       reg_new_temp(dst->prev->prev);
-                                       reg_new_temp(dst->prev);
-                                       reg_new_temp(dst);
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
-                                       reg_free_temp(src->prev->prev);
-                                       reg_free_temp(src->prev->prev->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_free_temp(rd, src->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev);
+                                       reg_free_temp(rd, src->prev->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev->prev->prev);
+                                       reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
                                        break;
 
                                        /* pop 2 push 2 swap */
                                        
                                case ICMD_SWAP:
-                                       reg_new_temp(dst->prev);
-                                       reg_new_temp(dst);
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 2 push 1 */
@@ -1190,9 +1125,9 @@ static void allocate_scratch_registers()
                                case ICMD_FCMPG:
                                case ICMD_DCMPL:
                                case ICMD_DCMPG:
-                                       reg_free_temp(src);
-                                       reg_free_temp(src->prev);
-                                       reg_new_temp(dst);
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 1 push 1 */
@@ -1202,7 +1137,6 @@ static void allocate_scratch_registers()
                                case ICMD_IMULCONST:
                                case ICMD_IDIVPOW2:
                                case ICMD_IREMPOW2:
-                               case ICMD_IREM0X10001:
                                case ICMD_IANDCONST:
                                case ICMD_IORCONST:
                                case ICMD_IXORCONST:
@@ -1215,7 +1149,6 @@ static void allocate_scratch_registers()
                                case ICMD_LMULCONST:
                                case ICMD_LDIVPOW2:
                                case ICMD_LREMPOW2:
-                               case ICMD_LREM0X10001:
                                case ICMD_LANDCONST:
                                case ICMD_LORCONST:
                                case ICMD_LXORCONST:
@@ -1260,8 +1193,8 @@ static void allocate_scratch_registers()
                                case ICMD_ANEWARRAY:
 
                                case ICMD_GETFIELD:
-                                       reg_free_temp(src);
-                                       reg_new_temp(dst);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 0 push 1 */
@@ -1269,8 +1202,7 @@ static void allocate_scratch_registers()
                                case ICMD_GETSTATIC:
 
                                case ICMD_NEW:
-
-                                       reg_new_temp(dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop many push any */
@@ -1279,41 +1211,39 @@ static void allocate_scratch_registers()
                                case ICMD_INVOKESPECIAL:
                                case ICMD_INVOKESTATIC:
                                case ICMD_INVOKEINTERFACE:
-                                       {
-                                               i = iptr->op1;
-                                               while (--i >= 0) {
-                                                       reg_free_temp(src);
-                                                       src = src->prev;
-                                               }
-                                               if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
-                                                       reg_new_temp(dst);
-                                               break;
+                                       i = iptr->op1;
+                                       while (--i >= 0) {
+                                               reg_free_temp(rd, src);
+                                               src = src->prev;
                                        }
+                                       if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
+                                               reg_new_temp(rd, dst);
+                                       break;
 
                                case ICMD_BUILTIN3:
-                                       reg_free_temp(src);
+                                       reg_free_temp(rd, src);
                                        src = src->prev;
                                case ICMD_BUILTIN2:
-                                       reg_free_temp(src);
+                                       reg_free_temp(rd, src);
                                        src = src->prev;
                                case ICMD_BUILTIN1:
-                                       reg_free_temp(src);
+                                       reg_free_temp(rd, src);
                                        src = src->prev;
                                        if (iptr->op1 != TYPE_VOID)
-                                               reg_new_temp(dst);
+                                               reg_new_temp(rd, dst);
                                        break;
 
                                case ICMD_MULTIANEWARRAY:
                                        i = iptr->op1;
                                        while (--i >= 0) {
-                                               reg_free_temp(src);
+                                               reg_free_temp(rd, src);
                                                src = src->prev;
                                        }
-                                       reg_new_temp(dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                default:
-                                       printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+                                       printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
                                        panic("Missing ICMD code during register allocation");
                                } /* switch */
                                iptr++;