-/* 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 557 2003-11-02 22:51:59Z twisti $
+ $Id: reg.inc 2333 2005-04-22 13:26:36Z twisti $
*/
-#include "toolbox/memory.h"
+#include "arch.h"
+#include "mm/memory.h"
+#include "vm/method.h"
+#include "vm/resolve.h"
+#include "vm/jit/reg.h"
-varinfo5 *locals;
-varinfo5 *interfaces;
+/* function prototypes for this file */
-static int intregsnum; /* absolute number of integer registers */
-static int floatregsnum; /* absolute number of float registers */
+static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
+static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
+static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
-static int intreg_ret; /* register to return integer values */
-int intreg_argnum; /* number of integer argument registers */
-static int floatreg_ret; /* register for return float values */
-static int fltreg_argnum; /* number of float argument registers */
+/* reg_init ********************************************************************
+ TODO
+
+*******************************************************************************/
-static int *argintregs; /* scratch integer registers */
-static int *tmpintregs; /* scratch integer registers */
-static int *savintregs; /* saved integer registers */
-static int *argfltregs; /* scratch float registers */
-static int *tmpfltregs; /* scratch float registers */
-static int *savfltregs; /* saved float registers */
-static int *freeargintregs; /* free argument integer registers */
-static int *freetmpintregs; /* free scratch integer registers */
-static int *freesavintregs; /* free saved integer registers */
-static int *freeargfltregs; /* free argument float registers */
-static int *freetmpfltregs; /* free scratch float registers */
-static int *freesavfltregs; /* free saved float registers */
-
-#ifdef USETWOREGS
-static int *secondregs; /* used for longs in 2 32 bit registers */
-#endif
-
-static int *freemem; /* free scratch memory */
-static int memuse; /* used memory count */
-static int ifmemuse; /* interface used memory count */
-static int maxmemuse; /* maximal used memory count (spills) */
-static int freememtop; /* free memory count */
-
-static int tmpintregcnt; /* scratch integer register count */
-static int savintregcnt; /* saved integer register count */
-static int tmpfltregcnt; /* scratch float register count */
-static int savfltregcnt; /* saved float register count */
-
-static int iftmpintregcnt; /* iface scratch integer register count */
-static int ifsavintregcnt; /* iface saved integer register count */
-static int iftmpfltregcnt; /* iface scratch float register count */
-static int ifsavfltregcnt; /* iface saved float register count */
-
-static int argintreguse; /* used argument integer register count */
-static int tmpintreguse; /* used scratch integer register count */
-static int savintreguse; /* used saved integer register count */
-static int argfltreguse; /* used argument float register count */
-static int tmpfltreguse; /* used scratch float register count */
-static int savfltreguse; /* used saved float register count */
-
-static int maxargintreguse; /* max used argument int register count */
-static int maxtmpintreguse; /* max used scratch int register count */
-static int maxsavintreguse; /* max used saved int register count */
-static int maxargfltreguse; /* max used argument float register count */
-static int maxtmpfltreguse; /* max used scratch float register count */
-static int maxsavfltreguse; /* max used saved float register count */
-
-static int freearginttop; /* free argument integer register count */
-static int freetmpinttop; /* free scratch integer register count */
-static int freesavinttop; /* free saved integer register count */
-static int freeargflttop; /* free argument float register count */
-static int freetmpflttop; /* free scratch float register count */
-static int freesavflttop; /* free saved float register count */
-
-static int savedregs_num; /* total number of registers to be saved */
-int arguments_num; /* size of parameter field in the stackframe */
+void reg_init()
+{
+ /* void */
+}
+/* reg_setup *******************************************************************
-/* function reg_init ***********************************************************
+ TODO
- initialises the register-allocator
-
*******************************************************************************/
-void reg_init()
+void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
{
- int n;
- int i;
+ s4 i;
varinfo5 *v;
-
- if (!tmpintregs) {
- if (TYPE_INT != 0 || TYPE_ADR != 4)
- panic ("JAVA-Basictypes have been changed");
-
- intreg_argnum = 0;
- tmpintregcnt = 0;
- savintregcnt = 0;
-
- for (intregsnum = 0; nregdescint[intregsnum] != REG_END; intregsnum++) {
- switch (nregdescint[intregsnum]) {
- case REG_SAV: savintregcnt++;
- break;
- case REG_TMP: tmpintregcnt++;
- break;
- case REG_ARG: intreg_argnum++;
- }
+
+ /* setup the integer register table */
+ rd->intreg_argnum = 0;
+ rd->tmpintregcnt = 0;
+ rd->savintregcnt = 0;
+
+ for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
+ switch (nregdescint[rd->intregsnum]) {
+ case REG_SAV:
+ rd->savintregcnt++;
+ break;
+ case REG_TMP:
+ rd->tmpintregcnt++;
+ break;
+ case REG_ARG:
+ rd->intreg_argnum++;
+ break;
}
+ }
- argintregs = MNEW(int, intreg_argnum);
- tmpintregs = MNEW(int, tmpintregcnt);
- savintregs = MNEW(int, savintregcnt);
- freeargintregs = MNEW(int, intreg_argnum);
- freetmpintregs = MNEW(int, tmpintregcnt);
- freesavintregs = MNEW(int, savintregcnt);
+ rd->argintregs = DMNEW(s4, rd->intreg_argnum);
+ rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
+ rd->savintregs = DMNEW(s4, rd->savintregcnt);
+ rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
+ rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
+ rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
#ifdef USETWOREGS
- secondregs = MNEW(int, intregsnum);
+ rd->secondregs = DMNEW(s4, rd->intregsnum);
#endif
- intreg_argnum = 0;
- argintreguse = 0;
- tmpintreguse = 0;
- savintreguse = 0;
-
- for (n = 0; n < intregsnum; n++) {
- switch (nregdescint[n]) {
- case REG_RET: intreg_ret = n;
- break;
- case REG_SAV: savintregs[savintreguse++] = n;
- break;
- case REG_TMP: tmpintregs[tmpintreguse++] = n;
- break;
- case REG_ARG: argintregs[intreg_argnum++] = n;
- argintreguse++;
- break;
- }
+ rd->intreg_argnum = 0;
+ rd->argintreguse = 0;
+ rd->tmpintreguse = 0;
+ rd->savintreguse = 0;
+
+ for (i = 0; i < rd->intregsnum; i++) {
+ switch (nregdescint[i]) {
+ case REG_RET:
+ rd->intreg_ret = i;
+ break;
+ case REG_SAV:
+ rd->savintregs[rd->savintreguse++] = i;
+ break;
+ case REG_TMP:
+ rd->tmpintregs[rd->tmpintreguse++] = i;
+ break;
+ case REG_ARG:
+ rd->argintregs[rd->intreg_argnum++] = i;
+ rd->argintreguse++;
+ break;
}
+ }
#if defined(__X86_64__)
- /*
- * on x86_64 the argument registers are not in ascending order
- * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
- */
-
- n = argintregs[3];
- argintregs[3] = argintregs[0];
- argintregs[0] = n;
-
- n = argintregs[2];
- argintregs[2] = argintregs[1];
- argintregs[1] = n;
+ /*
+ * on x86_64 the argument registers are not in ascending order
+ * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
+ */
+ i = rd->argintregs[3];
+ rd->argintregs[3] = rd->argintregs[0];
+ rd->argintregs[0] = i;
+
+ i = rd->argintregs[2];
+ rd->argintregs[2] = rd->argintregs[1];
+ rd->argintregs[1] = i;
#endif
#ifdef USETWOREGS
- for (n = 1; n < intreg_argnum; n++)
- secondregs[argintregs[n - 1]] = argintregs[n];
- for (n = 1; n < tmpintregcnt; n++)
- secondregs[tmpintregs[n - 1]] = tmpintregs[n];
- for (n = 1; n < savintregcnt; n++)
- secondregs[savintregs[n - 1]] = savintregs[n];
-
- secondregs[REG_ITMP1] = REG_ITMP2;
- secondregs[REG_ITMP3] = REG_ITMP2;
- secondregs[REG_RESULT] = REG_RESULT + 1;
- secondregs[argintregs[intreg_argnum - 1]] = REG_ITMP3;
+ for (i = 1; i < rd->intreg_argnum; i++)
+ rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
+ for (i = 1; i < rd->tmpintregcnt; i++)
+ rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
+ for (i = 1; i < rd->savintregcnt; i++)
+ rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
+
+ rd->secondregs[REG_ITMP1] = REG_ITMP2;
+ rd->secondregs[REG_ITMP3] = REG_ITMP2;
+ rd->secondregs[REG_RESULT] = REG_RESULT + 1;
+ rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
#endif
- fltreg_argnum = 0;
- tmpfltregcnt = 0;
- savfltregcnt = 0;
-
- for (floatregsnum = 0; nregdescfloat[floatregsnum] != REG_END; floatregsnum++) {
- switch (nregdescfloat[floatregsnum]) {
- case REG_SAV: savfltregcnt++;
- break;
- case REG_TMP: tmpfltregcnt++;
- break;
- case REG_ARG: fltreg_argnum++;
- break;
- }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ /* setup the address register table */
+ rd->adrreg_argnum = 0;
+ rd->tmpadrregcnt = 0;
+ rd->savadrregcnt = 0;
+
+ for (rd->adrregsnum = 0; nregdescadr[rd->adrregsnum] != REG_END; rd->adrregsnum++) {
+ switch (nregdescadr[rd->adrregsnum]) {
+ case REG_SAV:
+ rd->savadrregcnt++;
+ break;
+ case REG_TMP:
+ rd->tmpadrregcnt++;
+ break;
+ case REG_ARG:
+ rd->adrreg_argnum++;
+ break;
}
+ }
- argfltregs = MNEW(int, fltreg_argnum);
- tmpfltregs = MNEW(int, tmpfltregcnt);
- savfltregs = MNEW(int, savfltregcnt);
- freeargfltregs = MNEW(int, fltreg_argnum);
- freetmpfltregs = MNEW(int, tmpfltregcnt);
- freesavfltregs = MNEW(int, savfltregcnt);
-
- fltreg_argnum = 0;
- argfltreguse = 0;
- tmpfltreguse = 0;
- savfltreguse = 0;
-
- for (n = 0; n < floatregsnum; n++) {
- switch (nregdescfloat[n]) {
- case REG_RET:
- floatreg_ret = n;
- break;
- case REG_SAV: savfltregs[savfltreguse++] = n;
- break;
- case REG_TMP: tmpfltregs[tmpfltreguse++] = n;
- break;
- case REG_ARG: argfltregs[fltreg_argnum++] = n;
- argfltreguse++;
- break;
- }
+ 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);
+
+ rd->adrreg_argnum = 0;
+ rd->argadrreguse = 0;
+ rd->tmpadrreguse = 0;
+ rd->savadrreguse = 0;
+
+ for (i = 0; i < rd->adrregsnum; i++) {
+ switch (nregdescadr[i]) {
+ case REG_RET:
+ rd->adrreg_ret = i;
+ break;
+ case REG_SAV:
+ rd->savadrregs[rd->savadrreguse++] = i;
+ break;
+ case REG_TMP:
+ rd->tmpadrregs[rd->tmpadrreguse++] = i;
+ break;
+ case REG_ARG:
+ 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;
+
+ 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);
+
+ rd->fltreg_argnum = 0;
+ rd->argfltreguse = 0;
+ rd->tmpfltreguse = 0;
+ rd->savfltreguse = 0;
+
+ 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;
+ }
+ }
- freemem = DMNEW(int, maxstack);
- locals = DMNEW(varinfo5, maxlocals);
- interfaces = DMNEW(varinfo5, maxstack);
- for (v = locals, i = maxlocals; i > 0; v++, i--) {
+ 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;
v[0][TYPE_ADR].type = -1;
}
- for (v = interfaces, i = maxstack; i > 0; v++, i--) {
+ for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
v[0][TYPE_INT].type = -1;
v[0][TYPE_INT].flags = 0;
v[0][TYPE_LNG].type = -1;
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_free ***********************************************************
+
+ releases all allocated space for registers
+
+*******************************************************************************/
+
+void reg_free(methodinfo *m, registerdata *rd)
+{
+ /* void */
+}
-/* function reg_close **********************************************************
- releases all allocated space for registers
+/* reg_close *******************************************************************
+
+ TODO
*******************************************************************************/
void reg_close()
{
- if (argintregs) MFREE(argintregs, int, intreg_argnum);
- if (argfltregs) MFREE(argfltregs, int, fltreg_argnum);
- if (tmpintregs) MFREE(tmpintregs, int, tmpintregcnt);
- if (savintregs) MFREE(savintregs, int, savintregcnt);
- if (tmpfltregs) MFREE(tmpfltregs, int, tmpfltregcnt);
- if (savfltregs) MFREE(savfltregs, int, savfltregcnt);
-
- if (freeargintregs) MFREE(freeargintregs, int, intreg_argnum);
- if (freeargfltregs) MFREE(freeargfltregs, int, fltreg_argnum);
- if (freetmpintregs) MFREE(freetmpintregs, int, tmpintregcnt);
- if (freesavintregs) MFREE(freesavintregs, int, savintregcnt);
- if (freetmpfltregs) MFREE(freetmpfltregs, int, tmpfltregcnt);
- if (freesavfltregs) MFREE(freesavfltregs, int, savfltregcnt);
-
-#ifdef USETWOREGS
- if (secondregs) MFREE(secondregs, int, intregsnum);
-#endif
+ /* void */
}
*******************************************************************************/
-void regalloc()
+void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
{
- interface_regalloc();
- allocate_scratch_registers();
- local_regalloc();
+ 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
}
*******************************************************************************/
-static void interface_regalloc ()
+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;
-
+
/* 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;
-#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 (arguments_num > fltreg_argnum)
- ifmemuse = arguments_num - fltreg_argnum;
-#else
- if (arguments_num > intreg_argnum)
- ifmemuse = arguments_num - intreg_argnum;
+ } else {
+ rd->ifmemuse = 0;
+ }
#endif
- else
- 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
- iftmpintregcnt = tmpintregcnt;
- ifsavintregcnt = savintregcnt;
- iftmpfltregcnt = tmpfltregcnt;
- ifsavfltregcnt = savfltregcnt;
-
- for (s = 0; s < 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 = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
- interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
- interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
+ saved = (rd->interfaces[s][TYPE_INT].flags |
+ rd->interfaces[s][TYPE_LNG].flags |
+ rd->interfaces[s][TYPE_FLT].flags |
+ rd->interfaces[s][TYPE_DBL].flags |
+ rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
for (t = TYPE_INT; t <= TYPE_ADR; t++) {
- v = &interfaces[s][t];
+ v = &rd->interfaces[s][t];
if (v->type >= 0) {
#ifdef USETWOREGS
regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
#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 |= interfaces[s][fltalloc].flags & INMEMORY;
- v->regoff = interfaces[s][fltalloc].regoff;
+ v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
+ v->regoff = rd->interfaces[s][fltalloc].regoff;
+ }
+ else if (!m->isleafmethod &&(rd->ifargfltregcnt < rd->fltreg_argnum)) {
+ v->regoff = rd->argfltregs[rd->ifargfltregcnt++];
}
- else if (iftmpfltregcnt > 0) {
- iftmpfltregcnt--;
- v->regoff = tmpfltregs[iftmpfltregcnt];
+ else if (rd->iftmpfltregcnt > 0) {
+ rd->iftmpfltregcnt--;
+ v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
}
- else if (ifsavfltregcnt > 0) {
- ifsavfltregcnt--;
- v->regoff = savfltregs[ifsavfltregcnt];
+ else if (rd->ifsavfltregcnt > 0) {
+ rd->ifsavfltregcnt--;
+ v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
}
else {
v->flags |= INMEMORY;
- v->regoff = ifmemuse;
- ifmemuse += regsneeded+1;
+ v->regoff = rd->ifmemuse;
+ rd->ifmemuse += regsneeded + 1;
}
fltalloc = t;
}
*/
if (IS_2_WORD_TYPE(t)) {
v->flags |= INMEMORY;
- v->regoff = ifmemuse++;
+ v->regoff = rd->ifmemuse++;
} else {
#endif
if (intalloc >= 0) {
- v->flags |= interfaces[s][intalloc].flags & INMEMORY;
- v->regoff = interfaces[s][intalloc].regoff;
+ v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
+ v->regoff = rd->interfaces[s][intalloc].regoff;
}
- else if (iftmpintregcnt > regsneeded) {
- iftmpintregcnt -= regsneeded+1;
- v->regoff = tmpintregs[iftmpintregcnt];
+ else if (!m->isleafmethod &&(rd->ifargintregcnt +regsneeded < rd->intreg_argnum)) {
+ v->regoff = rd->argintregs[rd->ifargintregcnt];
+ rd->ifargintregcnt+=regsneeded+1;
}
- else if (ifsavintregcnt > regsneeded) {
- ifsavintregcnt -= regsneeded+1;
- v->regoff = savintregs[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 = ifmemuse;
- 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 |= interfaces[s][fltalloc].flags & INMEMORY;
- v->regoff = interfaces[s][fltalloc].regoff;
+ v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
+ v->regoff = rd->interfaces[s][fltalloc].regoff;
}
- else if (ifsavfltregcnt > 0) {
- ifsavfltregcnt--;
- v->regoff = savfltregs[ifsavfltregcnt];
+ else if (rd->ifsavfltregcnt > 0) {
+ rd->ifsavfltregcnt--;
+ v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
}
else {
v->flags |= INMEMORY;
- v->regoff = ifmemuse;
- ifmemuse += regsneeded+1;
+ v->regoff = rd->ifmemuse;
+ rd->ifmemuse += regsneeded + 1;
}
fltalloc = t;
}
*/
if (IS_2_WORD_TYPE(t)) {
v->flags |= INMEMORY;
- v->regoff = ifmemuse++;
+ v->regoff = rd->ifmemuse++;
} else {
#endif
if (intalloc >= 0) {
- v->flags |= interfaces[s][intalloc].flags & INMEMORY;
- v->regoff = interfaces[s][intalloc].regoff;
+ v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
+ v->regoff = rd->interfaces[s][intalloc].regoff;
}
- else if (ifsavintregcnt > regsneeded) {
- ifsavintregcnt -= regsneeded+1;
- v->regoff = savintregs[ifsavintregcnt];
+ else if (rd->ifsavintregcnt > regsneeded) {
+ rd->ifsavintregcnt -= regsneeded + 1;
+ v->regoff = rd->savintregs[rd->ifsavintregcnt];
}
else {
v->flags |= INMEMORY;
- v->regoff = ifmemuse;
- ifmemuse += regsneeded+1;
+ v->regoff = rd->ifmemuse;
+ rd->ifmemuse += regsneeded + 1;
}
#if defined(__I386__)
}
#endif
intalloc = t;
}
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ }
+#endif
}
} /* if (type >= 0) */
} /* for t */
} /* for s */
- maxmemuse = ifmemuse;
- maxtmpintreguse = iftmpintregcnt;
- maxsavintreguse = ifsavintregcnt;
- maxtmpfltreguse = iftmpfltregcnt;
- maxsavfltreguse = 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
}
*******************************************************************************/
-static void local_regalloc()
+static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
{
int s, t, tt;
int intalloc, fltalloc;
varinfo *v;
int regsneeded = 0;
int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
-
- if (isleafmethod) {
+
+ if (m->isleafmethod) {
int arg, doublewordarg, iargcnt, fargcnt;
+#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 < maxlocals; s++) {
+ for (s = 0; s < cd->maxlocals; s++) {
intalloc = -1; fltalloc = -1;
for (tt = 0; tt <= 4; tt++) {
t = typeloop[tt];
- v = &locals[s][t];
+ v = &rd->locals[s][t];
if (v->type >= 0) {
#ifdef USETWOREGS
regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#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 = locals[s][fltalloc].flags;
- v->regoff = locals[s][fltalloc].regoff;
+ v->flags = rd->locals[s][fltalloc].flags;
+ v->regoff = rd->locals[s][fltalloc].regoff;
}
- else if (!doublewordarg && (arg < mparamcount)
- && (fargcnt < fltreg_argnum)) {
+ else if (!doublewordarg && (arg < m->paramcount) &&
+ (fargcnt < rd->fltreg_argnum)) {
v->flags = 0;
- v->regoff = argfltregs[fargcnt];
+ v->regoff = rd->argfltregs[fargcnt];
}
- else if (maxtmpfltreguse > 0) {
- maxtmpfltreguse--;
+ else if (rd->maxtmpfltreguse > 0) {
+ rd->maxtmpfltreguse--;
v->flags = 0;
- v->regoff = tmpfltregs[maxtmpfltreguse];
+ v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
}
- else if (maxsavfltreguse > 0) {
- maxsavfltreguse--;
+ else if (rd->maxsavfltreguse > 0) {
+ rd->maxsavfltreguse--;
v->flags = 0;
- v->regoff = savfltregs[maxsavfltreguse];
+ v->regoff = rd->savfltregs[rd->maxsavfltreguse];
}
else {
v->flags = INMEMORY;
- v->regoff = maxmemuse;
- maxmemuse += regsneeded+1;
+ v->regoff = rd->maxmemuse;
+ rd->maxmemuse += regsneeded + 1;
}
fltalloc = t;
*/
if (IS_2_WORD_TYPE(t)) {
v->flags = INMEMORY;
- v->regoff = maxmemuse++;
+ v->regoff = rd->maxmemuse++;
} else {
#endif
#if !defined(CONSECUTIVE_INTARGS)
iargcnt = arg;
#endif
if (intalloc >= 0) {
- v->flags = locals[s][intalloc].flags;
- v->regoff = locals[s][intalloc].regoff;
+ v->flags = rd->locals[s][intalloc].flags;
+ v->regoff = rd->locals[s][intalloc].regoff;
}
- else if (!doublewordarg && (arg < mparamcount)
+ else if (!doublewordarg && (arg < m->paramcount)
#ifndef USETWOREGS
- && ((regtouse = iargcnt) < intreg_argnum)
+ && ((regtouse = iargcnt) < rd->intreg_argnum)
#else
- && ((regtouse = s) < intreg_argnum - regsneeded)
+ && ((regtouse = s) < rd->intreg_argnum - regsneeded)
#endif
) {
v->flags = 0;
- v->regoff = argintregs[regtouse];
+ v->regoff = rd->argintregs[regtouse];
}
- else if (maxtmpintreguse > regsneeded) {
- maxtmpintreguse -= regsneeded + 1;
+ else if (rd->maxtmpintreguse > regsneeded) {
+ rd->maxtmpintreguse -= regsneeded + 1;
v->flags = 0;
- v->regoff = tmpintregs[maxtmpintreguse];
+ v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
}
- else if (maxsavintreguse > regsneeded) {
- maxsavintreguse -= regsneeded + 1;
+ else if (rd->maxsavintreguse > regsneeded) {
+ rd->maxsavintreguse -= regsneeded + 1;
v->flags = 0;
- v->regoff = savintregs[maxsavintreguse];
+ v->regoff = rd->savintregs[rd->maxsavintreguse];
}
/*
* use unused argument registers as local registers
*/
- else if (!doublewordarg && (arg >= mparamcount)
- && (iargcnt < intreg_argnum)) {
+ else if (!doublewordarg && (arg >= m->paramcount) &&
+ (iargcnt < rd->intreg_argnum)) {
v->flags = 0;
- v->regoff = argintregs[iargcnt];
+ v->regoff = rd->argintregs[iargcnt];
iargcnt++;
arg++;
}
else {
v->flags = INMEMORY;
- v->regoff = maxmemuse;
- maxmemuse += regsneeded+1;
+ v->regoff = rd->maxmemuse;
+ rd->maxmemuse += regsneeded + 1;
}
#if defined(__I386__)
}
#endif
intalloc = t;
}
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ }
+#endif
}
}
- if (arg < mparamcount) {
+ if (arg < m->paramcount) {
if (doublewordarg) {
doublewordarg = 0;
/* what type was the double arg? */
- if (IS_FLT_DBL_TYPE(mparamtypes[arg])) {
+ if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
fargcnt++;
} else {
}
arg++;
- } else if (IS_2_WORD_TYPE(mparamtypes[arg])) {
+ } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
doublewordarg = 1;
} else {
- if (IS_FLT_DBL_TYPE(mparamtypes[arg])) {
+#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++;
}
}
return;
}
- for (s = 0; s < maxlocals; s++) {
+ for (s = 0; s < cd->maxlocals; s++) {
intalloc = -1; fltalloc = -1;
for (tt=0; tt<=4; tt++) {
t = typeloop[tt];
- v = &locals[s][t];
+ v = &rd->locals[s][t];
if (v->type >= 0) {
#ifdef USETWOREGS
regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#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 = locals[s][fltalloc].flags;
- v->regoff = locals[s][fltalloc].regoff;
+ v->flags = rd->locals[s][fltalloc].flags;
+ v->regoff = rd->locals[s][fltalloc].regoff;
}
- else if (maxsavfltreguse > 0) {
- maxsavfltreguse--;
+ else if (rd->maxsavfltreguse > 0) {
+ rd->maxsavfltreguse--;
v->flags = 0;
- v->regoff = savfltregs[maxsavfltreguse];
+ v->regoff = rd->savfltregs[rd->maxsavfltreguse];
}
else {
v->flags = INMEMORY;
- v->regoff = maxmemuse;
- maxmemuse += regsneeded+1;
+ v->regoff = rd->maxmemuse;
+ rd->maxmemuse += regsneeded + 1;
}
fltalloc = t;
}
*/
if (IS_2_WORD_TYPE(t)) {
v->flags = INMEMORY;
- v->regoff = maxmemuse++;
+ v->regoff = rd->maxmemuse++;
} else {
#endif
if (intalloc >= 0) {
- v->flags = locals[s][intalloc].flags;
- v->regoff = locals[s][intalloc].regoff;
+ v->flags = rd->locals[s][intalloc].flags;
+ v->regoff = rd->locals[s][intalloc].regoff;
}
- else if (maxsavintreguse > regsneeded) {
- maxsavintreguse -= regsneeded+1;
+ else if (rd->maxsavintreguse > regsneeded) {
+ rd->maxsavintreguse -= regsneeded+1;
v->flags = 0;
- v->regoff = savintregs[maxsavintreguse];
+ v->regoff = rd->savintregs[rd->maxsavintreguse];
}
else {
v->flags = INMEMORY;
- v->regoff = maxmemuse;
- maxmemuse += regsneeded+1;
+ v->regoff = rd->maxmemuse;
+ rd->maxmemuse += regsneeded + 1;
}
#if defined(__I386__)
}
#endif
intalloc = t;
}
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ }
+#endif
+
}
}
}
}
+static void reg_init_temp(methodinfo *m, registerdata *rd)
+{
+ 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
+ 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
-static void reg_init_temp()
-{
- freememtop = 0;
- memuse = ifmemuse;
-
- freearginttop = 0;
- freetmpinttop = 0;
- freesavinttop = 0;
- freeargflttop = 0;
- freetmpflttop = 0;
- freesavflttop = 0;
-
- tmpintreguse = iftmpintregcnt;
- savintreguse = ifsavintregcnt;
- tmpfltreguse = iftmpfltregcnt;
- savfltreguse = ifsavfltregcnt;
-
- /*
- * all argument registers are available
- */
- argintreguse = intreg_argnum;
- argfltreguse = fltreg_argnum;
-}
+ rd->freearginttop = 0;
+ rd->freeargflttop = 0;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ rd->freeargadrtop = 0;
+#endif
+ 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(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
-#define reg_new_temp(s) if (s->varkind == TEMPVAR) reg_new_temp_func(s)
-static void reg_new_temp_func(stackptr s)
+static void reg_new_temp_func(registerdata *rd, stackptr s)
{
- int regsneeded = 0;
+ s4 regsneeded;
+ s4 tryagain;
- /* Try to allocate a saved register if there is no temporary one available. */
- /* This is what happens during the second run. */
- int tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
+ /* Try to allocate a saved register if there is no temporary one */
+ /* available. This is what happens during the second run. */
+ tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
#ifdef USETWOREGS
regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+ regsneeded = 0;
#endif
for(; tryagain; --tryagain) {
if (tryagain == 1) {
if (!(s->flags & SAVEDVAR))
s->flags |= SAVEDTMP;
- if (IS_FLT_DBL_TYPE(s->type)) {
- if (freesavflttop > 0) {
- freesavflttop--;
- s->regoff = freesavfltregs[freesavflttop];
+#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 if (savfltreguse > 0) {
- savfltreguse--;
- if (savfltreguse < maxsavfltreguse)
- maxsavfltreguse = savfltreguse;
- s->regoff = savfltregs[savfltreguse];
+ } else {
+#endif
+ if (IS_FLT_DBL_TYPE(s->type)) {
+ if (rd->freesavflttop > 0) {
+ rd->freesavflttop--;
+ s->regoff = rd->freesavfltregs[rd->freesavflttop];
+ return;
+
+ } else if (rd->savfltreguse > 0) {
+ rd->savfltreguse--;
+ if (rd->savfltreguse < rd->maxsavfltreguse)
+ rd->maxsavfltreguse = rd->savfltreguse;
+ s->regoff = rd->savfltregs[rd->savfltreguse];
return;
}
- }
- else {
+
+ } else {
#if defined(__I386__)
/*
* for i386 put all longs in memory
*/
if (!IS_2_WORD_TYPE(s->type)) {
#endif
- if (freesavinttop > regsneeded) {
- freesavinttop -= regsneeded + 1;
- s->regoff = freesavintregs[freesavinttop];
+ if (rd->freesavinttop > regsneeded) {
+ rd->freesavinttop -= regsneeded + 1;
+ s->regoff = rd->freesavintregs[rd->freesavinttop];
return;
- }
- else if (savintreguse > regsneeded) {
- savintreguse -= regsneeded + 1;
- if (savintreguse < maxsavintreguse)
- maxsavintreguse = savintreguse;
- s->regoff = savintregs[savintreguse];
+
+ } else if (rd->savintreguse > regsneeded) {
+ rd->savintreguse -= regsneeded + 1;
+ if (rd->savintreguse < rd->maxsavintreguse)
+ rd->maxsavintreguse = rd->savintreguse;
+ s->regoff = rd->savintregs[rd->savintreguse];
return;
}
#if defined(__I386__)
}
#endif
}
- }
- else {
- if (IS_FLT_DBL_TYPE(s->type)) {
- if (freetmpflttop > 0) {
- freetmpflttop--;
- s->regoff = freetmpfltregs[freetmpflttop];
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ }
+#endif
+ } else {
+#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 (tmpfltreguse > 0) {
- tmpfltreguse--;
- if (tmpfltreguse < maxtmpfltreguse)
- maxtmpfltreguse = tmpfltreguse;
- s->regoff = tmpfltregs[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 {
+ } 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 (freetmpinttop > regsneeded) {
- freetmpinttop -= regsneeded + 1;
- s->regoff = freetmpintregs[freetmpinttop];
+ if (rd->freearginttop > regsneeded) {
+ rd->freearginttop -= regsneeded + 1;
+ s->regoff = rd->freeargintregs[rd->freearginttop];
+ s->flags |= TMPARG;
return;
- }
- else if (tmpintreguse > regsneeded) {
- tmpintreguse -= regsneeded + 1;
- if (tmpintreguse < maxtmpintreguse)
- maxtmpintreguse = tmpintreguse;
- s->regoff = tmpintregs[tmpintreguse];
+ } 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 (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 (freememtop > regsneeded) {
- freememtop -= regsneeded+1;
- s->regoff = freemem[freememtop];
- }
- else {
- s->regoff = memuse;
- memuse += regsneeded+1;
- if (memuse > maxmemuse)
- maxmemuse = memuse;
+ if (rd->freememtop > regsneeded) {
+ rd->freememtop -= regsneeded + 1;
+ s->regoff = rd->freemem[rd->freememtop];
+
+ } else {
+ s->regoff = rd->memuse;
+ rd->memuse += regsneeded + 1;
+ if (rd->memuse > rd->maxmemuse)
+ rd->maxmemuse = rd->memuse;
}
s->flags |= INMEMORY;
}
+#define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
-#define reg_free_temp(s) if (s->varkind == TEMPVAR) reg_free_temp_func(s)
-static void reg_free_temp_func(stackptr s)
+static void reg_free_temp_func(registerdata *rd, stackptr s)
{
- int regsneeded = 0;
+ s4 regsneeded;
#ifdef USETWOREGS
regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+ regsneeded = 0;
#endif
if (s->flags & INMEMORY) {
- freemem[freememtop] = s->regoff;
+ rd->freemem[rd->freememtop] = s->regoff;
if (regsneeded)
- freemem[freememtop + 1] = s->regoff + 1;
- freememtop += regsneeded + 1;
- }
- else if (IS_FLT_DBL_TYPE(s->type)) {
+ rd->freemem[rd->freememtop + 1] = s->regoff + 1;
+ rd->freememtop += regsneeded + 1;
+
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ } else if (s->type == TYPE_ADR) {
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
s->flags &= ~SAVEDTMP;
- freesavfltregs[freesavflttop++] = s->regoff;
+ rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
+
} else
- freetmpfltregs[freetmpflttop++] = s->regoff;
- }
- else {
+ rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
+#endif
+ } else if (IS_FLT_DBL_TYPE(s->type)) {
+ if (s->flags & (SAVEDVAR | SAVEDTMP)) {
+ s->flags &= ~SAVEDTMP;
+ rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
+ } else
+ if (s->flags & TMPARG) {
+ s->flags &= ~TMPARG;
+ rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
+ } else
+ rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
+ } else {
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
s->flags &= ~SAVEDTMP;
- freesavintregs[freesavinttop] = s->regoff;
+ rd->freesavintregs[rd->freesavinttop] = s->regoff;
#ifdef USETWOREGS
if (regsneeded)
- freesavintregs[freesavinttop + 1] = secondregs[s->regoff];
+ rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
#endif
- freesavinttop += regsneeded + 1;
- } else {
- freetmpintregs[freetmpinttop] = s->regoff;
+ rd->freesavinttop += regsneeded + 1;
+
+ } else if (s->flags & TMPARG) {
+ s->flags &= ~TMPARG;
+ rd->freeargintregs[rd->freearginttop] = s->regoff;
#ifdef USETWOREGS
if (regsneeded)
- freetmpintregs[freetmpinttop + 1] = secondregs[s->regoff];
+ rd->freeargintregs[rd->freearginttop + 1] = rd->secondregs[s->regoff];
#endif
- 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()
+static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
{
- int opcode;
- int i;
- int len;
+ s4 opcode;
+ s4 i;
+ s4 len;
stackptr src;
stackptr dst;
instruction *iptr;
basicblock *bptr;
- /* b_count = block_count; */
+ bptr = m->basicblocks;
- bptr = block;
while (bptr != NULL) {
-
if (bptr->flags >= BBREACHED) {
dst = bptr->instack;
- reg_init_temp();
+
+ /* initialize temp registers */
+ reg_init_temp(m, rd);
+
iptr = bptr->iinstr;
len = bptr->icount;
-
+
while (--len >= 0) {
src = dst;
dst = iptr->dst;
case ICMD_NOP:
case ICMD_ELSE_ICONST:
case ICMD_CHECKASIZE:
+ case ICMD_CHECKEXCEPTION:
case ICMD_IINC:
case ICMD_JSR:
case ICMD_RET:
case ICMD_RETURN:
case ICMD_GOTO:
+ case ICMD_PUTSTATICCONST:
+ case ICMD_INLINE_START:
+ case ICMD_INLINE_END:
break;
/* pop 0 push 1 const */
case ICMD_FLOAD:
case ICMD_DLOAD:
case ICMD_ALOAD:
- reg_new_temp(dst);
+ reg_new_temp(rd, dst);
break;
/* pop 2 push 1 */
case ICMD_BALOAD:
case ICMD_CALOAD:
case ICMD_SALOAD:
-
- reg_free_temp(src);
- reg_free_temp(src->prev);
- reg_new_temp(dst);
+ reg_free_temp(rd, src);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst);
break;
/* pop 3 push 0 */
case ICMD_BASTORE:
case ICMD_CASTORE:
case ICMD_SASTORE:
-
- reg_free_temp(src);
- reg_free_temp(src->prev);
- reg_free_temp(src->prev->prev);
+ reg_free_temp(rd, src);
+ reg_free_temp(rd, src->prev);
+ reg_free_temp(rd, src->prev->prev);
break;
/* pop 1 push 0 store */
case ICMD_ATHROW:
case ICMD_PUTSTATIC:
+ case ICMD_PUTFIELDCONST:
/* pop 1 push 0 branch */
case ICMD_NULLCHECKPOP:
case ICMD_MONITORENTER:
case ICMD_MONITOREXIT:
- reg_free_temp(src);
+ reg_free_temp(rd, src);
break;
/* pop 2 push 0 branch */
case ICMD_POP2:
case ICMD_PUTFIELD:
- reg_free_temp(src);
- reg_free_temp(src->prev);
+
+ case ICMD_IASTORECONST:
+ case ICMD_LASTORECONST:
+ case ICMD_AASTORECONST:
+ case ICMD_BASTORECONST:
+ case ICMD_CASTORECONST:
+ case ICMD_SASTORECONST:
+ reg_free_temp(rd, src);
+ reg_free_temp(rd, src->prev);
break;
/* pop 0 push 1 dup */
case ICMD_DUP:
- reg_new_temp(dst);
+ reg_new_temp(rd, dst);
break;
/* pop 0 push 2 dup */
case ICMD_DUP2:
- reg_new_temp(dst->prev);
- reg_new_temp(dst);
+ reg_new_temp(rd, dst->prev);
+ reg_new_temp(rd, dst);
break;
/* pop 2 push 3 dup */
case ICMD_DUP_X1:
- reg_new_temp(dst->prev->prev);
- reg_new_temp(dst->prev);
- reg_new_temp(dst);
- reg_free_temp(src);
- reg_free_temp(src->prev);
+ reg_free_temp(rd, src);
+ reg_new_temp(rd, dst);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst->prev);
+ reg_new_temp(rd, dst->prev->prev);
break;
/* pop 3 push 4 dup */
case ICMD_DUP_X2:
- reg_new_temp(dst->prev->prev->prev);
- reg_new_temp(dst->prev->prev);
- reg_new_temp(dst->prev);
- reg_new_temp(dst);
- reg_free_temp(src);
- reg_free_temp(src->prev);
- reg_free_temp(src->prev->prev);
+ reg_free_temp(rd, src);
+ reg_new_temp(rd, dst);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst->prev);
+ reg_free_temp(rd, src->prev->prev);
+ reg_new_temp(rd, dst->prev->prev);
+ reg_new_temp(rd, dst->prev->prev->prev);
break;
/* pop 3 push 5 dup */
case ICMD_DUP2_X1:
- reg_new_temp(dst->prev->prev->prev->prev);
- reg_new_temp(dst->prev->prev->prev);
- reg_new_temp(dst->prev->prev);
- reg_new_temp(dst->prev);
- reg_new_temp(dst);
- reg_free_temp(src);
- reg_free_temp(src->prev);
- reg_free_temp(src->prev->prev);
+ reg_free_temp(rd, src);
+ reg_new_temp(rd, dst);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst->prev);
+ reg_free_temp(rd, src->prev->prev);
+ reg_new_temp(rd, dst->prev->prev);
+ reg_new_temp(rd, dst->prev->prev->prev);
+ reg_new_temp(rd, dst->prev->prev->prev->prev);
break;
/* pop 4 push 6 dup */
case ICMD_DUP2_X2:
- reg_new_temp(dst->prev->prev->prev->prev->prev);
- reg_new_temp(dst->prev->prev->prev->prev);
- reg_new_temp(dst->prev->prev->prev);
- reg_new_temp(dst->prev->prev);
- reg_new_temp(dst->prev);
- reg_new_temp(dst);
- reg_free_temp(src);
- reg_free_temp(src->prev);
- reg_free_temp(src->prev->prev);
- reg_free_temp(src->prev->prev->prev);
+ reg_free_temp(rd, src);
+ reg_new_temp(rd, dst);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst->prev);
+ reg_free_temp(rd, src->prev->prev);
+ reg_new_temp(rd, dst->prev->prev);
+ reg_free_temp(rd, src->prev->prev->prev);
+ reg_new_temp(rd, dst->prev->prev->prev);
+ reg_new_temp(rd, dst->prev->prev->prev->prev);
+ reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
break;
/* pop 2 push 2 swap */
case ICMD_SWAP:
- reg_new_temp(dst->prev);
- reg_new_temp(dst);
- reg_free_temp(src);
- reg_free_temp(src->prev);
+ reg_free_temp(rd, src);
+ reg_new_temp(rd, dst->prev);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst);
break;
/* pop 2 push 1 */
case ICMD_FCMPG:
case ICMD_DCMPL:
case ICMD_DCMPG:
- reg_free_temp(src);
- reg_free_temp(src->prev);
- reg_new_temp(dst);
+ reg_free_temp(rd, src);
+ reg_free_temp(rd, src->prev);
+ reg_new_temp(rd, dst);
break;
/* pop 1 push 1 */
case ICMD_IADDCONST:
case ICMD_ISUBCONST:
case ICMD_IMULCONST:
+ case ICMD_IMULPOW2:
case ICMD_IDIVPOW2:
case ICMD_IREMPOW2:
- case ICMD_IREM0X10001:
case ICMD_IANDCONST:
case ICMD_IORCONST:
case ICMD_IXORCONST:
case ICMD_LADDCONST:
case ICMD_LSUBCONST:
case ICMD_LMULCONST:
+ case ICMD_LMULPOW2:
case ICMD_LDIVPOW2:
case ICMD_LREMPOW2:
- case ICMD_LREM0X10001:
case ICMD_LANDCONST:
case ICMD_LORCONST:
case ICMD_LXORCONST:
case ICMD_ANEWARRAY:
case ICMD_GETFIELD:
- reg_free_temp(src);
- reg_new_temp(dst);
+ reg_free_temp(rd, src);
+ reg_new_temp(rd, dst);
break;
/* pop 0 push 1 */
case ICMD_GETSTATIC:
case ICMD_NEW:
-
- reg_new_temp(dst);
+ reg_new_temp(rd, dst);
break;
/* pop many push any */
case ICMD_INVOKESPECIAL:
case ICMD_INVOKESTATIC:
case ICMD_INVOKEINTERFACE:
- {
- i = iptr->op1;
- while (--i >= 0) {
- reg_free_temp(src);
- src = src->prev;
- }
- if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
- reg_new_temp(dst);
- break;
+ i = iptr->op1;
+ while (--i >= 0) {
+ reg_free_temp(rd, src);
+ src = src->prev;
}
+#if 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)
+#endif
+ reg_new_temp(rd, dst);
+ break;
case ICMD_BUILTIN3:
- reg_free_temp(src);
+ reg_free_temp(rd, src);
src = src->prev;
case ICMD_BUILTIN2:
- reg_free_temp(src);
+ reg_free_temp(rd, src);
src = src->prev;
case ICMD_BUILTIN1:
- reg_free_temp(src);
+ reg_free_temp(rd, src);
src = src->prev;
if (iptr->op1 != TYPE_VOID)
- reg_new_temp(dst);
+ reg_new_temp(rd, dst);
break;
case ICMD_MULTIANEWARRAY:
i = iptr->op1;
while (--i >= 0) {
- reg_free_temp(src);
+ reg_free_temp(rd, src);
src = src->prev;
}
- reg_new_temp(dst);
+ reg_new_temp(rd, dst);
break;
default:
- printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
+ printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
panic("Missing ICMD code during register allocation");
} /* switch */
iptr++;
}
+#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