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