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