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