3 # This file is part of libFirm.
4 # Copyright (C) 2012 Karlsruhe Institute of Technology.
6 from jinja2 import Environment, Template
7 from spec_util import is_dynamic_pinned, isAbstract, load_spec
8 from filters import format_arguments, filter_isnot, filter_hasnot, filter_notset
11 """writes an error message to stderr"""
12 sys.stderr.write("Error: " + msg + "\n");
15 """writes a warning message to stderr"""
16 sys.stderr.write("Warning: " + msg + "\n");
18 def format_args(arglist):
19 return "\n".join(arglist)
21 def format_block(node):
22 if hasattr(node, "knownBlock"):
23 if hasattr(node, "knownGraph"):
30 env.filters['args'] = format_args
31 env.filters['block'] = format_block
32 env.filters['arguments'] = format_arguments
33 env.filters['isnot'] = filter_isnot
34 env.filters['notset'] = filter_notset
35 env.filters['hasnot'] = filter_hasnot
37 def get_io_type(type, attrname, node):
38 if type == "ir_tarval*":
39 importcmd = "read_tarval(env)"
40 exportcmd = "write_tarval(env, %(val)s);"
41 elif type == "ir_mode*":
42 importcmd = "read_mode_ref(env)"
43 exportcmd = "write_mode_ref(env, %(val)s);"
44 elif type == "ir_entity*":
45 importcmd = "read_entity_ref(env)"
46 exportcmd = "write_entity_ref(env, %(val)s);"
47 elif type == "ir_type*":
48 importcmd = "read_type_ref(env)"
49 exportcmd = "write_type_ref(env, %(val)s);"
51 importcmd = "read_long(env)"
52 exportcmd = "write_long(env, %(val)s);"
53 elif type == "ir_relation":
54 importcmd = "read_relation(env)"
55 exportcmd = "write_relation(env, %(val)s);"
56 elif type == "ir_where_alloc":
57 importcmd = "read_where_alloc(env)"
58 exportcmd = "write_where_alloc(env, %(val)s);"
59 elif type == "ir_align":
60 importcmd = "read_align(env)"
61 exportcmd = "write_align(env, %(val)s);"
62 elif type == "ir_volatility":
63 importcmd = "read_volatility(env)"
64 exportcmd = "write_volatility(env, %(val)s);"
65 elif type == "ir_cons_flags":
66 importcmd = "cons_none"
67 exportcmd = "" # can't really export cons_flags
68 elif type == "op_pin_state":
69 importcmd = "read_pin_state(env)"
70 exportcmd = "write_pin_state(env, node);"
71 elif type == "ir_builtin_kind":
72 importcmd = "read_builtin_kind(env)"
73 exportcmd = "write_builtin_kind(env, node);"
74 elif type == "cond_kind":
75 importcmd = "read_cond_kind(env)"
76 exportcmd = "write_cond_kind(env, node);"
77 elif type == "cond_jmp_predicate":
78 importcmd = "read_cond_jmp_predicate(env)"
79 exportcmd = "write_cond_jmp_predicate(env, node);"
81 importcmd = "read_int(env)"
82 exportcmd = "write_int(env, %(val)s);"
83 elif type == "unsigned":
84 importcmd = "read_unsigned(env)"
85 exportcmd = "write_unsigned(env, %(val)s);"
87 importcmd = "read_long(env)"
88 exportcmd = "write_long(env, %(val)s);"
89 elif type == "ir_switch_table*":
90 importcmd = "read_switch_table(env)"
91 exportcmd = "write_switch_table(env, %(val)s);"
93 warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
94 importcmd = "/* BAD: %s %s */ (%s)0" % (type, attrname, type)
95 exportcmd = "// BAD: %s" % type
96 return (importcmd, exportcmd)
98 def prepare_attr(node, attr):
99 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
100 attr["importcmd"] = importcmd
101 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(node)" % (node.name, attr["name"])}
104 def preprocess_node(node):
105 if node.customSerializer:
108 # construct node arguments
111 for input in node.ins:
112 arguments.append("in_%s" % input[0])
114 if node.arity == "variable" or node.arity == "dynamic":
115 arguments.append("n_preds")
116 arguments.append("preds")
118 if not hasattr(node, "mode"):
119 arguments.append("mode")
121 for attr in node.attrs:
122 prepare_attr(node, attr)
123 if "to_flags" in attr:
124 node.constructorFlags = True
125 attr['to_flags'] = attr['to_flags'] % (attr["name"])
127 extraattrs.append(attr)
129 arguments.append(attr["name"])
131 for arg in node.constructor_args:
132 if arg['type'] != "ir_cons_flags" and arg['name'] != "flags":
133 error("only ir_cons_flags constructor arg supported in irio")
135 node.constructorFlags = True
136 arguments.append("flags")
138 node.arguments = arguments
139 node.extraattrs = extraattrs
140 node.dynamic_pinned = is_dynamic_pinned(node)
142 io_template = env.from_string('''/* Warning: automatically generated code */
143 {%- for node in nodes|notset('customSerializer') %}
144 static ir_node *read_{{node.name}}(read_env_t *env)
146 {%- if not node.knownBlock %}
147 ir_node *block = read_node_ref(env);
149 {%- for input in node.ins %}
150 ir_node *in_{{input[0]}} = read_node_ref(env);
152 {%- if not hasattr(node, "mode") %}
153 ir_mode *mode = read_mode_ref(env);
155 {%- for attr in node.attrs %}
156 {{attr.type}} {{attr.name}} = {{attr.importcmd}};
158 {%- if node.dynamic_pinned %}
159 op_pin_state pin_state = read_pin_state(env);
161 {%- if "fragile" in node.flags %}
162 bool throws = read_throws(env);
164 {%- if node.arity == "dynamic" or node.arity == "variable" %}
165 int n_preds = read_preds(env);
166 ir_node **preds = (ir_node**)obstack_finish(&env->preds_obst);
168 {%- if node.constructorFlags %}
169 ir_cons_flags flags = cons_none;
172 {%- if node.constructorFlags %}
173 {%- for attr in node.attrs %}
174 {%- if "to_flags" in attr %}
175 flags |= {{attr.to_flags}};
178 {%- if node.dynamic_pinned %}
179 flags |= pin_state == op_pin_state_floats ? cons_floats : cons_none;
181 {%- if "fragile" in node.flags %}
182 flags |= throws ? cons_throws_exception : cons_none;
185 res = new_r_{{node.name}}(
186 {%- filter arguments %}
188 {{node.arguments|args}}
189 {%- if node.dynamic_pinned and not hasattr(node, "pinned_init") %}
194 {%- if node.arity == "dynamic" or node.arity == "variable" %}
195 obstack_free(&env->preds_obst, preds);
197 {%- for attr in node.extraattrs %}
198 set_{{node.name}}_{{attr.name}}(res, {{attr.name}});
200 {%- if not node.constructorFlags %}
201 {%- if node.dynamic_pinned and hasattr(node, "pinned_init") %}
202 set_irn_pinned(res, pin_state);
204 {%- if "fragile" in node.flags and hasattr(node, "throws_init") %}
205 ir_set_throws_exception(res, throws);
212 {%- for node in nodes|notset('customSerializer') %}
213 static void write_{{node.name}}(write_env_t *env, const ir_node *node)
215 write_symbol(env, "{{node.name}}");
216 write_node_nr(env, node);
217 {%- if not node.knownBlock %}
218 write_node_ref(env, get_nodes_block(node));
220 {%- for input in node.ins %}
221 write_node_ref(env, get_{{node.name}}_{{input[0]}}(node));
223 {%- if not hasattr(node, "mode") %}
224 write_mode_ref(env, get_irn_mode(node));
226 {%- for attr in node.attrs %}
229 {%- if node.dynamic_pinned %}
230 write_pin_state(env, get_irn_pinned(node));
232 {%- if "fragile" in node.flags %}
233 write_throws(env, ir_throws_exception(node));
235 {%- if node.arity == "dynamic" or node.arity == "variable" %}
236 write_pred_refs(env, node, {% if node.ins %}n_{{node.name}}_max+1{% else %}0{%endif%});
241 static void register_generated_node_readers(void)
243 {%- for node in nodes|notset('customSerializer') %}
244 register_node_reader(new_id_from_str("{{node.name}}"), read_{{node.name}});
248 static void register_generated_node_writers(void)
250 {%- for node in nodes|notset('customSerializer') %}
251 register_node_writer(op_{{node.name}}, write_{{node.name}});
259 print "usage: %s specname(ignored) destdirectory" % argv[0]
265 spec = load_spec(specfile)
271 preprocess_node(node)
272 real_nodes.append(node)
274 file = open(gendir + "/gen_irio.inl", "w");
275 file.write(io_template.render(nodes = real_nodes, hasattr=hasattr))