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