bugfixes
[libfirm] / ir / ir / irvrfy.c
index 1deb11b..0f852aa 100644 (file)
@@ -1,10 +1,14 @@
-/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
-** All rights reserved.
-**
-** Authors: Christian Schaefer
-**
-x**
-*/
+/*
+ * Project:     libFIRM
+ * File name:   ir/ir/irvrfy.c
+ * Purpose:     Check irnodes for correctness.
+ * Author:      Christian Schaefer
+ * Modified by: Goetz Lindenmaier. Till Riedel
+ * Created:
+ * CVS-ID:      $Id$
+ * Copyright:   (c) 1998-2003 Universität Karlsruhe
+ * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -14,326 +18,720 @@ x**
 # include "irvrfy.h"
 # include "irgwalk.h"
 
-void
-irn_vrfy (ir_node *n)
+#ifdef NDEBUG
+/*
+ * in RELEASE mode, returns ret if the expression expr evaluates to zero
+ * in ASSERT mode, asserts the expression expr (and the string string).
+ */
+#define ASSERT_AND_RET(expr, string, ret)              if (!(expr)) return (ret)
+
+/*
+ * in RELEASE mode, returns ret if the expression expr evaluates to zero
+ * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts
+ */
+#define ASSERT_AND_RET_DBG(expr, string, ret, blk)     if (!(expr)) return (ret)
+#else
+#define ASSERT_AND_RET(expr, string, ret)              do { assert((expr) && string); if (!(expr)) return (ret); } while(0)
+#define ASSERT_AND_RET_DBG(expr, string, ret, blk)     do { if (!(expr)) { { blk } assert(0 && string); return (ret); } } while(0)
+#endif
+
+/* @@@ replace use of array "in" by access functions. */
+ir_node **get_irn_in(ir_node *node);
+
+INLINE static int
+vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
+  ir_node *pred;
+  ir_mode *mode;
+  int proj;
+
+  pred = skip_nop(get_Proj_pred(p));
+  assert(get_irn_mode(pred) == mode_T);
+  mode = get_irn_mode(p);
+  proj = get_Proj_proj(p);
+
+  switch (get_irn_opcode(pred)) {
+    case iro_Start:
+      ASSERT_AND_RET(
+          (
+          (proj == pns_initial_exec   && mode == mode_X) ||
+           (proj == pns_global_store   && mode == mode_M) ||
+           (proj == pns_frame_base     && mode_is_reference(mode)) ||
+           (proj == pns_globals        && mode_is_reference(mode)) ||
+           (proj == pns_args           && mode == mode_T) ||
+          (proj == pns_value_arg_base && mode_is_reference(mode))
+         ),
+          "wrong Proj from Start", 0);
+      break;
+
+    case iro_Cond:
+      ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from Cond", 0);
+      break;
+
+    case iro_Raise:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_X) ||
+           (proj == 1 && mode == mode_M)),
+          "wrong Proj from Raise", 0);
+      break;
+
+    case iro_InstOf:
+      ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from InstOf", 0);
+      break;
+
+    case iro_Call:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_M) ||
+           (proj == 1 && mode == mode_X) ||
+           (proj == 2 && mode == mode_T) ||
+           (proj == 3 && mode == mode_M)),
+          "wrong Proj from Call", 0);
+      break;
+
+    case iro_Quot:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_M) ||
+           (proj == 1 && mode == mode_X) ||
+           (proj == 2 && mode_is_float(mode))),
+          "wrong Proj from Quot", 0);
+      break;
+
+    case iro_DivMod:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_M) ||
+           (proj == 1 && mode == mode_X) ||
+           (proj == 2 && mode == mode_Is) ||
+           (proj == 3 && mode_is_int(mode))),
+          "wrong Proj from DivMod", 0);
+      break;
+
+    case iro_Div:
+    case iro_Mod:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_M) ||
+           (proj == 1 && mode == mode_X) ||
+           (proj == 2 && mode_is_int(mode))),
+          "wrong Proj from Div or Mod", 0);
+      break;
+
+    case iro_Cmp:
+      ASSERT_AND_RET(
+          (proj >= 0 && proj <= 15 && mode == mode_b),
+          "wrong Proj from Cmp", 0);
+      break;
+
+    case iro_Load:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_M) ||
+           (proj == 1 && mode == mode_X) ||
+           (proj == 2 && mode_is_data(mode))),
+          "wrong Proj from Load", 0);
+      break;
+
+    case iro_Store:
+      ASSERT_AND_RET(
+          ((proj == 0 && mode == mode_M) ||
+           (proj == 1 && mode == mode_X)),
+          "wrong Proj from Store", 0);
+      break;
+
+    case iro_Alloc:
+      ASSERT_AND_RET(
+          (
+          (proj == 0 && mode == mode_M) ||
+           (proj == 1 /* && mode == mode_X*/) ||
+           (proj == 2 && mode_is_reference(mode))
+         ),
+          "wrong Proj from Alloc", 0);
+      break;
+
+    case iro_Proj:
+      {
+        type *mt; /* A method type */
+        pred = skip_nop(get_Proj_pred(pred));
+        ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
+        switch (get_irn_opcode(pred))
+        {
+          case iro_Start:
+            {
+              ASSERT_AND_RET(
+                  (proj >= 0 && mode_is_data(mode)),
+                  "wrong Proj from Proj from Start", 0);
+              mt = get_entity_type(get_irg_ent(irg));
+              ASSERT_AND_RET(
+                  (proj < get_method_n_params(mt)),
+                  "More Projs for args than args in type", 0);
+              if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
+                /* value argument */ break;
+
+              ASSERT_AND_RET(
+                  (mode == get_type_mode(get_method_param_type(mt, proj))),
+                  "Mode of Proj from Start doesn't match mode of param type.", 0);
+            }
+            break;
+
+          case iro_Call:
+            {
+              ASSERT_AND_RET(
+                  (proj >= 0 && mode_is_data(mode)),
+                  "wrong Proj from Proj from Call", 0);
+              mt = get_Call_type(pred);
+              ASSERT_AND_RET(
+                  (proj < get_method_n_ress(mt)),
+                  "More Projs for results than results in type.", 0);
+              if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
+                /* value result */ break;
+
+              ASSERT_AND_RET(
+                  (mode == get_type_mode(get_method_res_type(mt, proj))),
+                  "Mode of Proj from Call doesn't match mode of result type.", 0);
+            }
+            break;
+
+          case iro_Tuple:
+            /* We don't test */
+            break;
+
+          default:
+            ASSERT_AND_RET(0, "Unknown opcode", 0);
+        }
+        break;
+
+      }
+    case iro_Tuple:
+      /* We don't test */
+      break;
+
+    case iro_CallBegin:
+      break;
+
+    case iro_EndReg:
+      break;
+
+    case iro_EndExcept:
+      break;
+
+    default:
+      ASSERT_AND_RET(0, "Unknown opcode", 0);
+  }
+
+  /* all went ok */
+  return 1;
+}
+
+int irn_vrfy_irg(ir_node *n, ir_graph *irg)
 {
   int i;
-  int opcode;
-  ir_mode *mymode, *op1mode, *op2mode, *op3mode;
-  int op_is_symmetric = 1;     /* 0: asymmetric
-                                  1: operands have identical modes
-                                  2: modes of operands == mode of this node */
+  int opcode, opcode1;
+  ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
+  int op_is_symmetric = 1;  /*  0: asymmetric
+                               1: operands have identical modes
+                               2: modes of operands == mode of this node */
+  type *mt; /* A method type */
 
   ir_node **in;
 
+  if (! interprocedural_view) {
+    /*
+     * do NOT check placement in interprocedural view, as we don't always know
+     * the "right" graph ...
+     */
+    ASSERT_AND_RET(node_is_in_irgs_storage(irg, n), "Node is not stored on proper IR graph!", 0);
+  }
+
   opcode = get_irn_opcode (n);
+
+  /* We don't want to test nodes whose predecessors are Bad or Unknown,
+     as we would have to special case that for each operation. */
+  if (opcode != iro_Phi && opcode != iro_Block)
+    for (i = 0; i < get_irn_arity(n); i++) {
+      opcode1 = get_irn_opcode(get_irn_n(n, i));
+      if (opcode1 == iro_Bad || opcode1 == iro_Unknown)
+        return 1;
+    }
+
   mymode = get_irn_mode (n);
   in = get_irn_in (n);
 
-  switch (opcode) {
-
-  case iro_Start:
-    assert (
-           /* Start: BB --> X x M x P x data1 x ... x datan */
-           mymode == mode_T
-          );
-    break;
-  case iro_Jmp:
-    assert (
-           /* Jmp: BB --> X */
-           mymode == mode_X
-          );
-    break;
-  case iro_Cond:
-    op1mode = get_irn_mode(in[1]);
-    assert (
-           /* Cond: BB x b --> X x X */
-           (op1mode == mode_b
-           /* Cond: BB x Iu --> X^n */
-           || op1mode == mode_I)
-           );
-            assert (mymode == mode_T);
-    break;
-  case iro_Return:
-    op1mode = get_irn_mode(in[1]);
-    /* Return: BB x M x data1 x ... x datan --> X */
-    /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
-    assert ( op1mode == mode_M );  /* operand M */
-    for (i=2; i < get_irn_arity(n); i++) {
-      assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
-    };
-    assert ( mymode == mode_X );   /* result X */
-    break;
-  case iro_Raise:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert (
-           /* Sel: BB x M x P --> X x M */
-           op1mode == mode_M && op2mode == mode_p
-           && mymode == mode_T
-          );
-    break;
-  case iro_Const:
-    assert (
-           /* Const: BB --> data */
-           mode_is_data (mymode) ||
-            mymode == mode_b      /* we want boolean constants for static evaluation
-                                     of Cmp. */
-          );
-    break;
-  case iro_SymConst:
-    assert (
-           /* SymConst: BB --> Iu or
-                         BB --> P */
-           (mymode == mode_I) || (mymode == mode_p)
-          );
-    break;
-  case iro_Sel:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert (
-           /* Sel: BB x M x P x Iu^n --> P */
-           op1mode == mode_M && op2mode == mode_p
-            && mymode == mode_p
-          );
-    for (i=3; i < get_irn_arity(n); i++) {
-           assert (get_irn_mode(in[i]) == mode_I); }
-    break;
-  case iro_Call:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-      /* Call: BB x M x P x data1 x ... x datan
-                 --> M x datan+1 x ... x data n+m */
-    assert ( op1mode == mode_M && op2mode == mode_p );  /* operand M x P */
-    for (i=3; i < get_irn_arity(n); i++) {
-      assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
-    };
-    assert ( mymode == mode_T );   /* result T */
-    break;
-  case iro_Add:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert (
-           /* common Add: BB x num x num --> num */
-           (mymode == op1mode && mymode == op2mode
-             && mode_is_num(mymode))
-           ||  /* Pointer Add: BB x P x Is --> P */
-           (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
-           ||  /* Pointer Add: BB x Is x P --> P */
-           (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
-           );
-      if (op1mode == mode_p || op2mode == mode_p) {
-       /* BB x P x Is --> P or BB x Is x P --> P */
-        op_is_symmetric = 0; /* ArmRoq */
+  switch (opcode)
+  {
+
+    case iro_Block:
+      for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
+       ir_node *pred =  get_Block_cfgpred(n, i);
+       ASSERT_AND_RET((is_Bad(pred) || (get_irn_mode(pred) == mode_X)), "Block node", 0);
+      }
+      // End block may only have Return, Raise or fragile ops as preds.
+      if (n == get_irg_end_block(irg))
+       for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
+         ir_node *pred =  skip_Proj(get_Block_cfgpred(n, i));
+         if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
+           break;   // We can not test properly.  How many tuples are there?
+         ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
+                         is_Bad(pred)                    ||
+                         (get_irn_op(pred) == op_Raise)  ||
+                         is_fragile_op(pred)               ),
+                        "End Block node", 0);
+       }
+      break;
+
+    case iro_Start:
+      ASSERT_AND_RET(
+          /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
+          mymode == mode_T, "Start node", 0
+          );
+      break;
+
+    case iro_Jmp:
+      ASSERT_AND_RET(
+          /* Jmp: BB --> X */
+          mymode == mode_X, "Jmp node", 0
+          );
+      break;
+
+    case iro_Break:
+      ASSERT_AND_RET(
+          /* Jmp: BB --> X */
+          mymode == mode_X, "Jmp node", 0
+          );
+      break;
+
+    case iro_Cond:
+      op1mode = get_irn_mode(in[1]);
+      ASSERT_AND_RET(
+          /* Cond: BB x b --> X x X */
+          (op1mode == mode_b ||
+           /* Cond: BB x int --> X^n */
+           mode_is_int(op1mode) ),  "Cond node", 0
+          );
+      ASSERT_AND_RET(mymode == mode_T, "Cond mode is not a tuple", 0);
+      break;
+
+    case iro_Return:
+      op1mode = get_irn_mode(in[1]);
+      /* Return: BB x M x data1 x ... x datan --> X */
+      /* printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));*/
+      ASSERT_AND_RET( op1mode == mode_M, "Return node", 0 );  /* operand M */
+      for (i=2; i < get_irn_arity(n); i++) {
+        ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Return node", 0 );  /* operand datai */
+      };
+      ASSERT_AND_RET( mymode == mode_X, "Result X", 0 );   /* result X */
+      /* Compare returned results with result types of method type */
+      mt = get_entity_type(get_irg_ent(irg));
+      ASSERT_AND_RET( get_Return_n_ress(n) == get_method_n_ress(mt),
+          "Number of results for Return doesn't match number of results in type.", 0 );
+      for (i = 0; i < get_Return_n_ress(n); i++)
+        ASSERT_AND_RET(
+            get_irn_mode(get_Return_res(n, i)) == get_type_mode(get_method_res_type(mt, i)),
+            "Mode of result for Return doesn't match mode of result type.", 0);
+      break;
+
+    case iro_Raise:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Sel: BB x M x ref --> X x M */
+          op1mode == mode_M && mode_is_reference(op2mode) &&
+          mymode == mode_T, "Raise node", 0
+          );
+      break;
+
+    case iro_Const:
+      ASSERT_AND_RET(
+          /* Const: BB --> data */
+          (mode_is_data (mymode) ||
+           mymode == mode_b)      /* we want boolean constants for static evaluation */
+          ,"Const node", 0        /* of Cmp. */
+          );
+      break;
+
+    case iro_SymConst:
+      ASSERT_AND_RET(
+          /* SymConst: BB --> int*/
+          (mode_is_int(mymode) ||
+           /* SymConst: BB --> ref */
+           mode_is_reference(mymode))
+          ,"SymConst node", 0);
+      break;
+
+    case iro_Sel:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Sel: BB x M x ref x int^n --> ref */
+          (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
+         "Sel node", 0
+          );
+      for (i=3; i < get_irn_arity(n); i++)
+      {
+        ASSERT_AND_RET(mode_is_int(get_irn_mode(in[i])), "Sel node", 0);
+      }
+      break;
+
+    case iro_InstOf:
+      ASSERT_AND_RET(mode_T == mymode, "mode of Instof is not a tuple", 0);
+      ASSERT_AND_RET(mode_is_data(op1mode), "Instof not on data", 0);
+      break;
+
+    case iro_Call:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      /* Call: BB x M x ref x data1 x ... x datan
+         --> M x datan+1 x ... x data n+m */
+      ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 );  /* operand M x ref */
+      for (i=3; i < get_irn_arity(n); i++) {
+        ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 );  /* operand datai */
+      };
+      ASSERT_AND_RET( mymode == mode_T, "Call result not a tuple", 0 );   /* result T */
+      /* Compare arguments of node with those of type */
+      mt = get_Call_type(n);
+
+      if (get_method_variadicity(mt) == variadicity_variadic) {
+        ASSERT_AND_RET(
+            get_Call_n_params(n) >= get_method_n_params(mt),
+            "Number of args for Call doesn't match number of args in variadic type.",
+            0);
+      }
+      else {
+        ASSERT_AND_RET(
+            get_Call_n_params(n) == get_method_n_params(mt),
+            "Number of args for Call doesn't match number of args in non variadic type.",
+            0);
+      }
+
+      for (i = 0; i < get_method_n_params(mt); i++) {
+        ASSERT_AND_RET_DBG(
+            get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
+            "Mode of arg for Call doesn't match mode of arg type.", 0,
+           {
+             int i;
+
+             fprintf(stderr, "Assertion for Call type-check failed: %s(", get_type_name(mt));
+             for (i = 0; i < get_method_n_params(mt); ++i) {
+               fprintf(stderr, "%s ", get_mode_name(get_type_mode(get_method_param_type(mt, i))));
+             }
+             fprintf(stderr, ") != CALL(");
+
+             for (i = 0; i < get_Call_n_params(n); ++i) {
+               fprintf(stderr, "%s ", get_mode_name(get_irn_mode(get_Call_param(n, i))));
+             }
+             fprintf(stderr, ")\n");
+
+           }
+           );
+      }
+      break;
+
+    case iro_Add:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          (
+           /* common Add: BB x numP x numP --> numP */
+          (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
+           /* Pointer Add: BB x ref x int --> ref */
+           (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
+           /* Pointer Add: BB x int x ref --> ref */
+           (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
+         ),
+          "Add node", 0
+          );
+      if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
+        /* BB x ref x int --> ref or BB x int x ref --> ref */
+        op_is_symmetric = 0;
       } else {
-       /* BB x num x num --> num */
+        /* BB x num x num --> num or BB x ref x ref */
         op_is_symmetric = 2;
       }
-    break;
-  case iro_Sub:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert (
-           /* common Sub: BB x num x num --> num */
-           (mymode ==op1mode && mymode == op2mode
-            && mode_is_num(op1mode))
-           ||  /* Pointer Sub: BB x P x Is --> P */
-           (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
-           ||  /* Pointer Sub: BB x Is x P --> P */
-           (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
-           ||  /* Pointer Sub: BB x P x P --> Is */
-           (op1mode == mode_p && op2mode == mode_p && mymode == mode_i)
-           );
-      if (op1mode == mode_p && op2mode == mode_p) {
-        op_is_symmetric = 1; /* ArmRoq */
-      } else if (op1mode == mode_p || op2mode == mode_p) {
-        op_is_symmetric = 0; /* ArmRoq */
+      break;
+
+    case iro_Sub:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* common Sub: BB x numP x numP --> numP */
+          ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
+           /* Pointer Sub: BB x ref x int --> ref */
+           (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
+           /* Pointer Sub: BB x int x ref --> ref */
+           (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
+           /* Pointer Sub: BB x ref x ref --> int */
+           (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
+          "Sub node", 0
+          );
+      if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
+        op_is_symmetric = 0;
       } else {
         op_is_symmetric = 2;
       }
-    break;
-  case iro_Minus:
-    op1mode = get_irn_mode(in[1]);
-    assert (
-           /* Minus: BB x float --> float */
-           op1mode == mymode && mode_is_float (op1mode)
-          );
-    op_is_symmetric = 2;
-    break;
-  case iro_Mul:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert (
-           /* Mul: BB x num x num --> num */
-           mymode == op1mode && mymode == op2mode
-           && mode_is_num (op1mode)
-          );
-    op_is_symmetric = 2;
-    break;
-  case iro_Quot:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    op3mode = get_irn_mode(in[3]);
-    assert (
-           /* Quot: BB x M x float x float --> M x X x float */
-           op1mode == mode_M && op2mode == op3mode
-           && mode_is_float(op2mode) && mymode == mode_T
-          );
-    op_is_symmetric = 2;
-    break;
-  case iro_DivMod:;
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    op3mode = get_irn_mode(in[3]);
-    assert (
-           /* DivMod: BB x M x num x num --> M x X x Is x Is */
-           op1mode == mode_M && op2mode == op3mode
-           && mode_is_num (op2mode) && mymode == mode_T
-           );
-    op_is_symmetric = 1;
-    break;
-  case iro_Div:
-  case iro_Mod:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    op3mode = get_irn_mode(in[3]);
-    assert (
-           /* Div or Mod: BB x M x num x num --> M x X x Is */
-           op1mode == mode_M && op2mode == op3mode &&
-           mode_is_num (op2mode) && mymode == mode_T
-           );
-    op_is_symmetric = 1;
-    break;
-  case iro_Abs:
-    op1mode = get_irn_mode(in[1]);
-    assert (
-           /* Abs: BB x num --> num */
-           op1mode == mymode && mode_is_num (op1mode)
-          );
-    op_is_symmetric = 2;
-    break;
-  case iro_And:
-  case iro_Or:
-  case iro_Eor:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert(
-          /* And or Or or Eor: BB x int x int --> int */
-          mymode == op1mode && mymode == op2mode
-          && mode_is_int (mymode)
-         );
-    op_is_symmetric = 2;
-    break;
-  case iro_Not:
-    op1mode = get_irn_mode(in[1]);
-    assert(
-          /* Not: BB x int --> int */
-          mymode == op1mode
-          && mode_is_int (mymode)
-         );
-    op_is_symmetric = 2;
-    break;
-
-  case iro_Cmp:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert(
-          /* Cmp: BB x datab x datab --> b16 */
-           op1mode == op2mode && mode_is_data (op1mode)
-           && mymode == mode_T
-         );
-    break;
-  case iro_Shl:
-  case iro_Shr:
-  case iro_Shrs:
-  case iro_Rot:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert(
-          /* Shl, Shr, Shrs or Rot: BB x int x Iu --> int */
-          mode_is_int (op1mode) && op2mode == mode_I
-           && op1mode == mymode
-         );
-    break;
-  case iro_Conv:
-    op1mode = get_irn_mode(in[1]);
-    assert(
-           /* Conv: BB x datab1 --> datab2 */
-          mode_is_datab (op1mode)
-           && mode_is_data (mymode)
-         );
-    break;
-  case iro_Phi:
-           /* Phi: BB x dataM^n --> dataM */
-    /* for some reason "<=" aborts. Is there a problem with get_store? */
-    for (i=1; i < get_irn_arity(n); i++) {
-      if (!is_Bad(in[i]))
-       assert ( get_irn_mode(in[i]) == mymode );
-    };
-    assert ( mode_is_dataM(mymode) );
-    break;
-  case iro_Load:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert(
-           /* Load: BB x M x P --> M x X x data */
-           op1mode == mode_M && op2mode == mode_p
-         );
-    assert ( mymode == mode_T );
-    break;
-  case iro_Store:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    op3mode = get_irn_mode(in[3]);
-    assert(
-           /* Load: BB x M x P x data --> M x X */
-           op1mode == mode_M && op2mode == mode_p
-           && mode_is_data (op3mode)
-         );
-    assert(mymode == mode_T);
-    break;
-  case iro_Alloc:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    assert(
-           /* Alloc: BB x M x Iu --> M x X x P */
-           op1mode == mode_M && op2mode == mode_I
-           && mymode == mode_T
-         );
-    break;
-  case iro_Free:
-    op1mode = get_irn_mode(in[1]);
-    op2mode = get_irn_mode(in[2]);
-    op3mode = get_irn_mode(in[3]);
-    assert(
-           /* Free: BB x M x P x Iu --> M */
-           op1mode == mode_M && op2mode == mode_p && op3mode == mode_I
-           && mymode == mode_M
-         );
-    break;
-  case iro_Sync:
-           /* Sync: BB x M^n --> M */
-    for (i=1; i < get_irn_arity(n); i++) {
-      assert ( get_irn_mode(in[i]) == mode_M );
-    };
-    assert ( mymode == mode_M );
-    break;
-
-  default: ;
+      break;
+
+    case iro_Minus:
+      op1mode = get_irn_mode(in[1]);
+      ASSERT_AND_RET(
+          /* Minus: BB x float --> float */
+          op1mode == mymode && get_mode_sort(op1mode) == irms_float_number, "Minus node", 0
+          );
+      op_is_symmetric = 2;
+      break;
+
+    case iro_Mul:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Mul: BB x int1 x int1 --> int2 */
+          ((mode_is_int(op1mode)   && op2mode == op1mode && mode_is_int(mymode)) ||
+          (mode_is_float(op1mode) && op2mode == op1mode && mymode == op1mode)),
+          "Mul node",0
+          );
+      op_is_symmetric = 2;
+      break;
+
+    case iro_Quot:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      op3mode = get_irn_mode(in[3]);
+      ASSERT_AND_RET(
+          /* Quot: BB x M x float x float --> M x X x float */
+          op1mode == mode_M && op2mode == op3mode &&
+          get_mode_sort(op2mode) == irms_float_number &&
+          mymode == mode_T,
+          "Quot node",0
+          );
+      op_is_symmetric = 2;
+      break;
+
+    case iro_DivMod:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      op3mode = get_irn_mode(in[3]);
+      ASSERT_AND_RET(
+          /* DivMod: BB x M x int x int --> M x X x int x int */
+          op1mode == mode_M &&
+          mode_is_int(op2mode) &&
+          op3mode == op2mode &&
+          mymode == mode_T,
+          "DivMod node", 0
+          );
+      op_is_symmetric = 1;
+      break;
+
+    case iro_Div:
+    case iro_Mod:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      op3mode = get_irn_mode(in[3]);
+      ASSERT_AND_RET(
+          /* Div or Mod: BB x M x int x int --> M x X x int */
+          op1mode == mode_M &&
+          op2mode == op3mode &&
+          mode_is_int(op2mode) &&
+          mymode == mode_T,
+          "Div or Mod node", 0
+          );
+      op_is_symmetric = 1;
+      break;
+
+    case iro_Abs:
+      op1mode = get_irn_mode(in[1]);
+      ASSERT_AND_RET(
+          /* Abs: BB x num --> num */
+          op1mode == mymode &&
+          mode_is_num (op1mode),
+          "Abs node",0
+          );
+      op_is_symmetric = 2;
+      break;
+
+    case iro_And:
+    case iro_Or:
+    case iro_Eor:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* And or Or or Eor: BB x int x int --> int */
+          mode_is_int(mymode) &&
+          op2mode == op1mode &&
+          mymode == op2mode,
+          "And, Or or Eor node", 0
+          );
+      op_is_symmetric = 2;
+      break;
+
+    case iro_Not:
+      op1mode = get_irn_mode(in[1]);
+      ASSERT_AND_RET(
+          /* Not: BB x int --> int */
+          mode_is_int(mymode) &&
+          mymode == op1mode,
+          "Not node", 0
+          );
+      op_is_symmetric = 2;
+      break;
+
+
+    case iro_Cmp:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Cmp: BB x datab x datab --> b16 */
+          mode_is_data (op1mode) &&
+          op2mode == op1mode &&
+          mymode == mode_T,
+          "Cmp node", 0
+          );
+      break;
+
+    case iro_Shl:
+    case iro_Shr:
+    case iro_Shrs:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      assert(
+          /* Shl, Shr or Shrs: BB x int x int_u --> int */
+          mode_is_int(op1mode) &&
+          mode_is_int(op2mode) &&
+          !mode_is_signed(op2mode) &&
+          mymode == op1mode &&
+          "Shl, Shr, Shr or Rot node"
+          );
+      break;
+
+    case iro_Rot:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Rot: BB x int x int --> int */
+          mode_is_int(op1mode) &&
+          mode_is_int(op2mode) &&
+          mymode == op1mode,
+          "Rot node",0
+          );
+      break;
+
+    case iro_Conv:
+      op1mode = get_irn_mode(in[1]);
+      ASSERT_AND_RET(
+          /* Conv: BB x datab1 --> datab2 */
+          mode_is_datab(op1mode) && mode_is_data(mymode),
+          "Conv node", 0
+          );
+      break;
+
+    case iro_Cast:
+      op1mode = get_irn_mode(in[1]);
+      ASSERT_AND_RET(
+          /* Conv: BB x datab1 --> datab2 */
+          mode_is_data(op1mode) && op1mode == mymode,
+          "Cast node", 0
+          );
+      break;
+
+    case iro_Phi:
+      /* Phi: BB x dataM^n --> dataM */
+      /* for some reason "<=" aborts. int there a problem with get_store? */
+      for (i=1; i < get_irn_arity(n); i++) {
+        if (!is_Bad(in[i]) && (get_irn_op(in[i]) != op_Unknown))
+          ASSERT_AND_RET( get_irn_mode(in[i]) == mymode, "Phi node", 0);
+      };
+      ASSERT_AND_RET( mode_is_dataM(mymode), "Phi node", 0 );
+      break;
+
+    case iro_Load:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Load: BB x M x ref --> M x X x data */
+          op1mode == mode_M && mode_is_reference(op2mode),
+          "Load node", 0
+          );
+      ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
+      break;
+
+    case iro_Store:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      op3mode = get_irn_mode(in[3]);
+      ASSERT_AND_RET(
+          /* Load: BB x M x ref data --> M x X */
+          op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
+          "Store node", 0
+          );
+      ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
+      break;
+
+    case iro_Alloc:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Alloc: BB x M x int_u --> M x X x ref */
+          op1mode == mode_M &&
+          mode_is_int(op2mode) &&
+          !mode_is_signed(op2mode) &&
+          mymode == mode_T,
+          "Alloc node", 0
+          );
+      break;
+
+    case iro_Free:
+      op1mode = get_irn_mode(in[1]);
+      op2mode = get_irn_mode(in[2]);
+      ASSERT_AND_RET(
+          /* Free: BB x M x ref --> M */
+          op1mode == mode_M && mode_is_reference(op2mode) &&
+          mymode == mode_M,
+          "Free node",0
+          );
+      break;
+
+    case iro_Sync:
+      /* Sync: BB x M^n --> M */
+      for (i=1; i < get_irn_arity(n); i++) {
+        ASSERT_AND_RET( get_irn_mode(in[i]) == mode_M, "Sync node", 0 );
+      };
+      ASSERT_AND_RET( mymode == mode_M, "Sync node", 0 );
+      break;
+
+    case iro_Proj:
+      return vrfy_Proj_proj(n, irg);
+      break;
+
+    default:
+      break;
   }
+
+  /* All went ok */
+  return 1;
+}
+
+int irn_vrfy(ir_node *n)
+{
+  return irn_vrfy_irg(n, current_ir_graph);
 }
 
 /*******************************************************************/
 /* Verify the whole graph.                                         */
 /*******************************************************************/
 
-void
-vrfy_wrap (ir_node *node, void *env) {
-  irn_vrfy(node);
+static void vrfy_wrap(ir_node *node, void *env)
+{
+  int *res = env;
+
+  *res = irn_vrfy(node);
 }
 
-void
-irg_vrfy (ir_graph *irg)
+int irg_vrfy(ir_graph *irg)
 {
-  irg_walk(irg->end, vrfy_wrap, NULL, NULL);
+  int res = 1;
+  ir_graph *rem;
+
+  rem = current_ir_graph;
+  current_ir_graph = irg;
+
+  assert(get_irg_pinned(irg) == pinned);
+
+  irg_walk(irg->end, vrfy_wrap, NULL, &res);
+
+  current_ir_graph = rem;
+
+  return res;
 }