4 from jinja2 import Environment, Template
5 from jinja2.filters import do_dictsort
6 from spec_util import is_dynamic_pinned, verify_node
7 from ir_spec import nodes
9 def format_argdecls(node, first = False, voidwhenempty = False):
10 if not node.has_key("args") or len(node["args"]) == 0:
21 for arg in node["args"]:
22 res = res + (comma + arg["type"] + " " + arg["name"])
26 def format_args(node, first = False):
27 if not node.has_key("args"):
35 for arg in node["args"]:
36 res = res + (comma + arg["name"])
40 def format_blockdecl(node):
41 if node.get("knownBlock"):
44 return ", ir_node *block"
46 def format_block(node):
47 if node.get("knownBlock"):
52 def format_curblock(node):
53 if node.get("knownBlock"):
56 return ", current_ir_graph->current_block"
58 def format_insdecl(node):
60 if arity == "variable" and len(node["ins"]) == 0 or arity == "dynamic" or arity == 0:
63 if arity == "variable":
64 insarity = len(node["ins"])
65 res = "int r_arity = arity + " + `insarity` + ";\n\tir_node **r_in;\n\t" \
66 + "NEW_ARR_A(ir_node *, r_in, r_arity);\n\t"
68 for input in node["ins"]:
69 res += "r_in[" + `i` + "] = irn_" + input + ";\n\t"
71 res += "memcpy(&r_in[" + `insarity` + "], in, sizeof(ir_node *) * arity);\n\t"
73 res = "ir_node *in[" + `arity` + "];\n\t"
75 for input in node["ins"]:
76 res += "in[" + `i` + "] = irn_" + input + ";\n\t"
80 def format_arity_and_ins(node):
82 if arity == "dynamic":
84 elif arity == "variable":
85 if len(node["ins"]) == 0:
88 return "r_arity, r_in"
92 return `arity` + ", in"
94 def format_arity(node):
95 if "arity_override" in node:
96 return node["arity_override"]
98 if arity == "dynamic":
99 return "oparity_dynamic"
100 if arity == "variable":
101 return "oparity_variable"
103 return "oparity_zero"
105 return "oparity_unary"
107 return "oparity_binary"
109 return "oparity_trinary"
112 def format_pinned(node):
113 pinned = node["pinned"]
115 return "op_pin_state_pinned"
117 return "op_pin_state_floats"
118 if pinned == "exception":
119 return "op_pin_state_exc_pinned"
120 if pinned == "memory":
121 return "op_pin_state_mem_pinned"
122 print "WARNING: Unknown pinned state %s in format pined" % pinned
125 def format_flags(node):
126 flags = node['flags']
127 flags = re.split("\s*,\s*", flags)
128 flags = map(lambda x : "irop_flag_" + x, flags)
129 return " | ".join(flags)
131 def format_attr_size(node):
132 if "attr_struct" not in node:
134 return "sizeof(%s)" % node['attr_struct']
136 def format_opindex(node):
137 if "op_index" in node:
138 return node["op_index"]
141 def filter_isnot(list, flag):
143 for nodename, node in list:
146 result.append((nodename, node))
150 env.filters['argdecls'] = format_argdecls
151 env.filters['args'] = format_args
152 env.filters['blockdecl'] = format_blockdecl
153 env.filters['block'] = format_block
154 env.filters['curblock'] = format_curblock
155 env.filters['insdecl'] = format_insdecl
156 env.filters['arity_and_ins'] = format_arity_and_ins
157 env.filters['arity'] = format_arity
158 env.filters['pinned'] = format_pinned
159 env.filters['flags'] = format_flags
160 env.filters['attr_size'] = format_attr_size
161 env.filters['isnot'] = filter_isnot
162 env.filters['opindex'] = format_opindex
164 def add_attr(list, type, name, init = None, initname = None):
166 initname = "." + name
168 list.append(dict(type = type, name = name, init = init, initname = initname))
170 list.append(dict(type = type, name = name, initname = initname))
172 def prepare_attr(attr):
174 return dict(type = attr["type"], name = attr["name"], init = attr["init"])
176 return dict(type = attr["type"], name = attr["name"])
178 def preprocess_node(nodename, node):
179 # set default attributes
181 parent = nodes[node["is_a"]]
182 node["ins"] = parent["ins"]
183 if "op_index" in parent:
184 node["op_index"] = parent["op_index"]
185 if "pinned" in parent:
186 node["pinned"] = parent["pinned"]
188 node["outs"] = parent["outs"]
191 node["mode"] = "mode_T"
193 node["dbdecl"] = "dbg_info *db, "
194 node["dbdeclnocomma"] = "dbg_info *db"
196 if "flags" not in node and "abstract" not in node:
197 print "WARNING: no flags specified for %s (you should say at least 'none')\n" % nodename
199 node.setdefault("ins", [])
200 node.setdefault("arity", len(node["ins"]))
201 node.setdefault("attrs", [])
202 node.setdefault("constrname", nodename);
203 node.setdefault("constructor_args", [])
204 node.setdefault("attrs_name", nodename.lower())
205 node.setdefault("block", "block")
206 node.setdefault("flags", "none")
208 verify_node(nodename, node)
210 # construct node arguments
214 for input in node["ins"]:
215 arguments.append(dict(type = "ir_node *", name = "irn_" + input))
217 if node["arity"] == "variable" or node["arity"] == "dynamic":
218 arguments.append(dict(type = "int", name = "arity"))
219 arguments.append(dict(type = "ir_node **", name = "in"))
221 if "mode" not in node:
222 arguments.append(dict(type = "ir_mode *", name = "mode"))
223 node["mode"] = "mode"
225 attrs_with_special = 0
226 for attr in node["attrs"]:
227 attr.setdefault("initname", "." + attr["name"])
229 if "special" in attr:
230 if not "init" in attr:
231 print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename
234 if attrs_with_special != 0:
235 print "Node type %s has more than one attribute with a \"special\" entry" % nodename
238 attrs_with_special += 1
240 if "prefix" in attr["special"]:
241 specialname = attr["special"]["prefix"] + nodename
242 elif "suffix" in attr["special"]:
243 specialname = nodename + attr["special"]["suffix"]
245 print "Unknown special constructor type for node type %s" % nodename
248 specialconstrs.append(
250 constrname = specialname,
254 elif not "init" in attr:
255 arguments.append(prepare_attr(attr))
257 # dynamic pin state means more constructor arguments
258 if is_dynamic_pinned(node):
259 if "pinned_init" in node:
260 initattrs.append(dict(
261 initname = ".exc.pin_state",
262 init = node["pinned_init"]
265 node["constructor_args"].append(
268 type = "op_pin_state"
271 initattrs.append(dict(
272 initname = ".exc.pin_state",
276 for arg in node["constructor_args"]:
277 arguments.append(prepare_attr(arg))
278 if arg["type"] == "ir_cons_flags":
280 initattrs.append(dict(initname = ".exc.pin_state",
281 init = name + " & cons_floats ? op_pin_state_floats : op_pin_state_pinned"))
282 initattrs.append(dict(initname = ".volatility",
283 init = name + " & cons_volatile ? volatility_is_volatile : volatility_non_volatile"))
284 initattrs.append(dict(initname = ".aligned",
285 init = name + " & cons_unaligned ? align_non_aligned : align_is_aligned"))
287 node["args"] = arguments
288 node["initattrs"] = initattrs
289 node["special_constructors"] = specialconstrs
291 #############################
293 constructor_template = env.from_string('''
295 ir_node *new_rd_{{node["constrname"]}}({{node["dbdecl"]}}ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
298 ir_graph *rem = current_ir_graph;
300 current_ir_graph = irg;
301 res = new_ir_node({{node["db"]}}, irg, {{node["block"]}}, op_{{nodename}}, {{node["mode"]}}, {{node|arity_and_ins}});
302 {% for attr in node["attrs"] -%}
303 res->attr.{{node["attrs_name"]}}{{attr["initname"]}} =
304 {%- if "init" in attr %} {{ attr["init"] -}};
305 {%- else %} {{ attr["name"] -}};
308 {%- for attr in node["initattrs"] -%}
309 res->attr.{{node["attrs_name"]}}{{attr["initname"]}} = {{ attr["init"] -}};
312 {% if node["optimize"] != False -%}
313 res = optimize_node(res);
315 IRN_VRFY_IRG(res, irg);
316 current_ir_graph = rem;
320 ir_node *new_r_{{node["constrname"]}}(ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
322 {% if node["nodbginfo"] -%}
323 return new_rd_{{node["constrname"]}}(irg{{node|block}}{{node|args}});
325 return new_rd_{{node["constrname"]}}(NULL, irg{{node|block}}{{node|args}});
329 ir_node *new_d_{{node["constrname"]}}({{node["dbdeclnocomma"]}}{{node|argdecls(node["nodbginfo"])}})
333 {% if node["nodbginfo"] -%}
334 res = new_rd_{{node["constrname"]}}(current_ir_graph{{node|curblock}}{{node|args}});
336 res = new_rd_{{node["constrname"]}}(db, current_ir_graph{{node|curblock}}{{node|args}});
342 ir_node *new_{{node["constrname"]}}({{node|argdecls(True, True)}})
344 {% if node["nodbginfo"] -%}
345 return new_d_{{node["constrname"]}}({{node|args(True)}});
347 return new_d_{{node["constrname"]}}(NULL{{node|args}});
352 irnode_h_template = env.from_string('''
353 /* Warning: automatically generated code */
355 {% for nodename, node in nodes|isnot('custom_is') %}
356 static inline int _is_{{nodename}}(const ir_node *node)
358 assert(node != NULL);
359 return _get_irn_op(node) == op_{{nodename}};
363 {% for nodename, node in nodes %}
364 #define is_{{nodename}}(node) _is_{{nodename}}(node)
369 irnode_template = env.from_string('''
370 /* Warning: automatically generated code */
371 {% for nodename, node in nodes %}
372 int (is_{{nodename}})(const ir_node *node)
374 return _is_{{nodename}}(node);
379 irop_template = env.from_string('''
380 /* Warning: automatically generated code */
381 {% for nodename, node in nodes %}
382 ir_op *op_{{nodename}}; ir_op *get_op_{{nodename}}(void) { return op_{{nodename}}; }
387 {% for nodename, node in nodes %}
388 op_{{nodename}} = new_ir_op(iro_{{nodename}}, "{{nodename}}", {{node|pinned}}, {{node|flags}}, {{node|arity}}, {{node|opindex}}, {{node|attr_size}}, NULL);
396 {% for nodename, node in nodes %}
397 free_ir_op(op_{{nodename}}); op_{{nodename}} = NULL;
402 #############################
405 """the main function"""
408 print "usage: %s specname(ignored) destdirectory" % argv[0]
414 niymap = ["ASM", "CallBegin", "Const", "Const_type", "Const_long",
415 "defaultProj", "Dummy", "Phi", "simpleSel", "SymConst", "SymConst_type",
418 file = open(gendir + "/gen_ir_cons.c.inl", "w")
419 for nodename, node in do_dictsort(nodes):
420 preprocess_node(nodename, node)
421 if nodename in niymap:
423 if "abstract" not in node and "singleton" not in node:
424 file.write(constructor_template.render(vars()))
426 if "special_constructors" in node:
427 for special in node["special_constructors"]:
428 node["constrname"] = special["constrname"]
429 special["attr"]["init"] = special["attr"]["special"]["init"]
430 file.write(constructor_template.render(vars()))
435 for nodename, node in nodes.iteritems():
436 if "abstract" in node:
438 real_nodes[nodename] = node
439 real_nodes = do_dictsort(real_nodes)
441 file = open(gendir + "/gen_irnode.h", "w")
442 file.write(irnode_h_template.render(nodes = real_nodes))
445 file = open(gendir + "/gen_irnode.c.inl", "w")
446 file.write(irnode_template.render(nodes = real_nodes))
449 file = open(gendir + "/gen_irop.c.inl", "w")
450 file.write(irop_template.render(nodes = real_nodes))
453 if __name__ == "__main__":