Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Andreas Krall
- Stefan Ring
- Christian Thalinger
- Christian Ullrich
- Michael Starzinger
- Edwin Steiner
-
- $Id: simplereg.c 6286 2007-01-10 10:03:38Z twisti $
-
*/
#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 "mm/memory.h"
+
#include "vm/builtin.h"
#include "vm/exceptions.h"
-#include "mm/memory.h"
-#include "vm/method.h"
-#include "vm/options.h"
#include "vm/resolve.h"
#include "vm/stringlocal.h"
+
+#include "vm/jit/abi.h"
#include "vm/jit/reg.h"
-#include "vm/jit/allocator/simplereg.h"
#include "vm/jit/show.h"
+#include "vm/jit/allocator/simplereg.h"
+
+#include "vmcore/method.h"
+#include "vmcore/options.h"
#if 0
static void simplereg_allocate_temporaries(jitdata *jd);
+/* size of a stackslot used by the internal ABI */
+
+#if defined(HAS_4BYTE_STACKSLOT)
+# define SIZE_OF_STACKSLOT 4
+#else
+# define SIZE_OF_STACKSLOT 8
+#endif
+
+
/* total number of registers */
#if defined(HAS_ADDRESS_REGISTER_FILE)
#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 NEW_MEM_SLOT(r) \
do { \
- (r) = rd->memuse; \
+ (r) = rd->memuse * SIZE_OF_STACKSLOT; \
rd->memuse += memneeded + 1; \
} while (0)
do { \
if ( (memneeded) && (rd->memuse & 1)) \
rd->memuse++; \
- (r) = rd->memuse; \
+ (r) = rd->memuse * SIZE_OF_STACKSLOT; \
rd->memuse += memneeded + 1; \
} while (0)
PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse); \
rd->memuse++; \
} \
- (r) = rd->memuse; \
+ (r) = rd->memuse * SIZE_OF_STACKSLOT; \
rd->memuse += memneeded + 1; \
} while (0)
}
else {
flags |= INMEMORY;
- regoff = rd->memuse++;
+ regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else /* !IS_ADR_TYPE */
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
*/
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 & ~SAVEDVAR;
}
else {
flags |= INMEMORY;
- regoff = rd->memuse++;
+ regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else
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
*/
registerdata *rd;
methoddesc *md;
- int p, s, t, tt, lm;
+ int p, s, t, tt, varindex;
int intalloc, fltalloc;
varinfo *v;
int intregsneeded = 0;
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;
}
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 {
-#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
*/
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;
codegendata *cd;
registerdata *rd;
- int s, t, tt, lm;
+ int s, t, tt, varindex;
int intalloc, fltalloc;
varinfo *v;
int memneeded = 0;
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;
}
else {
v->flags = INMEMORY;
- v->vv.regoff = rd->memuse++;
+ v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
}
}
else {
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
*/
v->flags = INMEMORY;
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];
/* 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)
}
}
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 this is a copy of another variable, just decrement the copy counter */
- /* XXX split reg/mem variables on arm may need special handling here */
-
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;
}
}
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 */
methodinfo *m;
codegendata *cd;
registerdata *rd;
- int i,type;
+ int i;
s4 len;
+#if 0
stackptr src, src_old;
stackptr dst;
instruction *iptr;
+#endif
basicblock *bptr;
int size_interface; /* == maximum size of in/out stack at basic block boundaries */
bool in_register;