Unified variables changes for common/i386.
[cacao.git] / src / vm / jit / stack.h
index 02b2d41553accc0e55282dd4a4743574eab772ae..abcbf59ffc8143de5960d0425194d5b0e1c94a57 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Ullrich
 
-   $Id: stack.h 5303 2006-09-05 10:39:58Z edwin $
+   $Id: stack.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
  * against maximum stack depth only at block boundaries?
  */
 
-/* XXX we should find a way to remove the opc/op1 check */
-#if defined(ENABLE_VERIFIER)
-#define NEW_CHECKOVERFLOW \
-       do { \
-               if (stackdepth > m->maxstack) \
-                       if ((iptr->opc != ICMD_ACONST) || !(iptr->flags.bits & INS_FLAG_NOCHECK)) \
-                               goto throw_stack_overflow; \
-       } while(0)
-#else /* !ENABLE_VERIFIER */
-#define NEW_CHECKOVERFLOW
-#endif /* ENABLE_VERIFIER */
-
 /* XXX we should find a way to remove the opc/op1 check */
 #if defined(ENABLE_VERIFIER)
 #define CHECKOVERFLOW \
        do { \
                if (stackdepth > m->maxstack) \
-                       if ((iptr[0].opc != ICMD_ACONST) || (iptr[0].op1 == 0)) \
+                       if ((iptr->opc != ICMD_ACONST) || INSTRUCTION_MUST_CHECK(iptr)) \
                                goto throw_stack_overflow; \
        } while(0)
 #else /* !ENABLE_VERIFIER */
 /* ALLOCATING STACK SLOTS                           */
 /*--------------------------------------------------*/
 
-#define NEWSTACK(s,v,n) \
+#define NEWSTACK(s,v,n)        \
     do { \
         new->prev = curstack; \
         new->type = (s); \
         new->varkind = (v); \
         new->varnum = (n); \
         curstack = new; \
+               jd->var[(n)].type = (s); \
+               jd->var[(n)].flags = 0;  \
         new++; \
     } while (0)
 
 /* allocate the input stack for an exception handler */
 #define NEWXSTACK   {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
 
-
 /*--------------------------------------------------*/
 /* STACK MANIPULATION                               */
 /*--------------------------------------------------*/
     } while (0)
 
 
-/*--------------------------------------------------*/
-/* STACK OPERATIONS MODELING                        */
-/*--------------------------------------------------*/
-
-/* The following macros are used to model the stack manipulations of
- * different kinds of instructions.
- *
- * These macros check the input stackdepth and they set the output
- * stackdepth and the output stack of the instruction (iptr->dst).
- *
- * These macros do *not* check for stack overflows!
- */
-
-#define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
-#define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
-#define STORE(s)    {REQUIRE_1;POP(s);SETDST;stackdepth--;}
-
-#define OP1_0(s) \
-    do { \
-        REQUIRE_1; \
-        POP(s); \
-        SETDST; \
-        stackdepth--; \
-    } while (0)
-
-#define OP1_0ANY \
-    do { \
-        REQUIRE_1; \
-        POPANY; \
-        SETDST; \
-        stackdepth--; \
-    } while (0)
-
-#define OP0_1(s) \
-    do { \
-        NEWSTACKn(s, stackdepth); \
-        SETDST; \
-        stackdepth++; \
-    } while (0)
-
-#define OP1_1(s,d) \
-    do { \
-        REQUIRE_1; \
-        POP(s); \
-        NEWSTACKn(d, stackdepth - 1);\
-        SETDST; \
-    } while (0)
-
-#define OP2_0(s) \
-    do { \
-        REQUIRE_2; \
-        POP(s); \
-        POP(s); \
-        SETDST; \
-        stackdepth -= 2; \
-    } while (0)
-
-#define OPTT2_0(t,b) \
-    do { \
-        REQUIRE_2; \
-        POP(t); \
-        POP(b); \
-        SETDST; \
-        stackdepth -= 2; \
-    } while (0)
-
-#define OP2_1(s) \
-    do { \
-        REQUIRE_2; \
-        POP(s); \
-        POP(s); \
-        NEWSTACKn(s, stackdepth - 2); \
-        SETDST; \
-        stackdepth--; \
-    } while (0)
-
-#define OP2IAT_1(s) \
-    do { \
-        REQUIRE_2; \
-        POP(TYPE_INT); \
-        POP(TYPE_ADR); \
-        NEWSTACKn(s, stackdepth - 2); \
-        SETDST; \
-        stackdepth--; \
-    } while (0)
-
-#define OP2IT_1(s) \
-    do { \
-        REQUIRE_2; \
-        POP(TYPE_INT); \
-        POP(s); \
-        NEWSTACKn(s, stackdepth - 2); \
-        SETDST; \
-        stackdepth--; \
-    } while (0)
-
-#define OPTT2_1(s,d) \
-    do { \
-        REQUIRE_2; \
-        POP(s); \
-        POP(s); \
-        NEWSTACKn(d, stackdepth - 2); \
-        SETDST; \
-        stackdepth--; \
-    } while (0)
-
-#define OP2_2(s) \
-    do { \
-        REQUIRE_2; \
-        POP(s); \
-        POP(s); \
-        NEWSTACKn(s, stackdepth - 2); \
-        NEWSTACKn(s, stackdepth - 1); \
-        SETDST; \
-    } while (0)
-
-#define OP3TIA_0(s) \
-    do { \
-        REQUIRE_3; \
-        POP(s); \
-        POP(TYPE_INT); \
-        POP(TYPE_ADR); \
-        SETDST; \
-        stackdepth -= 3; \
-    } while (0)
-
-#define OP3_0(s) \
-    do { \
-        REQUIRE_3; \
-        POP(s); \
-        POP(s); \
-        POP(s); \
-        SETDST; \
-        stackdepth -= 3; \
-    } while (0)
-
-#define POPMANY(i) \
-    do { \
-        REQUIRE((i)); \
-        stackdepth -= (i); \
-        while(--(i) >= 0) { \
-            POPANY; \
-        } \
-        SETDST; \
-    } while (0)
-
-/* Do not copy Interface Stackslots over DUP! */
-#define DUP         {REQUIRE_1; \
-                            if (CURKIND != STACKVAR) { \
-                                                NEWSTACK(CURTYPE,CURKIND,curstack->varnum); \
-                                        } else { \
-                                                NEWSTACK(CURTYPE, TEMPVAR, stackdepth); \
-                                        } \
-                                        SETDST; stackdepth++;}
-#define SWAP        {REQUIRE_2;COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
-                    new[0].prev=curstack;new[1].prev=new;\
-                    curstack=new+1;new+=2;SETDST;}
-#define DUP_X1      {REQUIRE_2;COPY(curstack,new);COPY(curstack,new+2);POPANY;\
-                    COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
-                    new[1].prev=new;new[2].prev=new+1;\
-                    curstack=new+2;new+=3;SETDST;stackdepth++;}
-#define DUP2_X1     {REQUIRE_3;COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
-                    COPY(curstack,new);COPY(curstack,new+3);POPANY;\
-                    COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
-                    new[1].prev=new;new[2].prev=new+1;\
-                    new[3].prev=new+2;new[4].prev=new+3;\
-                    curstack=new+4;new+=5;SETDST;stackdepth+=2;}
-#define DUP_X2      {REQUIRE_3;COPY(curstack,new);COPY(curstack,new+3);POPANY;\
-                    COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
-                    new[0].prev=curstack;new[1].prev=new;\
-                    new[2].prev=new+1;new[3].prev=new+2;\
-                    curstack=new+3;new+=4;SETDST;stackdepth++;}
-#define DUP2_X2     {REQUIRE_4;COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
-                    COPY(curstack,new);COPY(curstack,new+4);POPANY;\
-                    COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
-                    new[0].prev=curstack;new[1].prev=new;\
-                    new[2].prev=new+1;new[3].prev=new+2;\
-                    new[4].prev=new+3;new[5].prev=new+4;\
-                    curstack=new+5;new+=6;SETDST;stackdepth+=2;}
-
-
 /*--------------------------------------------------*/
 /* MACROS FOR HANDLING BASIC BLOCKS                 */
 /*--------------------------------------------------*/
  * block to another. The destination block receives the copy as its
  * input stack.
  */
-#define COPYCURSTACK(copy) {\
+#if defined(NEW_VAR)
+# define COPYCURSTACK(copy) {\
+       stackptr s;\
+       if(curstack){\
+               s=curstack;\
+               new+=stackdepth;\
+               copy=new;\
+               while(s){\
+                       copy--;                                                         \
+                       copy->prev=copy-1;\
+                       copy->type=s->type;\
+                       copy->flags=0;\
+                       copy->varkind=STACKVAR;\
+                       copy->varnum=s->varnum;\
+                       SET_OUTVAR(s);             \
+                       s=s->prev;\
+                       }\
+               copy->prev=NULL;\
+               copy=new-1;\
+               }\
+       else\
+               copy=NULL;\
+}
+#else
+# define COPYCURSTACK(copy) {\
        int d;\
        stackptr s;\
        if(curstack){\
        else\
                copy=NULL;\
 }
+#endif
 
 /* MARKREACHED marks the destination block <b> as reached. If this
  * block has been reached before we check if stack depth and types
  * c...current stack
  */
 
+/* XXX this macro is much too big! */
+
 #define MARKREACHED(b,c) \
     do { \
                if ((b) <= (bptr)) \
                        (b)->bitflags |= BBFLAG_REPLACEMENT; \
            if ((b)->flags < BBREACHED) { \
+                       int locali; \
                    COPYCURSTACK((c)); \
             (b)->flags = BBREACHED; \
             (b)->instack = (c); \
             (b)->indepth = stackdepth; \
+                       (b)->invars = DMNEW(s4, stackdepth); \
+                       for (locali = stackdepth; locali--; (c) = (c)->prev) {  \
+                               (b)->invars[locali] = (c)->varnum;                                      \
+                               SET_OUTVAR((c));                                                        \
+                       }                                                                                                               \
         } else { \
             stackptr s = curstack; \
             stackptr t = (b)->instack; \
     } while (0)
 
 
+/* external macros ************************************************************/
+
+#define BLOCK_OF(index)                                              \
+    (jd->new_basicblocks + jd->new_basicblockindex[index])
+
+
 /* function prototypes ********************************************************/
 
 bool stack_init(void);