I was annoyed by the compiler warnings about implicit conversions.
[libfirm] / scripts / ir_spec.py
1 from spec_util import abstract, setnodedefaults
2
3 class Op(object):
4         "Base class for firm nodes"
5 abstract(Op)
6
7 class Unop(Op):
8         "Unary nodes have exactly 1 input"
9         name     = "unop"
10         ins      = [ "op" ]
11         op_index = 0
12         pinned   = "no"
13 abstract(Unop)
14
15 class Binop(Op):
16         "Binary nodes have exactly 2 inputs"
17         name     = "binop"
18         ins      = [ "left", "right" ]
19         op_index = 0
20         pinned   = "no"
21 abstract(Binop)
22
23 class Abs(Unop):
24         flags = []
25
26 class Add(Binop):
27         flags = ["commutative"]
28
29 class Alloc(Op):
30         ins   = [ "mem", "size" ]
31         outs  = [ "M", "X_regular", "X_except", "res" ]
32         flags = [ "fragile", "uses_memory" ]
33         attrs = [
34                 dict(
35                         name = "type",
36                         type = "ir_type*"
37                 ),
38                 dict(
39                         name = "where",
40                         type = "ir_where_alloc"
41                 )
42         ]
43         pinned      = "yes"
44         attr_struct = "alloc_attr"
45         d_post = '''
46         firm_alloc_frag_arr(res, op_Alloc, &res->attr.alloc.exc.frag_arr);
47         '''
48
49 class Anchor(Op):
50         mode        = "mode_ANY"
51         arity       = "variable"
52         flags       = [ "dump_noblock" ]
53         pinned      = "yes"
54         knownBlock  = True
55         singleton   = True
56
57 class And(Binop):
58         flags    = [ "commutative" ]
59
60 class ASM(Op):
61         mode          = "mode_T"
62         arity         = "variable"
63         flags         = [ "keep", "uses_memory" ]
64         attr_struct   = "asm_attr"
65         pinned        = "memory"
66         pinned_init   = "op_pin_state_pinned"
67         attrs = [
68                 dict(
69                         name = "input_constraints",
70                         type = "ir_asm_constraint*",
71                 ),
72                 dict(
73                         name = "n_output_constraints",
74                         type = "int",
75                 ),
76                 dict(
77                         name = "output_constraints",
78                         type = "ir_asm_constraint*",
79                 ),
80                 dict(
81                         name = "n_clobbers",
82                         type = "int",
83                 ),
84                 dict(
85                         name = "clobbers",
86                         type = "ident**",
87                 ),
88                 dict(
89                         name = "text",
90                         type = "ident*",
91                 ),
92         ]
93         java_noconstr = True
94
95 class Bad(Op):
96         mode        = "mode_Bad"
97         flags       = [ "cfopcode", "fragile", "start_block", "dump_noblock" ]
98         pinned      = "yes"
99         knownBlock  = True
100         singleton   = True
101         attr_struct = "irg_attr"
102         init = '''
103         res->attr.irg.irg = irg;
104         '''
105
106 class Block(Op):
107         mode        = "mode_BB"
108         knownBlock  = True
109         block       = "NULL"
110         pinned      = "yes"
111         optimize    = False
112         arity       = "variable"
113         flags       = [ "labeled" ]
114         attr_struct = "block_attr"
115         java_noconstr = True
116
117         init = '''
118         /* macroblock header */
119         res->in[0] = res;
120
121         res->attr.block.is_dead     = 0;
122         res->attr.block.is_mb_head  = 1;
123         res->attr.block.irg.irg     = irg;
124         res->attr.block.backedge    = new_backedge_arr(irg->obst, arity);
125         res->attr.block.in_cg       = NULL;
126         res->attr.block.cg_backedge = NULL;
127         res->attr.block.extblk      = NULL;
128         res->attr.block.mb_depth    = 0;
129         res->attr.block.entity      = NULL;
130
131         set_Block_matured(res, 1);
132         set_Block_block_visited(res, 0);
133         '''
134
135         d_pre = '''
136         int i;
137         int has_unknown = 0;
138         '''
139
140         d_post = '''
141         /* Create and initialize array for Phi-node construction. */
142         if (get_irg_phase_state(current_ir_graph) == phase_building) {
143                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,
144                                                       current_ir_graph->n_loc);
145                 memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
146         }
147
148         for (i = arity - 1; i >= 0; i--)
149                 if (is_Unknown(in[i])) {
150                         has_unknown = 1;
151                         break;
152                 }
153
154         if (!has_unknown) res = optimize_node(res);
155
156         current_ir_graph->current_block = res;
157
158         IRN_VRFY_IRG(res, current_ir_graph);
159         '''
160
161         java_add   = '''
162         public void addPred(Node node) {
163                 binding_cons.add_immBlock_pred(ptr, node.ptr);
164         }
165
166         public void mature() {
167                 binding_cons.mature_immBlock(ptr);
168         }
169
170         @Override
171         public Block getBlock() {
172                 return null;
173         }
174
175         public boolean blockVisited() {
176                 return 0 != binding.Block_block_visited(ptr);
177         }
178
179         public void markBlockVisited() {
180                 binding.mark_Block_block_visited(ptr);
181         }
182
183         public boolean isBad() {
184                 return binding.is_Bad(ptr) != 0;
185         }
186         '''
187
188 class Borrow(Binop):
189         flags = []
190
191 class Bound(Op):
192         ins    = [ "mem", "index", "lower", "upper" ]
193         outs   = [ "M", "X_regular", "X_except", "res" ]
194         flags  = [ "fragile", "highlevel" ]
195         pinned = "exception"
196         pinned_init = "op_pin_state_pinned"
197         attr_struct = "bound_attr"
198         d_post = '''
199         firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
200         '''
201
202 class Break(Op):
203         mode   = "mode_X"
204         flags  = [ "cfopcode" ]
205         pinned = "yes"
206
207 class Builtin(Op):
208         ins      = [ "mem" ]
209         arity    = "variable"
210         outs     = [ "M", "X_regular", "X_except", "T_result", "P_value_res_base" ]
211         flags    = [ "uses_memory" ]
212         attrs    = [
213                 dict(
214                         type = "ir_builtin_kind",
215                         name = "kind"
216                 ),
217                 dict(
218                         type = "ir_type*",
219                         name = "type"
220                 )
221         ]
222         pinned      = "memory"
223         pinned_init = "op_pin_state_pinned"
224         attr_struct = "builtin_attr"
225         init   = '''
226         assert((get_unknown_type() == type) || is_Method_type(type));
227         '''
228
229 class Call(Op):
230         ins      = [ "mem", "ptr" ]
231         arity    = "variable"
232         outs     = [ "M", "X_regular", "X_except", "T_result", "P_value_res_base" ]
233         flags    = [ "fragile", "uses_memory" ]
234         attrs    = [
235                 dict(
236                         type = "ir_type*",
237                         name = "type"
238                 ),
239                 dict(
240                         type = "unsigned",
241                         name = "tail_call",
242                         # the tail call attribute can only be set by analysis
243                         init = "0"
244                 )
245         ]
246         attr_struct = "call_attr"
247         pinned      = "memory"
248         pinned_init = "op_pin_state_pinned"
249         init = '''
250         assert((get_unknown_type() == type) || is_Method_type(type));
251         '''
252         d_post = '''
253         firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
254         '''
255
256 class CallBegin(Op):
257         ins   = [ "ptr" ]
258         outs  = [ "" ] # TODO
259         flags         = [ "cfopcode", "ip_cfopcode" ]
260         pinned        = "yes"
261         # TODO: attribute with call...
262         attr_struct   = "callbegin_attr"
263         attrs         = [
264                 dict(
265                         type = "ir_node*",
266                         name = "call"
267                 )
268         ]
269         java_noconstr = True
270
271 class Carry(Binop):
272         flags = [ "commutative" ]
273
274 class Cast(Unop):
275         mode     = "get_irn_mode(irn_op)"
276         flags    = [ "highlevel" ]
277         attrs    = [
278                 dict(
279                         type = "ir_type*",
280                         name = "type"
281                 )
282         ]
283         attr_struct = "cast_attr"
284         init     = "assert(is_atomic_type(type));"
285
286 class Cmp(Binop):
287         outs  = [ "False", "Eq", "Lt", "Le", "Gt", "Ge", "Lg", "Leg", "Uo", "Ue", "Ul", "Ule", "Ug", "Uge", "Ne", "True" ]
288         flags = []
289
290 class Cond(Op):
291         ins      = [ "selector" ]
292         outs     = [ "false", "true" ]
293         flags    = [ "cfopcode", "forking" ]
294         pinned   = "yes"
295         attrs    = [
296                 dict(
297                         name = "kind",
298                         type = "cond_kind",
299                         init = "dense"
300                 ),
301                 dict(
302                         name = "default_proj",
303                         type = "long",
304                         init = "0"
305                 ),
306                 dict(
307                         name = "jmp_pred",
308                         type = "cond_jmp_predicate",
309                         init = "COND_JMP_PRED_NONE"
310                 )
311         ]
312         attr_struct = "cond_attr"
313
314 class Confirm(Op):
315         ins      = [ "value", "bound" ]
316         mode     = "get_irn_mode(irn_value)"
317         flags    = [ "highlevel" ]
318         pinned   = "yes"
319         attrs    = [
320                 dict(
321                         name = "cmp",
322                         type = "pn_Cmp"
323                 ),
324         ]
325         attr_struct = "confirm_attr"
326
327 class Const(Op):
328         mode       = ""
329         flags      = [ "constlike", "start_block" ]
330         knownBlock = True
331         pinned     = "no"
332         attrs_name = "con"
333         attrs      = [
334                 dict(
335                         type = "tarval*",
336                         name = "tarval",
337                 )
338         ]
339         attr_struct = "const_attr"
340
341 class Conv(Unop):
342         flags = []
343         attrs = [
344                 dict(
345                         name = "strict",
346                         type = "int",
347                         init = "0",
348                         special = dict(
349                                 prefix = "strict",
350                                 init = "1"
351                         )
352                 )
353         ]
354         attr_struct = "conv_attr"
355
356 class CopyB(Op):
357         ins   = [ "mem", "dst", "src" ]
358         outs  = [ "M", "X_regular", "X_except" ]
359         flags = [ "fragile", "highlevel", "uses_memory" ]
360         attrs = [
361                 dict(
362                         name = "type",
363                         type = "ir_type*"
364                 )
365         ]
366         attr_struct = "copyb_attr"
367         pinned      = "memory"
368         pinned_init = "op_pin_state_pinned"
369         d_post = '''
370         firm_alloc_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
371         '''
372
373 class Div(Op):
374         ins   = [ "mem", "left", "right" ]
375         outs  = [ "M", "X_regular", "X_except", "res" ]
376         flags = [ "fragile", "uses_memory" ]
377         attrs_name = "divmod"
378         attrs = [
379                 dict(
380                         type = "ir_mode*",
381                         name = "resmode"
382                 ),
383                 dict(
384                         name = "no_remainder",
385                         type = "int",
386                         init = "0",
387                         special = dict(
388                                 suffix = "RL",
389                                 init = "1"
390                         )
391                 )
392         ]
393         attr_struct = "divmod_attr"
394         pinned      = "exception"
395         op_index    = 1
396         arity_override = "oparity_binary"
397         d_post = '''
398         firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
399         '''
400
401 class DivMod(Op):
402         ins   = [ "mem", "left", "right" ]
403         outs  = [ "M", "X_regular", "X_except", "res_div", "res_mod" ]
404         flags = [ "fragile", "uses_memory" ]
405         attrs_name = "divmod"
406         attrs = [
407                 dict(
408                         type = "ir_mode*",
409                         name = "resmode"
410                 ),
411         ]
412         attr_struct = "divmod_attr"
413         pinned      = "exception"
414         op_index    = 1
415         arity_override = "oparity_binary"
416         d_post = '''
417         firm_alloc_frag_arr(res, op_DivMod, &res->attr.except.frag_arr);
418         '''
419
420 class Dummy(Op):
421         ins   = []
422         flags = [ "cfopcode", "fragile", "start_block", "constlike",
423                   "dump_noblock" ]
424         knownBlock = True
425         pinned     = "yes"
426         block      = "get_irg_start_block(irg)"
427
428 class End(Op):
429         mode       = "mode_X"
430         pinned     = "yes"
431         arity      = "dynamic"
432         flags      = [ "cfopcode" ]
433         singleton  = True
434
435 class EndExcept(Op):
436         mode      = "mode_X"
437         pinned    = "yes"
438         arity     = "dynamic"
439         flags     = [ "cfopcode", "ip_cfopcode" ]
440         singleton = True
441
442 class EndReg(Op):
443         mode      = "mode_X"
444         pinned    = "yes"
445         arity     = "dynamic"
446         flags     = [ "cfopcode", "ip_cfopcode" ]
447         singleton = True
448
449 class Eor(Binop):
450         flags    = [ "commutative" ]
451
452 class Filter(Op):
453         ins   = [ "pred" ]
454         flags = []
455         attrs = [
456                 dict(
457                         name = "proj",
458                         type = "long"
459                 )
460         ]
461         pinned      = "yes"
462         attr_struct = "filter_attr"
463         java_noconstr = True
464
465 class Free(Op):
466         ins    = [ "mem", "ptr", "size" ]
467         mode   = "mode_M"
468         flags  = [ "uses_memory" ]
469         pinned = "yes"
470         attrs  = [
471                 dict(
472                         name = "type",
473                         type = "ir_type*"
474                 ),
475                 dict(
476                         name = "where",
477                         type = "ir_where_alloc"
478                 )
479         ]
480         attr_struct = "free_attr"
481
482 class Id(Op):
483         ins    = [ "pred" ]
484         pinned = "no"
485         flags  = []
486
487 class IJmp(Op):
488         mode     = "mode_X"
489         pinned   = "yes"
490         ins      = [ "target" ]
491         flags    = [ "cfopcode", "forking", "keep" ]
492
493 class InstOf(Op):
494         ins   = [ "store", "obj" ]
495         outs  = [ "M", "X_regular", "X_except", "res" ]
496         flags = [ "highlevel" ]
497         attrs = [
498                 dict(
499                         name = "type",
500                         type = "ir_type*"
501                 )
502         ]
503         attr_struct = "io_attr"
504         pinned      = "memory"
505         pinned_init = "op_pin_state_floats"
506
507 class Jmp(Op):
508         mode     = "mode_X"
509         pinned   = "yes"
510         ins      = []
511         flags    = [ "cfopcode" ]
512
513 class Load(Op):
514         ins      = [ "mem", "ptr" ]
515         outs     = [ "M", "X_regular", "X_except", "res" ]
516         flags    = [ "fragile", "uses_memory" ]
517         pinned   = "exception"
518         pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
519         attrs    = [
520                 dict(
521                         type = "ir_mode*",
522                         name = "mode",
523                         java_name = "load_mode"
524                 ),
525         ]
526         attr_struct = "load_attr"
527         constructor_args = [
528                 dict(
529                         type = "ir_cons_flags",
530                         name = "flags",
531                 ),
532         ]
533         d_post = '''
534         firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
535         '''
536
537 class Minus(Unop):
538         flags = []
539
540 class Mod(Op):
541         ins   = [ "mem", "left", "right" ]
542         outs  = [ "M", "X_regular", "X_except", "res" ]
543         flags = [ "fragile", "uses_memory" ]
544         attrs_name = "divmod"
545         attrs = [
546                 dict(
547                         type = "ir_mode*",
548                         name = "resmode"
549                 ),
550         ]
551         attr_struct = "divmod_attr"
552         pinned      = "exception"
553         op_index    = 1
554         arity_override = "oparity_binary"
555         d_post = '''
556         firm_alloc_frag_arr(res, op_Mod, &res->attr.except.frag_arr);
557         '''
558
559 class Mul(Binop):
560         flags = [ "commutative" ]
561
562 class Mulh(Binop):
563         flags = [ "commutative" ]
564
565 class Mux(Op):
566         ins    = [ "sel", "false", "true" ]
567         flags  = []
568         pinned = "no"
569
570 class NoMem(Op):
571         mode       = "mode_M"
572         flags      = [ "dump_noblock", "dump_noinput" ]
573         pinned     = "yes"
574         knownBlock = True
575         singleton  = True
576
577 class Not(Unop):
578         flags = []
579
580 class Or(Binop):
581         flags = [ "commutative" ]
582
583 class Phi(Op):
584         pinned      = "yes"
585         arity       = "variable"
586         flags       = []
587         attr_struct = "phi_attr"
588         custom_is   = True
589         java_noconstr = True
590         init = '''
591         /* Memory Phis in endless loops must be kept alive.
592            As we can't distinguish these easily we keep all of them alive. */
593         if (is_Phi(res) && mode == mode_M)
594                 add_End_keepalive(get_irg_end(irg), res);
595         '''
596
597 class Pin(Op):
598         ins      = [ "op" ]
599         mode     = "get_irn_mode(irn_op)"
600         flags    = [ "highlevel" ]
601         pinned   = "yes"
602
603 class Proj(Op):
604         ins      = [ "pred" ]
605         flags    = []
606         pinned   = "no"
607         attrs    = [
608                 dict(
609                         type = "long",
610                         name = "proj",
611                         initname = ""
612                 )
613         ]
614         attr_struct = "long"
615         custom_is   = True
616
617 class Quot(Op):
618         ins   = [ "mem", "left", "right" ]
619         outs  = [ "M", "X_regular", "X_except", "res" ]
620         flags = [ "fragile", "uses_memory" ]
621         attrs_name = "divmod"
622         attrs = [
623                 dict(
624                         type = "ir_mode*",
625                         name = "resmode"
626                 ),
627         ]
628         attr_struct = "divmod_attr"
629         pinned      = "exception"
630         op_index    = 1
631         arity_override = "oparity_binary"
632         d_post = '''
633         firm_alloc_frag_arr(res, op_Quot, &res->attr.except.frag_arr);
634         '''
635
636 class Raise(Op):
637         ins    = [ "mem", "exo_ptr" ]
638         outs   = [ "M", "X" ]
639         flags  = [ "highlevel", "cfopcode" ]
640         pinned = "yes"
641
642 class Return(Op):
643         ins      = [ "mem" ]
644         arity    = "variable"
645         mode     = "mode_X"
646         flags    = [ "cfopcode" ]
647         pinned   = "yes"
648
649 class Rotl(Binop):
650         flags    = []
651
652 class Sel(Op):
653         ins    = [ "mem", "ptr" ]
654         arity  = "variable"
655         flags  = []
656         mode   = "is_Method_type(get_entity_type(entity)) ? mode_P_code : mode_P_data"
657         pinned = "no"
658         attrs  = [
659                 dict(
660                         type = "ir_entity*",
661                         name = "entity"
662                 )
663         ]
664         attr_struct = "sel_attr"
665
666 class Shl(Binop):
667         flags = []
668
669 class Shr(Binop):
670         flags = []
671
672 class Shrs(Binop):
673         flags = []
674
675 class Start(Op):
676         mode       = "mode_T"
677         pinned     = "yes"
678         flags      = [ "cfopcode" ]
679         singleton  = True
680
681 class Store(Op):
682         ins      = [ "mem", "ptr", "value" ]
683         outs     = [ "M", "X_regular", "X_except" ]
684         flags    = [ "fragile", "uses_memory" ]
685         pinned   = "exception"
686         attr_struct = "store_attr"
687         pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
688         constructor_args = [
689                 dict(
690                         type = "ir_cons_flags",
691                         name = "flags",
692                 ),
693         ]
694         d_post = '''
695         firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
696         '''
697
698 class Sub(Binop):
699         flags = []
700
701 class SymConst(Op):
702         mode       = "mode_P"
703         flags      = [ "constlike", "start_block" ]
704         knownBlock = True
705         pinned     = "no"
706         attrs      = [
707                 dict(
708                         type = "ir_entity*",
709                         name = "entity"
710                 )
711         ]
712         attr_struct = "symconst_attr"
713         java_noconstr = True
714
715 class Sync(Op):
716         mode     = "mode_M"
717         flags    = []
718         pinned   = "no"
719         optimize = False
720         arity    = "dynamic"
721
722 class Tuple(Op):
723         arity  = "variable"
724         mode   = "mode_T"
725         pinned = "no"
726         flags  = [ "labeled" ]
727         java_noconstr = True
728
729 class Unknown(Op):
730         knownBlock = True
731         pinned     = "yes"
732         block      = "get_irg_start_block(irg)"
733         flags      = [ "cfopcode", "fragile", "start_block", "constlike",
734                        "dump_noblock" ]
735
736 # Prepare node list
737
738 def getOpList(namespace):
739         nodes = []
740         for t in namespace.values():
741                 if type(t) != type:
742                         continue
743
744                 if issubclass(t, Op):
745                         setnodedefaults(t)
746                         nodes.append(t)
747         return nodes
748
749 nodes = getOpList(globals())
750 nodes = sorted(nodes, lambda x,y: cmp(x.name, y.name))