* Removed all Id tags.
[cacao.git] / src / vm / jit / allocator / simplereg.c
index c0bc56d9624889afac2be479fe309a620aaf5bcc..a2a14bdc9088aa69e9cb5def082a1f37a3e6f161 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/allocator/simplereg.c - register allocator
 
-   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   Copyright (C) 1996-2005, 2007 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
    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 6016 2006-11-19 14:50:08Z 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 "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
@@ -71,6 +65,15 @@ static void simplereg_allocate_locals(jitdata *jd);
 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)
@@ -165,7 +168,7 @@ static void simplereg_allocate_temporaries(jitdata *jd);
 #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)
 
@@ -173,7 +176,7 @@ static void simplereg_allocate_temporaries(jitdata *jd);
 #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)
 
@@ -206,7 +209,7 @@ static void simplereg_allocate_temporaries(jitdata *jd);
 
 #define NEW_MEM_SLOT(r)                                              \
     do {                                                             \
-        (r) = rd->memuse;                                            \
+        (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
         rd->memuse += memneeded + 1;                                 \
     } while (0)
 
@@ -214,7 +217,7 @@ static void simplereg_allocate_temporaries(jitdata *jd);
     do {                                                             \
         if ( (memneeded) && (rd->memuse & 1))                        \
             rd->memuse++;                                            \
-        (r) = rd->memuse;                                            \
+        (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
         rd->memuse += memneeded + 1;                                 \
     } while (0)
 
@@ -224,7 +227,7 @@ static void simplereg_allocate_temporaries(jitdata *jd);
                        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)
 
@@ -406,7 +409,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                        } 
                                        else {
                                                flags |= INMEMORY;
-                                               regoff = rd->memuse++;
+                                               regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }                                               
                                } 
                                else /* !IS_ADR_TYPE */
@@ -436,7 +439,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                                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
                                                 */
@@ -445,7 +448,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                                        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;
@@ -488,7 +491,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                        }
                                        else {
                                                flags |= INMEMORY;
-                                               regoff = rd->memuse++;
+                                               regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }                                               
                                } 
                                else
@@ -511,7 +514,7 @@ static void simplereg_allocate_interfaces(jitdata *jd)
                                                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
                                                 */
@@ -569,7 +572,7 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
        registerdata *rd;
        methoddesc *md;
 
-       int     p, s, t, tt, lm;
+       int     p, s, t, tt, varindex;
        int     intalloc, fltalloc;
        varinfo *v;
        int     intregsneeded = 0;
@@ -597,11 +600,11 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
                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;
@@ -650,7 +653,7 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
                                }
                                else {
                                        v->flags |= INMEMORY;
-                                       v->vv.regoff = rd->memuse++;
+                                       v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                }                                               
                        } 
                        else {
@@ -663,11 +666,9 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 #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) {
@@ -675,11 +676,10 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
                                                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;
@@ -693,7 +693,7 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
 
                                } 
                                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
                                         */
@@ -721,13 +721,12 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
                                                        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;
@@ -740,7 +739,8 @@ static void simplereg_allocate_locals_leafmethod(jitdata *jd)
                                                                 (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;
@@ -778,7 +778,7 @@ static void simplereg_allocate_locals(jitdata *jd)
        codegendata  *cd;
        registerdata *rd;
 
-       int     s, t, tt, lm;
+       int     s, t, tt, varindex;
        int     intalloc, fltalloc;
        varinfo *v;
        int     memneeded = 0;
@@ -802,11 +802,11 @@ static void simplereg_allocate_locals(jitdata *jd)
                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;
@@ -824,7 +824,7 @@ static void simplereg_allocate_locals(jitdata *jd)
                                        }
                                        else {
                                                v->flags = INMEMORY;
-                                               v->vv.regoff = rd->memuse++;
+                                               v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
                                        }
                                } 
                                else {
@@ -845,7 +845,7 @@ static void simplereg_allocate_locals(jitdata *jd)
                                        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
                                         */
@@ -874,7 +874,7 @@ static void simplereg_allocate_locals(jitdata *jd)
                                                        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];
@@ -928,14 +928,14 @@ static void simplereg_init(jitdata *jd, registerdata *rd)
        /* 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)
@@ -1017,6 +1017,10 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
        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;
@@ -1060,7 +1064,7 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
                                        }
                                } 
                                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
                                         */
@@ -1116,7 +1120,7 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
 
                                } 
                                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
                                         */
@@ -1165,16 +1169,22 @@ static void simplereg_new_temp(jitdata *jd, s4 index)
 
 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;
                }
        }
@@ -1422,7 +1432,7 @@ static void simplereg_allocate_temporaries(jitdata *jd)
                                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 */
@@ -1601,14 +1611,15 @@ static void simplereg_allocate_temporaries(jitdata *jd)
                                                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 */
@@ -1791,9 +1802,8 @@ static void simplereg_allocate_temporaries(jitdata *jd)
                                        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++;
@@ -1810,11 +1820,13 @@ void simplereg_make_statistics(jitdata *jd)
        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;