d82c9c5945013c5879c42f2c2f9fc3351303573d
[libfirm] / ir / ir / irvrfy.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Christian Schaefer
5 **
6 **
7 */
8
9 # include "irgraph_t.h"
10 # include "irvrfy.h"
11 # include "irgwalk.h"
12
13 void
14 irn_vrfy (ir_node *n)
15 {
16   int i;
17   int opcode;
18   ir_mode *mymode, *op1mode, *op2mode, *op3mode;
19   int op_is_symmetric = 1;      /* 0: asymmetric
20                                    1: operands have identical modes
21                                    2: modes of operands == mode of this node */
22
23   ir_node **in;
24
25   opcode = get_irn_opcode (n);
26   mymode = get_irn_mode (n);
27   in = get_irn_in (n);
28
29   switch (opcode) {
30
31   case iro_Start:
32     assert (
33             /* Start: BB --> X x M x P x data1 x ... x datan */
34             mymode == mode_T
35            );
36     break;
37   case iro_Jmp:
38     assert (
39             /* Jmp: BB --> X */
40             mymode == mode_X
41            );
42     break;
43   case iro_Cond:
44     op1mode = get_irn_mode(in[1]);
45     assert (
46             /* Cond: BB x b --> X x X */
47             (op1mode == mode_b
48             /* Cond: BB x Iu --> X^n */
49             || op1mode == mode_I)
50            );
51             assert (mymode == mode_T);
52     break;
53   case iro_Return:
54     op1mode = get_irn_mode(in[1]);
55       /* Return: BB x M x data1 x ... x datan --> X */
56     //printf("mode: %s, code %s\n", ID_TO_STR(n->mode->name), ID_TO_STR(n->op->name));
57     assert ( op1mode == mode_M );  /* operand M */
58     for (i=2; i < get_irn_arity(n); i++) {
59       assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
60     };
61     assert ( mymode == mode_X );   /* result X */
62     break;
63   case iro_Raise:
64     op1mode = get_irn_mode(in[1]);
65     op2mode = get_irn_mode(in[2]);
66     assert (
67             /* Sel: BB x M x P --> X x M */
68             op1mode == mode_M && op2mode == mode_p
69             && mymode == mode_T
70            );
71     break;
72   case iro_Const:
73     assert (
74             /* Const: BB --> data */
75             mode_is_data (mymode) ||
76             mymode == mode_b      /* we want boolean constants for static evaluation
77                                      of Cmp. */
78            );
79     break;
80   case iro_SymConst:
81     assert (
82             /* SymConst: BB --> Iu or
83                          BB --> P */
84             (mymode == mode_I) || (mymode == mode_p)
85            );
86     break;
87   case iro_Sel:
88     op1mode = get_irn_mode(in[1]);
89     op2mode = get_irn_mode(in[2]);
90     assert (
91             /* Sel: BB x M x P x Iu^n --> P */
92             op1mode == mode_M && op2mode == mode_p
93             && mymode == mode_p
94            );
95     for (i=3; i < get_irn_arity(n); i++) {
96             assert (get_irn_mode(in[i]) == mode_I); }
97     break;
98   case iro_Call:
99     op1mode = get_irn_mode(in[1]);
100     op2mode = get_irn_mode(in[2]);
101       /* Call: BB x M x P x data1 x ... x datan
102                  --> M x datan+1 x ... x data n+m */
103     assert ( op1mode == mode_M && op2mode == mode_p );  /* operand M x P */
104     for (i=3; i < get_irn_arity(n); i++) {
105       assert ( mode_is_data(get_irn_mode(in[i])) );  /* operand datai */
106     };
107     assert ( mymode == mode_T );   /* result T */
108     break;
109   case iro_Add:
110     op1mode = get_irn_mode(in[1]);
111     op2mode = get_irn_mode(in[2]);
112     assert (
113             /* common Add: BB x num x num --> num */
114             (mymode == op1mode && mymode == op2mode
115              && mode_is_num(mymode))
116             ||  /* Pointer Add: BB x P x Is --> P */
117             (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
118             ||  /* Pointer Add: BB x Is x P --> P */
119             (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
120            );
121       if (op1mode == mode_p || op2mode == mode_p) {
122         /* BB x P x Is --> P or BB x Is x P --> P */
123         op_is_symmetric = 0; /* ArmRoq */
124       } else {
125         /* BB x num x num --> num */
126         op_is_symmetric = 2;
127       }
128     break;
129   case iro_Sub:
130     op1mode = get_irn_mode(in[1]);
131     op2mode = get_irn_mode(in[2]);
132     assert (
133             /* common Sub: BB x num x num --> num */
134             (mymode ==op1mode && mymode == op2mode
135              && mode_is_num(op1mode))
136             ||  /* Pointer Sub: BB x P x Is --> P */
137             (op1mode == mode_p && op2mode == mode_i && mymode == mode_p)
138             ||  /* Pointer Sub: BB x Is x P --> P */
139             (op1mode == mode_i && op2mode == mode_p && mymode == mode_p)
140             ||  /* Pointer Sub: BB x P x P --> Is */
141             (op1mode == mode_p && op2mode == mode_p && mymode == mode_i)
142            );
143       if (op1mode == mode_p && op2mode == mode_p) {
144         op_is_symmetric = 1; /* ArmRoq */
145       } else if (op1mode == mode_p || op2mode == mode_p) {
146         op_is_symmetric = 0; /* ArmRoq */
147       } else {
148         op_is_symmetric = 2;
149       }
150     break;
151   case iro_Minus:
152     op1mode = get_irn_mode(in[1]);
153     assert (
154             /* Minus: BB x float --> float */
155             op1mode == mymode && mode_is_float (op1mode)
156            );
157     op_is_symmetric = 2;
158     break;
159   case iro_Mul:
160     op1mode = get_irn_mode(in[1]);
161     op2mode = get_irn_mode(in[2]);
162     assert (
163             /* Mul: BB x num x num --> num */
164             mymode == op1mode && mymode == op2mode
165             && mode_is_num (op1mode)
166            );
167     op_is_symmetric = 2;
168     break;
169   case iro_Quot:
170     op1mode = get_irn_mode(in[1]);
171     op2mode = get_irn_mode(in[2]);
172     op3mode = get_irn_mode(in[3]);
173     assert (
174             /* Quot: BB x M x float x float --> M x X x float */
175             op1mode == mode_M && op2mode == op3mode
176             && mode_is_float(op2mode) && mymode == mode_T
177            );
178     op_is_symmetric = 2;
179     break;
180   case iro_DivMod:;
181     op1mode = get_irn_mode(in[1]);
182     op2mode = get_irn_mode(in[2]);
183     op3mode = get_irn_mode(in[3]);
184     assert (
185             /* DivMod: BB x M x num x num --> M x X x Is x Is */
186             op1mode == mode_M && op2mode == op3mode
187             && mode_is_num (op2mode) && mymode == mode_T
188            );
189     op_is_symmetric = 1;
190     break;
191   case iro_Div:
192   case iro_Mod:
193     op1mode = get_irn_mode(in[1]);
194     op2mode = get_irn_mode(in[2]);
195     op3mode = get_irn_mode(in[3]);
196     assert (
197             /* Div or Mod: BB x M x num x num --> M x X x Is */
198             op1mode == mode_M && op2mode == op3mode &&
199             mode_is_num (op2mode) && mymode == mode_T
200            );
201     op_is_symmetric = 1;
202     break;
203   case iro_Abs:
204     op1mode = get_irn_mode(in[1]);
205     assert (
206             /* Abs: BB x num --> num */
207             op1mode == mymode && mode_is_num (op1mode)
208            );
209     op_is_symmetric = 2;
210     break;
211   case iro_And:
212   case iro_Or:
213   case iro_Eor:
214     op1mode = get_irn_mode(in[1]);
215     op2mode = get_irn_mode(in[2]);
216     assert(
217            /* And or Or or Eor: BB x int x int --> int */
218            mymode == op1mode && mymode == op2mode
219            && mode_is_int (mymode)
220           );
221     op_is_symmetric = 2;
222     break;
223   case iro_Not:
224     op1mode = get_irn_mode(in[1]);
225     assert(
226            /* Not: BB x int --> int */
227            mymode == op1mode
228            && mode_is_int (mymode)
229           );
230     op_is_symmetric = 2;
231     break;
232
233   case iro_Cmp:
234     op1mode = get_irn_mode(in[1]);
235     op2mode = get_irn_mode(in[2]);
236     assert(
237            /* Cmp: BB x datab x datab --> b16 */
238            op1mode == op2mode && mode_is_data (op1mode)
239            && mymode == mode_T
240           );
241     break;
242   case iro_Shl:
243   case iro_Shr:
244   case iro_Shrs:
245   case iro_Rot:
246     op1mode = get_irn_mode(in[1]);
247     op2mode = get_irn_mode(in[2]);
248     assert(
249            /* Shl, Shr, Shrs or Rot: BB x int x Iu --> int */
250            mode_is_int (op1mode) && op2mode == mode_I
251            && op1mode == mymode
252           );
253     break;
254   case iro_Conv:
255     op1mode = get_irn_mode(in[1]);
256     assert(
257            /* Conv: BB x datab1 --> datab2 */
258            mode_is_datab (op1mode)
259            && mode_is_data (mymode)
260           );
261     break;
262   case iro_Phi:
263            /* Phi: BB x dataM^n --> dataM */
264     /* for some reason "<=" aborts. Is there a problem with get_store? */
265     for (i=1; i < get_irn_arity(n); i++) {
266       if (!is_Bad(in[i]))
267         assert ( get_irn_mode(in[i]) == mymode );
268     };
269     assert ( mode_is_dataM(mymode) );
270     break;
271   case iro_Load:
272     op1mode = get_irn_mode(in[1]);
273     op2mode = get_irn_mode(in[2]);
274     assert(
275            /* Load: BB x M x P --> M x X x data */
276            op1mode == mode_M && op2mode == mode_p
277           );
278     assert ( mymode == mode_T );
279     break;
280   case iro_Store:
281     op1mode = get_irn_mode(in[1]);
282     op2mode = get_irn_mode(in[2]);
283     op3mode = get_irn_mode(in[3]);
284     assert(
285            /* Load: BB x M x P x data --> M x X */
286            op1mode == mode_M && op2mode == mode_p
287            && mode_is_data (op3mode)
288           );
289     assert(mymode == mode_T);
290     break;
291   case iro_Alloc:
292     op1mode = get_irn_mode(in[1]);
293     op2mode = get_irn_mode(in[2]);
294     assert(
295            /* Alloc: BB x M x Iu --> M x X x P */
296            op1mode == mode_M && op2mode == mode_I
297            && mymode == mode_T
298           );
299     break;
300   case iro_Free:
301     op1mode = get_irn_mode(in[1]);
302     op2mode = get_irn_mode(in[2]);
303     op3mode = get_irn_mode(in[3]);
304     assert(
305            /* Free: BB x M x P x Iu --> M */
306            op1mode == mode_M && op2mode == mode_p && op3mode == mode_I
307            && mymode == mode_M
308           );
309     break;
310   case iro_Sync:
311            /* Sync: BB x M^n --> M */
312     for (i=1; i < get_irn_arity(n); i++) {
313       assert ( get_irn_mode(in[i]) == mode_M );
314     };
315     assert ( mymode == mode_M );
316     break;
317
318   default: ;
319   }
320 }
321
322 /*******************************************************************/
323 /* Verify the whole graph.                                         */
324 /*******************************************************************/
325
326 void
327 vrfy_wrap (ir_node *node, void *env) {
328   irn_vrfy(node);
329 }
330
331 void
332 irg_vrfy (ir_graph *irg)
333 {
334   irg_walk(irg->end, vrfy_wrap, NULL, NULL);
335 }