/* src/vm/jit/allocator/simplereg.c - register allocator
- 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
+ Copyright (C) 1996-2005, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Andreas Krall
-
- Changes: Stefan Ring
- Christian Thalinger
- Christian Ullrich
- Michael Starzinger
- Edwin Steiner
-
- $Id: simplereg.c 5710 2006-10-06 23:41:02Z edwin $
-
*/
#include "config.h"
-#include "vm/types.h"
#include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
#include "arch.h"
#include "md-abi.h"
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
-#include "mm/memory.h"
-#include "vm/method.h"
+#include "mm/memory.hpp"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/method.hpp"
#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/stringlocal.h"
+#include "vm/resolve.hpp"
+#include "vm/string.hpp"
+
+#include "vm/jit/abi.h"
#include "vm/jit/reg.h"
+#include "vm/jit/show.hpp"
#include "vm/jit/allocator/simplereg.h"
-#include "vm/jit/show.h"
#if 0
static void simplereg_allocate_temporaries(jitdata *jd);
+/* size of a stackslot used by the internal ABI */
+
+#define SIZE_OF_STACKSLOT 8
+
+
+/* total number of registers */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
+#else
+#define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
+#endif
+
+
/* macros for handling register stacks ****************************************/
#define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
#define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
#define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
-#define TAKE_ARG_FLT(r) POP_FRONT(rd->argfltregs, rd->argfltreguse, r)
+#define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
#define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
#define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
#define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
#define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
-#define TAKE_ARG_INT(r) POP_FRONT_INT(rd->argintregs, rd->argintreguse, r)
+#define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
#define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
#define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
#define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
+/* macros for allocating memory slots ****************************************/
+
+#define NEW_MEM_SLOT(r) \
+ do { \
+ (r) = rd->memuse * SIZE_OF_STACKSLOT; \
+ rd->memuse += 1; \
+ } while (0)
+
+#define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
+#define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
+#define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
+
+
/* macros for creating/freeing temporary variables ***************************/
#define NEW_TEMP_REG(index) \
/* macro for getting a unique register index *********************************/
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-#define SIMPLEREG_REG_INDEX(regoff, type) \
+#define REG_INDEX_NON_ADR(regoff, type) \
(IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
#else
-#define SIMPLEREG_REG_INDEX(regoff, type) \
+#define REG_INDEX_NON_ADR(regoff, type) \
(IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
#endif
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define REG_INDEX(regoff, type) \
+ (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
+#else
+#define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
+#endif
+
/* regalloc ********************************************************************
Does a simple register allocation.
-
+
*******************************************************************************/
-
+
bool regalloc(jitdata *jd)
{
/* There is a problem with the use of unused float argument
/* simplereg_allocate_interfaces ***********************************************
Allocates registers for all interface variables.
-
+
*******************************************************************************/
-
+
static void simplereg_allocate_interfaces(jitdata *jd)
{
methodinfo *m;
+ codeinfo *code;
codegendata *cd;
registerdata *rd;
int s, t, tt, saved;
int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
/* in case more vars are packed into this interface slot */
- int memneeded = 0;
- /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
- /* on HAS_4BYTE_STACKSLOT architectures */
+ /* Allocate LNG and DBL types first to ensure 2 registers */
+ /* on some architectures. */
int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
- int flags, regoff;
+ int flags, regoff;
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
int intregsneeded;
#endif
/* get required compiler data */
- m = jd->m;
- cd = jd->cd;
- rd = jd->rd;
+ m = jd->m;
+ code = jd->code;
+ cd = jd->cd;
+ rd = jd->rd;
/* 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)) {
+ if (checksync && code_is_synchronized(code)) {
/* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
if (rd->memuse < 1)
rd->memuse = 1;
}
#endif
- if (jd->isleafmethod) {
+ if (code_is_leafmethod(code)) {
/* Reserve argument register, which will be used for Locals acting */
/* as Parameters */
if (rd->argintreguse < m->parseddesc->argintreguse)
if (rd->argadrreguse < m->parseddesc->argadrreguse)
rd->argadrreguse = m->parseddesc->argadrreguse;
#endif
+ }
- }
-
- for (s = 0; s < cd->maxstack; s++) {
+ for (s = 0; s < jd->maxinterfaces; s++) {
intalloc = -1; fltalloc = -1;
+ /* check if the interface at this stack depth must be a SAVEDVAR */
+
saved = 0;
for (tt = 0; tt <=4; tt++) {
}
}
+ /* allocate reg/mem for each type the interface is used as */
+
for (tt = 0; tt <= 4; tt++) {
t = typeloop[tt];
if (jd->interface_map[s * 5 + t].flags == UNUSED)
continue;
flags = saved;
- regoff = -1; /* XXX for debugging */
+ regoff = -1; /* initialize to invalid value */
#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 defined(HAS_ADDRESS_REGISTER_FILE)
if (IS_ADR_TYPE(t)) {
- if (!jd->isleafmethod && AVAIL_ARG_ADR) {
+ if (!code_is_leafmethod(code) && AVAIL_ARG_ADR) {
flags |= ARGREG;
TAKE_ARG_ADR(regoff);
}
}
else {
flags |= INMEMORY;
- regoff = rd->memuse++;
+ regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else /* !IS_ADR_TYPE */
if (IS_FLT_DBL_TYPE(t)) {
if (fltalloc >= 0) {
/* Reuse memory slot(s)/register(s) for shared interface slots */
- flags |= jd->interface_map[fltalloc].flags & INMEMORY;
+ flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
regoff = jd->interface_map[fltalloc].regoff;
}
else if (AVAIL_ARG_FLT) {
}
else {
flags |= INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
- /* Align doubles in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_FLT_DBL(regoff);
}
fltalloc = s * 5 + t;
- }
+ }
else { /* !IS_FLT_DBL_TYPE(t) */
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
if (IS_2_WORD_TYPE(t)) {
flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if (rd->memuse & 1)
- rd->memuse++;
-#endif
- regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(regoff);
}
else
-#endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
+#endif
if (intalloc >= 0) {
/* Reuse memory slot(s)/register(s) for shared interface slots */
- flags |= jd->interface_map[intalloc].flags & INMEMORY;
+ flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
+ regoff = jd->interface_map[intalloc].regoff;
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ /* reuse lower half */
if (!(flags & INMEMORY)
&& IS_2_WORD_TYPE(intalloc % 5))
- regoff = GET_LOW_REG(
- jd->interface_map[intalloc].regoff);
- else
+ regoff = GET_LOW_REG(regoff);
#endif
- regoff =
- jd->interface_map[intalloc].regoff;
}
else {
if (AVAIL_ARG_INT) {
}
else {
flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(regoff);
}
}
}
else {
flags |= INMEMORY;
- regoff = rd->memuse++;
+ regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else
{
if (IS_FLT_DBL_TYPE(t)) {
if (fltalloc >= 0) {
- flags |= jd->interface_map[fltalloc].flags & INMEMORY;
+ flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
regoff = jd->interface_map[fltalloc].regoff;
}
else {
}
else {
flags |= INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
- /* Align doubles in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_FLT_DBL(regoff);
}
}
fltalloc = s * 5 + t;
}
else { /* IS_INT_LNG */
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
if (IS_2_WORD_TYPE(t)) {
flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if (rd->memuse & 1)
- rd->memuse++;
-#endif
- regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(regoff);
}
else
#endif
{
if (intalloc >= 0) {
- flags |= jd->interface_map[intalloc].flags & INMEMORY;
+ flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
+ regoff = jd->interface_map[intalloc].regoff;
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+ /* reuse lower half */
if (!(flags & INMEMORY)
&& IS_2_WORD_TYPE(intalloc % 5))
- regoff =
- GET_LOW_REG(
- jd->interface_map[intalloc].regoff);
- else
+ regoff = GET_LOW_REG(regoff);
#endif
- regoff =
- jd->interface_map[intalloc].regoff;
}
else {
if (AVAIL_SAV_INT) {
}
else {
flags |= INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(regoff);
}
}
intalloc = s*5 + t;
/* simplereg_allocate_locals_leafmethod ****************************************
Allocates registers for all local variables of a leafmethod.
-
+
*******************************************************************************/
-
+
static void simplereg_allocate_locals_leafmethod(jitdata *jd)
{
methodinfo *m;
codegendata *cd;
registerdata *rd;
+ methoddesc *md;
- int p, s, t, tt, lm;
+ int p, s, t, tt, varindex;
int intalloc, fltalloc;
varinfo *v;
int intregsneeded = 0;
- int memneeded = 0;
int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
int fargcnt, iargcnt;
#ifdef HAS_ADDRESS_REGISTER_FILE
cd = jd->cd;
rd = jd->rd;
- methoddesc *md = m->parseddesc;
+ md = m->parseddesc;
iargcnt = rd->argintreguse;
fargcnt = rd->argfltreguse;
#ifdef HAS_ADDRESS_REGISTER_FILE
aargcnt = rd->argadrreguse;
#endif
- for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
+ for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
intalloc = -1; fltalloc = -1;
for (tt = 0; tt <= 4; tt++) {
t = typeloop[tt];
- lm = jd->local_map[s * 5 + t];
- if (lm == UNUSED)
+ varindex = jd->local_map[s * 5 + t];
+ if (varindex == UNUSED)
continue;
- v = VAR(lm);
+ v = VAR(varindex);
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
#endif
-#if defined(HAS_4BYTE_STACKSLOT)
- memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
-#endif
/*
* The order of
}
/* use unused argument registers as local registers */
else if ((p >= md->paramcount) &&
- (aargcnt < ADR_ARG_CNT)) {
+ (aargcnt < ADR_ARG_CNT))
+ {
v->flags = 0;
POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
}
}
else {
v->flags |= INMEMORY;
- v->vv.regoff = rd->memuse++;
+ v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else {
#if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
/* We can only use float arguments as local variables,
* if we do not pass them in integer registers. */
- else if ((p < md->paramcount) &&
- !md->params[p].inmemory) {
+ else if ((p < md->paramcount) && !md->params[p].inmemory) {
v->flags = 0;
- v->vv.regoff = rd->argfltregs[md->params[p].regoff];
+ v->vv.regoff = md->params[p].regoff;
}
#endif
else if (AVAIL_TMP_FLT) {
TAKE_TMP_FLT(v->vv.regoff);
}
/* use unused argument registers as local registers */
- else if ((p >= md->paramcount) &&
- (fargcnt < FLT_ARG_CNT)) {
+ else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
v->flags = 0;
- POP_FRONT(rd->argfltregs, fargcnt, v->vv.regoff);
+ POP_FRONT(abi_registers_float_argument,
+ fargcnt, v->vv.regoff);
}
else if (AVAIL_SAV_FLT) {
v->flags = 0;
}
else {
v->flags = INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
- /* Align doubles in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
}
fltalloc = jd->local_map[s * 5 + t];
}
else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
if (IS_2_WORD_TYPE(t)) {
v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if (rd->memuse & 1)
- rd->memuse++;
-#endif
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
}
else
#endif
v->vv.regoff = VAR(intalloc)->vv.regoff;
}
else if ((p < md->paramcount) &&
- !md->params[p].inmemory) {
+ !md->params[p].inmemory)
+ {
v->flags = 0;
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
if (IS_2_WORD_TYPE(t))
- v->vv.regoff = PACK_REGS(
- rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
- rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
+ v->vv.regoff =
+ PACK_REGS(GET_LOW_REG(md->params[p].regoff),
+ GET_HIGH_REG(md->params[p].regoff));
else
#endif
- v->vv.regoff =
- rd->argintregs[md->params[p].regoff];
+ v->vv.regoff = md->params[p].regoff;
}
else if (AVAIL_TMP_INT) {
v->flags = 0;
(iargcnt + intregsneeded < INT_ARG_CNT))
{
v->flags = 0;
- POP_FRONT_INT(rd->argintregs, iargcnt, v->vv.regoff);
+ POP_FRONT_INT(abi_registers_integer_argument,
+ iargcnt, v->vv.regoff);
}
else if (AVAIL_SAV_INT) {
v->flags = 0;
}
else {
v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
}
}
intalloc = jd->local_map[s * 5 + t];
/* simplereg_allocate_locals ***************************************************
Allocates registers for all local variables.
-
+
*******************************************************************************/
-
+
static void simplereg_allocate_locals(jitdata *jd)
{
+ codeinfo *code;
codegendata *cd;
registerdata *rd;
- int s, t, tt, lm;
+ int s, t, tt, varindex;
int intalloc, fltalloc;
varinfo *v;
- int memneeded = 0;
int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
s4 intregsneeded;
/* get required compiler data */
- cd = jd->cd;
- rd = jd->rd;
+ code = jd->code;
+ cd = jd->cd;
+ rd = jd->rd;
- if (jd->isleafmethod) {
+ if (code_is_leafmethod(code)) {
simplereg_allocate_locals_leafmethod(jd);
return;
}
- for (s = 0; s < cd->maxlocals; s++) {
+ for (s = 0; s < jd->maxlocals; s++) {
intalloc = -1; fltalloc = -1;
for (tt=0; tt<=4; tt++) {
t = typeloop[tt];
- lm = jd->local_map[s * 5 + t];
- if (lm == UNUSED)
+ varindex = jd->local_map[s * 5 + t];
+ if (varindex == UNUSED)
continue;
- v = VAR(lm);
+ v = VAR(varindex);
#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 (AVAIL_SAV_ADR) {
}
else {
v->flags = INMEMORY;
- v->vv.regoff = rd->memuse++;
+ v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else {
}
else {
v->flags = INMEMORY;
-#if defined(ALIGN_DOUBLES_IN_MEMORY)
- /* Align doubles in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
}
fltalloc = jd->local_map[s * 5 + t];
}
else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
if (IS_2_WORD_TYPE(t)) {
v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if (rd->memuse & 1)
- rd->memuse++;
-#endif
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
}
else {
#endif
}
else {
v->flags = INMEMORY;
-#if defined(ALIGN_LONGS_IN_MEMORY)
- /* Align longs in Memory */
- if ( (memneeded) && (rd->memuse & 1))
- rd->memuse++;
-#endif
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
+ NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
}
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
}
#endif
intalloc = jd->local_map[s * 5 + t];
int i;
rd->freememtop = 0;
-#if defined(HAS_4BYTE_STACKSLOT)
- rd->freememtop_2 = 0;
-#endif
rd->freetmpinttop = 0;
rd->freesavinttop = 0;
rd->freeargadrtop = 0;
#endif
- rd->regisoutvar = DMNEW(int, INT_REG_CNT + FLT_REG_CNT);
- rd->regcopycount = DMNEW(int, INT_REG_CNT + FLT_REG_CNT);
- MZERO(rd->regcopycount, int, INT_REG_CNT + FLT_REG_CNT);
+ rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
+ rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
+ MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
/* memcopycount is dynamically allocated when needed */
/* record the interface registers as used */
for (i=0; i<rd->argintreguse; ++i)
- rd->intusedinout[rd->argintregs[i]] = 1;
+ rd->intusedinout[abi_registers_integer_argument[i]] = 1;
for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
rd->intusedinout[rd->tmpintregs[i]] = 1;
for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
rd->intusedinout[rd->savintregs[i]] = 1;
for (i=0; i<rd->argfltreguse; ++i)
- rd->fltusedinout[rd->argfltregs[i]] = 1;
+ rd->fltusedinout[abi_registers_float_argument[i]] = 1;
for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
rd->fltusedinout[rd->tmpfltregs[i]] = 1;
for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
#ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
s4 intregsneeded;
#endif
- s4 memneeded;
s4 tryagain;
registerdata *rd;
varinfo *v;
rd = jd->rd;
v = VAR(index);
+ /* assert that constants are not allocated */
+
+ assert(v->type != TYPE_RET);
+
/* Try to allocate a saved register if there is no temporary one */
/* available. This is what happens during the second run. */
tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
#endif
-#if defined(HAS_4BYTE_STACKSLOT)
- memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
-#else
- memneeded = 0;
-#endif
-
for(; tryagain; --tryagain) {
if (tryagain == 1) {
if (!(v->flags & SAVEDVAR))
}
}
else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
}
else {
-#if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+#if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
/*
* for i386 put all longs in memory
*/
} /* if (tryagain == 1) else */
} /* for(; tryagain; --tryagain) */
-#if defined(HAS_4BYTE_STACKSLOT)
- if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
- POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
- }
- else
-#endif /*defined(HAS_4BYTE_STACKSLOT) */
- if ((memneeded == 0) && (rd->freememtop > 0)) {
- POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
- }
- else {
-#if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
- /* align 2 Word Types */
- if ((memneeded) && ((rd->memuse & 1) == 1)) {
- /* Put patched memory slot on freemem */
- PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse);
- rd->memuse++;
- }
-#endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
- v->vv.regoff = rd->memuse;
- rd->memuse += memneeded + 1;
- }
+ /* spill to memory */
+
v->flags |= INMEMORY;
+
+ if (rd->freememtop > 0)
+ POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
+ else
+ NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
}
static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
{
- /* if this is a copy of another variable, just decrement the copy counter */
+ /* assert that constants are not freed */
+
+ assert(type != TYPE_RET);
- /* XXX split reg/mem variables on arm may need special handling here */
+ /* if this is a copy of another variable, just decrement the copy counter */
if (flags & INMEMORY) {
+ int32_t memindex;
+
if (flags & INOUT)
return;
- if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
- rd->memcopycount[regoff]--;
+ memindex = regoff / SIZE_OF_STACKSLOT;
+
+ if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
+ rd->memcopycount[memindex]--;
return;
}
}
else {
s4 regindex;
- regindex = SIMPLEREG_REG_INDEX(regoff, type);
+ regindex = REG_INDEX(regoff, type);
/* do not free interface registers that are needed as outvars */
}
if (flags & INMEMORY) {
-#if defined(HAS_4BYTE_STACKSLOT)
- if (IS_2_WORD_TYPE(type))
- PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
- else
-#endif
- PUSH_BACK(rd->freemem, rd->freememtop, regoff);
-
+ PUSH_BACK(rd->freemem, rd->freememtop, regoff);
return;
}
/* assert that all copy counts are zero */
-#if !defined(NDEBUG)
- for (i=0; i < INT_REG_CNT + FLT_REG_CNT; ++i)
+#if !defined(NDEBUG) && !defined(ENABLE_SSA)
+ for (i=0; i < TOTAL_REG_CNT; ++i)
assert(rd->regcopycount[i] == 0);
#endif
/* reset outvar flags */
- MZERO(rd->regisoutvar, int, INT_REG_CNT + FLT_REG_CNT);
+ MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
/* set allocation of invars */
for (i=0; i<bptr->indepth; ++i)
{
v = VAR(bptr->invars[i]);
+ if (v->type == TYPE_RET)
+ continue;
v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
v->flags = jd->interface_map[5*i + v->type].flags;
if (!(v->flags & INMEMORY))
- rd->regcopycount[SIMPLEREG_REG_INDEX(v->vv.regoff, v->type)] = 1;
+ rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
}
/* set allocation of outvars */
for (i=0; i<bptr->outdepth; ++i)
{
v = VAR(bptr->outvars[i]);
+ if (v->type == TYPE_RET)
+ continue;
v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
v->flags = jd->interface_map[5*i + v->type].flags;
if (!(v->flags & INMEMORY)) {
- regindex = SIMPLEREG_REG_INDEX(v->vv.regoff, v->type);
+ regindex = REG_INDEX(v->vv.regoff, v->type);
rd->regcopycount[regindex] = 1;
rd->regisoutvar[regindex] = 1;
}
/* free interface registers not used in this block */
- for (i=0; i < 5 * m->maxstack; ++i) {
+ for (i=0; i < 5 * jd->maxinterfaces; ++i) {
type = i%5;
regoff = jd->interface_map[i].regoff;
flags = jd->interface_map[i].flags;
if (!(flags & INMEMORY)) {
- if (!rd->regcopycount[SIMPLEREG_REG_INDEX(regoff, type)]) {
+ if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
flags, regoff, type));
simplereg_free(rd, flags, regoff, type);
/* mark it, so it is not freed again */
- rd->regcopycount[SIMPLEREG_REG_INDEX(regoff, type)] = -1;
+ rd->regcopycount[REG_INDEX(regoff, type)] = -1;
}
}
}
/* reset copy counts */
- for (i=0; i < INT_REG_CNT + FLT_REG_CNT; ++i)
- rd->regcopycount[i] = 0;
+ MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
/* iterate over ICMDS to allocate temporary variables */
/* pop 0 push 0 */
case ICMD_JSR:
-#if !defined(NDEBUG)
- /* avoid problems with show_allocation */
- VAROP(iptr->dst)->vv.regoff = 0;
-#endif
case ICMD_NOP:
case ICMD_CHECKNULL:
case ICMD_IINC:
case ICMD_PUTSTATICCONST:
case ICMD_INLINE_START:
case ICMD_INLINE_END:
- case ICMD_INLINE_GOTO:
+ case ICMD_INLINE_BODY:
break;
/* pop 0 push 1 const */
case ICMD_FCONST:
case ICMD_DCONST:
case ICMD_ACONST:
+ case ICMD_GETEXCEPTION:
/* pop 0 push 1 load */
case ICMD_IF_LCMPGT:
case ICMD_IF_LCMPLE:
- case ICMD_IF_FCMPEQ:
- case ICMD_IF_FCMPNE:
-
- case ICMD_IF_FCMPL_LT:
- case ICMD_IF_FCMPL_GE:
- case ICMD_IF_FCMPL_GT:
- case ICMD_IF_FCMPL_LE:
-
- case ICMD_IF_FCMPG_LT:
- case ICMD_IF_FCMPG_GE:
- case ICMD_IF_FCMPG_GT:
- case ICMD_IF_FCMPG_LE:
-
- case ICMD_IF_DCMPEQ:
- case ICMD_IF_DCMPNE:
-
- case ICMD_IF_DCMPL_LT:
- case ICMD_IF_DCMPL_GE:
- case ICMD_IF_DCMPL_GT:
- case ICMD_IF_DCMPL_LE:
-
- case ICMD_IF_DCMPG_LT:
- case ICMD_IF_DCMPG_GE:
- case ICMD_IF_DCMPG_GT:
- case ICMD_IF_DCMPG_LE:
-
case ICMD_IF_ACMPEQ:
case ICMD_IF_ACMPNE:
v = VAROP(iptr->dst);
if (v->flags & INMEMORY) {
- if (v->vv.regoff >= rd->memcopycountsize) {
- int newsize = (v->vv.regoff + 1) * 2;
+ int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
+ if (memindex >= rd->memcopycountsize) {
+ int newsize = (memindex + 1) * 2;
i = rd->memcopycountsize;
rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
MZERO(rd->memcopycount + i, int, newsize - i);
rd->memcopycountsize = newsize;
}
- rd->memcopycount[v->vv.regoff]++;
+ rd->memcopycount[memindex]++;
}
else {
/* XXX split reg/mem variables on arm may need special handling here */
- s4 regindex = SIMPLEREG_REG_INDEX(v->vv.regoff, v->type);
+ s4 regindex = REG_INDEX(v->vv.regoff, v->type);
rd->regcopycount[regindex]++;
}
break;
default:
- *exceptionptr =
- new_internalerror("Unknown ICMD %d during register allocation",
- iptr->opc);
+ exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
+ iptr->opc);
return;
} /* switch */
iptr++;
methodinfo *m;
codegendata *cd;
registerdata *rd;
- int i,type;
+ int i;
s4 len;
- stackptr src, src_old;
- stackptr dst;
+#if 0
+ stackelement_t* src, src_old;
+ stackelement_t* dst;
instruction *iptr;
+#endif
basicblock *bptr;
int size_interface; /* == maximum size of in/out stack at basic block boundaries */
bool in_register;
count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
if (in_register) count_method_in_register++;
if (in_register) {
- printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
+/* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
}
}
#endif /* defined(ENABLE_STATISTICS) */