4 from jinja2 import Environment, Template
5 from jinja2.filters import do_dictsort
6 from spec_util import is_dynamic_pinned, verify_node, isAbstract, setdefault
7 from ir_spec import nodes
9 def format_argdecls(node, first = False, voidwhenempty = False):
10 if len(node.arguments) == 0:
16 arguments = map(lambda arg: arg["type"] + " " + arg["name"], node.arguments)
20 res += ", ".join(arguments)
23 def format_args(node, first = False):
25 if not first and node.arguments != []:
28 arguments = map(lambda arg: arg["name"], node.arguments)
29 res += ", ".join(arguments)
32 def format_blockdecl(node):
33 if hasattr(node, "knownBlock"):
34 return "ir_graph *irg"
36 return "ir_node *block"
38 def format_irgassign(node):
39 if hasattr(node, "knownBlock"):
42 return "ir_graph *irg = get_Block_irg(block);\n"
44 def format_block(node):
45 if hasattr(node, "knownBlock"):
50 def format_curblock(node):
51 if hasattr(node, "knownBlock"):
52 return "current_ir_graph"
54 return "current_ir_graph->current_block"
56 def format_insdecl(node):
58 if arity == "variable" and len(node.ins) == 0 or arity == "dynamic" or arity == 0:
61 if arity == "variable":
62 insarity = len(node.ins)
63 res = "int r_arity = arity + " + `insarity` + ";\n\tir_node **r_in;\n\t" \
64 + "NEW_ARR_A(ir_node *, r_in, r_arity);\n\t"
66 for input in node.ins:
67 res += "r_in[" + `i` + "] = irn_" + input + ";\n\t"
69 res += "memcpy(&r_in[" + `insarity` + "], in, sizeof(ir_node *) * arity);\n\t"
71 res = "ir_node *in[" + `arity` + "];\n\t"
73 for input in node.ins:
74 res += "in[" + `i` + "] = irn_" + input + ";\n\t"
78 def format_arity_and_ins(node):
80 if arity == "dynamic":
82 elif arity == "variable":
83 if len(node.ins) == 0:
86 return "r_arity, r_in"
90 return `arity` + ", in"
92 def format_arity(node):
93 if hasattr(node, "arity_override"):
94 return node.arity_override
96 if arity == "dynamic":
97 return "oparity_dynamic"
98 if arity == "variable":
99 return "oparity_variable"
101 return "oparity_zero"
103 return "oparity_unary"
105 return "oparity_binary"
107 return "oparity_trinary"
110 def format_pinned(node):
113 return "op_pin_state_pinned"
115 return "op_pin_state_floats"
116 if pinned == "exception":
117 return "op_pin_state_exc_pinned"
118 if pinned == "memory":
119 return "op_pin_state_mem_pinned"
120 print "WARNING: Unknown pinned state %s in format pined" % pinned
123 def format_flags(node):
124 flags = map(lambda x : "irop_flag_" + x, node.flags)
126 flags = [ "irop_flag_none" ]
127 return " | ".join(flags)
129 def format_attr_size(node):
130 if not hasattr(node, "attr_struct"):
132 return "sizeof(%s)" % node.attr_struct
134 def format_opindex(node):
135 if hasattr(node, "op_index"):
139 def filter_isnot(list, flag):
142 if hasattr(node, flag):
148 env.filters['argdecls'] = format_argdecls
149 env.filters['args'] = format_args
150 env.filters['blockdecl'] = format_blockdecl
151 env.filters['irgassign'] = format_irgassign
152 env.filters['block'] = format_block
153 env.filters['curblock'] = format_curblock
154 env.filters['insdecl'] = format_insdecl
155 env.filters['arity_and_ins'] = format_arity_and_ins
156 env.filters['arity'] = format_arity
157 env.filters['pinned'] = format_pinned
158 env.filters['flags'] = format_flags
159 env.filters['attr_size'] = format_attr_size
160 env.filters['isnot'] = filter_isnot
161 env.filters['opindex'] = format_opindex
163 def prepare_attr(attr):
165 return dict(type = attr["type"], name = attr["name"], init = attr["init"])
167 return dict(type = attr["type"], name = attr["name"])
169 def preprocess_node(node):
172 setdefault(node, "attrs_name", node.name.lower())
173 setdefault(node, "block", "block")
175 # construct node arguments
179 for input in node.ins:
180 arguments.append(dict(type = "ir_node *", name = "irn_" + input))
182 if node.arity == "variable" or node.arity == "dynamic":
183 arguments.append(dict(type = "int", name = "arity"))
184 arguments.append(dict(type = "ir_node **", name = "in"))
186 if not hasattr(node, "mode"):
187 arguments.append(dict(type = "ir_mode *", name = "mode"))
190 attrs_with_special = 0
191 for attr in node.attrs:
192 attr.setdefault("initname", "." + attr["name"])
194 if "special" in attr:
195 if not "init" in attr:
196 print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % node.name
199 if attrs_with_special != 0:
200 print "Node type %s has more than one attribute with a \"special\" entry" % node.name
203 attrs_with_special += 1
205 if "prefix" in attr["special"]:
206 specialname = attr["special"]["prefix"] + node.name
207 elif "suffix" in attr["special"]:
208 specialname = node.name + attr["special"]["suffix"]
210 print "Unknown special constructor type for node type %s" % node.name
213 specialconstrs.append(
215 constrname = specialname,
219 elif not "init" in attr:
220 arguments.append(prepare_attr(attr))
222 # dynamic pin state means more constructor arguments
223 if is_dynamic_pinned(node):
224 if hasattr(node, "pinned_init"):
225 initattrs.append(dict(
226 initname = ".exc.pin_state",
227 init = node.pinned_init
230 node.constructor_args.append(
233 type = "op_pin_state"
236 initattrs.append(dict(
237 initname = ".exc.pin_state",
241 for arg in node.constructor_args:
242 arguments.append(prepare_attr(arg))
243 if arg["type"] == "ir_cons_flags":
245 initattrs.append(dict(initname = ".exc.pin_state",
246 init = name + " & cons_floats ? op_pin_state_floats : op_pin_state_pinned"))
247 initattrs.append(dict(initname = ".volatility",
248 init = name + " & cons_volatile ? volatility_is_volatile : volatility_non_volatile"))
249 initattrs.append(dict(initname = ".aligned",
250 init = name + " & cons_unaligned ? align_non_aligned : align_is_aligned"))
252 node.arguments = arguments
253 node.initattrs = initattrs
254 node.special_constructors = specialconstrs
256 #############################
258 constructor_template = env.from_string('''
260 ir_node *new_rd_{{node.constrname}}(dbg_info *dbgi, {{node|blockdecl}}{{node|argdecls}})
263 ir_graph *rem = current_ir_graph;
266 current_ir_graph = irg;
267 res = new_ir_node(dbgi, irg, {{node.block}}, op_{{node.name}}, {{node.mode}}, {{node|arity_and_ins}});
268 {% for attr in node.attrs -%}
269 res->attr.{{node.attrs_name}}{{attr["initname"]}} =
270 {%- if "init" in attr %} {{ attr["init"] -}};
271 {%- else %} {{ attr["name"] -}};
274 {%- for attr in node.initattrs -%}
275 res->attr.{{node.attrs_name}}{{attr["initname"]}} = {{ attr["init"] -}};
278 {% if node.optimize != False -%}
279 res = optimize_node(res);
281 IRN_VRFY_IRG(res, irg);
282 current_ir_graph = rem;
286 ir_node *new_r_{{node.constrname}}({{node|blockdecl}}{{node|argdecls}})
288 return new_rd_{{node.constrname}}(NULL, {{node|block}}{{node|args}});
291 ir_node *new_d_{{node.constrname}}(dbg_info *dbgi{{node|argdecls}})
295 res = new_rd_{{node.constrname}}(dbgi, {{node|curblock}}{{node|args}});
300 ir_node *new_{{node.constrname}}({{node|argdecls(True, True)}})
302 return new_d_{{node.constrname}}(NULL{{node|args}});
306 irnode_h_template = env.from_string('''
307 /* Warning: automatically generated code */
309 {% for node in nodes|isnot('custom_is') %}
310 static inline int _is_{{node.name}}(const ir_node *node)
312 assert(node != NULL);
313 return _get_irn_op(node) == op_{{node.name}};
317 {% for node in nodes %}
318 #define is_{{node.name}}(node) _is_{{node.name}}(node)
323 irnode_template = env.from_string('''
324 /* Warning: automatically generated code */
325 {% for node in nodes %}
326 int (is_{{node.name}})(const ir_node *node)
328 return _is_{{node.name}}(node);
333 irop_template = env.from_string('''
334 /* Warning: automatically generated code */
335 {% for node in nodes %}
336 ir_op *op_{{node.name}}; ir_op *get_op_{{node.name}}(void) { return op_{{node.name}}; }
341 {% for node in nodes %}
342 op_{{node.name}} = new_ir_op(iro_{{node.name}}, "{{node.name}}", {{node|pinned}}, {{node|flags}}, {{node|arity}}, {{node|opindex}}, {{node|attr_size}}, NULL);
350 {% for node in nodes %}
351 free_ir_op(op_{{node.name}}); op_{{node.name}} = NULL;
357 #############################
361 print "usage: %s specname(ignored) destdirectory" % argv[0]
367 niymap = [ "ASM", "Const", "Phi", "SymConst", "Sync"]
373 real_nodes.append(node)
375 file = open(gendir + "/gen_ir_cons.c.inl", "w")
376 for node in real_nodes:
377 preprocess_node(node)
379 if node.name in niymap:
382 if not isAbstract(node) and not hasattr(node, "singleton"):
383 file.write(constructor_template.render(vars()))
385 if hasattr(node, "special_constructors"):
386 for special in node.special_constructors:
387 node.constrname = special["constrname"]
388 special["attr"]["init"] = special["attr"]["special"]["init"]
389 file.write(constructor_template.render(vars()))
393 file = open(gendir + "/gen_irnode.h", "w")
394 file.write(irnode_h_template.render(nodes = real_nodes))
397 file = open(gendir + "/gen_irnode.c.inl", "w")
398 file.write(irnode_template.render(nodes = real_nodes))
401 file = open(gendir + "/gen_irop.c.inl", "w")
402 file.write(irop_template.render(nodes = real_nodes))