+# Firm node specifications
+# The comments are in (standard python) restructured text format and are used
+# to generate documentation.
+from spec_util import abstract, op
+
+name = "ir"
+
+@abstract
+@op
+class Unop(object):
+ """Unary nodes have exactly 1 input"""
+ name = "unop"
+ ins = [
+ ("op", "operand"),
+ ]
+ op_index = 0
+ pinned = "no"
+
+@abstract
+@op
+class Binop(object):
+ """Binary nodes have exactly 2 inputs"""
+ name = "binop"
+ ins = [
+ ( "left", "first operand" ),
+ ( "right", "second operand" ),
+ ]
+ op_index = 0
+ pinned = "no"
+
+@op
+class Add(Binop):
+ """returns the sum of its operands"""
+ flags = [ "commutative" ]
+
+@op
+class Alloc:
+ """allocates a block of memory.
+ It can be specified whether the memory should be allocated to the stack
+ or to the heap.
+ Allocates memory for one or more objects (depending on value on count input).
+ """
+ ins = [
+ ("mem", "memory dependency" ),
+ ("count", "number of objects to allocate" ),
+ ]
+ outs = [
+ ("M", "memory result"),
+ ("res", "pointer to newly allocated memory"),
+ ("X_regular", "control flow when no exception occurs"),
+ ("X_except", "control flow when exception occured"),
+ ]
+ attrs = [
+ dict(
+ name = "type",
+ type = "ir_type*",
+ comment = "type of the objects to allocate",
+ ),
+ dict(
+ name = "where",
+ type = "ir_where_alloc",
+ comment = "whether to allocate the variable on the stack or heap",
+ )
+ ]
+ flags = [ "fragile", "uses_memory" ]
+ pinned = "exception"
+ throws_init = "false"
+ pinned_init = "op_pin_state_pinned"
+ attr_struct = "alloc_attr"
+
+@op
+class Anchor:
+ """utiliy node used to "hold" nodes in a graph that might possibly not be
+ 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
+ known. All other well-known graph-nodes like Start, End, NoMem, Bad, ...
+ are found by looking at the respective Anchor operand."""
+ mode = "mode_ANY"
+ arity = "variable"
+ flags = [ "dump_noblock" ]
+ pinned = "yes"
+ attr_struct = "irg_attr"
+ knownBlock = True
+ singleton = True
+ noconstructor = True
+ customSerializer = True
+
+@op
+class And(Binop):
+ """returns the result of a bitwise and operation of its operands"""
+ flags = [ "commutative" ]
+
+@op
+class ASM:
+ """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)
+ """
+ mode = "mode_T"
+ arity = "variable"
+ input_name = "input"
+ flags = [ "keep", "uses_memory" ]
+ pinned = "memory"
+ pinned_init = "op_pin_state_pinned"
+ attr_struct = "asm_attr"
+ attrs_name = "assem"
+ customSerializer = True
+ ins = [
+ ("mem", "memory dependency"),
+ ]