ir_spec.py 26.4 KB
Newer Older
1
2
3
# This file is part of libFirm.
# Copyright (C) 2012 Karlsruhe Institute of Technology.
#
Matthias Braun's avatar
Matthias Braun committed
4
5
6
# Firm node specifications
# The comments are in (standard python) restructured text format and are used
# to generate documentation.
7
8
from irops import abstract, op, Attribute, prepare_nodes
from jinjautil import export
9

Matthias Braun's avatar
Matthias Braun committed
10
name = "ir"
11

12
13
14
15
16
17
18
19
20
class Node(object):
	pinned           = "no"
	flags            = []
	ins              = []
	attrs            = []
	constructor      = True
	constructor_args = []
	block            = None

Matthias Braun's avatar
Matthias Braun committed
21
22
@abstract
@op
23
class Binop(Node):
24
	"""Binary nodes have exactly 2 inputs"""
25
	name     = "binop"
26
	ins      = [
27
28
		("left",   "first operand"),
		("right", "second operand"),
29
	]
30
31
	op_index       = 0
	arity_override = "oparity_binary"
32

33
34
@abstract
@op
35
class EntConst(Node):
36
37
38
39
	"""Symbolic constant that represents an aspect of an entity"""
	name       = "entconst"
	flags      = [ "constlike", "start_block" ]
	attrs      = [
40
		Attribute("entity", type="ir_entity*", comment="entity to operate on"),
41
42
43
44
	]
	attr_struct = "entconst_attr"
	attrs_name  = "entc"

45
46
@abstract
@op
47
class TypeConst(Node):
48
49
50
51
	"""A symbolic constant that represents an aspect of a type"""
	name       = "typeconst"
	flags      = [ "constlike", "start_block" ]
	attrs      = [
52
		Attribute("type", type="ir_type*", comment="type to operate on"),
53
54
55
56
	]
	attr_struct = "typeconst_attr"
	attrs_name  = "typec"

Matthias Braun's avatar
Matthias Braun committed
57
@op
58
class Add(Binop):
59
	"""returns the sum of its operands"""
60
	flags = [ "commutative" ]
61

62
63
64
@op
class Address(EntConst):
	"""Symbolic constant that represents the address of an entity (variable or method)"""
65
	mode = "mode_P"
66

67
68
69
70
@op
class Align(TypeConst):
	"""A symbolic constant that represents the alignment of a type"""

Matthias Braun's avatar
Matthias Braun committed
71
@op
72
class Alloc(Node):
73
74
75
76
	"""Allocates a block of memory on the stack."""
	ins = [
		("mem",  "memory dependency" ),
		("size", "size of the block in bytes" ),
77
	]
78
79
80
	outs = [
		("M",   "memory result"),
		("res", "pointer to newly allocated memory"),
81
	]
82
	attrs = [
83
84
		Attribute("alignment", type="unsigned",
		          comment="alignment of the memory block (must be a power of 2)"),
85
	]
86
	flags       = [ "uses_memory", "const_memory" ]
87
	pinned      = "yes"
88
89
	attr_struct = "alloc_attr"

Matthias Braun's avatar
Matthias Braun committed
90
@op
91
class Anchor(Node):
92
	"""Utility node used to "hold" nodes in a graph that might possibly not be
93
94
95
	reachable by other means or which should be reachable immediately without
	searching through the graph.
	Each firm-graph contains exactly one anchor node whose address is always
96
	known. All other well-known graph-nodes like Start, End, NoMem, ...
97
	are found by looking at the respective Anchor operand."""
98
99
100
101
102
103
104
105
106
107
	ins = [
		("end_block",   "block the end node belongs to" ),
		("start_block", "block the start node belongs to" ),
		("end",         "end node of this ir_graph" ),
		("start",       "start node of this ir_graph" ),
		("frame",       "frame of this ir_graph" ),
		("initial_mem", "initial memory of this ir_graph" ),
		("args",        "argument proj of the start node" ),
		("no_mem",      "the only NoMem node of this ir_graph" ),
	]
108
109
110
111
112
	mode        = "mode_ANY"
	flags       = [ "dump_noblock" ]
	pinned      = "yes"
	singleton   = True
	constructor = False
113

Matthias Braun's avatar
Matthias Braun committed
114
@op
115
class And(Binop):
116
	"""returns the result of a bitwise and operation of its operands"""
117
118
	flags    = [ "commutative" ]

Matthias Braun's avatar
Matthias Braun committed
119
@op
120
class ASM(Node):
Matthias Braun's avatar
Matthias Braun committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
	"""executes assembler fragments of the target machine.

	The node contains a template for an assembler snippet. The compiler will
	replace occurences of %0 to %9 with input/output registers,
	%% with a single % char. Some backends allow additional specifiers (for
	example %w3, %l3, %h3 on x86 to get a 16bit, 8hit low, 8bit high part
	of a register).
	After the replacements the text is emitted into the final assembly.

	The clobber list contains names of registers which have an undefined value
	after the assembler instruction is executed; it may also contain 'memory'
	or 'cc' if global state/memory changes or the condition code registers
	(some backends implicitely set cc, memory clobbers on all ASM statements).

	Example (an i386 instruction)::

		ASM(text="btsl %1, %0",
			input_constraints = ["=m", "r"],
			clobbers = ["cc"])

	As there are no output, the %0 references the first input which is just an
	address which the asm operation writes to. %1 references to an input which
	is passed as a register. The condition code register has an unknown value
	after the instruction.

	(This format is inspired by the gcc extended asm syntax)
	"""
148
149
150
151
152
153
154
155
156
	mode        = "mode_T"
	arity       = "variable"
	input_name  = "input"
	flags       = [ "keep", "uses_memory" ]
	pinned      = "exception"
	pinned_init = "op_pin_state_pinned"
	attr_struct = "asm_attr"
	attrs_name  = "assem"
	ins         = [
157
158
		("mem",    "memory dependency"),
	]
159
	attrs       = [
160
161
162
163
164
165
166
167
168
169
170
		Attribute("input_constraints", type="ir_asm_constraint*",
		          comment="input constraints"),
		Attribute("n_output_constraints", type="size_t", noprop=True,
		          comment="number of output constraints"),
		Attribute("output_constraints", type="ir_asm_constraint*",
		          comment="output constraints"),
		Attribute("n_clobbers", type="size_t", noprop=True,
		          comment="number of clobbered registers/memory"),
		Attribute("clobbers", type="ident**",
		          comment="list of clobbered registers/memory"),
		Attribute("text", type="ident*", comment="assembler text"),
171
172
173
	]
	# constructor is written manually at the moment, because of the clobbers+
	# constraints arrays needing special handling (2 arguments for 1 attribute)
174
	constructor = False
175

Matthias Braun's avatar
Matthias Braun committed
176
@op
177
class Bad(Node):
178
179
180
181
182
183
	"""Bad nodes indicate invalid input, which is values which should never be
	computed.

	The typical use case for the Bad node is removing unreachable code.
	Frontends should set the current_block to Bad when it is clear that
	following code must be unreachable (ie. after a goto or return statement).
184
	Optimizations also set block predecessors to Bad when it becomes clear,
185
186
	that a control flow edge can never be executed.

187
	The gigo optimizations ensures that nodes with Bad as their block, get
Christoph Mallon's avatar
Christoph Mallon committed
188
	replaced by Bad themselves. Nodes with at least 1 Bad input get exchanged
189
190
191
192
	with Bad too. Exception to this rule are Block, Phi, Tuple and End node;
	This is because removing inputs from a Block is hairy operation (requiring,
	Phis to be shortened too for example). So instead of removing block inputs
	they are set to Bad, and the actual removal is left to the control flow
193
	optimization phase. Block, Phi, Tuple with only Bad inputs however are
194
195
196
197
	replaced by Bad right away.

	In the future we may use the Bad node to model poison values that arise
	from undefined behaviour like reading uninitialized local variables in C."""
Matthias Braun's avatar
Matthias Braun committed
198
	flags         = [ "start_block", "dump_noblock" ]
199
	pinned        = "yes"
200

Matthias Braun's avatar
Matthias Braun committed
201
@op
202
class Deleted(Node):
203
204
	"""Internal node which is temporary set to nodes which are already removed
	from the graph."""
205
206
207
208
	mode        = "mode_Bad"
	flags       = [ ]
	pinned      = "yes"
	constructor = False
209

Matthias Braun's avatar
Matthias Braun committed
210
@op
211
class Block(Node):
212
	"""A basic block"""
213
214
215
216
217
218
219
220
	mode        = "mode_BB"
	block       = "NULL"
	pinned      = "yes"
	arity       = "variable"
	input_name  = "cfgpred"
	flags       = []
	attr_struct = "block_attr"
	attrs       = [
221
222
		Attribute("entity", type="ir_entity*", init="NULL",
		          comment="entity representing this block"),
223
	]
224
	serializer  = False
Moritz Kroll's avatar
Moritz Kroll committed
225
226

	init = '''
227
	res->attr.block.backedge    = new_backedge_arr(get_irg_obstack(irg), arity);
Moritz Kroll's avatar
Moritz Kroll committed
228
	set_Block_matured(res, 1);
229
230

	/* Create and initialize array for Phi-node construction. */
231
	if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION)) {
232
		res->attr.block.graph_arr = NEW_ARR_DZ(ir_node*, get_irg_obstack(irg), irg->n_loc);
233
	}
234
	'''
235

Matthias Braun's avatar
Matthias Braun committed
236
@op
237
class Builtin(Node):
238
	"""performs a backend-specific builtin."""
239
	ins         = [
240
241
		("mem", "memory dependency"),
	]
242
243
244
	arity       = "variable"
	input_name  = "param"
	outs        = [
245
246
		("M", "memory result"),
		# results follow here
247
	]
248
	mode        = "mode_T"
249
250
	flags       = [ "uses_memory" ]
	attrs       = [
251
252
253
		Attribute("kind", type="ir_builtin_kind", comment="kind of builtin"),
		Attribute("type", type="ir_type*",
		          comment="method type for the builtin call"),
254
	]
255
	pinned      = "exception"
256
257
	pinned_init = "op_pin_state_pinned"
	attr_struct = "builtin_attr"
258
	init        = '''
259
260
261
	assert((get_unknown_type() == type) || is_Method_type(type));
	'''

Matthias Braun's avatar
Matthias Braun committed
262
@op
263
class Call(Node):
264
265
266
267
	"""Calls other code. Control flow is transfered to ptr, additional
	operands are passed to the called code. Called code usually performs a
	return operation. The operands of this return operation are the result
	of the Call node."""
268
	ins         = [
269
270
271
		("mem",   "memory dependency"),
		("ptr",   "pointer to called code"),
	]
272
273
274
	arity       = "variable"
	input_name  = "param"
	outs        = [
Matthias Braun's avatar
Matthias Braun committed
275
		("M",                "memory result"),
276
		("T_result",         "tuple containing all results"),
Matthias Braun's avatar
Matthias Braun committed
277
278
		("X_regular",        "control flow when no exception occurs"),
		("X_except",         "control flow when exception occured"),
279
	]
280
281
	flags       = [ "fragile", "uses_memory" ]
	attrs       = [
282
283
		Attribute("type", type="ir_type*",
		          comment="type of the call (usually type of the called procedure)"),
284
285
	]
	attr_struct = "call_attr"
286
	pinned      = "exception"
287
	pinned_init = "op_pin_state_pinned"
288
	throws_init = "false"
289
290
	init = '''
	assert((get_unknown_type() == type) || is_Method_type(type));
291
	'''
292

Matthias Braun's avatar
Matthias Braun committed
293
@op
294
class Cmp(Binop):
295
	"""Compares its two operands and checks whether a specified
296
	   relation (like less or equal) is fulfilled."""
297
	flags = []
298
299
	mode  = "mode_b"
	attrs = [
300
301
		Attribute("relation", type="ir_relation",
		          comment="Comparison relation"),
302
303
	]
	attr_struct = "cmp_attr"
304

Matthias Braun's avatar
Matthias Braun committed
305
@op
306
class Cond(Node):
307
	"""Conditionally change control flow."""
308
309
310
	ins      = [
		("selector",  "condition parameter"),
	]
311
312
313
314
	outs     = [
		("false", "control flow if operand is \"false\""),
		("true",  "control flow if operand is \"true\""),
	]
315
316
	flags    = [ "cfopcode", "forking" ]
	pinned   = "yes"
317
	attrs    = [
318
319
320
		Attribute("jmp_pred", type="cond_jmp_predicate",
		          init="COND_JMP_PRED_NONE",
		          comment = "can indicate the most likely jump"),
321
	]
322
	attr_struct = "cond_attr"
323

Matthias Braun's avatar
Matthias Braun committed
324
@op
325
class Switch(Node):
Matthias Braun's avatar
Matthias Braun committed
326
327
328
329
330
331
332
333
334
	"""Change control flow. The destination is choosen based on an integer input value which is looked up in a table.

	Backends can implement this efficiently using a jump table."""
	ins    = [
		("selector", "input selector"),
	]
	outs   = [
		("default", "control flow if no other case matches"),
	]
335
	mode   = "mode_T"
Matthias Braun's avatar
Matthias Braun committed
336
337
338
	flags  = [ "cfopcode", "forking" ]
	pinned = "yes"
	attrs  = [
339
340
341
342
		Attribute("n_outs", type="unsigned",
		          comment="number of outputs (including pn_Switch_default)"),
		Attribute("table", type="ir_switch_table*",
		          comment="table describing mapping from input values to Proj numbers"),
Matthias Braun's avatar
Matthias Braun committed
343
344
345
346
	]
	attr_struct = "switch_attr"
	attrs_name  = "switcha"

Matthias Braun's avatar
Matthias Braun committed
347
@op
348
class Confirm(Node):
349
350
351
352
353
354
355
356
357
	"""Specifies constraints for a value. This allows explicit representation
	of path-sensitive properties. (Example: This value is always >= 0 on 1
	if-branch then all users within that branch are rerouted to a confirm-node
	specifying this property).

	A constraint is specified for the relation between value and bound.
	value is always returned.
	Note that this node does NOT check or assert the constraint, it merely
	specifies it."""
358
359
360
361
	ins      = [
		("value",  "value to express a constraint for"),
		("bound",  "value to compare against"),
	]
362
	mode     = "get_irn_mode(irn_value)"
Matthias Braun's avatar
Matthias Braun committed
363
	flags    = [ ]
364
	pinned   = "yes"
365
	attrs    = [
366
367
		Attribute("relation", type="ir_relation",
		          comment="relation of value to bound"),
368
369
370
	]
	attr_struct = "confirm_attr"

Matthias Braun's avatar
Matthias Braun committed
371
@op
372
class Const(Node):
373
	"""Returns a constant value."""
374
	flags      = [ "constlike", "start_block" ]
375
	mode       = "get_tarval_mode(tarval)"
376
	attrs      = [
377
378
		Attribute("tarval", type="ir_tarval*",
		          comment="constant value (a tarval object)"),
379
380
	]
	attr_struct = "const_attr"
381
	attrs_name  = "con"
382

Matthias Braun's avatar
Matthias Braun committed
383
@op
384
class Conv(Node):
385
	"""Converts values between modes"""
386
387
388
389
	flags  = []
	ins    = [
		("op", "operand")
	]
390

Matthias Braun's avatar
Matthias Braun committed
391
@op
392
class Bitcast(Node):
Matthias Braun's avatar
Matthias Braun committed
393
394
395
396
397
398
399
	"""Converts a value between modes with different arithmetics but same
	number of bits by reinterpreting the bits in the new mode"""
	flags = []
	ins = [
		("op", "operand")
	]

Matthias Braun's avatar
Matthias Braun committed
400
@op
401
class CopyB(Node):
Matthias Braun's avatar
Matthias Braun committed
402
	"""Copies a block of memory with statically known size/type."""
403
404
405
406
407
	ins   = [
		("mem",  "memory dependency"),
		("dst",  "destination address"),
		("src",  "source address"),
	]
408
409
	mode  = "mode_M"
	flags = [ "uses_memory" ]
410
	attrs = [
411
412
413
414
415
		Attribute("type", type="ir_type*", comment="type of copied data"),
		Attribute("volatility", type="ir_volatility",
		          init="flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
		          to_flags="%s == volatility_is_volatile ? cons_volatile : cons_none",
		          comment="volatile CopyB nodes have a visible side-effect and may not be optimized"),
416
417
	]
	attr_struct = "copyb_attr"
418
	constructor_args = [
419
420
		Attribute("flags", type="ir_cons_flags",
		          comment="specifies volatility"),
421
	]
422

Matthias Braun's avatar
Matthias Braun committed
423
@op
424
class Div(Node):
425
	"""returns the quotient of its 2 operands"""
426
427
428
429
430
	ins   = [
		("mem",   "memory dependency"),
		("left",  "first operand"),
		("right", "second operand"),
	]
431
	outs  = [
Matthias Braun's avatar
Matthias Braun committed
432
		("M",         "memory result"),
433
		("res",       "result of computation"),
Matthias Braun's avatar
Matthias Braun committed
434
435
		("X_regular", "control flow when no exception occurs"),
		("X_except",  "control flow when exception occured"),
436
	]
437
	flags = [ "fragile", "uses_memory", "const_memory" ]
438
	attrs = [
439
440
441
		Attribute("resmode", type="ir_mode*",
		          comment="mode of the result value"),
		Attribute("no_remainder", type="int", init="0"),
442
	]
443
	attr_struct = "div_attr"
444
	pinned      = "exception"
445
	throws_init = "false"
446
447
	op_index    = 1
	arity_override = "oparity_binary"
448

Matthias Braun's avatar
Matthias Braun committed
449
@op
450
class Dummy(Node):
451
452
453
	"""A placeholder value. This is used when constructing cyclic graphs where
	you have cases where not all predecessors of a phi-node are known. Dummy
	nodes are used for the unknown predecessors and replaced later."""
454
455
	ins        = []
	flags      = [ "cfopcode", "start_block", "constlike", "dump_noblock" ]
456
457
	pinned     = "yes"

Matthias Braun's avatar
Matthias Braun committed
458
@op
459
class End(Node):
460
461
	"""Last node of a graph. It references nodes in endless loops (so called
	keepalive edges)"""
462
463
464
	mode             = "mode_X"
	pinned           = "yes"
	arity            = "dynamic"
465
	input_name       = "keepalive"
466
467
468
	flags            = [ "cfopcode" ]
	block            = "get_irg_end_block(irg)"
	singleton        = True
469

Matthias Braun's avatar
Matthias Braun committed
470
@op
471
class Eor(Binop):
Matthias Braun's avatar
Matthias Braun committed
472
473
474
	"""returns the result of a bitwise exclusive or operation of its operands.

	This is also known as the Xor operation."""
475
	flags    = [ "commutative" ]
476

Matthias Braun's avatar
Matthias Braun committed
477
@op
478
class Free(Node):
479
	"""Frees a block of memory previously allocated by an Alloc node"""
480
481
482
	ins = [
		("mem", "memory dependency" ),
		("ptr", "pointer to the object to free"),
483
	]
484
	mode   = "mode_M"
485
	flags  = [ "uses_memory", "const_memory" ]
486
487
	pinned = "yes"

Matthias Braun's avatar
Matthias Braun committed
488
@op
489
class Id(Node):
Matthias Braun's avatar
Matthias Braun committed
490
491
492
493
	"""Returns its operand unchanged.

	This is mainly used when exchanging nodes. Usually you shouldn't see Id
	nodes since the getters/setters for node inputs skip them automatically."""
494
495
496
	ins    = [
	   ("pred", "the value which is returned unchanged")
	]
497
498
	flags       = []
	constructor = False
499

Matthias Braun's avatar
Matthias Braun committed
500
@op
501
class IJmp(Node):
502
503
504
	"""Jumps to the code in its argument. The code has to be in the same
	function and the the destination must be one of the blocks reachable
	by the tuple results"""
505
506
	mode     = "mode_X"
	pinned   = "yes"
507
508
509
	ins      = [
	   ("target", "target address of the jump"),
	]
510
	flags    = [ "cfopcode", "forking", "keep", "unknown_jump" ]
511

Matthias Braun's avatar
Matthias Braun committed
512
@op
513
class Jmp(Node):
514
	"""Jumps to the block connected through the out-value"""
515
516
517
518
519
	mode     = "mode_X"
	pinned   = "yes"
	ins      = []
	flags    = [ "cfopcode" ]

Matthias Braun's avatar
Matthias Braun committed
520
@op
521
class Load(Node):
522
	"""Loads a value from memory (heap or stack)."""
523
524
525
526
	ins   = [
		("mem", "memory dependency"),
		("ptr",  "address to load from"),
	]
527
	outs  = [
Matthias Braun's avatar
Matthias Braun committed
528
		("M",         "memory result"),
529
		("res",       "result of load operation"),
Matthias Braun's avatar
Matthias Braun committed
530
531
		("X_regular", "control flow when no exception occurs"),
		("X_except",  "control flow when exception occured"),
532
	]
533
	flags    = [ "fragile", "uses_memory", "const_memory" ]
534
	pinned   = "exception"
535
	attrs    = [
536
537
		Attribute("mode", type="ir_mode*",
		          comment="mode of the value to be loaded"),
538
539
                Attribute("type", type="ir_type*",
                          comment="The type of the object which is stored at ptr (need not match with mode)"),
540
541
542
543
544
545
546
547
		Attribute("volatility", type="ir_volatility",
		          init="flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
		          to_flags="%s == volatility_is_volatile ? cons_volatile : cons_none",
		          comment="volatile loads are a visible side-effect and may not be optimized"),
		Attribute("unaligned", type="ir_align",
		          init="flags & cons_unaligned ? align_non_aligned : align_is_aligned",
		          to_flags="%s == align_non_aligned ? cons_unaligned : cons_none",
		          comment="pointers to unaligned loads don't need to respect the load-mode/type alignments"),
548
549
	]
	attr_struct = "load_attr"
550
	constructor_args = [
551
552
		Attribute("flags", type="ir_cons_flags",
		          comment="specifies alignment, volatility and pin state"),
553
	]
554
	pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
555
	throws_init = "(flags & cons_throws_exception) != 0"
556

Matthias Braun's avatar
Matthias Braun committed
557
@op
558
class Minus(Node):
Andreas Seltenreich's avatar
Andreas Seltenreich committed
559
	"""returns the additive inverse of its operand"""
560
561
562
563
	flags  = []
	ins    = [
		("op", "operand")
	]
564

Matthias Braun's avatar
Matthias Braun committed
565
@op
566
class Mod(Node):
567
568
569
	"""returns the remainder of its operands from an implied division.

	Examples:
570

571
572
573
574
575
	* mod(5,3)   produces 2
	* mod(5,-3)  produces 2
	* mod(-5,3)  produces -2
	* mod(-5,-3) produces -2
	"""
576
577
578
579
580
	ins   = [
		("mem",   "memory dependency"),
		("left",  "first operand"),
		("right", "second operand"),
	]
581
	outs  = [
Matthias Braun's avatar
Matthias Braun committed
582
		("M",         "memory result"),
583
		("res",       "result of computation"),
Matthias Braun's avatar
Matthias Braun committed
584
585
		("X_regular", "control flow when no exception occurs"),
		("X_except",  "control flow when exception occured"),
586
	]
587
	flags = [ "fragile", "uses_memory", "const_memory" ]
588
	attrs = [
589
		Attribute("resmode", type="ir_mode*", comment="mode of the result"),
590
	]
591
	attr_struct = "mod_attr"
592
	pinned      = "exception"
593
	throws_init = "false"
594
595
	op_index    = 1
	arity_override = "oparity_binary"
Matthias Braun's avatar
Matthias Braun committed
596

597
class Mul(Binop):
598
	"""returns the product of its operands"""
599
600
601
	flags = [ "commutative" ]

class Mulh(Binop):
602
603
	"""returns the upper word of the product of its operands (the part which
	would not fit into the result mode of a normal Mul anymore)"""
604
605
	flags = [ "commutative" ]

Matthias Braun's avatar
Matthias Braun committed
606
@op
607
class Mux(Node):
608
609
	"""returns the false or true operand depending on the value of the sel
	operand"""
610
611
612
613
614
	ins    = [
	   ("sel",   "value making the output selection"),
	   ("false", "selected if sel input is false"),
	   ("true",  "selected if sel input is true"),
	]
615
616
	flags  = []

Matthias Braun's avatar
Matthias Braun committed
617
@op
618
class NoMem(Node):
619
	"""Placeholder node for cases where you don't need any memory input"""
620
	mode          = "mode_M"
621
	flags         = [ "dump_noblock", "start_block" ]
622
623
	pinned        = "yes"
	singleton     = True
624

Matthias Braun's avatar
Matthias Braun committed
625
@op
626
class Not(Node):
627
	"""returns the bitwise complement of a value. Works for boolean values, too."""
628
629
630
631
	flags  = []
	ins    = [
		("op", "operand")
	]
632

633
634
635
636
@op
class Offset(EntConst):
	"""Symbolic constant that represents the offset of an entity in its owner type."""

Matthias Braun's avatar
Matthias Braun committed
637
@op
638
class Or(Binop):
639
	"""returns the result of a bitwise or operation of its operands"""
640
641
	flags = [ "commutative" ]

Matthias Braun's avatar
Matthias Braun committed
642
@op
643
class Phi(Node):
644
645
646
	"""Choose a value based on control flow. A phi node has 1 input for each
	predecessor of its block. If a block is entered from its nth predecessor
	all phi nodes produce their nth input as result."""
647
648
649
650
651
	pinned      = "yes"
	arity       = "variable"
	input_name  = "pred"
	flags       = []
	attrs       = [
652
653
654
		Attribute("loop", type="int", init="0",
		          comment="wether Phi represents the observable effect of a (possibly) nonterminating loop"),
	]
655
656
	attr_struct = "phi_attr"
	init        = '''
657
	res->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), arity);'''
658
	serializer  = False
659

Matthias Braun's avatar
Matthias Braun committed
660
@op
661
class Pin(Node):
662
663
664
	"""Pin the value of the node node in the current block. No users of the Pin
	node can float above the Block of the Pin. The node cannot float behind
	this block. Often used to Pin the NoMem node."""
665
666
667
	ins      = [
		("op", "value which is pinned"),
	]
668
	mode     = "get_irn_mode(irn_op)"
Matthias Braun's avatar
Matthias Braun committed
669
	flags    = [ ]
670
671
	pinned   = "yes"

Matthias Braun's avatar
Matthias Braun committed
672
@op
673
class Proj(Node):
674
	"""returns an entry of a tuple value"""
675
	ins        = [
676
677
		("pred", "the tuple value from which a part is extracted"),
	]
678
679
	flags      = []
	block      = "get_nodes_block(irn_pred)"
680
	usesGraph  = False
681
	attrs      = [
682
		Attribute("num", type="unsigned",
683
		          comment="number of tuple component to be extracted"),
684
	]
685
	attr_struct = "proj_attr"
686

Matthias Braun's avatar
Matthias Braun committed
687
@op
688
class Raise(Node):
689
690
691
	"""Raises an exception. Unconditional change of control flow. Writes an
	explicit Except variable to memory to pass it to the exception handler.
	Must be lowered to a Call to a runtime check function."""
692
693
694
695
	ins    = [
		("mem",     "memory dependency"),
		("exo_ptr", "pointer to exception object to be thrown"),
	]
696
	outs  = [
Matthias Braun's avatar
Matthias Braun committed
697
698
		("M", "memory result"),
		("X", "control flow to exception handler"),
699
	]
Matthias Braun's avatar
Matthias Braun committed
700
	flags  = [ "cfopcode" ]
701
702
	pinned = "yes"

Matthias Braun's avatar
Matthias Braun committed
703
@op
704
class Return(Node):
705
706
	"""Returns from the current function. Takes memory and return values as
	operands."""
707
	ins        = [
708
709
		("mem", "memory dependency"),
	]
710
711
712
713
714
	arity      = "variable"
	input_name = "res"
	mode       = "mode_X"
	flags      = [ "cfopcode" ]
	pinned     = "yes"
715

Matthias Braun's avatar
Matthias Braun committed
716
@op
717
class Sel(Node):
718
719
	"""Computes the address of an array element from the array base pointer and
	an index.
720

721
722
723
724
725
726
	A Sel node must only produce a NULL pointer if the ptr input is NULL."""
	ins = [
		("ptr",   "pointer to array to select from"),
		("index", "index to select"),
	]
	flags  = []
727
	mode   = "mode_P"
728
729
730
731
732
733
734
	attrs  = [
		Attribute("type", type="ir_type*",
		          comment="array type"),
	]
	attr_struct = "sel_attr"

@op
735
class Member(Node):
736
737
738
739
740
	"""Computes the address of a compound type member given the base address
	of an instance of the compound type.

	A Member node must only produce a NULL pointer if the ptr input is NULL."""
	ins = [
741
742
		("ptr", "pointer to object to select from"),
	]
743
	flags   = []
744
	mode    = "mode_P"
745
	attrs   = [
746
747
		Attribute("entity", type="ir_entity*",
		          comment="entity which is selected"),
748
	]
749
	attr_struct = "member_attr"
750

Matthias Braun's avatar
Matthias Braun committed
751
@op
752
class Shl(Binop):
753
	"""Returns its first operands bits shifted left by the amount of the 2nd
754
755
756
757
	operand.
	The right input (shift amount) must be an unsigned integer value.
	If the result mode has modulo_shift!=0, then the effective shift amount is
	the right input modulo this modulo_shift amount."""
758
759
	flags = []

Matthias Braun's avatar
Matthias Braun committed
760
@op
761
class Shr(Binop):
762
	"""Returns its first operands bits shifted right by the amount of the 2nd
763
764
765
766
	operand. No special handling for the sign bit is performed (zero extension).
	The right input (shift amount) must be an unsigned integer value.
	If the result mode has modulo_shift!=0, then the effective shift amount is
	the right input modulo this modulo_shift amount."""
767
768
	flags = []

Matthias Braun's avatar
Matthias Braun committed
769
@op
770
class Shrs(Binop):
771
772
	"""Returns its first operands bits shifted right by the amount of the 2nd
	operand. The leftmost bit (usually the sign bit) stays the same
773
774
775
776
	(sign extension).
	The right input (shift amount) must be an unsigned integer value.
	If the result mode has modulo_shift!=0, then the effective shift amount is
	the right input modulo this modulo_shift amount."""
777
778
	flags = []

Matthias Braun's avatar
Matthias Braun committed
779
@op
780
class Start(Node):
781
	"""The first node of a graph. Execution starts with this node."""
782
	outs = [
783
784
785
786
		("M",              "initial memory"),
		("P_frame_base",   "frame base pointer"),
		("T_args",         "function arguments")
	]
787
788
789
790
	mode      = "mode_T"
	pinned    = "yes"
	flags     = [ "start_block" ]
	singleton = True
791

Matthias Braun's avatar
Matthias Braun committed
792
@op
793
class Store(Node):
794
	"""Stores a value into memory (heap or stack)."""
795
796
797
798
799
	ins   = [
	   ("mem",   "memory dependency"),
	   ("ptr",   "address to store to"),
	   ("value", "value to store"),
	]
800
	outs  = [
Matthias Braun's avatar
Matthias Braun committed
801
802
803
		("M",         "memory result"),
		("X_regular", "control flow when no exception occurs"),
		("X_except",  "control flow when exception occured"),
804
	]
805
806
807
808
	flags    = [ "fragile", "uses_memory" ]
	pinned   = "exception"
	attr_struct = "store_attr"
	pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
809
	throws_init = "(flags & cons_throws_exception) != 0"
810
	attrs = [
811
812
                Attribute("type", type="ir_type*",
                          comment="The type of the object which is stored at ptr (need not match with value's type)"),
813
814
815
816
817
818
819
820
		Attribute("volatility", type="ir_volatility",
		          init="flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
		          to_flags="%s == volatility_is_volatile ? cons_volatile : cons_none",
		          comment="volatile stores are a visible side-effect and may not be optimized"),
		Attribute("unaligned", type="ir_align",
		          init="flags & cons_unaligned ? align_non_aligned : align_is_aligned",
		          to_flags="%s == align_non_aligned ? cons_unaligned : cons_none",
		          comment="pointers to unaligned stores don't need to respect the load-mode/type alignments"),
821
	]
822
	constructor_args = [
823
824
		Attribute("flags", type="ir_cons_flags",
		          comment="specifies alignment, volatility and pin state"),
825
826
	]

Matthias Braun's avatar
Matthias Braun committed
827
@op
828
class Sub(Binop):
829
	"""returns the difference of its operands"""
830
831
	flags = []

832
@op
833
834
class Size(TypeConst):
	"""A symbolic constant that represents the size of a type"""
835

Matthias Braun's avatar
Matthias Braun committed
836
@op
837
class Sync(Node):
838
839
840
841
842
	"""The Sync operation unifies several partial memory blocks. These blocks
	have to be pairwise disjunct or the values in common locations have to
	be identical.  This operation allows to specify all operations that
	eventually need several partial memory blocks as input with a single
	entrance by unifying the memories with a preceding Sync operation."""
843
844
845
846
	mode       = "mode_M"
	flags      = []
	arity      = "dynamic"
	input_name = "pred"
847

Matthias Braun's avatar
Matthias Braun committed
848
@op
849
class Tuple(Node):
850
851
852
853
854
855
856
	"""Builds a Tuple from single values.

	This is needed to implement optimizations that remove a node that produced
	a tuple.  The node can be replaced by the Tuple operation so that the
	following Proj nodes have not to be changed. (They are hard to find due to
	the implementation with pointers in only one direction.) The Tuple node is
	smaller than any other node, so that a node can be changed into a Tuple by
857
	just changing its opcode and giving it a new in array."""
858
859
860
861
	arity      = "variable"
	input_name = "pred"
	mode       = "mode_T"
	flags      = []
862

Matthias Braun's avatar
Matthias Braun committed
863
@op
864
class Unknown(Node):
865
	"""Returns an unknown (at compile- and runtime) value. It is a valid
Matthias Braun's avatar
Matthias Braun committed
866
867
	optimization to replace an Unknown by any other constant value.

Matthias Braun's avatar
Matthias Braun committed
868
	Be careful when optimising Unknown values, you cannot simply replace
Matthias Braun's avatar
Matthias Braun committed
869
870
	Unknown+x or Unknown<x with a new Unknown node if there are multiple
	users of the original unknown node!"""
871
	pinned     = "yes"
Matthias Braun's avatar
Matthias Braun committed
872
	flags      = [ "start_block", "constlike", "dump_noblock" ]
873
874
875
876
877

(nodes, abstract_nodes) = prepare_nodes(globals())
export(nodes, "nodes")
export(abstract_nodes, "abstract_nodes")
export(globals(), "spec")