ir_spec.py 14.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from spec_util import abstract, setnodedefaults

class Op(object):
	"Base class for firm nodes"
abstract(Op)

class Unop(Op):
	"Unary nodes have exactly 1 input"
	name     = "unop"
	ins      = [ "op" ]
	op_index = 0
	pinned   = "no"
abstract(Unop)

class Binop(Op):
	"Binary nodes have exactly 2 inputs"
	name     = "binop"
	ins      = [ "left", "right" ]
	op_index = 0
	pinned   = "no"
abstract(Binop)

class Abs(Unop):
	flags = []

class Add(Binop):
	flags = ["commutative"]

class Alloc(Op):
	ins   = [ "mem", "size" ]
	outs  = [ "M", "X_regular", "X_except", "res" ]
	flags = [ "fragile", "uses_memory" ]
33
34
35
36
37
38
39
40
41
	attrs = [
		dict(
			name = "type",
			type = "ir_type*"
		),
		dict(
			name = "where",
			type = "ir_where_alloc"
		)
42
43
44
	]
	pinned      = "yes"
	attr_struct = "alloc_attr"
45
46
47
	d_post = '''
	firm_alloc_frag_arr(res, op_Alloc, &res->attr.alloc.exc.frag_arr);
	'''
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

class Anchor(Op):
	mode        = "mode_ANY"
	arity       = "variable"
	flags       = [ "dump_noblock" ]
	pinned      = "yes"
	knownBlock  = True
	singleton   = True

class And(Binop):
	flags    = [ "commutative" ]

class ASM(Op):
	mode          = "mode_T"
	arity         = "variable"
	flags         = [ "keep", "uses_memory" ]
	attr_struct   = "asm_attr"
	pinned        = "memory"
	pinned_init   = "op_pin_state_pinned"
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	attrs = [
		dict(
			name = "input_constraints",
			type = "ir_asm_constraint*",
		),
		dict(
			name = "n_output_constraints",
			type = "int",
		),
		dict(
			name = "output_constraints",
			type = "ir_asm_constraint*",
		),
		dict(
			name = "n_clobbers",
			type = "int",
		),
		dict(
			name = "clobbers",
			type = "ident**",
		),
		dict(
			name = "text",
			type = "ident*",
		),
92
93
94
95
	]
	java_noconstr = True

class Bad(Op):
Matthias Braun's avatar
Matthias Braun committed
96
97
98
99
100
101
	mode        = "mode_Bad"
	flags       = [ "cfopcode", "fragile", "start_block", "dump_noblock" ]
	pinned      = "yes"
	knownBlock  = True
	singleton   = True
	attr_struct = "irg_attr"
102
103
	init = '''
	res->attr.irg.irg = irg;
104
105
106
107
108
109
110
111
112
113
114
115
	'''

class Block(Op):
	mode        = "mode_BB"
	knownBlock  = True
	block       = "NULL"
	pinned      = "yes"
	optimize    = False
	arity       = "variable"
	flags       = [ "labeled" ]
	attr_struct = "block_attr"
	java_noconstr = True
Moritz Kroll's avatar
Moritz Kroll committed
116
117
118
119
120
121
122

	init = '''
	/* macroblock header */
	res->in[0] = res;

	res->attr.block.is_dead     = 0;
	res->attr.block.is_mb_head  = 1;
123
	res->attr.block.irg.irg     = irg;
Moritz Kroll's avatar
Moritz Kroll committed
124
125
126
127
128
	res->attr.block.backedge    = new_backedge_arr(irg->obst, arity);
	res->attr.block.in_cg       = NULL;
	res->attr.block.cg_backedge = NULL;
	res->attr.block.extblk      = NULL;
	res->attr.block.mb_depth    = 0;
129
	res->attr.block.entity      = NULL;
Moritz Kroll's avatar
Moritz Kroll committed
130
131
132

	set_Block_matured(res, 1);
	set_Block_block_visited(res, 0);
133
134

	/* Create and initialize array for Phi-node construction. */
135
136
137
	if (get_irg_phase_state(irg) == phase_building) {
		res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
		memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
138
	}
139
	'''
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	java_add   = '''
	public void addPred(Node node) {
		binding_cons.add_immBlock_pred(ptr, node.ptr);
	}

	public void mature() {
		binding_cons.mature_immBlock(ptr);
	}

	@Override
	public Block getBlock() {
		return null;
	}

	public boolean blockVisited() {
		return 0 != binding.Block_block_visited(ptr);
	}

	public void markBlockVisited() {
		binding.mark_Block_block_visited(ptr);
161
162
163
164
165
	}

	public boolean isBad() {
		return binding.is_Bad(ptr) != 0;
	}
166
167
168
169
170
171
172
173
174
175
176
177
	'''

class Borrow(Binop):
	flags = []

class Bound(Op):
	ins    = [ "mem", "index", "lower", "upper" ]
 	outs   = [ "M", "X_regular", "X_except", "res" ]
 	flags  = [ "fragile", "highlevel" ]
	pinned = "exception"
	pinned_init = "op_pin_state_pinned"
	attr_struct = "bound_attr"
178
179
180
	d_post = '''
	firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
	'''
181
182
183
184
185
186
187
188
189

class Break(Op):
	mode   = "mode_X"
	flags  = [ "cfopcode" ]
	pinned = "yes"

class Builtin(Op):
	ins      = [ "mem" ]
	arity    = "variable"
190
	outs     = [ "M", "X_regular", "X_except", "T_result", "P_value_res_base" ]
191
	flags    = [ "uses_memory" ]
192
	attrs    = [
193
194
195
196
		dict(
			type = "ir_builtin_kind",
			name = "kind"
		),
197
		dict(
198
199
200
			type = "ir_type*",
			name = "type"
		)
201
202
203
204
	]
	pinned      = "memory"
	pinned_init = "op_pin_state_pinned"
	attr_struct = "builtin_attr"
205
	init   = '''
206
207
208
	assert((get_unknown_type() == type) || is_Method_type(type));
	'''

209
210
211
class Call(Op):
	ins      = [ "mem", "ptr" ]
	arity    = "variable"
212
	outs     = [ "M", "X_regular", "X_except", "T_result", "P_value_res_base" ]
213
	flags    = [ "fragile", "uses_memory" ]
214
	attrs    = [
215
216
217
		dict(
			type = "ir_type*",
			name = "type"
218
219
220
221
222
223
		),
		dict(
			type = "unsigned",
			name = "tail_call",
			# the tail call attribute can only be set by analysis
			init = "0"
224
		)
225
226
227
228
	]
	attr_struct = "call_attr"
	pinned      = "memory"
	pinned_init = "op_pin_state_pinned"
229
230
	init = '''
	assert((get_unknown_type() == type) || is_Method_type(type));
231
	'''
232
233
234
	d_post = '''
	firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
	'''
235

236
237
238
239
240
class CallBegin(Op):
	ins   = [ "ptr" ]
	outs  = [ "" ] # TODO
	flags         = [ "cfopcode", "ip_cfopcode" ]
	pinned        = "yes"
241
	# TODO: attribute with call...
242
	attr_struct   = "callbegin_attr"
243
244
245
246
247
	attrs         = [
		dict(
			type = "ir_node*",
			name = "call"
		)
248
249
250
251
252
253
	]
	java_noconstr = True

class Carry(Binop):
	flags = [ "commutative" ]

Michael Beck's avatar
Michael Beck committed
254
class Cast(Unop):
255
256
	mode     = "get_irn_mode(irn_op)"
	flags    = [ "highlevel" ]
257
258
259
260
261
	attrs    = [
		dict(
			type = "ir_type*",
			name = "type"
		)
262
263
	]
	attr_struct = "cast_attr"
264
	init     = "assert(is_atomic_type(type));"
265
266
267
268
269
270
271
272
273
274

class Cmp(Binop):
	outs  = [ "False", "Eq", "Lt", "Le", "Gt", "Ge", "Lg", "Leg", "Uo", "Ue", "Ul", "Ule", "Ug", "Uge", "Ne", "True" ]
	flags = []

class Cond(Op):
	ins      = [ "selector" ]
	outs     = [ "false", "true" ]
	flags    = [ "cfopcode", "forking" ]
	pinned   = "yes"
275
276
277
278
279
280
281
282
283
284
285
	attrs    = [
		dict(
			name = "default_proj",
			type = "long",
			init = "0"
		),
		dict(
			name = "jmp_pred",
			type = "cond_jmp_predicate",
			init = "COND_JMP_PRED_NONE"
		)
286
	]
287
	attr_struct = "cond_attr"
288

289
290
291
292
293
class Confirm(Op):
	ins      = [ "value", "bound" ]
	mode     = "get_irn_mode(irn_value)"
	flags    = [ "highlevel" ]
	pinned   = "yes"
294
295
296
297
298
	attrs    = [
		dict(
			name = "cmp",
			type = "pn_Cmp"
		),
299
300
301
302
303
304
305
306
307
	]
	attr_struct = "confirm_attr"

class Const(Op):
	mode       = ""
	flags      = [ "constlike", "start_block" ]
	knownBlock = True
	pinned     = "no"
	attrs_name = "con"
308
309
310
311
312
	attrs      = [
		dict(
			type = "tarval*",
			name = "tarval",
		)
313
314
	]
	attr_struct = "const_attr"
315

316
317
class Conv(Unop):
	flags = []
318
319
320
321
322
323
324
325
326
327
	attrs = [
		dict(
			name = "strict",
			type = "int",
			init = "0",
			special = dict(
				prefix = "strict",
				init = "1"
			)
		)
328
329
330
331
332
333
334
	]
	attr_struct = "conv_attr"

class CopyB(Op):
	ins   = [ "mem", "dst", "src" ]
	outs  = [ "M", "X_regular", "X_except" ]
	flags = [ "fragile", "highlevel", "uses_memory" ]
335
336
	attrs = [
		dict(
337
338
			name = "type",
			type = "ir_type*"
339
		)
340
341
342
343
	]
	attr_struct = "copyb_attr"
	pinned      = "memory"
	pinned_init = "op_pin_state_pinned"
344
345
346
	d_post = '''
	firm_alloc_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
	'''
347

348
349
350
351
352
class Div(Op):
	ins   = [ "mem", "left", "right" ]
	outs  = [ "M", "X_regular", "X_except", "res" ]
	flags = [ "fragile", "uses_memory" ]
	attrs_name = "divmod"
353
354
355
356
357
	attrs = [
		dict(
			type = "ir_mode*",
			name = "resmode"
		),
Moritz Kroll's avatar
Moritz Kroll committed
358
359
360
361
362
363
364
365
		dict(
			name = "no_remainder",
			type = "int",
			init = "0",
			special = dict(
				suffix = "RL",
				init = "1"
			)
366
		)
367
368
369
370
371
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
372
373
374
	d_post = '''
	firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
	'''
375

376
377
378
379
380
class DivMod(Op):
	ins   = [ "mem", "left", "right" ]
	outs  = [ "M", "X_regular", "X_except", "res_div", "res_mod" ]
	flags = [ "fragile", "uses_memory" ]
	attrs_name = "divmod"
381
382
383
384
385
	attrs = [
		dict(
			type = "ir_mode*",
			name = "resmode"
		),
386
387
388
389
390
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
391
392
393
	d_post = '''
	firm_alloc_frag_arr(res, op_DivMod, &res->attr.except.frag_arr);
	'''
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

class Dummy(Op):
	ins   = []
	flags = [ "cfopcode", "fragile", "start_block", "constlike",
	          "dump_noblock" ]
	knownBlock = True
	pinned     = "yes"
	block      = "get_irg_start_block(irg)"

class End(Op):
	mode       = "mode_X"
	pinned     = "yes"
	arity      = "dynamic"
	flags      = [ "cfopcode" ]
	singleton  = True

class EndExcept(Op):
	mode      = "mode_X"
	pinned    = "yes"
	arity     = "dynamic"
	flags     = [ "cfopcode", "ip_cfopcode" ]
415
416
	singleton = True

417
418
419
420
421
class EndReg(Op):
	mode      = "mode_X"
	pinned    = "yes"
	arity     = "dynamic"
	flags     = [ "cfopcode", "ip_cfopcode" ]
422
	singleton = True
423

424
425
class Eor(Binop):
	flags    = [ "commutative" ]
426

427
428
429
class Filter(Op):
	ins   = [ "pred" ]
	flags = []
430
431
432
433
434
	attrs = [
		dict(
			name = "proj",
			type = "long"
		)
435
436
437
	]
	pinned      = "yes"
	attr_struct = "filter_attr"
438
	java_noconstr = True
439

440
441
442
443
444
class Free(Op):
	ins    = [ "mem", "ptr", "size" ]
	mode   = "mode_M"
	flags  = [ "uses_memory" ]
	pinned = "yes"
445
	attrs  = [
446
		dict(
447
448
			name = "type",
			type = "ir_type*"
449
450
		),
		dict(
451
452
			name = "where",
			type = "ir_where_alloc"
453
		)
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
	]
	attr_struct = "free_attr"

class Id(Op):
	ins    = [ "pred" ]
	pinned = "no"
	flags  = []

class IJmp(Op):
	mode     = "mode_X"
	pinned   = "yes"
	ins      = [ "target" ]
	flags    = [ "cfopcode", "forking", "keep" ]

class InstOf(Op):
	ins   = [ "store", "obj" ]
470
	outs  = [ "M", "X_regular", "X_except", "res" ]
471
	flags = [ "highlevel" ]
472
473
474
475
476
	attrs = [
		dict(
			name = "type",
			type = "ir_type*"
		)
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
	]
	attr_struct = "io_attr"
	pinned      = "memory"
	pinned_init = "op_pin_state_floats"

class Jmp(Op):
	mode     = "mode_X"
	pinned   = "yes"
	ins      = []
	flags    = [ "cfopcode" ]

class Load(Op):
	ins      = [ "mem", "ptr" ]
	outs     = [ "M", "X_regular", "X_except", "res" ]
	flags    = [ "fragile", "uses_memory" ]
	pinned   = "exception"
	pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
494
495
496
497
498
499
	attrs    = [
		dict(
			type = "ir_mode*",
			name = "mode",
			java_name = "load_mode"
		),
500
501
	]
	attr_struct = "load_attr"
502
503
	constructor_args = [
		dict(
Moritz Kroll's avatar
Moritz Kroll committed
504
			type = "ir_cons_flags",
505
506
			name = "flags",
		),
507
	]
508
509
510
	d_post = '''
	firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
	'''
511
512
513
514
515
516
517
518
519

class Minus(Unop):
	flags = []

class Mod(Op):
	ins   = [ "mem", "left", "right" ]
	outs  = [ "M", "X_regular", "X_except", "res" ]
	flags = [ "fragile", "uses_memory" ]
	attrs_name = "divmod"
520
	attrs = [
521
		dict(
522
523
			type = "ir_mode*",
			name = "resmode"
524
		),
525
526
527
528
529
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
530
531
532
	d_post = '''
	firm_alloc_frag_arr(res, op_Mod, &res->attr.except.frag_arr);
	'''
Matthias Braun's avatar
Matthias Braun committed
533

534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
class Mul(Binop):
	flags = [ "commutative" ]

class Mulh(Binop):
	flags = [ "commutative" ]

class Mux(Op):
	ins    = [ "sel", "false", "true" ]
	flags  = []
	pinned = "no"

class NoMem(Op):
	mode       = "mode_M"
	flags      = [ "dump_noblock", "dump_noinput" ]
	pinned     = "yes"
	knownBlock = True
	singleton  = True

class Not(Unop):
	flags = []

class Or(Binop):
	flags = [ "commutative" ]

class Phi(Op):
	pinned      = "yes"
	arity       = "variable"
	flags       = []
	attr_struct = "phi_attr"
	custom_is   = True
	java_noconstr = True
Matthias Braun's avatar
Matthias Braun committed
565
566
567
568
569
570
	init = '''
	/* Memory Phis in endless loops must be kept alive.
	   As we can't distinguish these easily we keep all of them alive. */
   	if (is_Phi(res) && mode == mode_M)
		add_End_keepalive(get_irg_end(irg), res);
	'''
571
572
573
574
575
576
577
578
579
580
581

class Pin(Op):
	ins      = [ "op" ]
	mode     = "get_irn_mode(irn_op)"
	flags    = [ "highlevel" ]
	pinned   = "yes"

class Proj(Op):
	ins      = [ "pred" ]
	flags    = []
	pinned   = "no"
582
583
584
	attrs    = [
		dict(
			type = "long",
585
586
			name = "proj",
			initname = ""
587
		)
588
589
590
591
592
593
594
595
596
	]
	attr_struct = "long"
	custom_is   = True

class Quot(Op):
	ins   = [ "mem", "left", "right" ]
	outs  = [ "M", "X_regular", "X_except", "res" ]
	flags = [ "fragile", "uses_memory" ]
	attrs_name = "divmod"
597
	attrs = [
598
		dict(
599
600
601
			type = "ir_mode*",
			name = "resmode"
		),
602
603
604
605
606
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
607
608
609
	d_post = '''
	firm_alloc_frag_arr(res, op_Quot, &res->attr.except.frag_arr);
	'''
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

class Raise(Op):
	ins    = [ "mem", "exo_ptr" ]
	outs   = [ "M", "X" ]
	flags  = [ "highlevel", "cfopcode" ]
	pinned = "yes"

class Return(Op):
	ins      = [ "mem" ]
	arity    = "variable"
	mode     = "mode_X"
	flags    = [ "cfopcode" ]
	pinned   = "yes"

class Rotl(Binop):
	flags    = []

class Sel(Op):
	ins    = [ "mem", "ptr" ]
	arity  = "variable"
	flags  = []
	mode   = "is_Method_type(get_entity_type(entity)) ? mode_P_code : mode_P_data"
	pinned = "no"
633
	attrs  = [
634
		dict(
635
636
637
			type = "ir_entity*",
			name = "entity"
		)
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
	]
	attr_struct = "sel_attr"

class Shl(Binop):
	flags = []

class Shr(Binop):
	flags = []

class Shrs(Binop):
	flags = []

class Start(Op):
	mode       = "mode_T"
	pinned     = "yes"
	flags      = [ "cfopcode" ]
	singleton  = True

class Store(Op):
	ins      = [ "mem", "ptr", "value" ]
	outs     = [ "M", "X_regular", "X_except" ]
	flags    = [ "fragile", "uses_memory" ]
	pinned   = "exception"
	attr_struct = "store_attr"
	pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
663
	constructor_args = [
664
		dict(
665
666
			type = "ir_cons_flags",
			name = "flags",
667
		),
668
	]
669
670
671
	d_post = '''
	firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
	'''
672
673
674
675
676
677
678
679
680

class Sub(Binop):
	flags = []

class SymConst(Op):
	mode       = "mode_P"
	flags      = [ "constlike", "start_block" ]
	knownBlock = True
	pinned     = "no"
681
	attrs      = [
682
		dict(
683
684
			type = "ir_entity*",
			name = "entity"
685
		)
686
687
688
689
690
691
692
693
694
	]
	attr_struct = "symconst_attr"
	java_noconstr = True

class Sync(Op):
	mode     = "mode_M"
	flags    = []
	pinned   = "no"
	optimize = False
695
	arity    = "dynamic"
696

697
698
699
700
701
class Tuple(Op):
	arity  = "variable"
	mode   = "mode_T"
	pinned = "no"
	flags  = [ "labeled" ]
702
	java_noconstr = True
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

class Unknown(Op):
	knownBlock = True
	pinned     = "yes"
	block      = "get_irg_start_block(irg)"
	flags      = [ "cfopcode", "fragile", "start_block", "constlike",
	               "dump_noblock" ]

# Prepare node list

def getOpList(namespace):
	nodes = []
	for t in namespace.values():
		if type(t) != type:
			continue

		if issubclass(t, Op):
			setnodedefaults(t)
			nodes.append(t)
	return nodes

nodes = getOpList(globals())
nodes = sorted(nodes, lambda x,y: cmp(x.name, y.name))