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