3 from jinja2 import Environment, Template
4 from jinja2.filters import do_dictsort
5 from spec_util import is_dynamic_pinned, verify_node
8 def format_argdecls(node, first = False, voidwhenempty = False):
9 if not node.has_key("args") or len(node["args"]) == 0:
20 for arg in node["args"]:
21 res = res + (comma + arg["type"] + " " + arg["name"])
25 def format_args(node, first = False):
26 if not node.has_key("args"):
34 for arg in node["args"]:
35 res = res + (comma + arg["name"])
39 def format_blockdecl(node):
40 if node.get("knownBlock"):
43 return ", ir_node *block"
45 def format_block(node):
46 if node.get("knownBlock"):
51 def format_curblock(node):
52 if node.get("knownBlock"):
55 return ", current_ir_graph->current_block"
57 def format_insdecl(node):
59 if arity == "variable" and len(node["ins"]) == 0 or arity == "dynamic" or arity == 0:
62 if arity == "variable":
63 insarity = len(node["ins"])
64 res = "int r_arity = arity + " + `insarity` + ";\n\tir_node **r_in;\n\t" \
65 + "NEW_ARR_A(ir_node *, r_in, r_arity);\n\t"
67 for input in node["ins"]:
68 res += "r_in[" + `i` + "] = irn_" + input + ";\n\t"
70 res += "memcpy(&r_in[" + `insarity` + "], in, sizeof(ir_node *) * arity);\n\t"
72 res = "ir_node *in[" + `arity` + "];\n\t"
74 for input in node["ins"]:
75 res += "in[" + `i` + "] = irn_" + input + ";\n\t"
79 def format_arity_and_ins(node):
81 if arity == "dynamic":
83 elif arity == "variable":
84 if len(node["ins"]) == 0:
87 return "r_arity, r_in"
91 return `arity` + ", in"
94 env.filters['argdecls'] = format_argdecls
95 env.filters['args'] = format_args
96 env.filters['blockdecl'] = format_blockdecl
97 env.filters['block'] = format_block
98 env.filters['curblock'] = format_curblock
99 env.filters['insdecl'] = format_insdecl
100 env.filters['arity_and_ins'] = format_arity_and_ins
102 def add_attr(list, type, name, init = None, initname = None):
104 initname = "." + name
106 list.append(dict(type = type, name = name, init = init, initname = initname))
108 list.append(dict(type = type, name = name, initname = initname))
110 def prepare_attr(attr):
112 return dict(type = attr["type"], name = attr["name"], init = attr["init"])
114 return dict(type = attr["type"], name = attr["name"])
116 def preprocess_node(nodename, node):
117 # set default attributes
119 parent = ir_spec.nodes[node["is_a"]]
120 node["ins"] = parent["ins"]
122 node["outs"] = parent["outs"]
125 node["mode"] = "mode_T"
126 if "nodbginfo" in node:
129 node["dbdeclnocomma"] = ""
132 node["dbdecl"] = "dbg_info *db, "
133 node["dbdeclnocomma"] = "dbg_info *db"
135 node.setdefault("ins", [])
136 node.setdefault("arity", len(node["ins"]))
137 node.setdefault("attrs", [])
138 node.setdefault("constrname", nodename);
139 node.setdefault("constructor_args", [])
140 node.setdefault("attrs_name", nodename.lower())
141 node.setdefault("block", "block")
142 node.setdefault("pinned", "no")
147 # construct node arguments
151 for input in node["ins"]:
152 arguments.append(dict(type = "ir_node *", name = "irn_" + input))
154 # Special case for Builtin...
155 if nodename == "Builtin":
156 for attr in node["attrs"]:
157 if attr["name"] == "kind":
158 attr.setdefault("initname", "." + attr["name"])
159 arguments.append(prepare_attr(attr))
161 if node["arity"] == "variable":
162 arguments.append(dict(type = "int", name = "arity"))
163 arguments.append(dict(type = "ir_node **", name = "in"))
165 if "mode" not in node:
166 arguments.append(dict(type = "ir_mode *", name = "mode"))
167 node["mode"] = "mode"
169 attrs_with_special = 0
170 for attr in node["attrs"]:
171 if nodename == "Builtin" and attr["name"] == "kind":
174 attr.setdefault("initname", "." + attr["name"])
176 if "special" in attr:
177 if not "init" in attr:
178 print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename
181 if attrs_with_special != 0:
182 print "Node type %s has more than one attribute with a \"special\" entry" % nodename
185 attrs_with_special += 1
187 if "prefix" in attr["special"]:
188 specialname = attr["special"]["prefix"] + nodename
189 elif "suffix" in attr["special"]:
190 specialname = nodename + attr["special"]["suffix"]
192 print "Unknown special constructor type for node type %s" % nodename
195 specialconstrs.append(
197 constrname = specialname,
201 elif not "init" in attr:
202 arguments.append(prepare_attr(attr))
204 # dynamic pin state means more constructor arguments
205 if is_dynamic_pinned(node):
206 if "pinned_init" in node:
207 initattrs.append(dict(
208 initname = ".exc.pin_state",
209 init = "op_pin_state_" + node["pinned_init"]
212 node["constructor_args"].append(
215 type = "op_pin_state"
218 initattrs.append(dict(
219 initname = ".exc.pin_state",
223 for arg in node["constructor_args"]:
224 arguments.append(prepare_attr(arg))
225 if arg["type"] == "ir_cons_flags":
227 initattrs.append(dict(initname = ".exc.pin_state",
228 init = name + " & cons_floats ? op_pin_state_floats : op_pin_state_pinned"))
229 initattrs.append(dict(initname = ".volatility",
230 init = name + " & cons_volatile ? volatility_is_volatile : volatility_non_volatile"))
231 initattrs.append(dict(initname = ".aligned",
232 init = name + " & cons_unaligned ? align_non_aligned : align_is_aligned"))
234 node["args"] = arguments
235 node["initattrs"] = initattrs
236 node["special_constructors"] = specialconstrs
238 #############################
240 node_template = env.from_string('''
241 ir_node *new_rd_{{node["constrname"]}}({{node["dbdecl"]}}ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
244 ir_graph *rem = current_ir_graph;
246 current_ir_graph = irg;
247 res = new_ir_node({{node["db"]}}, irg, {{node["block"]}}, op_{{nodename}}, {{node["mode"]}}, {{node|arity_and_ins}});
248 {% for attr in node["attrs"] -%}
249 res->attr.{{node["attrs_name"]}}{{attr["initname"]}} =
250 {%- if "init" in attr %} {{ attr["init"] -}};
251 {%- else %} {{ attr["name"] -}};
254 {%- for attr in node["initattrs"] -%}
255 res->attr.{{node["attrs_name"]}}{{attr["initname"]}} = {{ attr["init"] -}};
258 {% if node["optimize"] != False -%}
259 res = optimize_node(res);
261 IRN_VRFY_IRG(res, irg);
262 current_ir_graph = rem;
266 ir_node *new_r_{{node["constrname"]}}(ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
268 {% if node["nodbginfo"] -%}
269 return new_rd_{{node["constrname"]}}(irg{{node|block}}{{node|args}});
271 return new_rd_{{node["constrname"]}}(NULL, irg{{node|block}}{{node|args}});
275 ir_node *new_d_{{node["constrname"]}}({{node["dbdeclnocomma"]}}{{node|argdecls(node["nodbginfo"])}})
279 {% if node["nodbginfo"] -%}
280 res = new_rd_{{node["constrname"]}}(current_ir_graph{{node|curblock}}{{node|args}});
282 res = new_rd_{{node["constrname"]}}(db, current_ir_graph{{node|curblock}}{{node|args}});
288 ir_node *new_{{node["constrname"]}}({{node|argdecls(True, True)}})
290 {% if node["nodbginfo"] -%}
291 return new_d_{{node["constrname"]}}({{node|args(True)}});
293 return new_d_{{node["constrname"]}}(NULL{{node|args}});
299 #############################
302 """the main function"""
305 print "usage: %s specname(ignored) destdirectory" % argv[0]
311 niymap = ["Anchor", "ASM", "Bad",
312 "CallBegin", "Const", "Const_type", "Const_long",
313 "defaultProj", "Dummy", "EndReg", "EndExcept",
315 "simpleSel", "SymConst", "SymConst_type", "Sync"]
317 file = open(gendir + "/gen_ir_cons.c.inl", "w")
318 for nodename, node in do_dictsort(ir_spec.nodes):
319 if nodename in niymap:
321 preprocess_node(nodename, node)
322 if not "abstract" in node:
323 file.write(node_template.render(vars()))
325 if "special_constructors" in node:
326 for special in node["special_constructors"]:
327 node["constrname"] = special["constrname"]
328 special["attr"]["init"] = special["attr"]["special"]["init"]
329 file.write(node_template.render(vars()))
333 if __name__ == "__main__":