ir_spec.py 14.8 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
48
49
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Alloc, &res->attr.alloc.exc.frag_arr);
	#endif
	'''
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

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"
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
	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*",
		),
94
95
96
97
98
99
100
101
102
	]
	java_noconstr = True

class Bad(Op):
	mode       = "mode_Bad"
	flags      = [ "cfopcode", "fragile", "start_block", "dump_noblock" ]
	pinned     = "yes"
	knownBlock = True
	singleton  = True
103
104
	init = '''
	res->attr.irg.irg = irg;
105
106
107
108
109
110
111
112
113
114
115
116
	'''

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
117
118
119
120
121
122
123

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

	res->attr.block.is_dead     = 0;
	res->attr.block.is_mb_head  = 1;
124
	res->attr.block.irg.irg     = irg;
Moritz Kroll's avatar
Moritz Kroll committed
125
126
127
128
129
	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;
130
	res->attr.block.entity      = NULL;
Moritz Kroll's avatar
Moritz Kroll committed
131
132
133

	set_Block_matured(res, 1);
	set_Block_block_visited(res, 0);
134
	'''
Moritz Kroll's avatar
Moritz Kroll committed
135

136
137
138
	d_pre = '''
	int i;
	int has_unknown = 0;
139
	'''
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

	d_post = '''
	/* Create and initialize array for Phi-node construction. */
	if (get_irg_phase_state(current_ir_graph) == phase_building) {
		res->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,
		                                      current_ir_graph->n_loc);
		memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
	}

	for (i = arity - 1; i >= 0; i--)
		if (is_Unknown(in[i])) {
			has_unknown = 1;
			break;
		}

	if (!has_unknown) res = optimize_node(res);

Moritz Kroll's avatar
Moritz Kroll committed
157
158
	current_ir_graph->current_block = res;

159
	IRN_VRFY_IRG(res, current_ir_graph);
160
	'''
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
	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);
182
183
184
185
186
	}

	public boolean isBad() {
		return binding.is_Bad(ptr) != 0;
	}
187
188
189
190
191
192
193
194
195
196
197
198
	'''

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"
199
200
201
202
203
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Bound, &res->attr.bound.exc.frag_arr);
	#endif
	'''
204
205
206
207
208
209
210
211
212
213
214

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

class Builtin(Op):
	ins      = [ "mem" ]
	arity    = "variable"
	outs     = [ "M_regular", "X_regular", "X_except", "T_result", "M_except", "P_value_res_base" ]
	flags    = [ "uses_memory" ]
215
	attrs    = [
216
217
218
219
		dict(
			type = "ir_builtin_kind",
			name = "kind"
		),
220
		dict(
221
222
223
			type = "ir_type*",
			name = "type"
		)
224
225
226
227
	]
	pinned      = "memory"
	pinned_init = "op_pin_state_pinned"
	attr_struct = "builtin_attr"
228
	init   = '''
229
230
231
	assert((get_unknown_type() == type) || is_Method_type(type));
	'''

232
233
234
235
236
class Call(Op):
	ins      = [ "mem", "ptr" ]
	arity    = "variable"
	outs     = [ "M_regular", "X_regular", "X_except", "T_result", "M_except", "P_value_res_base" ]
	flags    = [ "fragile", "uses_memory" ]
237
	attrs    = [
238
239
240
		dict(
			type = "ir_type*",
			name = "type"
241
		)
242
243
244
245
	]
	attr_struct = "call_attr"
	pinned      = "memory"
	pinned_init = "op_pin_state_pinned"
246
247
	init = '''
	assert((get_unknown_type() == type) || is_Method_type(type));
248
	'''
249
250
251
252
253
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Call, &res->attr.call.exc.frag_arr);
	#endif
	'''
254

255
256
257
258
259
class CallBegin(Op):
	ins   = [ "ptr" ]
	outs  = [ "" ] # TODO
	flags         = [ "cfopcode", "ip_cfopcode" ]
	pinned        = "yes"
260
	# TODO: attribute with call...
261
	attr_struct   = "callbegin_attr"
262
263
264
265
266
	attrs         = [
		dict(
			type = "ir_node*",
			name = "call"
		)
267
268
269
270
271
272
273
274
275
276
277
	]
	java_noconstr = True

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

class Cast(Op):
	ins      = [ "op" ]
	mode     = "get_irn_mode(irn_op)"
	flags    = [ "highlevel" ]
	pinned   = "no"
278
279
280
281
282
	attrs    = [
		dict(
			type = "ir_type*",
			name = "type"
		)
283
284
	]
	attr_struct = "cast_attr"
285
	init     = "assert(is_atomic_type(type));"
286
287
288
289
290
291
292
293
294
295

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"
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
	attrs    = [
		dict(
			name = "kind",
			type = "cond_kind",
			init = "dense"
		),
		dict(
			name = "default_proj",
			type = "long",
			init = "0"
		),
		dict(
			name = "jmp_pred",
			type = "cond_jmp_predicate",
			init = "COND_JMP_PRED_NONE"
		)
312
	]
313
	attr_struct = "cond_attr"
314

315
316
317
318
319
class Confirm(Op):
	ins      = [ "value", "bound" ]
	mode     = "get_irn_mode(irn_value)"
	flags    = [ "highlevel" ]
	pinned   = "yes"
320
321
322
323
324
	attrs    = [
		dict(
			name = "cmp",
			type = "pn_Cmp"
		),
325
326
327
328
329
330
331
332
333
	]
	attr_struct = "confirm_attr"

class Const(Op):
	mode       = ""
	flags      = [ "constlike", "start_block" ]
	knownBlock = True
	pinned     = "no"
	attrs_name = "con"
334
335
336
337
338
	attrs      = [
		dict(
			type = "tarval*",
			name = "tarval",
		)
339
340
	]
	attr_struct = "const_attr"
341

342
343
class Conv(Unop):
	flags = []
344
345
346
347
348
349
350
351
352
353
	attrs = [
		dict(
			name = "strict",
			type = "int",
			init = "0",
			special = dict(
				prefix = "strict",
				init = "1"
			)
		)
354
355
356
357
358
359
360
	]
	attr_struct = "conv_attr"

class CopyB(Op):
	ins   = [ "mem", "dst", "src" ]
	outs  = [ "M", "X_regular", "X_except" ]
	flags = [ "fragile", "highlevel", "uses_memory" ]
361
362
	attrs = [
		dict(
363
364
			name = "type",
			type = "ir_type*"
365
		)
366
367
368
369
	]
	attr_struct = "copyb_attr"
	pinned      = "memory"
	pinned_init = "op_pin_state_pinned"
370
371
372
373
374
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_CopyB, &res->attr.copyb.exc.frag_arr);
	#endif
	'''
375

376
377
378
379
380
class Div(Op):
	ins   = [ "mem", "left", "right" ]
	outs  = [ "M", "X_regular", "X_except", "res" ]
	flags = [ "fragile", "uses_memory" ]
	attrs_name = "divmod"
381
382
383
384
385
	attrs = [
		dict(
			type = "ir_mode*",
			name = "resmode"
		),
Moritz Kroll's avatar
Moritz Kroll committed
386
387
388
389
390
391
392
393
		dict(
			name = "no_remainder",
			type = "int",
			init = "0",
			special = dict(
				suffix = "RL",
				init = "1"
			)
394
		)
395
396
397
398
399
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
400
401
402
403
404
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);
	#endif
	'''
405

406
407
408
409
410
class DivMod(Op):
	ins   = [ "mem", "left", "right" ]
	outs  = [ "M", "X_regular", "X_except", "res_div", "res_mod" ]
	flags = [ "fragile", "uses_memory" ]
	attrs_name = "divmod"
411
412
413
414
415
	attrs = [
		dict(
			type = "ir_mode*",
			name = "resmode"
		),
416
417
418
419
420
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
421
422
423
424
425
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_DivMod, &res->attr.except.frag_arr);
	#endif
	'''
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446

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" ]
447
448
	singleton = True

449
450
451
452
453
class EndReg(Op):
	mode      = "mode_X"
	pinned    = "yes"
	arity     = "dynamic"
	flags     = [ "cfopcode", "ip_cfopcode" ]
454
	singleton = True
455

456
457
class Eor(Binop):
	flags    = [ "commutative" ]
458

459
460
461
class Filter(Op):
	ins   = [ "pred" ]
	flags = []
462
463
464
465
466
	attrs = [
		dict(
			name = "proj",
			type = "long"
		)
467
468
469
	]
	pinned      = "yes"
	attr_struct = "filter_attr"
470
	java_noconstr = True
471

472
473
474
475
476
class Free(Op):
	ins    = [ "mem", "ptr", "size" ]
	mode   = "mode_M"
	flags  = [ "uses_memory" ]
	pinned = "yes"
477
	attrs  = [
478
		dict(
479
480
			name = "type",
			type = "ir_type*"
481
482
		),
		dict(
483
484
			name = "where",
			type = "ir_where_alloc"
485
		)
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
	]
	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" ]
	outs  = [ "M", "X_regular", "X_except", "res", "M_except" ]
	flags = [ "highlevel" ]
504
505
506
507
508
	attrs = [
		dict(
			name = "type",
			type = "ir_type*"
		)
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
	]
	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"
526
527
528
529
530
531
	attrs    = [
		dict(
			type = "ir_mode*",
			name = "mode",
			java_name = "load_mode"
		),
532
533
	]
	attr_struct = "load_attr"
534
535
	constructor_args = [
		dict(
Moritz Kroll's avatar
Moritz Kroll committed
536
			type = "ir_cons_flags",
537
538
			name = "flags",
		),
539
	]
540
541
542
543
544
	d_post = '''
#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
#endif
	'''
545
546
547
548
549
550
551
552
553

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"
554
	attrs = [
555
		dict(
556
557
			type = "ir_mode*",
			name = "resmode"
558
		),
559
560
561
562
563
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
564
565
566
567
568
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Mod, &res->attr.except.frag_arr);
	#endif
	'''
Matthias Braun's avatar
Matthias Braun committed
569

570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
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
601
602
603
604
605
606
	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);
	'''
607
608
609
610
611
612
613
614
615
616
617

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

class Proj(Op):
	ins      = [ "pred" ]
	flags    = []
	pinned   = "no"
618
619
620
	attrs    = [
		dict(
			type = "long",
621
622
			name = "proj",
			initname = ""
623
		)
624
625
626
627
628
629
630
631
632
	]
	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"
633
	attrs = [
634
		dict(
635
636
637
			type = "ir_mode*",
			name = "resmode"
		),
638
639
640
641
642
	]
	attr_struct = "divmod_attr"
	pinned      = "exception"
	op_index    = 1
	arity_override = "oparity_binary"
643
644
645
646
647
	d_post = '''
	#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Quot, &res->attr.except.frag_arr);
	#endif
	'''
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670

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"
671
	attrs  = [
672
		dict(
673
674
675
			type = "ir_entity*",
			name = "entity"
		)
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
	]
	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"
701
	constructor_args = [
702
		dict(
703
704
			type = "ir_cons_flags",
			name = "flags",
705
		),
706
	]
707
708
709
710
711
	d_post = '''
#if PRECISE_EXC_CONTEXT
	firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
#endif
	'''
712
713
714
715
716
717
718
719
720

class Sub(Binop):
	flags = []

class SymConst(Op):
	mode       = "mode_P"
	flags      = [ "constlike", "start_block" ]
	knownBlock = True
	pinned     = "no"
721
	attrs      = [
722
		dict(
723
724
			type = "ir_entity*",
			name = "entity"
725
		)
726
727
728
729
730
731
732
733
734
	]
	attr_struct = "symconst_attr"
	java_noconstr = True

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

737
738
739
740
741
class Tuple(Op):
	arity  = "variable"
	mode   = "mode_T"
	pinned = "no"
	flags  = [ "labeled" ]
742
	java_noconstr = True
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

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))