* src/vm/jit/alpha/emit.c [ENABLE_THREADS] (threads/native/lock.h):
[cacao.git] / src / vm / jit / stack.h
index a1eb50e37ce160f18f2623feddac387e57c6fd11..dc63740e45bab2de15f15b77602607ecf426c9c7 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Ullrich
 
-   $Id: stack.h 4678 2006-03-22 23:17:27Z edwin $
+   $Id: stack.h 5234 2006-08-14 17:50:12Z christian $
 
 */
 
 
 /* macros used internally by analyse_stack ************************************/
 
-#if defined(ENABLE_LSRA)
-# define INC_LIFETIMES(a) { m->maxlifetimes += (a); }
-#else
-# define INC_LIFETIMES(a)
-#endif
-
 /* convenient abbreviations */
 #define CURKIND    curstack->varkind
 #define CURTYPE    curstack->type
 
 
+/*--------------------------------------------------*/
+/* STACK DEPTH CHECKING                             */
+/*--------------------------------------------------*/
+
+#if defined(ENABLE_VERIFIER)
+#define CHECK_STACK_DEPTH(depthA,depthB) \
+       do { \
+               if ((depthA) != (depthB)) \
+                       goto throw_stack_depth_error; \
+       } while (0)
+#else /* !ENABLE_VERIFIER */
+#define CHECK_STACK_DEPTH(depthA,depthB)
+#endif /* ENABLE_VERIFIER */
+
+
 /*--------------------------------------------------*/
 /* BASIC TYPE CHECKING                              */
 /*--------------------------------------------------*/
 #else /* !ENABLE_VERIFIER */
 #define REQUIRE(num)
 #endif /* ENABLE_VERIFIER */
-          
+
 #define REQUIRE_1     REQUIRE(1)
 #define REQUIRE_2     REQUIRE(2)
 #define REQUIRE_3     REQUIRE(3)
  * 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[0].opc != ICMD_ACONST) || (iptr[0].op1 == 0)) \
                                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++; \
     } while (0)
 
-
-/* Initialize regoff, so -sia can show regnames even before reg.inc */ 
-/* regs[rd->intregargnum has to be set for this */ 
-/* new->regoff = (IS_FLT_DBL_TYPE(s))?-1:rd->intreg_argnum; }*/
-
-#define NEWSTACK(s,v,n) { NEWSTACK_(s,v,n); INC_LIFETIMES(1); }
+/* Initialize regoff, so -sia can show regnames even before reg.inc */
+/* regs[rd->intregargnum] has to be set for this                    */
+/* new->regoff = (IS_FLT_DBL_TYPE(s))?-1:rd->intreg_argnum; }       */
 
 #define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
 #define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
  *
  * 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--;}
                                         } else { \
                                                 NEWSTACK(CURTYPE, TEMPVAR, stackdepth); \
                                         } \
-                                        SETDST; stackdepth++; INC_LIFETIMES(1);}
+                                        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++; INC_LIFETIMES(3);}
+                    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; INC_LIFETIMES(5);}
+                    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++; INC_LIFETIMES(4);}
+                    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; INC_LIFETIMES(6);}
+                    curstack=new+5;new+=6;SETDST;stackdepth+=2;}
 
 
 /*--------------------------------------------------*/
                copy=NULL;\
 }
 
-/* BBEND is called at the end of each basic block (after the last
- * instruction of the block has been processed).
- */
-
-
-#if defined(ENABLE_INTRP)
-#define IF_NO_INTRP(x) if (!opt_intrp) { x }
-#else
-#define IF_NO_INTRP(x) { x }
-#endif
-
-#define BBEND(s,i) { \
-       (i) = stackdepth - 1; \
-       copy = (s); \
-       while (copy) { \
-               if ((copy->varkind == STACKVAR) && (copy->varnum > (i))) \
-                       copy->varkind = TEMPVAR; \
-               else { \
-                       copy->varkind = STACKVAR; \
-                       copy->varnum = (i);\
-               } \
-        IF_NO_INTRP(rd->interfaces[(i)][copy->type].type = copy->type; \
-                    rd->interfaces[(i)][copy->type].flags |= copy->flags;) \
-               (i)--; copy = copy->prev; \
-       } \
-       (i) = bptr->indepth - 1; \
-       copy = bptr->instack; \
-       while (copy) { \
-        IF_NO_INTRP( \
-            rd->interfaces[(i)][copy->type].type = copy->type; \
-            if (copy->varkind == STACKVAR) { \
-                if (copy->flags & SAVEDVAR) \
-                    rd->interfaces[(i)][copy->type].flags |= SAVEDVAR; \
-            } \
-        ) \
-               (i)--; copy = copy->prev; \
-       } \
-}
-
-
 /* MARKREACHED marks the destination block <b> as reached. If this
  * block has been reached before we check if stack depth and types
  * match. Otherwise the destination block receives a copy of the
         } else { \
             stackptr s = curstack; \
             stackptr t = (b)->instack; \
-                   if ((b)->indepth != stackdepth) { \
-                *exceptionptr = new_verifyerror(m,"Stack depth mismatch"); \
-                return NULL; \
-            } \
+                       CHECK_STACK_DEPTH((b)->indepth, stackdepth); \
                    while (s) { \
                                CHECK_BASIC_TYPE(s->type,t->type); \
                            s = s->prev; \
 
 bool stack_init(void);
 
-methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd);
-
-void stack_print(codegendata *cd, stackptr s);
-void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd);
-void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr);
-void show_icmd(instruction *iptr, bool deadcode);
-
-/* machine dependent return value handling function */
-void md_return_alloc(methodinfo *m, registerdata *rd, s4 return_type,
-                                        stackptr stackslot);
+bool stack_analyse(jitdata *jd);
 
 #endif /* _STACK_H */