Enable lazy loading for i386.
[cacao.git] / src / vm / jit / reg.inc
index ba0f7ccfc901577383d7a36e504a871765fc69ad..09e7f54b55359ac5383c4ee4302a3a957f6f734a 100644 (file)
@@ -1,10 +1,9 @@
-/* jit/reg.inc - register allocator
+/* src/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 1342 2004-07-21 16:10:17Z twisti $
+   $Id: reg.inc 2333 2005-04-22 13:26:36Z twisti $
 
 */
 
 
-#include "jit/reg.h"
-#include "toolbox/memory.h"
+#include "arch.h"
+#include "mm/memory.h"
+#include "vm/method.h"          
+#include "vm/resolve.h"
+#include "vm/jit/reg.h"
 
 
 /* function prototypes for this file */
 
-static void interface_regalloc(methodinfo *m);
-static void local_regalloc(methodinfo *m);
-static void allocate_scratch_registers(methodinfo *m);
+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);
 
 
-/* function reg_init ***********************************************************
+/* reg_init ********************************************************************
 
-       initialises the register-allocator
+   TODO
        
 *******************************************************************************/
 
-void reg_init(methodinfo *m)
+void reg_init()
 {
-       s4 n;
-       registerdata *r;
+       /* void */
+}
+
 
-       /* allocate registers structure */
-       m->registerdata = NEW(registerdata);
+/* reg_setup *******************************************************************
 
-       /* keep code size smaller */
-       r = m->registerdata;
+   TODO
+
+*******************************************************************************/
+
+void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
+{
+       s4 i;
+       varinfo5 *v;
 
        /* setup the integer register table */
-       r->intreg_argnum = 0;
-       r->tmpintregcnt = 0;
-       r->savintregcnt = 0;
+       rd->intreg_argnum = 0;
+       rd->tmpintregcnt = 0;
+       rd->savintregcnt = 0;
 
-       for (r->intregsnum = 0; nregdescint[r->intregsnum] != REG_END; r->intregsnum++) {
-               switch (nregdescint[r->intregsnum]) {
+       for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
+               switch (nregdescint[rd->intregsnum]) {
                case REG_SAV:
-                       r->savintregcnt++;
+                       rd->savintregcnt++;
                        break;
                case REG_TMP:
-                       r->tmpintregcnt++;
+                       rd->tmpintregcnt++;
                        break;
                case REG_ARG:
-                       r->intreg_argnum++;
+                       rd->intreg_argnum++;
                        break;
                }
        }
 
-       r->argintregs = MNEW(s4, r->intreg_argnum);
-       r->tmpintregs = MNEW(s4, r->tmpintregcnt);
-       r->savintregs = MNEW(s4, r->savintregcnt);
-       r->freeargintregs = MNEW(s4, r->intreg_argnum);
-       r->freetmpintregs = MNEW(s4, r->tmpintregcnt);
-       r->freesavintregs = MNEW(s4, r->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
-       r->secondregs = MNEW(s4, r->intregsnum);
+       rd->secondregs = DMNEW(s4, rd->intregsnum);
 #endif
 
-       r->intreg_argnum = 0;
-       r->argintreguse = 0;
-       r->tmpintreguse = 0;
-       r->savintreguse = 0;
+       rd->intreg_argnum = 0;
+       rd->argintreguse = 0;
+       rd->tmpintreguse = 0;
+       rd->savintreguse = 0;
 
-       for (n = 0; n < r->intregsnum; n++) {
-               switch (nregdescint[n]) {
+       for (i = 0; i < rd->intregsnum; i++) {
+               switch (nregdescint[i]) {
                case REG_RET:
-                       r->intreg_ret = n
+                       rd->intreg_ret = i
                        break;
                case REG_SAV:
-                       r->savintregs[r->savintreguse++] = n;
+                       rd->savintregs[rd->savintreguse++] = i;
                        break;
                case REG_TMP:
-                       r->tmpintregs[r->tmpintreguse++] = n;
+                       rd->tmpintregs[rd->tmpintreguse++] = i; 
                        break;
                case REG_ARG:
-                       r->argintregs[r->intreg_argnum++] = n;
-                       r->argintreguse++;
+                       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 = r->tmpintregs[0];
-       r->tmpintregs[0] = r->tmpintregs[2];
-       r->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 = r->argintregs[3];
-       r->argintregs[3] = r->argintregs[0];
-       r->argintregs[0] = n;
+       i = rd->argintregs[3];
+       rd->argintregs[3] = rd->argintregs[0];
+       rd->argintregs[0] = i;
 
-       n = r->argintregs[2];
-       r->argintregs[2] = r->argintregs[1];
-       r->argintregs[1] = n;
+       i = rd->argintregs[2];
+       rd->argintregs[2] = rd->argintregs[1];
+       rd->argintregs[1] = i;
 #endif
                
 #ifdef USETWOREGS
-       for (n = 1; n < r->intreg_argnum; n++)
-               r->secondregs[r->argintregs[n - 1]] = r->argintregs[n];
-       for (n = 1; n < r->tmpintregcnt; n++)
-               r->secondregs[r->tmpintregs[n - 1]] = r->tmpintregs[n];
-       for (n = 1; n < r->savintregcnt; n++)
-               r->secondregs[r->savintregs[n - 1]] = r->savintregs[n];
-
-       r->secondregs[REG_ITMP1] = REG_ITMP2;
-       r->secondregs[REG_ITMP3] = REG_ITMP2;
-       r->secondregs[REG_RESULT] = REG_RESULT + 1;
-       r->secondregs[r->argintregs[r->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 */
-       r->fltreg_argnum = 0;
-       r->tmpfltregcnt = 0;
-       r->savfltregcnt = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       /* setup the address register table */
+       rd->adrreg_argnum = 0;
+       rd->tmpadrregcnt = 0;
+       rd->savadrregcnt = 0;
 
-       for (r->floatregsnum = 0; nregdescfloat[r->floatregsnum] != REG_END; r->floatregsnum++) {
-               switch (nregdescfloat[r->floatregsnum]) {
+       for (rd->adrregsnum = 0; nregdescadr[rd->adrregsnum] != REG_END; rd->adrregsnum++) {
+               switch (nregdescadr[rd->adrregsnum]) {
                case REG_SAV:
-                       r->savfltregcnt++;
+                       rd->savadrregcnt++;
                        break;
                case REG_TMP:
-                       r->tmpfltregcnt++;
+                       rd->tmpadrregcnt++;
                        break;
                case REG_ARG:
-                       r->fltreg_argnum++;
+                       rd->adrreg_argnum++;
                        break;
                }
        }
 
-       r->argfltregs = MNEW(s4, r->fltreg_argnum);
-       r->tmpfltregs = MNEW(s4, r->tmpfltregcnt);
-       r->savfltregs = MNEW(s4, r->savfltregcnt);
-       r->freeargfltregs = MNEW(s4, r->fltreg_argnum);
-       r->freetmpfltregs = MNEW(s4, r->tmpfltregcnt);
-       r->freesavfltregs = MNEW(s4, r->savfltregcnt);
+       rd->argadrregs = DMNEW(s4, rd->adrreg_argnum);
+       rd->tmpadrregs = DMNEW(s4, rd->tmpadrregcnt);
+       rd->savadrregs = DMNEW(s4, rd->savadrregcnt);
+       rd->freeargadrregs = DMNEW(s4, rd->adrreg_argnum);
+       rd->freetmpadrregs = DMNEW(s4, rd->tmpadrregcnt);
+       rd->freesavadrregs = DMNEW(s4, rd->savadrregcnt);
 
-       r->fltreg_argnum = 0;
-       r->argfltreguse = 0;
-       r->tmpfltreguse = 0;
-       r->savfltreguse = 0;
+       rd->adrreg_argnum = 0;
+       rd->argadrreguse = 0;
+       rd->tmpadrreguse = 0;
+       rd->savadrreguse = 0;
 
-       for (n = 0; n < r->floatregsnum; n++) {
-               switch (nregdescfloat[n]) {
+       for (i = 0; i < rd->adrregsnum; i++) {
+               switch (nregdescadr[i]) {
                case REG_RET:
-                       r->floatreg_ret = n
+                       rd->adrreg_ret = i
                        break;
                case REG_SAV:
-                       r->savfltregs[r->savfltreguse++] = n;
+                       rd->savadrregs[rd->savadrreguse++] = i;
                        break;
                case REG_TMP:
-                       r->tmpfltregs[r->tmpfltreguse++] = n;
+                       rd->tmpadrregs[rd->tmpadrreguse++] = i; 
                        break;
                case REG_ARG:
-                       r->argfltregs[r->fltreg_argnum++] = n;
-                       r->argfltreguse++;
+                       rd->argadrregs[rd->adrreg_argnum++] = i;
+                       rd->argadrreguse++;
                        break;
                }
        }
-}
 
+/* #if defined(????) */
+       /* 
+        * on xdsp the argument registers are in ascending order ???
+        */
+/* #endif */
+#endif
+               
+       /* setup the float register table */
+       rd->fltreg_argnum = 0;
+       rd->tmpfltregcnt = 0;
+       rd->savfltregcnt = 0;
 
-void reg_setup(methodinfo *m)
-{
-       s4 i;
-       varinfo5 *v;
+       for (rd->fltregsnum = 0; nregdescfloat[rd->fltregsnum] != REG_END; rd->fltregsnum++) {
+               switch (nregdescfloat[rd->fltregsnum]) {
+               case REG_SAV:
+                       rd->savfltregcnt++;
+                       break;
+               case REG_TMP:
+                       rd->tmpfltregcnt++;
+                       break;
+               case REG_ARG:
+                       rd->fltreg_argnum++;
+                       break;
+               }
+       }
+
+       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);
 
-       m->registerdata->freemem    = MNEW(s4, m->maxstack);
-       m->registerdata->locals     = MNEW(varinfo5, m->maxlocals);
-       m->registerdata->interfaces = MNEW(varinfo5, m->maxstack);
+       rd->fltreg_argnum = 0;
+       rd->argfltreguse = 0;
+       rd->tmpfltreguse = 0;
+       rd->savfltreguse = 0;
 
-       for (v = m->registerdata->locals, i = m->maxlocals; i > 0; v++, i--) {
+       for (i = 0; i < rd->fltregsnum; i++) {
+               switch (nregdescfloat[i]) {
+               case REG_RET:
+                       rd->fltreg_ret = i;
+                       break;
+               case REG_SAV:
+                       rd->savfltregs[rd->savfltreguse++] = i;
+                       break;
+               case REG_TMP:
+                       rd->tmpfltregs[rd->tmpfltreguse++] = i;
+                       break;
+               case REG_ARG:
+                       rd->argfltregs[rd->fltreg_argnum++] = i;
+                       rd->argfltreguse++;
+                       break;
+               }
+       }
+
+
+       rd->freemem    = DMNEW(s4, id->cummaxstack);
+       rd->locals     = DMNEW(varinfo5, id->cumlocals);
+       rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
+
+       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;
@@ -221,7 +270,7 @@ void reg_setup(methodinfo *m)
                v[0][TYPE_ADR].type = -1;
        }
 
-       for (v = m->registerdata->interfaces, i = m->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;
@@ -233,46 +282,40 @@ void reg_setup(methodinfo *m)
                v[0][TYPE_ADR].type = -1;
                v[0][TYPE_ADR].flags = 0;
        }
+#ifdef SPECIALMEMUSE
+       rd->ifmemuse = 6 + 8; /* 6*4=24 byte linkage area + 8*4=32 byte minimum parameter Area */
+#else
+       rd->ifmemuse = 0; /* init to zero -> analyse_stack will set it to a higher value, if appropriate */
+#endif
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       rd->argadrreguse = 0;
+#endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
+       rd->argintreguse = 0;/*Set argintreguse to rd->intreg_argnum to not use unused arguments as temp register*/
+       rd->argfltreguse = 0;/*Set argfltreguse to rd->fltreg_argnum to not use unused arguments as temp register*/
 }
 
 
-/* function reg_close **********************************************************
+/* function reg_free ***********************************************************
 
-       releases all allocated space for registers
+   releases all allocated space for registers
 
 *******************************************************************************/
 
-void reg_close(methodinfo *m)
+void reg_free(methodinfo *m, registerdata *rd)
 {
-       registerdata *r;
-
-       /* keep code size smaller */
-       r = m->registerdata;
+       /* void */
+}
 
-       if (r->argintregs) MFREE(r->argintregs, s4, r->intreg_argnum);
-       if (r->argfltregs) MFREE(r->argfltregs, s4, r->fltreg_argnum);
-       if (r->tmpintregs) MFREE(r->tmpintregs, s4, r->tmpintregcnt);
-       if (r->savintregs) MFREE(r->savintregs, s4, r->savintregcnt);
-       if (r->tmpfltregs) MFREE(r->tmpfltregs, s4, r->tmpfltregcnt);
-       if (r->savfltregs) MFREE(r->savfltregs, s4, r->savfltregcnt);
 
-       if (r->freeargintregs) MFREE(r->freeargintregs, s4, r->intreg_argnum);
-       if (r->freeargfltregs) MFREE(r->freeargfltregs, s4, r->fltreg_argnum);
-       if (r->freetmpintregs) MFREE(r->freetmpintregs, s4, r->tmpintregcnt);
-       if (r->freesavintregs) MFREE(r->freesavintregs, s4, r->savintregcnt);
-       if (r->freetmpfltregs) MFREE(r->freetmpfltregs, s4, r->tmpfltregcnt);
-       if (r->freesavfltregs) MFREE(r->freesavfltregs, s4, r->savfltregcnt);
+/* reg_close *******************************************************************
 
-#ifdef USETWOREGS
-       if (r->secondregs) MFREE(r->secondregs, s4, r->intregsnum);
-#endif
+   TODO
 
-       if (r->freemem) MFREE(r->freemem, s4, m->maxstack);
-       if (r->locals)  MFREE(r->locals, varinfo5, m->maxlocals);
-       if (r->interfaces) MFREE(r->interfaces, varinfo5, m->maxstack);
+*******************************************************************************/
 
-       FREE(m->registerdata, registerdata);
-       m->registerdata = NULL;
+void reg_close()
+{
+       /* void */
 }
 
 
@@ -282,21 +325,15 @@ void reg_close(methodinfo *m)
        
 *******************************************************************************/
        
-void regalloc(methodinfo *m)
+void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
 {
-#if defined(__I386__)
-       /* remove %ecx and/or %edx from tmpintregs */
-       int origtmpintregcnt = m->registerdata->tmpintregcnt;
-       if (method_uses_ecx) m->registerdata->tmpintregcnt--;
-       if (method_uses_edx) m->registerdata->tmpintregcnt--;
-#endif
-
-       interface_regalloc(m);
-       allocate_scratch_registers(m);
-       local_regalloc(m);
-
-#if defined(__I386__)
-       m->registerdata->tmpintregcnt = origtmpintregcnt;
+       interface_regalloc(m, cd, rd);
+       allocate_scratch_registers(m, rd);
+       local_regalloc(m, cd, rd);
+#ifdef INVOKE_NEW_DEBUG
+               if (compileverbose) {
+                       printf("maxmemuse by reg.inc: %3i\n",rd->maxmemuse);
+               }
 #endif
 }
 
@@ -307,74 +344,107 @@ void regalloc(methodinfo *m)
        
 *******************************************************************************/
        
-static void interface_regalloc(methodinfo *m)
+static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
 {
        int     s, t, saved;
-       int     intalloc, fltalloc;
+       int     intalloc, fltalloc; /* ?per Interface slot only one flt or one int type can be allocated to a register? */
        varinfo *v;
        int             regsneeded = 0;
-       registerdata *r;
 
        /* allocate stack space for passing arguments to called methods */
+#ifdef INVOKE_NEW_DEBUG
+       int temp;
+
+       if (compileverbose) {
+printf("analyse: argintru %3i argfltru %3i ifmemu %3i\n", rd->argintreguse, rd->argfltreguse, rd->ifmemuse);
+               temp = rd->ifmemuse;
+#if !defined(SPECIALMEMUSE)
+               /* For this to work properly the integer argument register count must be  */
+               /* less or equal the float argument register count (e.g. x86_64).         */
+               /* (arch.h: INT_ARG_CNT <= FLT_ARG_CNT)                                   */
+               if (rd->arguments_num > INT_ARG_CNT) {
+                       rd->ifmemuse = rd->arguments_num - INT_ARG_CNT;
 
-       /* keep code size smaller */
-       r = m->registerdata;
-
-#ifndef SPECIALMEMUSE
-#if defined(__X86_64__)
-       /*
-        * XXX: we have a problem here, but allocating a little more stack space
-        *      is better than having a bug
-        */
-       /*      if (arguments_num > (intreg_argnum + fltreg_argnum)) */
-       /*              ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
-       if (r->arguments_num > r->fltreg_argnum)
-               r->ifmemuse = r->arguments_num - r->fltreg_argnum;
-#else
-       if (r->arguments_num > r->intreg_argnum)
-               r->ifmemuse = r->arguments_num - r->intreg_argnum;
+               } else {
+                       rd->ifmemuse = 0;
+               }
 #endif
-       else
-               r->ifmemuse = 0;
+               if (compileverbose) {
+                       printf("ifmemuse by reg.inc: %3i by stack.c: %3i\n",rd->ifmemuse,temp);
+                       if (temp != rd->ifmemuse)
+                               printf("Warning: Difference in ifmemuse calculated the old way and the new way\n");
+               }
+               rd->ifmemuse = temp;
+       }
 #endif
 
-       r->iftmpintregcnt = r->tmpintregcnt;
-       r->ifsavintregcnt = r->savintregcnt;
-       r->iftmpfltregcnt = r->tmpfltregcnt;
-       r->ifsavfltregcnt = r->savfltregcnt;
-
-       for (s = 0; s < m->maxstack; s++) {
+       rd->iftmpintregcnt = rd->tmpintregcnt;
+       rd->ifsavintregcnt = rd->savintregcnt;
+       rd->iftmpfltregcnt = rd->tmpfltregcnt;
+       rd->ifsavfltregcnt = rd->savfltregcnt;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->iftmpadrregcnt = rd->tmpadrregcnt;
+       rd->ifsavadrregcnt = rd->savadrregcnt;
+#endif
+       rd->ifargintregcnt = rd->argintreguse;
+       rd->ifargfltregcnt = rd->argfltreguse;
+       for (s = 0; s < cd->maxstack; s++) {
                intalloc = -1; fltalloc = -1;
-               saved = (r->interfaces[s][TYPE_INT].flags |
-                                r->interfaces[s][TYPE_LNG].flags |
-                        r->interfaces[s][TYPE_FLT].flags |
-                                r->interfaces[s][TYPE_DBL].flags |
-                        r->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 = &r->interfaces[s][t];
+                       v = &rd->interfaces[s][t];
                        if (v->type >= 0) {
 #ifdef USETWOREGS
                                regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
 #endif
                                if (!saved) {
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       if (t == TYPE_ADR) {
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+                                               if (!m->isleafmethod &&(rd->ifargadrregcnt < rd->adrreg_argnum)) {
+                                                       v->regoff = rd->argadrregs[rd->ifargadrregcnt++];
+                                               } else 
+#endif 
+                                               if (rd->iftmpadrregcnt > 0) {
+                                                       rd->iftmpadrregcnt--;
+                                                       v->regoff = rd->tmpadrregs[rd->iftmpadrregcnt];
+                                               }
+                                               else if (rd->ifsavadrregcnt > 0) {
+                                                       rd->ifsavadrregcnt--;
+                                                       v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
+                                               }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
+                                               }                                               
+                                       } else {
+#endif
                                        if (IS_FLT_DBL_TYPE(t)) {
                                                if (fltalloc >= 0) {
-                                                       v->flags |= r->interfaces[s][fltalloc].flags & INMEMORY;
-                                                       v->regoff = r->interfaces[s][fltalloc].regoff;
+                                                       v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
+                                                       v->regoff = rd->interfaces[s][fltalloc].regoff;
+                                               }
+                                               else if (!m->isleafmethod &&(rd->ifargfltregcnt < rd->fltreg_argnum)) {
+                                                       v->regoff = rd->argfltregs[rd->ifargfltregcnt++];
                                                }
-                                               else if (r->iftmpfltregcnt > 0) {
-                                                       r->iftmpfltregcnt--;
-                                                       v->regoff = r->tmpfltregs[r->iftmpfltregcnt];
+                                               else if (rd->iftmpfltregcnt > 0) {
+                                                       rd->iftmpfltregcnt--;
+                                                       v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
                                                }
-                                               else if (r->ifsavfltregcnt > 0) {
-                                                       r->ifsavfltregcnt--;
-                                                       v->regoff = r->savfltregs[r->ifsavfltregcnt];
+                                               else if (rd->ifsavfltregcnt > 0) {
+                                                       rd->ifsavfltregcnt--;
+                                                       v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
                                                }
                                                else {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = r->ifmemuse;
-                                                       r->ifmemuse += regsneeded + 1;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
                                                }
                                                fltalloc = t;
                                        }
@@ -385,46 +455,66 @@ static void interface_regalloc(methodinfo *m)
                                                 */
                                                if (IS_2_WORD_TYPE(t)) {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = r->ifmemuse++;
+                                                       v->regoff = rd->ifmemuse++;
                                                } else {
 #endif
                                                        if (intalloc >= 0) {
-                                                               v->flags |= r->interfaces[s][intalloc].flags & INMEMORY;
-                                                               v->regoff = r->interfaces[s][intalloc].regoff;
+                                                               v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
+                                                               v->regoff = rd->interfaces[s][intalloc].regoff;
                                                        }
-                                                       else if (r->iftmpintregcnt > regsneeded) {
-                                                               r->iftmpintregcnt -= regsneeded + 1;
-                                                               v->regoff = r->tmpintregs[r->iftmpintregcnt];
+                                                       else if (!m->isleafmethod &&(rd->ifargintregcnt +regsneeded < rd->intreg_argnum)) {
+                                                               v->regoff = rd->argintregs[rd->ifargintregcnt];
+                                                               rd->ifargintregcnt+=regsneeded+1;
                                                        }
-                                                       else if (r->ifsavintregcnt > regsneeded) {
-                                                               r->ifsavintregcnt -= regsneeded + 1;
-                                                               v->regoff = r->savintregs[r->ifsavintregcnt];
+                                                       else if (rd->iftmpintregcnt > regsneeded) {
+                                                               rd->iftmpintregcnt -= regsneeded + 1;
+                                                               v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
+                                                       }
+                                                       else if (rd->ifsavintregcnt > regsneeded) {
+                                                               rd->ifsavintregcnt -= regsneeded + 1;
+                                                               v->regoff = rd->savintregs[rd->ifsavintregcnt];
                                                        }
                                                        else {
                                                                v->flags |= INMEMORY;
-                                                               v->regoff = r->ifmemuse;
-                                                               r->ifmemuse += regsneeded + 1;
+                                                               v->regoff = rd->ifmemuse;
+                                                               rd->ifmemuse += regsneeded + 1;
                                                        }
 #if defined(__I386__)
                                                }
 #endif
                                                intalloc = t;
                                        }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       }
+#endif
                                }
                                else {
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       if (t == TYPE_ADR) {
+                                               if (rd->ifsavadrregcnt > 0) {
+                                                       rd->ifsavadrregcnt--;
+                                                       v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
+                                               }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
+                                               }                                               
+                                       } else {
+#endif
                                        if (IS_FLT_DBL_TYPE(t)) {
                                                if (fltalloc >= 0) {
-                                                       v->flags |= r->interfaces[s][fltalloc].flags & INMEMORY;
-                                                       v->regoff = r->interfaces[s][fltalloc].regoff;
+                                                       v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
+                                                       v->regoff = rd->interfaces[s][fltalloc].regoff;
                                                }
-                                               else if (r->ifsavfltregcnt > 0) {
-                                                       r->ifsavfltregcnt--;
-                                                       v->regoff = r->savfltregs[r->ifsavfltregcnt];
+                                               else if (rd->ifsavfltregcnt > 0) {
+                                                       rd->ifsavfltregcnt--;
+                                                       v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
                                                }
                                                else {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = r->ifmemuse;
-                                                       r->ifmemuse += regsneeded + 1;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
                                                }
                                                fltalloc = t;
                                        }
@@ -435,39 +525,52 @@ static void interface_regalloc(methodinfo *m)
                                                 */
                                                if (IS_2_WORD_TYPE(t)) {
                                                        v->flags |= INMEMORY;
-                                                       v->regoff = r->ifmemuse++;
+                                                       v->regoff = rd->ifmemuse++;
                                                } else {
 #endif
                                                        if (intalloc >= 0) {
-                                                               v->flags |= r->interfaces[s][intalloc].flags & INMEMORY;
-                                                               v->regoff = r->interfaces[s][intalloc].regoff;
+                                                               v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
+                                                               v->regoff = rd->interfaces[s][intalloc].regoff;
                                                        }
-                                                       else if (r->ifsavintregcnt > regsneeded) {
-                                                               r->ifsavintregcnt -= regsneeded + 1;
-                                                               v->regoff = r->savintregs[r->ifsavintregcnt];
+                                                       else if (rd->ifsavintregcnt > regsneeded) {
+                                                               rd->ifsavintregcnt -= regsneeded + 1;
+                                                               v->regoff = rd->savintregs[rd->ifsavintregcnt];
                                                        }
                                                        else {
                                                                v->flags |= INMEMORY;
-                                                               v->regoff = r->ifmemuse;
-                                                               r->ifmemuse += regsneeded + 1;
+                                                               v->regoff = rd->ifmemuse;
+                                                               rd->ifmemuse += regsneeded + 1;
                                                        }
 #if defined(__I386__)
                                                }
 #endif
                                                intalloc = t;
                                        }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       }
+#endif
                                }
                        } /* if (type >= 0) */
                } /* for t */
        } /* for s */
 
-       r->maxmemuse = r->ifmemuse;
-       r->maxargintreguse = -1;
-       r->maxtmpintreguse = r->iftmpintregcnt;
-       r->maxsavintreguse = r->ifsavintregcnt;
-       r->maxargfltreguse = -1;
-       r->maxtmpfltreguse = r->iftmpfltregcnt;
-       r->maxsavfltreguse = r->ifsavfltregcnt;
+       rd->maxmemuse = rd->ifmemuse;
+
+       rd->maxargintreguse = rd->ifargintregcnt;
+       rd->maxargfltreguse = rd->ifargfltregcnt;
+
+       rd->maxtmpintreguse = rd->iftmpintregcnt;
+       rd->maxsavintreguse = rd->ifsavintregcnt;
+
+       rd->maxtmpfltreguse = rd->iftmpfltregcnt;
+       rd->maxsavfltreguse = rd->ifsavfltregcnt;
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+
+       rd->maxargadrreguse = rd->ifargadrregcnt;
+       rd->maxtmpadrreguse = rd->iftmpadrregcnt;
+       rd->maxsavadrreguse = rd->ifsavadrregcnt;
+#endif
 }
 
 
@@ -478,60 +581,89 @@ static void interface_regalloc(methodinfo *m)
        
 *******************************************************************************/
        
-static void local_regalloc(methodinfo *m)
+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 };
-       registerdata *r;
-
-       /* keep code size smaller */
-       r = m->registerdata;
 
        if (m->isleafmethod) {
                int arg, doublewordarg, iargcnt, fargcnt;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+               int aargcnt;
+#endif
 
                arg = 0, iargcnt = 0, fargcnt = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+               aargcnt = 0;
+#endif
                doublewordarg = 0;
-               for (s = 0; s < m->maxlocals; s++) {
+               for (s = 0; s < cd->maxlocals; s++) {
                        intalloc = -1; fltalloc = -1;
                        for (tt = 0; tt <= 4; tt++) {
                                t = typeloop[tt];
-                               v = &r->locals[s][t];
+                               v = &rd->locals[s][t];
 
                                if (v->type >= 0) {
 #ifdef USETWOREGS
                                        regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       if (t == TYPE_ADR) {
+                                               /* doublewordarg not possible for xdsp */
+#if !defined(CONSECUTIVE_ADDRESSARGS)
+                                               aargcnt = arg;
+#endif
+                                               if ((arg < m->paramcount) && (aargcnt < rd->adrreg_argnum)) {
+                                                       v->flags = 0;
+                                                       v->regoff = rd->argadrregs[aargcnt];
+                                               }
+                                               if (rd->maxtmpadrreguse > 0) {
+                                                       rd->maxtmpadrreguse--;
+                                                       v->flags = 0;
+                                                       v->regoff = rd->tmpadrregs[rd->maxtmpadrreguse];
+                                               }
+                                               else if (rd->maxsavadrreguse > 0) {
+                                                       rd->maxsavadrreguse--;
+                                                       v->flags = 0;
+                                                       v->regoff = rd->savadrregs[rd->maxsavadrreguse];
+                                               }
+                                               else {
+                                                       v->flags |= INMEMORY;
+                                                       v->regoff = rd->ifmemuse;
+                                                       rd->ifmemuse += regsneeded + 1;
+                                               }                                               
+                                       } else {
 #endif
                                        if (IS_FLT_DBL_TYPE(t)) {
 #if !defined(CONSECUTIVE_FLOATARGS)
                                                fargcnt = arg;
 #endif
                                                if (fltalloc >= 0) {
-                                                       v->flags = r->locals[s][fltalloc].flags;
-                                                       v->regoff = r->locals[s][fltalloc].regoff;
+                                                       v->flags = rd->locals[s][fltalloc].flags;
+                                                       v->regoff = rd->locals[s][fltalloc].regoff;
                                                }
                                                else if (!doublewordarg && (arg < m->paramcount) &&
-                                                                (fargcnt < r->fltreg_argnum)) {
+                                                                (fargcnt < rd->fltreg_argnum)) {
                                                        v->flags = 0;
-                                                       v->regoff = r->argfltregs[fargcnt];
+                                                       v->regoff = rd->argfltregs[fargcnt];
                                                }
-                                               else if (r->maxtmpfltreguse > 0) {
-                                                       r->maxtmpfltreguse--;
+                                               else if (rd->maxtmpfltreguse > 0) {
+                                                       rd->maxtmpfltreguse--;
                                                        v->flags = 0;
-                                                       v->regoff = r->tmpfltregs[r->maxtmpfltreguse];
+                                                       v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
                                                }
-                                               else if (r->maxsavfltreguse > 0) {
-                                                       r->maxsavfltreguse--;
+                                               else if (rd->maxsavfltreguse > 0) {
+                                                       rd->maxsavfltreguse--;
                                                        v->flags = 0;
-                                                       v->regoff = r->savfltregs[r->maxsavfltreguse];
+                                                       v->regoff = rd->savfltregs[rd->maxsavfltreguse];
                                                }
                                                else {
                                                        v->flags = INMEMORY;
-                                                       v->regoff = r->maxmemuse;
-                                                       r->maxmemuse += regsneeded + 1;
+                                                       v->regoff = rd->maxmemuse;
+                                                       rd->maxmemuse += regsneeded + 1;
                                                }
                                                fltalloc = t;
 
@@ -543,56 +675,59 @@ static void local_regalloc(methodinfo *m)
                                                 */
                                                if (IS_2_WORD_TYPE(t)) {
                                                        v->flags = INMEMORY;
-                                                       v->regoff = r->maxmemuse++;
+                                                       v->regoff = rd->maxmemuse++;
                                                } else {
 #endif
 #if !defined(CONSECUTIVE_INTARGS)
                                                        iargcnt = arg;
 #endif
                                                        if (intalloc >= 0) {
-                                                               v->flags = r->locals[s][intalloc].flags;
-                                                               v->regoff = r->locals[s][intalloc].regoff;
+                                                               v->flags = rd->locals[s][intalloc].flags;
+                                                               v->regoff = rd->locals[s][intalloc].regoff;
                                                        }
                                                        else if (!doublewordarg && (arg < m->paramcount)
 #ifndef USETWOREGS
-                                                                        && ((regtouse = iargcnt) < r->intreg_argnum)
+                                                                        && ((regtouse = iargcnt) < rd->intreg_argnum)
 #else
-                                                                        && ((regtouse = s) < r->intreg_argnum - regsneeded)
+                                                                        && ((regtouse = s) < rd->intreg_argnum - regsneeded)
 #endif
                                                                         ) {
                                                                v->flags = 0;
-                                                               v->regoff = r->argintregs[regtouse];
+                                                               v->regoff = rd->argintregs[regtouse];
                                                        }
-                                                       else if (r->maxtmpintreguse > regsneeded) {
-                                                               r->maxtmpintreguse -= regsneeded + 1;
+                                                       else if (rd->maxtmpintreguse > regsneeded) {
+                                                               rd->maxtmpintreguse -= regsneeded + 1;
                                                                v->flags = 0;
-                                                               v->regoff = r->tmpintregs[r->maxtmpintreguse];
+                                                               v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
                                                        }
-                                                       else if (r->maxsavintreguse > regsneeded) {
-                                                               r->maxsavintreguse -= regsneeded + 1;
+                                                       else if (rd->maxsavintreguse > regsneeded) {
+                                                               rd->maxsavintreguse -= regsneeded + 1;
                                                                v->flags = 0;
-                                                               v->regoff = r->savintregs[r->maxsavintreguse];
+                                                               v->regoff = rd->savintregs[rd->maxsavintreguse];
                                                        }
                                                        /*
                                                         * use unused argument registers as local registers
                                                         */
                                                        else if (!doublewordarg && (arg >= m->paramcount) &&
-                                                                        (iargcnt < r->intreg_argnum)) {
+                                                                        (iargcnt < rd->intreg_argnum)) {
                                                                v->flags = 0;
-                                                               v->regoff = r->argintregs[iargcnt];
+                                                               v->regoff = rd->argintregs[iargcnt];
                                                                iargcnt++;
                                                                arg++;
                                                        }
                                                        else {
                                                                v->flags = INMEMORY;
-                                                               v->regoff = r->maxmemuse;
-                                                               r->maxmemuse += regsneeded + 1;
+                                                               v->regoff = rd->maxmemuse;
+                                                               rd->maxmemuse += regsneeded + 1;
                                                        }
 #if defined(__I386__)
                                                }
 #endif
                                                intalloc = t;
                                        }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       }
+#endif
                                }
                        }
                        if (arg < m->paramcount) {
@@ -611,12 +746,20 @@ static void local_regalloc(methodinfo *m)
                                        doublewordarg = 1;
 
                                } else {
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       if ( TYPE_ADR == m->paramtypes[arg] ) {
+                                               aargcnt++;
+                                       } else {
+#endif
                                        if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
                                                fargcnt++;
 
                                        } else {
                                                iargcnt++;
                                        }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                                       }
+#endif
                                        arg++;
                                }
                        }
@@ -624,29 +767,43 @@ static void local_regalloc(methodinfo *m)
                return;
        }
 
-       for (s = 0; s < m->maxlocals; s++) {
+       for (s = 0; s < cd->maxlocals; s++) {
                intalloc = -1; fltalloc = -1;
                for (tt=0; tt<=4; tt++) {
                        t = typeloop[tt];
-                       v = &r->locals[s][t];
+                       v = &rd->locals[s][t];
                        if (v->type >= 0) {
 #ifdef USETWOREGS
                                regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               if ( t == TYPE_ADR ) {
+                                       if (rd->maxsavadrreguse > 0) {
+                                               rd->maxsavadrreguse--;
+                                               v->flags = 0;
+                                               v->regoff = rd->savadrregs[rd->maxsavadrreguse];
+                                       }
+                                       else {
+                                               v->flags = INMEMORY;
+                                               v->regoff = rd->maxmemuse;
+                                               rd->maxmemuse += regsneeded + 1;
+                                       }
+                               } else {
 #endif
                                if (IS_FLT_DBL_TYPE(t)) {
                                        if (fltalloc >= 0) {
-                                               v->flags = r->locals[s][fltalloc].flags;
-                                               v->regoff = r->locals[s][fltalloc].regoff;
+                                               v->flags = rd->locals[s][fltalloc].flags;
+                                               v->regoff = rd->locals[s][fltalloc].regoff;
                                        }
-                                       else if (r->maxsavfltreguse > 0) {
-                                               r->maxsavfltreguse--;
+                                       else if (rd->maxsavfltreguse > 0) {
+                                               rd->maxsavfltreguse--;
                                                v->flags = 0;
-                                               v->regoff = r->savfltregs[r->maxsavfltreguse];
+                                               v->regoff = rd->savfltregs[rd->maxsavfltreguse];
                                        }
                                        else {
                                                v->flags = INMEMORY;
-                                               v->regoff = r->maxmemuse;
-                                               r->maxmemuse += regsneeded + 1;
+                                               v->regoff = rd->maxmemuse;
+                                               rd->maxmemuse += regsneeded + 1;
                                        }
                                        fltalloc = t;
                                }
@@ -657,72 +814,88 @@ static void local_regalloc(methodinfo *m)
                                         */
                                        if (IS_2_WORD_TYPE(t)) {
                                                v->flags = INMEMORY;
-                                               v->regoff = r->maxmemuse++;
+                                               v->regoff = rd->maxmemuse++;
                                        } else {
 #endif
                                                if (intalloc >= 0) {
-                                                       v->flags = r->locals[s][intalloc].flags;
-                                                       v->regoff = r->locals[s][intalloc].regoff;
+                                                       v->flags = rd->locals[s][intalloc].flags;
+                                                       v->regoff = rd->locals[s][intalloc].regoff;
                                                }
-                                               else if (r->maxsavintreguse > regsneeded) {
-                                                       r->maxsavintreguse -= regsneeded+1;
+                                               else if (rd->maxsavintreguse > regsneeded) {
+                                                       rd->maxsavintreguse -= regsneeded+1;
                                                        v->flags = 0;
-                                                       v->regoff = r->savintregs[r->maxsavintreguse];
+                                                       v->regoff = rd->savintregs[rd->maxsavintreguse];
                                                }
                                                else {
                                                        v->flags = INMEMORY;
-                                                       v->regoff = r->maxmemuse;
-                                                       r->maxmemuse += regsneeded + 1;
+                                                       v->regoff = rd->maxmemuse;
+                                                       rd->maxmemuse += regsneeded + 1;
                                                }
 #if defined(__I386__)
                                        }
 #endif
                                        intalloc = t;
                                }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                               }
+#endif
+
                        }
                }
        }
 }
 
-
-
-static void reg_init_temp(methodinfo *m)
+static void reg_init_temp(methodinfo *m, registerdata *rd)
 {
-       registerdata *r;
-
-       /* keep code size smaller */
-       r = m->registerdata;
-
-       r->freememtop = 0;
-       r->memuse = r->ifmemuse;
+       rd->freememtop = 0;
+       rd->memuse = rd->ifmemuse;
+
+       rd->freetmpinttop = 0;
+       rd->freesavinttop = 0;
+       rd->freetmpflttop = 0;
+       rd->freesavflttop = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->freetmpadrtop = 0;
+       rd->freesavadrtop = 0;
+#endif
 
-       r->freetmpinttop = 0;
-       r->freesavinttop = 0;
-       r->freetmpflttop = 0;
-       r->freesavflttop = 0;
+       rd->tmpintreguse = rd->iftmpintregcnt;
+       rd->savintreguse = rd->ifsavintregcnt;
+       rd->tmpfltreguse = rd->iftmpfltregcnt;
+       rd->savfltreguse = rd->ifsavfltregcnt;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->tmpadrreguse = rd->iftmpadrregcnt;
+       rd->savadrreguse = rd->ifsavadrregcnt;
+#endif
 
-       r->tmpintreguse = r->iftmpintregcnt;
-       r->savintreguse = r->ifsavintregcnt;
-       r->tmpfltreguse = r->iftmpfltregcnt;
-       r->savfltreguse = r->ifsavfltregcnt;
+       rd->freearginttop = 0;
+       rd->freeargflttop = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       rd->freeargadrtop = 0;
+#endif
 
-       /* all argument registers are available */
-       r->argintreguse = r->intreg_argnum;
-       r->argfltreguse = r->fltreg_argnum;
+       if (!m->isleafmethod) {
+               rd->argintreguse = rd->ifargintregcnt;
+               rd->argfltreguse = rd->ifargfltregcnt;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+               rd->argadrreguse = rd->ifargadrregcnt;
+#endif
+       } else {
+               rd->argintreguse = rd->intreg_argnum;
+               rd->argfltreguse = rd->fltreg_argnum;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+               rd->argadrreguse = rd->adrreg_argnum;
+#endif
+       }
 }
 
-
-#define reg_new_temp(m,s) if (s->varkind == TEMPVAR) reg_new_temp_func(m, s)
+#define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
 
 
-static void reg_new_temp_func(methodinfo *m, stackptr s)
+static void reg_new_temp_func(registerdata *rd, stackptr s)
 {
        s4 regsneeded;
        s4 tryagain;
-       registerdata *r;
-
-       /* keep code size smaller */
-       r = m->registerdata;
 
        /* Try to allocate a saved register if there is no temporary one          */
        /* available. This is what happens during the second run.                 */
@@ -738,17 +911,33 @@ static void reg_new_temp_func(methodinfo *m, stackptr s)
                if (tryagain == 1) {
                        if (!(s->flags & SAVEDVAR))
                                s->flags |= SAVEDTMP;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       if (s->type == TYPE_ADR) {
+                               if (rd->freesavadrtop > 0) {
+                                       rd->freesavadrtop--;
+                                       s->regoff = rd->freesavadrregs[rd->freesavadrtop];
+                                       return;
+
+                               } else if (rd->savadrreguse > 0) {
+                                       rd->savadrreguse--;
+                                       if (rd->savadrreguse < rd->maxsavadrreguse)
+                                               rd->maxsavadrreguse = rd->savadrreguse;
+                                       s->regoff = rd->savadrregs[rd->savadrreguse];
+                                       return;
+                               }
+                       } else {
+#endif
                        if (IS_FLT_DBL_TYPE(s->type)) {
-                               if (r->freesavflttop > 0) {
-                                       r->freesavflttop--;
-                                       s->regoff = r->freesavfltregs[r->freesavflttop];
+                               if (rd->freesavflttop > 0) {
+                                       rd->freesavflttop--;
+                                       s->regoff = rd->freesavfltregs[rd->freesavflttop];
                                        return;
 
-                               } else if (r->savfltreguse > 0) {
-                                       r->savfltreguse--;
-                                       if (r->savfltreguse < r->maxsavfltreguse)
-                                               r->maxsavfltreguse = r->savfltreguse;
-                                       s->regoff = r->savfltregs[r->savfltreguse];
+                               } else if (rd->savfltreguse > 0) {
+                                       rd->savfltreguse--;
+                                       if (rd->savfltreguse < rd->maxsavfltreguse)
+                                               rd->maxsavfltreguse = rd->savfltreguse;
+                                       s->regoff = rd->savfltregs[rd->savfltreguse];
                                        return;
                                }
 
@@ -759,88 +948,128 @@ static void reg_new_temp_func(methodinfo *m, stackptr s)
                                 */
                                if (!IS_2_WORD_TYPE(s->type)) {
 #endif
-                                       if (r->freesavinttop > regsneeded) {
-                                               r->freesavinttop -= regsneeded + 1;
-                                               s->regoff = r->freesavintregs[r->freesavinttop];
+                                       if (rd->freesavinttop > regsneeded) {
+                                               rd->freesavinttop -= regsneeded + 1;
+                                               s->regoff = rd->freesavintregs[rd->freesavinttop];
                                                return;
 
-                                       } else if (r->savintreguse > regsneeded) {
-                                               r->savintreguse -= regsneeded + 1;
-                                               if (r->savintreguse < r->maxsavintreguse)
-                                                       r->maxsavintreguse = r->savintreguse;
-                                               s->regoff = r->savintregs[r->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
                        }
-
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       }
+#endif
                } else {
-                       if (IS_FLT_DBL_TYPE(s->type)) {
-                               if (r->freetmpflttop > 0) {
-                                       r->freetmpflttop--;
-                                       s->regoff = r->freetmpfltregs[r->freetmpflttop];
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       if (s->type == TYPE_ADR) {
+                               if (rd->freetmpadrtop > 0) {
+                                       rd->freetmpadrtop--;
+                                       s->regoff = rd->freetmpadrregs[rd->freetmpadrtop];
                                        return;
 
-                               } else if (r->tmpfltreguse > 0) {
-                                       r->tmpfltreguse--;
-                                       if (r->tmpfltreguse < r->maxtmpfltreguse)
-                                               r->maxtmpfltreguse = r->tmpfltreguse;
-                                       s->regoff = r->tmpfltregs[r->tmpfltreguse];
+                               } else if (rd->tmpadrreguse > 0) {
+                                       rd->tmpadrreguse--;
+                                       if (rd->tmpadrreguse < rd->maxtmpadrreguse)
+                                               rd->maxtmpadrreguse = rd->tmpadrreguse;
+                                       s->regoff = rd->tmpadrregs[rd->tmpadrreguse];
                                        return;
                                }
-
                        } else {
+#endif
+                               if (IS_FLT_DBL_TYPE(s->type)) {
+                                       if (rd->freeargflttop > 0) {
+                                               rd->freeargflttop --;
+                                               s->regoff = rd->freeargfltregs[rd->freeargflttop];
+                                               s->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->argfltreguse < rd->fltreg_argnum) {
+                                               if (rd->argfltreguse > rd->maxargfltreguse)
+                                                       rd->maxargfltreguse = rd->argfltreguse;
+                                               s->regoff = rd->argfltregs[rd->argfltreguse++];
+                                               s->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->freetmpflttop > 0) {
+                                               rd->freetmpflttop--;
+                                               s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
+                                               return;
+
+                                       } else if (rd->tmpfltreguse > 0) {
+                                               rd->tmpfltreguse--;
+                                               if (rd->tmpfltreguse < rd->maxtmpfltreguse)
+                                                       rd->maxtmpfltreguse = rd->tmpfltreguse;
+                                               s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
+                                               return;
+                                       }
+
+                               } else {
 #if defined(__I386__)
                                /*
                                 * for i386 put all longs in memory
                                 */
                                if (!IS_2_WORD_TYPE(s->type)) {
 #endif
-                                       if (r->freetmpinttop > regsneeded) {
-                                               r->freetmpinttop -= regsneeded + 1;
-                                               s->regoff = r->freetmpintregs[r->freetmpinttop];
+                                       if (rd->freearginttop > regsneeded) {
+                                               rd->freearginttop -= regsneeded + 1;
+                                               s->regoff = rd->freeargintregs[rd->freearginttop];
+                                               s->flags |= TMPARG;
+                                               return;
+                                       } else if (rd->argintreguse < rd->intreg_argnum - regsneeded) {
+                                               if (rd->argintreguse > rd->maxargintreguse)
+                                                       rd->maxargintreguse = rd->argintreguse;
+                                               s->regoff = rd->argintregs[rd->argintreguse];
+                                               s->flags |= TMPARG;
+                                               rd->argintreguse += regsneeded + 1;
+                                               return;
+                                       } else if (rd->freetmpinttop > regsneeded) {
+                                               rd->freetmpinttop -= regsneeded + 1;
+                                               s->regoff = rd->freetmpintregs[rd->freetmpinttop];
                                                return;
 
-                                       } else if (r->tmpintreguse > regsneeded) {
-                                               r->tmpintreguse -= regsneeded + 1;
-                                               if (r->tmpintreguse < r->maxtmpintreguse)
-                                                       r->maxtmpintreguse = r->tmpintreguse;
-                                               s->regoff = r->tmpintregs[r->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__)
                                }
 #endif
                        }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+                       }
+#endif
                }
        }
 
-       if (r->freememtop > regsneeded) {
-               r->freememtop -= regsneeded + 1;
-               s->regoff = r->freemem[r->freememtop];
+       if (rd->freememtop > regsneeded) {
+               rd->freememtop -= regsneeded + 1;
+               s->regoff = rd->freemem[rd->freememtop];
 
        } else {
-               s->regoff = r->memuse;
-               r->memuse += regsneeded + 1;
-               if (r->memuse > r->maxmemuse)
-                       r->maxmemuse = r->memuse;
+               s->regoff = rd->memuse;
+               rd->memuse += regsneeded + 1;
+               if (rd->memuse > rd->maxmemuse)
+                       rd->maxmemuse = rd->memuse;
        }
        s->flags |= INMEMORY;
 }
 
 
-#define reg_free_temp(m,s) if (s->varkind == TEMPVAR) reg_free_temp_func(m, s)
+#define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
 
 
-static void reg_free_temp_func(methodinfo *m, stackptr s)
+static void reg_free_temp_func(registerdata *rd, stackptr s)
 {
        s4 regsneeded;
-       registerdata *r;
-
-       /* keep code size smaller */
-       r = m->registerdata;
 
 #ifdef USETWOREGS
        regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
@@ -849,43 +1078,62 @@ static void reg_free_temp_func(methodinfo *m, stackptr s)
 #endif
 
        if (s->flags & INMEMORY) {
-               r->freemem[r->freememtop] = s->regoff;
+               rd->freemem[rd->freememtop] = s->regoff;
                if (regsneeded)
-                       r->freemem[r->freememtop + 1] = s->regoff + 1;
-               r->freememtop += regsneeded + 1;
+                       rd->freemem[rd->freememtop + 1] = s->regoff + 1;
+               rd->freememtop += regsneeded + 1;
 
-       } else if (IS_FLT_DBL_TYPE(s->type)) {
+#ifdef HAS_ADDRESS_REGISTER_FILE
+       } else if (s->type == TYPE_ADR) {
                if (s->flags & (SAVEDVAR | SAVEDTMP)) {
                        s->flags &= ~SAVEDTMP;
-                       r->freesavfltregs[r->freesavflttop++] = s->regoff;
+                       rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
 
                } else
-                       r->freetmpfltregs[r->freetmpflttop++] = s->regoff;
-
+                       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 {
                if (s->flags & (SAVEDVAR | SAVEDTMP)) {
                        s->flags &= ~SAVEDTMP;
-                       r->freesavintregs[r->freesavinttop] = s->regoff;
+                       rd->freesavintregs[rd->freesavinttop] = s->regoff;
 #ifdef USETWOREGS
                        if (regsneeded)
-                               r->freesavintregs[r->freesavinttop + 1] = r->secondregs[s->regoff];
+                               rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
 #endif
-                       r->freesavinttop += regsneeded + 1;
+                       rd->freesavinttop += regsneeded + 1;
 
-               } else {
-                       r->freetmpintregs[r->freetmpinttop] = s->regoff;
+               } else if (s->flags & TMPARG) {
+                       s->flags &= ~TMPARG;
+                       rd->freeargintregs[rd->freearginttop] = s->regoff;
 #ifdef USETWOREGS
                        if (regsneeded)
-                               r->freetmpintregs[r->freetmpinttop + 1] = r->secondregs[s->regoff];
+                               rd->freeargintregs[rd->freearginttop + 1] = rd->secondregs[s->regoff];
 #endif
-                       r->freetmpinttop += regsneeded + 1;
+                       rd->freearginttop += regsneeded + 1;
+               } else {
+                       rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
+#ifdef USETWOREGS
+                       if (regsneeded)
+                               rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
+#endif 
+                       rd->freetmpinttop += regsneeded + 1;
                }
        }
 }
 
 
 
-static void allocate_scratch_registers(methodinfo *m)
+static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
 {
        s4 opcode;
        s4 i;
@@ -902,7 +1150,7 @@ static void allocate_scratch_registers(methodinfo *m)
                        dst = bptr->instack;
 
                        /* initialize temp registers */
-                       reg_init_temp(m);
+                       reg_init_temp(m, rd);
 
                        iptr = bptr->iinstr;
                        len = bptr->icount;
@@ -925,6 +1173,9 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_RET:
                                case ICMD_RETURN:
                                case ICMD_GOTO:
+                               case ICMD_PUTSTATICCONST:
+                               case ICMD_INLINE_START:
+                               case ICMD_INLINE_END:
                                        break;
 
                                        /* pop 0 push 1 const */
@@ -942,7 +1193,7 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_FLOAD:
                                case ICMD_DLOAD:
                                case ICMD_ALOAD:
-                                       reg_new_temp(m, dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 2 push 1 */
@@ -956,9 +1207,9 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_BALOAD:
                                case ICMD_CALOAD:
                                case ICMD_SALOAD:
-                                       reg_free_temp(m, src);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst);
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 3 push 0 */
@@ -972,9 +1223,9 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_BASTORE:
                                case ICMD_CASTORE:
                                case ICMD_SASTORE:
-                                       reg_free_temp(m, src);
-                                       reg_free_temp(m, src->prev);
-                                       reg_free_temp(m, 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 */
@@ -998,6 +1249,7 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_ATHROW:
 
                                case ICMD_PUTSTATIC:
+                               case ICMD_PUTFIELDCONST:
 
                                        /* pop 1 push 0 branch */
 
@@ -1026,7 +1278,7 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_NULLCHECKPOP:
                                case ICMD_MONITORENTER:
                                case ICMD_MONITOREXIT:
-                                       reg_free_temp(m, src);
+                                       reg_free_temp(rd, src);
                                        break;
 
                                        /* pop 2 push 0 branch */
@@ -1060,80 +1312,80 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_BASTORECONST:
                                case ICMD_CASTORECONST:
                                case ICMD_SASTORECONST:
-                                       reg_free_temp(m, src);
-                                       reg_free_temp(m, src->prev);
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
                                        break;
 
                                        /* pop 0 push 1 dup */
                                        
                                case ICMD_DUP:
-                                       reg_new_temp(m, dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 0 push 2 dup */
                                        
                                case ICMD_DUP2:
-                                       reg_new_temp(m, dst->prev);
-                                       reg_new_temp(m, dst);
+                                       reg_new_temp(rd, dst->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 2 push 3 dup */
                                        
                                case ICMD_DUP_X1:
-                                       reg_free_temp(m, src);
-                                       reg_new_temp(m, dst);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst->prev);
-                                       reg_new_temp(m, dst->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_new_temp(rd, dst->prev->prev);
                                        break;
 
                                        /* pop 3 push 4 dup */
                                        
                                case ICMD_DUP_X2:
-                                       reg_free_temp(m, src);
-                                       reg_new_temp(m, dst);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst->prev);
-                                       reg_free_temp(m, src->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev);
-                                       reg_new_temp(m, dst->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_new_temp(rd, dst->prev->prev->prev);
                                        break;
 
                                        /* pop 3 push 5 dup */
                                        
                                case ICMD_DUP2_X1:
-                                       reg_free_temp(m, src);
-                                       reg_new_temp(m, dst);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst->prev);
-                                       reg_free_temp(m, src->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev->prev);
-                                       reg_new_temp(m, dst->prev->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_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_free_temp(m, src);
-                                       reg_new_temp(m, dst);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst->prev);
-                                       reg_free_temp(m, src->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev);
-                                       reg_free_temp(m, src->prev->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev->prev->prev);
-                                       reg_new_temp(m, dst->prev->prev->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_free_temp(m, src);
-                                       reg_new_temp(m, dst->prev);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst);
+                                       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 */
@@ -1182,9 +1434,9 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_FCMPG:
                                case ICMD_DCMPL:
                                case ICMD_DCMPG:
-                                       reg_free_temp(m, src);
-                                       reg_free_temp(m, src->prev);
-                                       reg_new_temp(m, dst);
+                                       reg_free_temp(rd, src);
+                                       reg_free_temp(rd, src->prev);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 1 push 1 */
@@ -1192,6 +1444,7 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_IADDCONST:
                                case ICMD_ISUBCONST:
                                case ICMD_IMULCONST:
+                               case ICMD_IMULPOW2:
                                case ICMD_IDIVPOW2:
                                case ICMD_IREMPOW2:
                                case ICMD_IANDCONST:
@@ -1204,6 +1457,7 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_LADDCONST:
                                case ICMD_LSUBCONST:
                                case ICMD_LMULCONST:
+                               case ICMD_LMULPOW2:
                                case ICMD_LDIVPOW2:
                                case ICMD_LREMPOW2:
                                case ICMD_LANDCONST:
@@ -1250,8 +1504,8 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_ANEWARRAY:
 
                                case ICMD_GETFIELD:
-                                       reg_free_temp(m, src);
-                                       reg_new_temp(m, dst);
+                                       reg_free_temp(rd, src);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop 0 push 1 */
@@ -1259,7 +1513,7 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_GETSTATIC:
 
                                case ICMD_NEW:
-                                       reg_new_temp(m, dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                        /* pop many push any */
@@ -1270,33 +1524,37 @@ static void allocate_scratch_registers(methodinfo *m)
                                case ICMD_INVOKEINTERFACE:
                                        i = iptr->op1;
                                        while (--i >= 0) {
-                                               reg_free_temp(m, src);
+                                               reg_free_temp(rd, src);
                                                src = src->prev;
                                        }
+#if defined(__X86_64__) || defined(__I386__)
+                                       if (((unresolved_method *) iptr->target)->methodref->parseddesc.md->returntype.type != TYPE_VOID)        
+#else
                                        if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
-                                               reg_new_temp(m, dst);
+#endif
+                                               reg_new_temp(rd, dst);
                                        break;
 
                                case ICMD_BUILTIN3:
-                                       reg_free_temp(m, src);
+                                       reg_free_temp(rd, src);
                                        src = src->prev;
                                case ICMD_BUILTIN2:
-                                       reg_free_temp(m, src);
+                                       reg_free_temp(rd, src);
                                        src = src->prev;
                                case ICMD_BUILTIN1:
-                                       reg_free_temp(m, src);
+                                       reg_free_temp(rd, src);
                                        src = src->prev;
                                        if (iptr->op1 != TYPE_VOID)
-                                               reg_new_temp(m, dst);
+                                               reg_new_temp(rd, dst);
                                        break;
 
                                case ICMD_MULTIANEWARRAY:
                                        i = iptr->op1;
                                        while (--i >= 0) {
-                                               reg_free_temp(m, src);
+                                               reg_free_temp(rd, src);
                                                src = src->prev;
                                        }
-                                       reg_new_temp(m, dst);
+                                       reg_new_temp(rd, dst);
                                        break;
 
                                default:
@@ -1311,6 +1569,156 @@ static void allocate_scratch_registers(methodinfo *m)
 }
 
 
+#ifdef STATISTICS
+void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
+       int i,type;
+       s4 len;
+       stackptr    src, src_old;
+       stackptr    dst;
+       instruction *iptr;
+       basicblock  *bptr;
+       int size_interface; /* == maximum size of in/out stack at basic block boundaries */
+       bool in_register;
+
+       in_register = true;
+
+       size_interface = 0;
+
+               /* count how many local variables are held in memory or register */
+               for(i=0; i < cd->maxlocals; i++)
+                       for (type=0; type <=4; type++)
+                               if (rd->locals[i][type].type != -1) { /* valid local */
+                                       if (rd->locals[i][type].flags & INMEMORY) {
+                                               count_locals_spilled++;
+                                               in_register=false;
+                                       }
+                                       else
+                                               count_locals_register++;
+                               }
+               /* count how many stack slots are held in memory or register */
+
+               bptr = m->basicblocks;
+               while (bptr != NULL) {
+                       if (bptr->flags >= BBREACHED) {
+
+#ifdef LSRA
+                       if (!opt_lsra) {
+#endif 
+                               /* check for memory moves from interface to BB instack */
+                               dst = bptr->instack;
+                               len = bptr->indepth;
+                               
+                               if (len > size_interface) size_interface = len;
+
+                               while (dst != NULL) {
+                                       len--;
+                                       if (dst->varkind != STACKVAR) {
+                                               if ( (dst->flags & INMEMORY) ||
+                                                        (rd->interfaces[len][dst->type].flags & INMEMORY) || 
+                                                        ( (dst->flags & INMEMORY) && 
+                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) && 
+                                                          (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
+                                               {
+                                                       /* one in memory or both inmemory at different offsets */
+                                                       count_mem_move_bb++;
+                                                       in_register=false;
+                                               }
+                                       }
+
+                                       dst = dst->prev;
+                               }
+
+                               /* check for memory moves from BB outstack to interface */
+                               dst = bptr->outstack;
+                               len = bptr->outdepth;
+                               if (len > size_interface) size_interface = len;
+
+                               while (dst) {
+                                       len--;
+                                       if (dst->varkind != STACKVAR) {
+                                               if ( (dst->flags & INMEMORY) || \
+                                                        (rd->interfaces[len][dst->type].flags & INMEMORY) || \
+                                                        ( (dst->flags & INMEMORY) && \
+                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) && \
+                                                          (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
+                                               {
+                                                       /* one in memory or both inmemory at different offsets */
+                                                       count_mem_move_bb++;
+                                                       in_register=false;
+                                               }
+                                       }
+
+                                       dst = dst->prev;
+                               }
+#ifdef LSRA
+                       }
+#endif 
+
+
+                               dst = bptr->instack;
+                               iptr = bptr->iinstr;
+                               len = bptr->icount;
+                               src_old = NULL;
+
+                               while (--len >= 0)  {
+                                       src = dst;
+                                       dst = iptr->dst;
+
+                                       if ((src!= NULL) && (src != src_old)) { /* new stackslot */
+                                               switch (src->varkind) {
+                                               case TEMPVAR:
+                                               case STACKVAR:
+                                                       if (!(src->flags & INMEMORY)) 
+                                                               count_ss_register++;
+                                                       else {
+                                                               count_ss_spilled++;
+                                                               in_register=false;
+                                                       }                               
+                                                       break;
+                                                       /*                                      case LOCALVAR: */
+                                                       /*                                              if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
+                                                       /*                                                      count_ss_register++; */
+                                                       /*                                              else */
+                                                       /*                                                      count_ss_spilled++; */
+                                                       /*                                              break; */
+                                               case ARGVAR:
+                                                       if (!(src->flags & INMEMORY)) 
+                                                               count_argument_mem_ss++;
+                                                       else
+                                                               count_argument_reg_ss++;
+                                                       break;
+
+
+                                                       /*                                              if (IS_FLT_DBL_TYPE(src->type)) { */
+                                                       /*                                                      if (src->varnum < FLT_ARG_CNT) { */
+                                                       /*                                                              count_ss_register++; */
+                                                       /*                                                              break; */
+                                                       /*                                                      } */
+                                                       /*                                              } else { */
+                                                       /* #if defined(__POWERPC__) */
+                                                       /*                                                      if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
+                                                       /* #else */
+                                                       /*                                                      if (src->varnum < INT_ARG_CNT) { */
+                                                       /* #endif */
+                                                       /*                                                              count_ss_register++; */
+                                                       /*                                                              break; */
+                                                       /*                                                      } */
+                                                       /*                                              } */
+                                                       /*                                              count_ss_spilled++; */
+                                                       /*                                              break; */
+                                               }
+                                       }
+                                       src_old = src;
+                                       
+                                       iptr++;
+                               } /* while instructions */
+                       } /* if */
+                       bptr = bptr->next;
+               } /* while blocks */
+               count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
+               if (in_register) count_method_in_register++;
+}
+#endif
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where