-/* 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
+ Christian Ullrich
- $Id: reg.inc 1342 2004-07-21 16:10:17Z twisti $
+ $Id: reg.inc 2938 2005-07-08 15:09:14Z 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);
- /* keep code size smaller */
- r = m->registerdata;
+/* reg_setup *******************************************************************
- /* setup the integer register table */
- r->intreg_argnum = 0;
- r->tmpintregcnt = 0;
- r->savintregcnt = 0;
+ TODO
- for (r->intregsnum = 0; nregdescint[r->intregsnum] != REG_END; r->intregsnum++) {
- switch (nregdescint[r->intregsnum]) {
- case REG_SAV:
- r->savintregcnt++;
- break;
- case REG_TMP:
- r->tmpintregcnt++;
- break;
- case REG_ARG:
- r->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);
-#ifdef USETWOREGS
- r->secondregs = MNEW(s4, r->intregsnum);
-#endif
+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->argintreguse = 0;
- r->tmpintreguse = 0;
- r->savintreguse = 0;
+ rd->argintregs = DMNEW(s4, INT_ARG_CNT);
+ rd->tmpintregs = DMNEW(s4, INT_TMP_CNT);
+ rd->savintregs = DMNEW(s4, INT_SAV_CNT);
+ rd->freeargintregs = DMNEW(s4, INT_ARG_CNT);
+ rd->freetmpintregs = DMNEW(s4, INT_TMP_CNT);
+ rd->freesavintregs = DMNEW(s4, INT_SAV_CNT);
- for (n = 0; n < r->intregsnum; n++) {
- switch (nregdescint[n]) {
+ rd->argintreguse = 0;
+ rd->tmpintreguse = 0;
+ rd->savintreguse = 0;
+
+ for (i = 0; i < INT_REG_CNT; 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->argintreguse++] = i;
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
+ assert(rd->savintreguse == INT_SAV_CNT);
+ assert(rd->tmpintreguse == INT_TMP_CNT);
+ assert(rd->argintreguse == INT_ARG_CNT);
#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;
-#endif
-
- /* setup the float register table */
- r->fltreg_argnum = 0;
- r->tmpfltregcnt = 0;
- r->savfltregcnt = 0;
-
- for (r->floatregsnum = 0; nregdescfloat[r->floatregsnum] != REG_END; r->floatregsnum++) {
- switch (nregdescfloat[r->floatregsnum]) {
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ /* setup the address register table */
+
+ rd->argadrregs = DMNEW(s4, ADR_ARG_CNT);
+ rd->tmpadrregs = DMNEW(s4, ADR_TMP_CNT);
+ rd->savadrregs = DMNEW(s4, ADR_SAV_CNT);
+ rd->freeargadrregs = DMNEW(s4, ADR_ARG_CNT);
+ rd->freetmpadrregs = DMNEW(s4, ADR_TMP_CNT);
+ rd->freesavadrregs = DMNEW(s4, ADR_SAV_CNT);
+
+ rd->adrreg_argnum = 0;
+ rd->argadrreguse = 0;
+ rd->tmpadrreguse = 0;
+ rd->savadrreguse = 0;
+
+ for (i = 0; i < ADR_REG_CNT; i++) {
+ switch (nregdescadr[i]) {
+ case REG_RET:
+ rd->adrreg_ret = i;
+ break;
case REG_SAV:
- r->savfltregcnt++;
+ rd->savadrregs[rd->savadrreguse++] = i;
break;
case REG_TMP:
- r->tmpfltregcnt++;
+ rd->tmpadrregs[rd->tmpadrreguse++] = i;
break;
case REG_ARG:
- r->fltreg_argnum++;
+ rd->argadrregs[rd->argadrreguse++] = i;
break;
}
}
+ assert(rd->savadrreguse == ADR_SAV_CNT);
+ assert(rd->tmpadrreguse == ADR_TMP_CNT);
+ assert(rd->argadrreguse == ADR_ARG_CNT);
+#endif
+
+ /* setup the float register table */
- 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->argfltregs = DMNEW(s4, FLT_ARG_CNT);
+ rd->tmpfltregs = DMNEW(s4, FLT_TMP_CNT);
+ rd->savfltregs = DMNEW(s4, FLT_SAV_CNT);
+ rd->freeargfltregs = DMNEW(s4, FLT_ARG_CNT);
+ rd->freetmpfltregs = DMNEW(s4, FLT_TMP_CNT);
+ rd->freesavfltregs = DMNEW(s4, FLT_SAV_CNT);
- r->fltreg_argnum = 0;
- r->argfltreguse = 0;
- r->tmpfltreguse = 0;
- r->savfltreguse = 0;
+ rd->argfltreguse = 0;
+ rd->tmpfltreguse = 0;
+ rd->savfltreguse = 0;
- for (n = 0; n < r->floatregsnum; n++) {
- switch (nregdescfloat[n]) {
+ for (i = 0; i < FLT_REG_CNT; i++) {
+ switch (nregdescfloat[i]) {
case REG_RET:
- r->floatreg_ret = n;
+ rd->fltreg_ret = i;
break;
case REG_SAV:
- r->savfltregs[r->savfltreguse++] = n;
+ rd->savfltregs[rd->savfltreguse++] = i;
break;
case REG_TMP:
- r->tmpfltregs[r->tmpfltreguse++] = n;
+ rd->tmpfltregs[rd->tmpfltreguse++] = i;
break;
case REG_ARG:
- r->argfltregs[r->fltreg_argnum++] = n;
- r->argfltreguse++;
+ rd->argfltregs[rd->argfltreguse++] = i;
break;
}
}
-}
-
-
-void reg_setup(methodinfo *m)
-{
- s4 i;
- varinfo5 *v;
+ assert(rd->savfltreguse == FLT_SAV_CNT);
+ assert(rd->tmpfltreguse == FLT_TMP_CNT);
+ assert(rd->argfltreguse == FLT_ARG_CNT);
- m->registerdata->freemem = MNEW(s4, m->maxstack);
- m->registerdata->locals = MNEW(varinfo5, m->maxlocals);
- m->registerdata->interfaces = MNEW(varinfo5, m->maxstack);
- for (v = m->registerdata->locals, i = m->maxlocals; i > 0; v++, i--) {
+ rd->freemem = DMNEW(s4, id->cummaxstack);
+#if defined(HAS_4BYTE_STACKSLOT)
+ rd->freemem_2 = DMNEW(s4, id->cummaxstack);
+#endif
+ 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 = 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;
v[0][TYPE_ADR].type = -1;
v[0][TYPE_ADR].flags = 0;
}
+
+#if defined(SPECIALMEMUSE)
+# if defined(__DARWIN__)
+ /* 6*4=24 byte linkage area + 8*4=32 byte minimum parameter Area */
+ rd->memuse = LA_WORD_SIZE + INT_ARG_CNT;
+# else
+ rd->memuse = LA_WORD_SIZE;
+# endif
+#else
+ rd->memuse = 0; /* init to zero -> analyse_stack will set it to a higher */
+ /* value, if appropriate */
+#endif
+
+ /* Set rd->argxxxreguse to XXX_ARG_CNBT to not use unused argument */
+ /* registers as temp registers */
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ rd->argadrreguse = 0;
+#endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
+ rd->argintreguse = 0;
+ rd->argfltreguse = 0;
}
-/* 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;
-
- 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);
-
-#ifdef USETWOREGS
- if (r->secondregs) MFREE(r->secondregs, s4, r->intregsnum);
-#endif
+ /* void */
+}
+
- 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);
+/* reg_close *******************************************************************
- FREE(m->registerdata, registerdata);
- m->registerdata = NULL;
+ TODO
+
+*******************************************************************************/
+
+void reg_close()
+{
+ /* void */
}
*******************************************************************************/
-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("memuse after reg.inc: %3i\n",rd->memuse);
+ }
#endif
}
*******************************************************************************/
-static void interface_regalloc(methodinfo *m)
+static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
{
- int s, t, saved;
- int intalloc, fltalloc;
+ int s, t, tt, saved;
+ int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
+ /* in case a more vars are packed into this interface slot */
varinfo *v;
- int regsneeded = 0;
- registerdata *r;
-
- /* allocate stack space for passing arguments to called methods */
-
- /* 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;
+ int intregsneeded = 0;
+ int memneeded = 0;
+ /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
+ /* on HAS_4BYTE_STACKSLOT architectures */
+ int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
+
+ /* rd->memuse was already set in stack.c to allocate stack space for */
+ /* passing arguments to called methods */
+#if defined(__I386__)
+ if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+ /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
+ if (rd->memuse < 1)
+ rd->memuse = 1;
+ }
#endif
- else
- r->ifmemuse = 0;
+#ifdef INVOKE_NEW_DEBUG
+ if (compileverbose) {
+ if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ printf("ACC_SYNCHRONIZED\n");
+ printf("analyse: argintru %3i argfltru %3i memuse %3i\n",
+ rd->argintreguse, rd->argfltreguse, rd->memuse);
+ }
#endif
- r->iftmpintregcnt = r->tmpintregcnt;
- r->ifsavintregcnt = r->savintregcnt;
- r->iftmpfltregcnt = r->tmpfltregcnt;
- r->ifsavfltregcnt = r->savfltregcnt;
- for (s = 0; s < m->maxstack; s++) {
+ 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];
+ for (tt = 0; tt <= 4; tt++) {
+ t = typeloop[tt];
+ v = &rd->interfaces[s][t];
if (v->type >= 0) {
-#ifdef USETWOREGS
- regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#if defined(HAS_4BYTE_STACKSLOT)
+ memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
#endif
if (!saved) {
- if (IS_FLT_DBL_TYPE(t)) {
- if (fltalloc >= 0) {
- v->flags |= r->interfaces[s][fltalloc].flags & INMEMORY;
- v->regoff = r->interfaces[s][fltalloc].regoff;
- }
- else if (r->iftmpfltregcnt > 0) {
- r->iftmpfltregcnt--;
- v->regoff = r->tmpfltregs[r->iftmpfltregcnt];
- }
- else if (r->ifsavfltregcnt > 0) {
- r->ifsavfltregcnt--;
- v->regoff = r->savfltregs[r->ifsavfltregcnt];
- }
- else {
- v->flags |= INMEMORY;
- v->regoff = r->ifmemuse;
- r->ifmemuse += regsneeded + 1;
- }
- fltalloc = t;
- }
- else {
-#if defined(__I386__)
- /*
- * for i386 put all longs in memory
- */
- if (IS_2_WORD_TYPE(t)) {
- v->flags |= INMEMORY;
- v->regoff = r->ifmemuse++;
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ if (IS_ADR_TYPE(t)) {
+ if (!m->isleafmethod
+ &&(rd->argadrreguse < ADR_ARG_CNT)) {
+ v->regoff = rd->argadrregs[rd->argadrreguset++];
+ } else if (rd->tmpadrreguse > 0) {
+ v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+ } else if (rd->savadrreguse > 0) {
+ v->regoff = rd->savadrregs[--rd->savadrreguse];
} else {
-#endif
- if (intalloc >= 0) {
- v->flags |= r->interfaces[s][intalloc].flags & INMEMORY;
- v->regoff = r->interfaces[s][intalloc].regoff;
- }
- else if (r->iftmpintregcnt > regsneeded) {
- r->iftmpintregcnt -= regsneeded + 1;
- v->regoff = r->tmpintregs[r->iftmpintregcnt];
- }
- else if (r->ifsavintregcnt > regsneeded) {
- r->ifsavintregcnt -= regsneeded + 1;
- v->regoff = r->savintregs[r->ifsavintregcnt];
- }
- else {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse++;
+ }
+ } else /* !IS_ADR_TYPE */
+#endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
+ {
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (fltalloc >= 0) {
+ /* Reuse memory slot(s)/register(s) for shared interface slots */
+ v->flags |= rd->interfaces[s][fltalloc].flags
+ & INMEMORY;
+ v->regoff = rd->interfaces[s][fltalloc].regoff;
+ } else if (!m->isleafmethod
+ && (rd->argfltreguse < FLT_ARG_CNT)) {
+ v->regoff = rd->argfltregs[rd->argfltreguse++];
+ } else if (rd->tmpfltreguse > 0) {
+ v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
+ } else if (rd->savfltreguse > 0) {
+ v->regoff = rd->savfltregs[--rd->savfltreguse];
+ } else {
v->flags |= INMEMORY;
- v->regoff = r->ifmemuse;
- r->ifmemuse += regsneeded + 1;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
}
-#if defined(__I386__)
- }
+ fltalloc = t;
+ } else { /* !IS_FLT_DBL_TYPE(t) */
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ /*
+ * for i386 put all longs in memory
+ */
+ if (IS_2_WORD_TYPE(t)) {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
+ } else
+#endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
+/* #if !defined(HAS_4BYTE_STACKSLOT) */
+ if (intalloc >= 0) {
+ /* Reuse memory slot(s)/register(s) for shared interface slots */
+ v->flags |=
+ rd->interfaces[s][intalloc].flags
+ & INMEMORY;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (!(v->flags & INMEMORY)
+ && IS_2_WORD_TYPE(intalloc))
+ v->regoff = GET_LOW_REG(
+ rd->interfaces[s][intalloc].regoff);
+ else
#endif
- intalloc = t;
- }
- }
- else {
- if (IS_FLT_DBL_TYPE(t)) {
- if (fltalloc >= 0) {
- v->flags |= r->interfaces[s][fltalloc].flags & INMEMORY;
- v->regoff = r->interfaces[s][fltalloc].regoff;
- }
- else if (r->ifsavfltregcnt > 0) {
- r->ifsavfltregcnt--;
- v->regoff = r->savfltregs[r->ifsavfltregcnt];
+ v->regoff =
+ rd->interfaces[s][intalloc].regoff;
+ } else
+/* #endif *//* !defined(HAS_4BYTE_STACKSLOT) */
+ if (!m->isleafmethod &&
+ (rd->argintreguse
+ + intregsneeded < INT_ARG_CNT)) {
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff=PACK_REGS(
+ rd->argintregs[rd->argintreguse],
+ rd->argintregs[rd->argintreguse + 1]);
+ else
+#endif
+ v->regoff =
+ rd->argintregs[rd->argintreguse];
+ rd->argintreguse += intregsneeded + 1;
+ }
+ else if (rd->tmpintreguse > intregsneeded) {
+ rd->tmpintreguse -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff=PACK_REGS(
+ rd->tmpintregs[rd->tmpintreguse],
+ rd->tmpintregs[rd->tmpintreguse + 1]);
+ else
+#endif
+ v->regoff =
+ rd->tmpintregs[rd->tmpintreguse];
+ }
+ else if (rd->savintreguse > intregsneeded) {
+ rd->savintreguse -= intregsneeded + 1;
+ v->regoff =
+ rd->savintregs[rd->savintreguse];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff=PACK_REGS(
+ rd->savintregs[rd->savintreguse],
+ rd->savintregs[rd->savintreguse + 1]);
+ else
+#endif
+ v->regoff =
+ rd->savintregs[rd->savintreguse];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
+ }
+
+ intalloc = t;
+ } /* if (IS_FLT_DBL_TYPE(t)) */
+ }
+ } else { /* (saved) */
+/* now the same like above, but without a chance to take a temporary register */
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ if (IS_ADR_TYPE(t)) {
+ if (rd->savadrreguse > 0) {
+ v->regoff = rd->savadrregs[--rd->savadrreguse];
}
else {
v->flags |= INMEMORY;
- v->regoff = r->ifmemuse;
- r->ifmemuse += regsneeded + 1;
- }
- fltalloc = t;
- }
- else {
-#if defined(__I386__)
- /*
- * for i386 put all longs in memory
- */
- if (IS_2_WORD_TYPE(t)) {
- v->flags |= INMEMORY;
- v->regoff = r->ifmemuse++;
- } else {
+ v->regoff = rd->memuse++;
+ }
+ } else
#endif
- if (intalloc >= 0) {
- v->flags |= r->interfaces[s][intalloc].flags & INMEMORY;
- v->regoff = r->interfaces[s][intalloc].regoff;
- }
- else if (r->ifsavintregcnt > regsneeded) {
- r->ifsavintregcnt -= regsneeded + 1;
- v->regoff = r->savintregs[r->ifsavintregcnt];
- }
- else {
- v->flags |= INMEMORY;
- v->regoff = r->ifmemuse;
- r->ifmemuse += regsneeded + 1;
- }
-#if defined(__I386__)
+ {
+ if (IS_FLT_DBL_TYPE(t)) {
+ if (fltalloc >= 0) {
+ v->flags |= rd->interfaces[s][fltalloc].flags
+ & INMEMORY;
+ v->regoff = rd->interfaces[s][fltalloc].regoff;
+ } else
+ if (rd->savfltreguse > 0) {
+ v->regoff = rd->savfltregs[--rd->savfltreguse];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
+ }
+ fltalloc = t;
}
+ else { /* IS_INT_LNG */
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ /*
+ * for i386 put all longs in memory
+ */
+ if (IS_2_WORD_TYPE(t)) {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
+ } else
#endif
- intalloc = t;
- }
- }
+ {
+/* #if !defined(HAS_4BYTE_STACKSLOT) */
+ if (intalloc >= 0) {
+ v->flags |=
+ rd->interfaces[s][intalloc].flags & INMEMORY;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (!(v->flags & INMEMORY)
+ && IS_2_WORD_TYPE(intalloc))
+ v->regoff =
+ GET_LOW_REG(
+ rd->interfaces[s][intalloc].regoff);
+ else
+#endif
+ v->regoff =
+ rd->interfaces[s][intalloc].regoff;
+ } else
+/* #endif */
+ {
+ if (rd->savintreguse > intregsneeded) {
+ rd->savintreguse -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff = PACK_REGS(
+ rd->savintregs[rd->savintreguse],
+ rd->savintregs[rd->savintreguse + 1]);
+ else
+#endif
+ v->regoff =
+ rd->savintregs[rd->savintreguse];
+ } else {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
+ }
+ }
+ intalloc = t;
+ }
+ } /* if (IS_FLT_DBL_TYPE(t) else */
+ } /* if (IS_ADR_TYPE(t)) else */
+ } /* if (saved) else */
} /* if (type >= 0) */
} /* for t */
} /* for s */
-
- 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;
}
*******************************************************************************/
-static void local_regalloc(methodinfo *m)
+static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
{
- int s, t, tt;
- int intalloc, fltalloc;
+ int p, 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;
+ int intregsneeded = 0;
+ int memneeded = 0;
+ int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
+ int fargcnt, iargcnt;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ int aargcnt;
+#endif
if (m->isleafmethod) {
- int arg, doublewordarg, iargcnt, fargcnt;
+ methoddesc *md = m->parseddesc;
- arg = 0, iargcnt = 0, fargcnt = 0;
- doublewordarg = 0;
- for (s = 0; s < m->maxlocals; s++) {
+ iargcnt = md->argintreguse;
+ fargcnt = md->argfltreguse;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ aargcnt = md->argadrreguse;
+#endif
+ for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
intalloc = -1; fltalloc = -1;
for (tt = 0; tt <= 4; tt++) {
t = typeloop[tt];
- v = &r->locals[s][t];
+ v = &rd->locals[s][t];
+
+ if (v->type < 0)
+ continue;
- if (v->type >= 0) {
-#ifdef USETWOREGS
- regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
#endif
- if (IS_FLT_DBL_TYPE(t)) {
-#if !defined(CONSECUTIVE_FLOATARGS)
- fargcnt = arg;
+#if defined(HAS_4BYTE_STACKSLOT)
+ memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+
+ /*
+ * The order of
+ *
+ * #ifdef HAS_ADDRESS_REGISTER_FILE
+ * if (IS_ADR_TYPE) {
+ * ...
+ * } else
+ * #endif
+ * if (IS_FLT_DBL) {
+ * ...
+ * } else { / int & lng
+ * ...
+ * }
+ *
+ * must not to be changed!
+ */
+
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ if (IS_ADR_TYPE(t)) {
+ if ((p < md->paramcount) && !md->params[p].inmemory) {
+ v->flags = 0;
+ v->regoff = rd->argadrregs[md->params[p].regoff];
+ }
+ if (rd->tmpadrreguse > 0) {
+ v->flags = 0;
+ v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
+ }
+ else if (rd->savadrreguse > 0) {
+ v->flags = 0;
+ v->regoff = rd->savadrregs[--rd->savadrreguse];
+ }
+ /* use unused argument registers as local registers */
+ else if ((p >= md->paramcount) &&
+ (aargcnt < ADR_ARG_CNT)) {
+ v->flags = 0;
+ v->regoff = rd->argadrregs[aargcnt++];
+ }
+ else {
+ v->flags |= INMEMORY;
+ v->regoff = rd->memuse++;
+ }
+ } 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 (!doublewordarg && (arg < m->paramcount) &&
- (fargcnt < r->fltreg_argnum)) {
+ else if ((p < md->paramcount) &&
+ !md->params[p].inmemory) {
v->flags = 0;
- v->regoff = r->argfltregs[fargcnt];
+ v->regoff = rd->argfltregs[md->params[p].regoff];
}
- else if (r->maxtmpfltreguse > 0) {
- r->maxtmpfltreguse--;
+ else if (rd->tmpfltreguse > 0) {
v->flags = 0;
- v->regoff = r->tmpfltregs[r->maxtmpfltreguse];
+ v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
}
- else if (r->maxsavfltreguse > 0) {
- r->maxsavfltreguse--;
+ else if (rd->savfltreguse > 0) {
v->flags = 0;
- v->regoff = r->savfltregs[r->maxsavfltreguse];
+ v->regoff = rd->savfltregs[--rd->savfltreguse];
+ }
+ /* use unused argument registers as local registers */
+ else if ((p >= m->paramcount) &&
+ (fargcnt < FLT_ARG_CNT)) {
+ v->flags = 0;
+ v->regoff = rd->argfltregs[fargcnt];
+ fargcnt++;
}
else {
v->flags = INMEMORY;
- v->regoff = r->maxmemuse;
- r->maxmemuse += regsneeded + 1;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
}
fltalloc = t;
} else {
- int regtouse;
-#if defined(__I386__)
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
if (IS_2_WORD_TYPE(t)) {
v->flags = INMEMORY;
- v->regoff = r->maxmemuse++;
- } else {
-#endif
-#if !defined(CONSECUTIVE_INTARGS)
- iargcnt = arg;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
+ } else
#endif
+ {
if (intalloc >= 0) {
- v->flags = r->locals[s][intalloc].flags;
- v->regoff = r->locals[s][intalloc].regoff;
- }
- else if (!doublewordarg && (arg < m->paramcount)
-#ifndef USETWOREGS
- && ((regtouse = iargcnt) < r->intreg_argnum)
-#else
- && ((regtouse = s) < r->intreg_argnum - regsneeded)
+ v->flags = rd->locals[s][intalloc].flags;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (!(v->flags & INMEMORY)
+ && IS_2_WORD_TYPE(intalloc))
+ v->regoff = GET_LOW_REG(
+ rd->locals[s][intalloc].regoff);
+ else
#endif
- ) {
+ v->regoff = rd->locals[s][intalloc].regoff;
+ }
+ else if ((p < md->paramcount) &&
+ !md->params[p].inmemory) {
v->flags = 0;
- v->regoff = r->argintregs[regtouse];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (IS_2_WORD_TYPE(t))
+/* For ARM: - if GET_LOW_REG(md->params[p].regoff) == R4, prevent here that */
+/* rd->argintregs[GET_HIGH_REG(md->...)) is used! */
+ v->regoff = PACK_REGS(
+ rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
+ rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
+ else
+#endif
+ v->regoff =
+ rd->argintregs[md->params[p].regoff];
}
- else if (r->maxtmpintreguse > regsneeded) {
- r->maxtmpintreguse -= regsneeded + 1;
+ else if (rd->tmpintreguse > intregsneeded) {
+ rd->tmpintreguse -= intregsneeded + 1;
v->flags = 0;
- v->regoff = r->tmpintregs[r->maxtmpintreguse];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff = PACK_REGS(
+ rd->tmpintregs[rd->tmpintreguse],
+ rd->tmpintregs[rd->tmpintreguse + 1]);
+ else
+#endif
+ v->regoff =
+ rd->tmpintregs[rd->tmpintreguse];
}
- else if (r->maxsavintreguse > regsneeded) {
- r->maxsavintreguse -= regsneeded + 1;
+ else if (rd->savintreguse > intregsneeded) {
+ rd->savintreguse -= intregsneeded + 1;
v->flags = 0;
- v->regoff = r->savintregs[r->maxsavintreguse];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff = PACK_REGS(
+ rd->savintregs[rd->savintreguse],
+ rd->savintregs[rd->savintreguse + 1]);
+ else
+#endif
+ v->regoff =rd->savintregs[rd->savintreguse];
}
/*
* use unused argument registers as local registers
*/
- else if (!doublewordarg && (arg >= m->paramcount) &&
- (iargcnt < r->intreg_argnum)) {
+ else if ((p >= m->paramcount) &&
+ (iargcnt < INT_ARG_CNT)) {
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->memuse;
+ rd->memuse += memneeded + 1;
}
-#if defined(__I386__)
}
-#endif
intalloc = t;
}
+#ifdef HAS_ADDRESS_REGISTER_FILE
}
- }
- if (arg < m->paramcount) {
- if (doublewordarg) {
- doublewordarg = 0;
- /* what type was the double arg? */
- if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
- fargcnt++;
-
- } else {
- iargcnt++;
- }
- arg++;
-
- } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
- doublewordarg = 1;
+#endif
+ } /* for (tt=0;...) */
- } else {
- if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
- fargcnt++;
+ /* If the current parameter is a 2-word type, the next local slot */
+ /* is skipped. */
- } else {
- iargcnt++;
- }
- arg++;
- }
- }
+ if (p < md->paramcount)
+ if (IS_2_WORD_TYPE(md->paramtypes[p].type))
+ s++;
}
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;
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
+ intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#if defined(HAS_4BYTE_STACKSLOT)
+ memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
+#endif
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ if ( IS_ADR_TYPE(t) ) {
+ if (rd->savadrreguse > 0) {
+ v->flags = 0;
+ v->regoff = rd->savadrregs[--rd->savadrreguse];
+ }
+ else {
+ v->flags = INMEMORY;
+ v->regoff = rd->memuse++;
+ }
+ } else {
#endif
if (IS_FLT_DBL_TYPE(t)) {
if (fltalloc >= 0) {
- v->flags = 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->savfltreguse > 0) {
v->flags = 0;
- v->regoff = r->savfltregs[r->maxsavfltreguse];
+ v->regoff = rd->savfltregs[--rd->savfltreguse];
}
else {
v->flags = INMEMORY;
- v->regoff = r->maxmemuse;
- r->maxmemuse += regsneeded + 1;
+ /* Align doubles in Memory */
+ if ( (memneeded) && (rd->memuse & 1))
+ rd->memuse++;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
}
fltalloc = t;
}
else {
-#if defined(__I386__)
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
if (IS_2_WORD_TYPE(t)) {
v->flags = INMEMORY;
- v->regoff = r->maxmemuse++;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
} 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;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (!(v->flags & INMEMORY)
+ && IS_2_WORD_TYPE(intalloc))
+ v->regoff = GET_LOW_REG(
+ rd->locals[s][intalloc].regoff);
+ else
+#endif
+ v->regoff = rd->locals[s][intalloc].regoff;
}
- else if (r->maxsavintreguse > regsneeded) {
- r->maxsavintreguse -= regsneeded+1;
+ else if (rd->savintreguse > intregsneeded) {
+ rd->savintreguse -= intregsneeded+1;
v->flags = 0;
- v->regoff = r->savintregs[r->maxsavintreguse];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ v->regoff = PACK_REGS(
+ rd->savintregs[rd->savintreguse],
+ rd->savintregs[rd->savintreguse + 1]);
+ else
+#endif
+ v->regoff =rd->savintregs[rd->savintreguse];
}
else {
v->flags = INMEMORY;
- v->regoff = r->maxmemuse;
- r->maxmemuse += regsneeded + 1;
+ v->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
}
-#if defined(__I386__)
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
}
#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;
+#if defined(HAS_4BYTE_STACKSLOT)
+ rd->freememtop_2 = 0;
+#endif
- r->freetmpinttop = 0;
- r->freesavinttop = 0;
- r->freetmpflttop = 0;
- r->freesavflttop = 0;
+ 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->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) {
+ /* Don't use not used Argument Registers in Leafmethods -> they could */
+ /* already be in use for Locals passed as parameter to this Method */
+ rd->argintreguse = INT_ARG_CNT;
+ rd->argfltreguse = FLT_ARG_CNT;
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ rd->argadrreguse = ADR_ARG_CNT;
+#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 intregsneeded;
+ s4 memneeded;
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. */
tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
-#ifdef USETWOREGS
- regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
+ intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+ intregsneeded = 0;
+#endif
+#if defined(HAS_4BYTE_STACKSLOT)
+ memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
#else
- regsneeded = 0;
+ memneeded = 0;
#endif
for(; tryagain; --tryagain) {
if (tryagain == 1) {
if (!(s->flags & SAVEDVAR))
s->flags |= SAVEDTMP;
- if (IS_FLT_DBL_TYPE(s->type)) {
- if (r->freesavflttop > 0) {
- r->freesavflttop--;
- s->regoff = r->freesavfltregs[r->freesavflttop];
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ if (IS_ADR_TYPE(s->type)) {
+ if (rd->freesavadrtop > 0) {
+ s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
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->savadrreguse > 0) {
+ s->regoff = rd->savadrregs[--rd->savadrreguse];
return;
}
-
- } else {
-#if defined(__I386__)
- /*
- * for i386 put all longs in memory
- */
- if (!IS_2_WORD_TYPE(s->type)) {
+ } else
#endif
- if (r->freesavinttop > regsneeded) {
- r->freesavinttop -= regsneeded + 1;
- s->regoff = r->freesavintregs[r->freesavinttop];
+ {
+ if (IS_FLT_DBL_TYPE(s->type)) {
+ if (rd->freesavflttop > 0) {
+ s->regoff = rd->freesavfltregs[--rd->freesavflttop];
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->savfltreguse > 0) {
+ s->regoff = rd->savfltregs[--rd->savfltreguse];
return;
}
-#if defined(__I386__)
- }
+ } else {
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ /*
+ * for i386 put all longs in memory
+ */
+ if (!IS_2_WORD_TYPE(s->type))
+#endif
+ {
+ if (rd->freesavinttop > intregsneeded) {
+ rd->freesavinttop -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ s->regoff = PACK_REGS(
+ rd->freesavintregs[rd->freesavinttop],
+ rd->freesavintregs[rd->freesavinttop + 1]);
+ else
#endif
+ s->regoff =
+ rd->freesavintregs[rd->freesavinttop];
+ return;
+ } else if (rd->savintreguse > intregsneeded) {
+ rd->savintreguse -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ s->regoff = PACK_REGS(
+ rd->savintregs[rd->savintreguse],
+ rd->savintregs[rd->savintreguse + 1]);
+ else
+#endif
+ s->regoff = rd->savintregs[rd->savintreguse];
+ return;
+ }
+ }
+ }
}
-
- } else {
- if (IS_FLT_DBL_TYPE(s->type)) {
- if (r->freetmpflttop > 0) {
- r->freetmpflttop--;
- s->regoff = r->freetmpfltregs[r->freetmpflttop];
+ } else { /* tryagain == 2 */
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ if (IS_ADR_TYPE(s->type)) {
+ if (rd->freetmpadrtop > 0) {
+ s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
return;
-
- } else if (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) {
+ s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
return;
}
-
- } else {
-#if defined(__I386__)
- /*
- * for i386 put all longs in memory
- */
- if (!IS_2_WORD_TYPE(s->type)) {
+ } else
#endif
- if (r->freetmpinttop > regsneeded) {
- r->freetmpinttop -= regsneeded + 1;
- s->regoff = r->freetmpintregs[r->freetmpinttop];
+ {
+ if (IS_FLT_DBL_TYPE(s->type)) {
+ if (rd->freeargflttop > 0) {
+ s->regoff = rd->freeargfltregs[--rd->freeargflttop];
+ s->flags |= TMPARG;
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->argfltreguse < FLT_ARG_CNT) {
+ s->regoff = rd->argfltregs[rd->argfltreguse++];
+ s->flags |= TMPARG;
+ return;
+ } else if (rd->freetmpflttop > 0) {
+ s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
+ return;
+ } else if (rd->tmpfltreguse > 0) {
+ s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
return;
}
-#if defined(__I386__)
- }
+
+ } else {
+#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ /*
+ * for i386 put all longs in memory
+ */
+ if (!IS_2_WORD_TYPE(s->type))
+#endif
+ {
+ if (rd->freearginttop > intregsneeded) {
+ rd->freearginttop -= intregsneeded + 1;
+ s->flags |= TMPARG;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ s->regoff = PACK_REGS(
+ rd->freeargintregs[rd->freearginttop],
+ rd->freeargintregs[rd->freearginttop + 1]);
+ else
+#endif
+ s->regoff =
+ rd->freeargintregs[rd->freearginttop];
+ return;
+ } else if (rd->argintreguse
+ < INT_ARG_CNT - intregsneeded) {
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ s->regoff = PACK_REGS(
+ rd->argintregs[rd->argintreguse],
+ rd->argintregs[rd->argintreguse + 1]);
+ else
+#endif
+ s->regoff = rd->argintregs[rd->argintreguse];
+ s->flags |= TMPARG;
+ rd->argintreguse += intregsneeded + 1;
+ return;
+ } else if (rd->freetmpinttop > intregsneeded) {
+ rd->freetmpinttop -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ s->regoff = PACK_REGS(
+ rd->freetmpintregs[rd->freetmpinttop],
+ rd->freetmpintregs[rd->freetmpinttop + 1]);
+ else
+#endif
+ s->regoff = rd->freetmpintregs[rd->freetmpinttop];
+ return;
+ } else if (rd->tmpintreguse > intregsneeded) {
+ rd->tmpintreguse -= intregsneeded + 1;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded)
+ s->regoff = PACK_REGS(
+ rd->tmpintregs[rd->tmpintreguse],
+ rd->tmpintregs[rd->tmpintreguse + 1]);
+ else
#endif
+ s->regoff = rd->tmpintregs[rd->tmpintreguse];
+ return;
+ }
+ } /* if (!IS_2_WORD_TYPE(s->type)) */
+ } /* if (IS_FLT_DBL_TYPE(s->type)) */
+ } /* if (IS_ADR_TYPE(s->type)) */
+ } /* if (tryagain == 1) else */
+ } /* for(; tryagain; --tryagain) */
+
+#if defined(HAS_4BYTE_STACKSLOT)
+ if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
+ rd->freememtop_2--;
+ s->regoff = rd->freemem_2[rd->freememtop_2];
+ } else
+#endif /*defined(HAS_4BYTE_STACKSLOT) */
+ if ((memneeded == 0) && (rd->freememtop > 0)) {
+ rd->freememtop--;;
+ s->regoff = rd->freemem[rd->freememtop];
+ } else {
+#if defined(HAS_4BYTE_STACKSLOT)
+ /* align 2 Word Types */
+ if ((memneeded) && ((rd->memuse & 1) == 1)) {
+ /* Put patched memory slot on freemem */
+ rd->freemem[rd->freememtop++] = rd->memuse;
+ rd->memuse++;
}
+#endif /*defined(HAS_4BYTE_STACKSLOT) */
+ s->regoff = rd->memuse;
+ rd->memuse += memneeded + 1;
}
- }
-
- if (r->freememtop > regsneeded) {
- r->freememtop -= regsneeded + 1;
- s->regoff = r->freemem[r->freememtop];
-
- } else {
- s->regoff = r->memuse;
- r->memuse += regsneeded + 1;
- if (r->memuse > r->maxmemuse)
- r->maxmemuse = r->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;
+ s4 intregsneeded;
+ s4 memneeded;
- /* keep code size smaller */
- r = m->registerdata;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#else
+ intregsneeded = 0;
+#endif
-#ifdef USETWOREGS
- regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
+#if defined(HAS_4BYTE_STACKSLOT)
+ memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
#else
- regsneeded = 0;
+ memneeded = 0;
#endif
if (s->flags & INMEMORY) {
- r->freemem[r->freememtop] = s->regoff;
- if (regsneeded)
- r->freemem[r->freememtop + 1] = s->regoff + 1;
- r->freememtop += regsneeded + 1;
+#if defined(HAS_4BYTE_STACKSLOT)
+ if (memneeded > 0) {
+ rd->freemem_2[rd->freememtop_2] = s->regoff;
+ rd->freememtop_2++;
+ } else
+#endif
+ {
+ rd->freemem[rd->freememtop] = s->regoff;
+ rd->freememtop++;
+ }
+#ifdef HAS_ADDRESS_REGISTER_FILE
+ } else if (IS_ADR_TYPE(s->type)) {
+ if (s->flags & (SAVEDVAR | SAVEDTMP)) {
+ s->flags &= ~SAVEDTMP;
+ rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
+ } else
+ rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
+#endif
} else if (IS_FLT_DBL_TYPE(s->type)) {
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
s->flags &= ~SAVEDTMP;
- r->freesavfltregs[r->freesavflttop++] = s->regoff;
-
+ rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
+ } else if (s->flags & TMPARG) {
+ s->flags &= ~TMPARG;
+ rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
} else
- r->freetmpfltregs[r->freetmpflttop++] = s->regoff;
-
- } else {
+ rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
+ } else { /* IS_INT_LNG_TYPE */
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
s->flags &= ~SAVEDTMP;
- r->freesavintregs[r->freesavinttop] = s->regoff;
-#ifdef USETWOREGS
- if (regsneeded)
- r->freesavintregs[r->freesavinttop + 1] = r->secondregs[s->regoff];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded) {
+ rd->freesavintregs[rd->freesavinttop] =
+ GET_LOW_REG(s->regoff);
+ rd->freesavintregs[rd->freesavinttop + 1] =
+ GET_HIGH_REG(s->regoff);
+ } else
#endif
- r->freesavinttop += regsneeded + 1;
-
+ rd->freesavintregs[rd->freesavinttop] = s->regoff;
+ rd->freesavinttop += intregsneeded + 1;
+
+ } else if (s->flags & TMPARG) {
+ s->flags &= ~TMPARG;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded) {
+ rd->freeargintregs[rd->freearginttop] =
+ GET_LOW_REG(s->regoff);
+ rd->freeargintregs[rd->freearginttop + 1] =
+ GET_HIGH_REG(s->regoff);
+ } else
+#endif
+ rd->freeargintregs[rd->freearginttop] = s->regoff;
+ rd->freearginttop += intregsneeded + 1;
} else {
- r->freetmpintregs[r->freetmpinttop] = s->regoff;
-#ifdef USETWOREGS
- if (regsneeded)
- r->freetmpintregs[r->freetmpinttop + 1] = r->secondregs[s->regoff];
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ if (intregsneeded) {
+ rd->freetmpintregs[rd->freetmpinttop] =
+ GET_LOW_REG(s->regoff);
+ rd->freetmpintregs[rd->freetmpinttop + 1] =
+ GET_HIGH_REG(s->regoff);
+ } else
#endif
- r->freetmpinttop += regsneeded + 1;
+ rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
+ rd->freetmpinttop += intregsneeded + 1;
}
}
}
-static void allocate_scratch_registers(methodinfo *m)
+static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
{
s4 opcode;
s4 i;
instruction *iptr;
basicblock *bptr;
+ /* initialize temp registers */
+ reg_init_temp(m, rd);
+
bptr = m->basicblocks;
while (bptr != NULL) {
if (bptr->flags >= BBREACHED) {
dst = bptr->instack;
- /* initialize temp registers */
- reg_init_temp(m);
iptr = bptr->iinstr;
len = bptr->icount;
case ICMD_NOP:
case ICMD_ELSE_ICONST:
+ case ICMD_CHECKNULL:
case ICMD_CHECKASIZE:
case ICMD_CHECKEXCEPTION:
case ICMD_IINC:
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(m, dst);
+ reg_new_temp(rd, dst);
break;
/* pop 2 push 1 */
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 */
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 */
case ICMD_ATHROW:
case ICMD_PUTSTATIC:
+ case ICMD_PUTFIELDCONST:
/* pop 1 push 0 branch */
case ICMD_TABLESWITCH:
case ICMD_LOOKUPSWITCH:
- 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 */
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 */
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 */
case ICMD_IADDCONST:
case ICMD_ISUBCONST:
case ICMD_IMULCONST:
+ case ICMD_IMULPOW2:
case ICMD_IDIVPOW2:
case ICMD_IREMPOW2:
case ICMD_IANDCONST:
case ICMD_LADDCONST:
case ICMD_LSUBCONST:
case ICMD_LMULCONST:
+ case ICMD_LMULPOW2:
case ICMD_LDIVPOW2:
case ICMD_LREMPOW2:
case ICMD_LANDCONST:
case ICMD_D2F:
case ICMD_CHECKCAST:
+ case ICMD_ARRAYCHECKCAST:
case ICMD_ARRAYLENGTH:
case ICMD_INSTANCEOF:
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 */
case ICMD_GETSTATIC:
case ICMD_NEW:
- reg_new_temp(m, dst);
+ reg_new_temp(rd, dst);
break;
/* pop many push any */
- case ICMD_INVOKEVIRTUAL:
- case ICMD_INVOKESPECIAL:
case ICMD_INVOKESTATIC:
+ case ICMD_INVOKESPECIAL:
+ case ICMD_INVOKEVIRTUAL:
case ICMD_INVOKEINTERFACE:
i = iptr->op1;
while (--i >= 0) {
- reg_free_temp(m, src);
+ reg_free_temp(rd, src);
src = src->prev;
}
- if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
- reg_new_temp(m, dst);
+ if (((unresolved_method *) iptr->target)->methodref->parseddesc.md->returntype.type != TYPE_VOID)
+ reg_new_temp(rd, dst);
break;
- case ICMD_BUILTIN3:
- reg_free_temp(m, src);
- src = src->prev;
- case ICMD_BUILTIN2:
- reg_free_temp(m, src);
- src = src->prev;
- case ICMD_BUILTIN1:
- reg_free_temp(m, src);
- src = src->prev;
- if (iptr->op1 != TYPE_VOID)
- reg_new_temp(m, dst);
+ case ICMD_BUILTIN:
+ i = iptr->op1;
+ while (--i >= 0) {
+ reg_free_temp(rd, src);
+ src = src->prev;
+ }
+ if (((builtintable_entry *) iptr->val.a)->md->returntype.type != TYPE_VOID)
+ 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:
- printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
- panic("Missing ICMD code during register allocation");
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Unknown ICMD %d during register allocation",
+ iptr->opc);
} /* switch */
iptr++;
} /* while instructions */
}
+#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