new_Block doesn't set current_block anymore; remove some unused and strange functions
[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         /* Create and initialize array for Phi-node construction. */
135         if (get_irg_phase_state(irg) == phase_building) {
136                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
137                 memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
138         }
139         '''
140
141         java_add   = '''
142         public void addPred(Node node) {
143                 binding_cons.add_immBlock_pred(ptr, node.ptr);
144         }
145
146         public void mature() {
147                 binding_cons.mature_immBlock(ptr);
148         }
149
150         @Override
151         public Block getBlock() {
152                 return null;
153         }
154
155         public boolean blockVisited() {
156                 return 0 != binding.Block_block_visited(ptr);
157         }
158
159         public void markBlockVisited() {
160                 binding.mark_Block_block_visited(ptr);
161         }
162
163         public boolean isBad() {
164                 return binding.is_Bad(ptr) != 0;
165         }
166         '''
167
168 class Borrow(Binop):
169         flags = []
170
171 class Bound(Op):
172         ins    = [ "mem", "index", "lower", "upper" ]
173         outs   = [ "M", "X_regular", "X_except", "res" ]
174         flags  = [ "fragile", "highlevel" ]
175         pinned = "exception"
176         pinned_init = "op_pin_state_pinned"
177         attr_struct = "bound_attr"
178         d_post = '''
179         firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
180         '''
181
182 class Break(Op):
183         mode   = "mode_X"
184         flags  = [ "cfopcode" ]
185         pinned = "yes"
186
187 class Builtin(Op):
188         ins      = [ "mem" ]
189         arity    = "variable"
190         outs     = [ "M", "X_regular", "X_except", "T_result", "P_value_res_base" ]
191         flags    = [ "uses_memory" ]
192         attrs    = [
193                 dict(
194                         type = "ir_builtin_kind",
195                         name = "kind"
196                 ),
197                 dict(
198                         type = "ir_type*",
199                         name = "type"
200                 )
201         ]
202         pinned      = "memory"
203         pinned_init = "op_pin_state_pinned"
204         attr_struct = "builtin_attr"
205         init   = '''
206         assert((get_unknown_type() == type) || is_Method_type(type));
207         '''
208
209 class Call(Op):
210         ins      = [ "mem", "ptr" ]
211         arity    = "variable"
212         outs     = [ "M", "X_regular", "X_except", "T_result", "P_value_res_base" ]
213         flags    = [ "fragile", "uses_memory" ]
214         attrs    = [
215                 dict(
216                         type = "ir_type*",
217                         name = "type"
218                 ),
219                 dict(
220                         type = "unsigned",
221                         name = "tail_call",
222                         # the tail call attribute can only be set by analysis
223                         init = "0"
224                 )
225         ]
226         attr_struct = "call_attr"
227         pinned      = "memory"
228         pinned_init = "op_pin_state_pinned"
229         init = '''
230         assert((get_unknown_type() == type) || is_Method_type(type));
231         '''
232         d_post = '''
233         firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
234         '''
235
236 class CallBegin(Op):
237         ins   = [ "ptr" ]
238         outs  = [ "" ] # TODO
239         flags         = [ "cfopcode", "ip_cfopcode" ]
240         pinned        = "yes"
241         # TODO: attribute with call...
242         attr_struct   = "callbegin_attr"
243         attrs         = [
244                 dict(
245                         type = "ir_node*",
246                         name = "call"
247                 )
248         ]
249         java_noconstr = True
250
251 class Carry(Binop):
252         flags = [ "commutative" ]
253
254 class Cast(Unop):
255         mode     = "get_irn_mode(irn_op)"
256         flags    = [ "highlevel" ]
257         attrs    = [
258                 dict(
259                         type = "ir_type*",
260                         name = "type"
261                 )
262         ]
263         attr_struct = "cast_attr"
264         init     = "assert(is_atomic_type(type));"
265
266 class Cmp(Binop):
267         outs  = [ "False", "Eq", "Lt", "Le", "Gt", "Ge", "Lg", "Leg", "Uo", "Ue", "Ul", "Ule", "Ug", "Uge", "Ne", "True" ]
268         flags = []
269
270 class Cond(Op):
271         ins      = [ "selector" ]
272         outs     = [ "false", "true" ]
273         flags    = [ "cfopcode", "forking" ]
274         pinned   = "yes"
275         attrs    = [
276                 dict(
277                         name = "default_proj",
278                         type = "long",
279                         init = "0"
280                 ),
281                 dict(
282                         name = "jmp_pred",
283                         type = "cond_jmp_predicate",
284                         init = "COND_JMP_PRED_NONE"
285                 )
286         ]
287         attr_struct = "cond_attr"
288
289 class Confirm(Op):
290         ins      = [ "value", "bound" ]
291         mode     = "get_irn_mode(irn_value)"
292         flags    = [ "highlevel" ]
293         pinned   = "yes"
294         attrs    = [
295                 dict(
296                         name = "cmp",
297                         type = "pn_Cmp"
298                 ),
299         ]
300         attr_struct = "confirm_attr"
301
302 class Const(Op):
303         mode       = ""
304         flags      = [ "constlike", "start_block" ]
305         knownBlock = True
306         pinned     = "no"
307         attrs_name = "con"
308         attrs      = [
309                 dict(
310                         type = "tarval*",
311                         name = "tarval",
312                 )
313         ]
314         attr_struct = "const_attr"
315
316 class Conv(Unop):
317         flags = []
318         attrs = [
319                 dict(
320                         name = "strict",
321                         type = "int",
322                         init = "0",
323                         special = dict(
324                                 prefix = "strict",
325                                 init = "1"
326                         )
327                 )
328         ]
329         attr_struct = "conv_attr"
330
331 class CopyB(Op):
332         ins   = [ "mem", "dst", "src" ]
333         outs  = [ "M", "X_regular", "X_except" ]
334         flags = [ "fragile", "highlevel", "uses_memory" ]
335         attrs = [
336                 dict(
337                         name = "type",
338                         type = "ir_type*"
339                 )
340         ]
341         attr_struct = "copyb_attr"
342         pinned      = "memory"
343         pinned_init = "op_pin_state_pinned"
344         d_post = '''
345         firm_alloc_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
346         '''
347
348 class Div(Op):
349         ins   = [ "mem", "left", "right" ]
350         outs  = [ "M", "X_regular", "X_except", "res" ]
351         flags = [ "fragile", "uses_memory" ]
352         attrs_name = "divmod"
353         attrs = [
354                 dict(
355                         type = "ir_mode*",
356                         name = "resmode"
357                 ),
358                 dict(
359                         name = "no_remainder",
360                         type = "int",
361                         init = "0",
362                         special = dict(
363                                 suffix = "RL",
364                                 init = "1"
365                         )
366                 )
367         ]
368         attr_struct = "divmod_attr"
369         pinned      = "exception"
370         op_index    = 1
371         arity_override = "oparity_binary"
372         d_post = '''
373         firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
374         '''
375
376 class DivMod(Op):
377         ins   = [ "mem", "left", "right" ]
378         outs  = [ "M", "X_regular", "X_except", "res_div", "res_mod" ]
379         flags = [ "fragile", "uses_memory" ]
380         attrs_name = "divmod"
381         attrs = [
382                 dict(
383                         type = "ir_mode*",
384                         name = "resmode"
385                 ),
386         ]
387         attr_struct = "divmod_attr"
388         pinned      = "exception"
389         op_index    = 1
390         arity_override = "oparity_binary"
391         d_post = '''
392         firm_alloc_frag_arr(res, op_DivMod, &res->attr.except.frag_arr);
393         '''
394
395 class Dummy(Op):
396         ins   = []
397         flags = [ "cfopcode", "fragile", "start_block", "constlike",
398                   "dump_noblock" ]
399         knownBlock = True
400         pinned     = "yes"
401         block      = "get_irg_start_block(irg)"
402
403 class End(Op):
404         mode       = "mode_X"
405         pinned     = "yes"
406         arity      = "dynamic"
407         flags      = [ "cfopcode" ]
408         singleton  = True
409
410 class EndExcept(Op):
411         mode      = "mode_X"
412         pinned    = "yes"
413         arity     = "dynamic"
414         flags     = [ "cfopcode", "ip_cfopcode" ]
415         singleton = True
416
417 class EndReg(Op):
418         mode      = "mode_X"
419         pinned    = "yes"
420         arity     = "dynamic"
421         flags     = [ "cfopcode", "ip_cfopcode" ]
422         singleton = True
423
424 class Eor(Binop):
425         flags    = [ "commutative" ]
426
427 class Filter(Op):
428         ins   = [ "pred" ]
429         flags = []
430         attrs = [
431                 dict(
432                         name = "proj",
433                         type = "long"
434                 )
435         ]
436         pinned      = "yes"
437         attr_struct = "filter_attr"
438         java_noconstr = True
439
440 class Free(Op):
441         ins    = [ "mem", "ptr", "size" ]
442         mode   = "mode_M"
443         flags  = [ "uses_memory" ]
444         pinned = "yes"
445         attrs  = [
446                 dict(
447                         name = "type",
448                         type = "ir_type*"
449                 ),
450                 dict(
451                         name = "where",
452                         type = "ir_where_alloc"
453                 )
454         ]
455         attr_struct = "free_attr"
456
457 class Id(Op):
458         ins    = [ "pred" ]
459         pinned = "no"
460         flags  = []
461
462 class IJmp(Op):
463         mode     = "mode_X"
464         pinned   = "yes"
465         ins      = [ "target" ]
466         flags    = [ "cfopcode", "forking", "keep" ]
467
468 class InstOf(Op):
469         ins   = [ "store", "obj" ]
470         outs  = [ "M", "X_regular", "X_except", "res" ]
471         flags = [ "highlevel" ]
472         attrs = [
473                 dict(
474                         name = "type",
475                         type = "ir_type*"
476                 )
477         ]
478         attr_struct = "io_attr"
479         pinned      = "memory"
480         pinned_init = "op_pin_state_floats"
481
482 class Jmp(Op):
483         mode     = "mode_X"
484         pinned   = "yes"
485         ins      = []
486         flags    = [ "cfopcode" ]
487
488 class Load(Op):
489         ins      = [ "mem", "ptr" ]
490         outs     = [ "M", "X_regular", "X_except", "res" ]
491         flags    = [ "fragile", "uses_memory" ]
492         pinned   = "exception"
493         pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
494         attrs    = [
495                 dict(
496                         type = "ir_mode*",
497                         name = "mode",
498                         java_name = "load_mode"
499                 ),
500         ]
501         attr_struct = "load_attr"
502         constructor_args = [
503                 dict(
504                         type = "ir_cons_flags",
505                         name = "flags",
506                 ),
507         ]
508         d_post = '''
509         firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
510         '''
511
512 class Minus(Unop):
513         flags = []
514
515 class Mod(Op):
516         ins   = [ "mem", "left", "right" ]
517         outs  = [ "M", "X_regular", "X_except", "res" ]
518         flags = [ "fragile", "uses_memory" ]
519         attrs_name = "divmod"
520         attrs = [
521                 dict(
522                         type = "ir_mode*",
523                         name = "resmode"
524                 ),
525         ]
526         attr_struct = "divmod_attr"
527         pinned      = "exception"
528         op_index    = 1
529         arity_override = "oparity_binary"
530         d_post = '''
531         firm_alloc_frag_arr(res, op_Mod, &res->attr.except.frag_arr);
532         '''
533
534 class Mul(Binop):
535         flags = [ "commutative" ]
536
537 class Mulh(Binop):
538         flags = [ "commutative" ]
539
540 class Mux(Op):
541         ins    = [ "sel", "false", "true" ]
542         flags  = []
543         pinned = "no"
544
545 class NoMem(Op):
546         mode       = "mode_M"
547         flags      = [ "dump_noblock", "dump_noinput" ]
548         pinned     = "yes"
549         knownBlock = True
550         singleton  = True
551
552 class Not(Unop):
553         flags = []
554
555 class Or(Binop):
556         flags = [ "commutative" ]
557
558 class Phi(Op):
559         pinned      = "yes"
560         arity       = "variable"
561         flags       = []
562         attr_struct = "phi_attr"
563         custom_is   = True
564         java_noconstr = True
565         init = '''
566         /* Memory Phis in endless loops must be kept alive.
567            As we can't distinguish these easily we keep all of them alive. */
568         if (is_Phi(res) && mode == mode_M)
569                 add_End_keepalive(get_irg_end(irg), res);
570         '''
571
572 class Pin(Op):
573         ins      = [ "op" ]
574         mode     = "get_irn_mode(irn_op)"
575         flags    = [ "highlevel" ]
576         pinned   = "yes"
577
578 class Proj(Op):
579         ins      = [ "pred" ]
580         flags    = []
581         pinned   = "no"
582         attrs    = [
583                 dict(
584                         type = "long",
585                         name = "proj",
586                         initname = ""
587                 )
588         ]
589         attr_struct = "long"
590         custom_is   = True
591
592 class Quot(Op):
593         ins   = [ "mem", "left", "right" ]
594         outs  = [ "M", "X_regular", "X_except", "res" ]
595         flags = [ "fragile", "uses_memory" ]
596         attrs_name = "divmod"
597         attrs = [
598                 dict(
599                         type = "ir_mode*",
600                         name = "resmode"
601                 ),
602         ]
603         attr_struct = "divmod_attr"
604         pinned      = "exception"
605         op_index    = 1
606         arity_override = "oparity_binary"
607         d_post = '''
608         firm_alloc_frag_arr(res, op_Quot, &res->attr.except.frag_arr);
609         '''
610
611 class Raise(Op):
612         ins    = [ "mem", "exo_ptr" ]
613         outs   = [ "M", "X" ]
614         flags  = [ "highlevel", "cfopcode" ]
615         pinned = "yes"
616
617 class Return(Op):
618         ins      = [ "mem" ]
619         arity    = "variable"
620         mode     = "mode_X"
621         flags    = [ "cfopcode" ]
622         pinned   = "yes"
623
624 class Rotl(Binop):
625         flags    = []
626
627 class Sel(Op):
628         ins    = [ "mem", "ptr" ]
629         arity  = "variable"
630         flags  = []
631         mode   = "is_Method_type(get_entity_type(entity)) ? mode_P_code : mode_P_data"
632         pinned = "no"
633         attrs  = [
634                 dict(
635                         type = "ir_entity*",
636                         name = "entity"
637                 )
638         ]
639         attr_struct = "sel_attr"
640
641 class Shl(Binop):
642         flags = []
643
644 class Shr(Binop):
645         flags = []
646
647 class Shrs(Binop):
648         flags = []
649
650 class Start(Op):
651         mode       = "mode_T"
652         pinned     = "yes"
653         flags      = [ "cfopcode" ]
654         singleton  = True
655
656 class Store(Op):
657         ins      = [ "mem", "ptr", "value" ]
658         outs     = [ "M", "X_regular", "X_except" ]
659         flags    = [ "fragile", "uses_memory" ]
660         pinned   = "exception"
661         attr_struct = "store_attr"
662         pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
663         constructor_args = [
664                 dict(
665                         type = "ir_cons_flags",
666                         name = "flags",
667                 ),
668         ]
669         d_post = '''
670         firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
671         '''
672
673 class Sub(Binop):
674         flags = []
675
676 class SymConst(Op):
677         mode       = "mode_P"
678         flags      = [ "constlike", "start_block" ]
679         knownBlock = True
680         pinned     = "no"
681         attrs      = [
682                 dict(
683                         type = "ir_entity*",
684                         name = "entity"
685                 )
686         ]
687         attr_struct = "symconst_attr"
688         java_noconstr = True
689
690 class Sync(Op):
691         mode     = "mode_M"
692         flags    = []
693         pinned   = "no"
694         optimize = False
695         arity    = "dynamic"
696
697 class Tuple(Op):
698         arity  = "variable"
699         mode   = "mode_T"
700         pinned = "no"
701         flags  = [ "labeled" ]
702         java_noconstr = True
703
704 class Unknown(Op):
705         knownBlock = True
706         pinned     = "yes"
707         block      = "get_irg_start_block(irg)"
708         flags      = [ "cfopcode", "fragile", "start_block", "constlike",
709                        "dump_noblock" ]
710
711 # Prepare node list
712
713 def getOpList(namespace):
714         nodes = []
715         for t in namespace.values():
716                 if type(t) != type:
717                         continue
718
719                 if issubclass(t, Op):
720                         setnodedefaults(t)
721                         nodes.append(t)
722         return nodes
723
724 nodes = getOpList(globals())
725 nodes = sorted(nodes, lambda x,y: cmp(x.name, y.name))