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_args(arglist):
9 #argstrings = map(lambda arg : arg["name"], arglist)
10 #return ", ".join(argstrings)
11 s = ", ".join(arglist)
16 def format_ifnset(string, node, key):
21 def format_block(node):
22 if node.get("knownBlock"):
25 return ", get_node(env, preds[0])"
28 env.filters['args'] = format_args
29 env.filters['ifnset'] = format_ifnset
30 env.filters['block'] = format_block
32 def get_io_type(type, attrname, nodename):
34 importcmd = "tarval *%s = read_tv(env);" % attrname
35 exportcmd = "write_tarval(env, %(val)s);";
36 elif type == "ir_mode*":
37 importcmd = "ir_mode *%s = read_mode(env);" % attrname
38 exportcmd = "write_mode(env, %(val)s);"
39 elif type == "ir_entity*":
40 importcmd = "ir_entity *%s = read_entity(env);" % attrname
41 exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));"""
42 elif type == "ir_type*":
43 importcmd = "ir_type *%s = read_type(env);" % attrname
44 exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));"""
45 elif type == "long" and nodename == "Proj":
46 importcmd = "long %s = read_long(env);" % attrname
47 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
48 elif type == "pn_Cmp" or type == "ir_where_alloc":
49 importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
50 exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
51 elif type == "ir_cons_flags" and nodename == "Store":
52 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
53 exportcmd = """write_pin_state(env, irn);
54 write_volatility(env, irn);
55 write_align(env, irn);"""
56 elif type == "ir_cons_flags" and nodename == "Load":
57 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
58 exportcmd = """write_pin_state(env, irn);
59 write_volatility(env, irn);
60 write_align(env, irn);"""
61 elif type == "op_pin_state":
62 importcmd = "op_pin_state %s = read_pin_state(env);" % attrname
63 exportcmd = "write_pin_state(env, irn);"
64 elif type == "ir_builtin_kind":
65 importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
66 exportcmd = "write_builtin_kind(env, irn);"
67 elif type == "cond_kind":
68 importcmd = "cond_kind %s = read_cond_kind(env);" % attrname
69 exportcmd = "write_cond_kind(env, irn);"
70 elif type == "cond_jmp_predicate":
71 importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname
72 exportcmd = "write_cond_jmp_predicate(env, irn);"
74 importcmd = "int %s = (int) read_long(env);" % attrname
75 exportcmd = """fprintf(env->file, "%%d ", %(val)s);"""
77 importcmd = "long %s = read_long(env);" % attrname
78 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
80 print "UNKNOWN TYPE: %s" % type
81 importcmd = """// BAD: %s %s
82 %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
83 exportcmd = "// BAD: %s" % type
84 return (importcmd, exportcmd)
86 def prepare_attr(nodename, attr):
87 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], nodename)
88 attr["importcmd"] = importcmd
89 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (nodename, attr["name"])}
91 def preprocess_node(nodename, node):
93 parent = ir_spec.nodes[node["is_a"]]
94 node["ins"] = parent["ins"]
96 node["outs"] = parent["outs"]
100 node["mode"] = "mode_T"
101 if "arity" not in node:
102 node["arity"] = len(node["ins"])
103 if "attrs" not in node:
105 if "constructor_args" not in node:
106 node["constructor_args"] = []
107 if "pinned" not in node:
108 node["pinned"] = "no"
109 # dynamic pin state means, we have to im/export that
110 if is_dynamic_pinned(node):
113 type = "op_pin_state"
115 if "pinned_init" in node:
116 newattr["init"] = node["pinned_init"]
117 node["attrs"].append(newattr)
121 # construct node arguments
126 for input in node["ins"]:
127 arguments.append("prednodes[%i]" % i)
130 if node["arity"] == "variable" or node["arity"] == "dynamic":
131 arguments.append("numpreds - %i" % (i + 1))
132 arguments.append("prednodes + %i" % i)
134 if "mode" not in node:
135 arguments.append("mode")
137 attrs_with_special = 0
138 for attr in node["attrs"]:
139 prepare_attr(nodename, attr)
140 if "special" in attr:
141 if not "init" in attr:
142 print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename
145 if attrs_with_special != 0:
146 print "Node type %s has more than one attribute with a \"special\" entry" % nodename
149 attrs_with_special += 1
151 if "prefix" in attr["special"]:
152 specialname = attr["special"]["prefix"] + nodename
153 elif "suffix" in attr["special"]:
154 specialname = nodename + attr["special"]["suffix"]
156 print "Unknown special constructor type for node type %s" %nodename
159 specialconstrs.append(
161 constrname = specialname,
162 attrname = attr["name"],
163 value = attr["special"]["init"]
167 if attr["type"] == "op_pin_state":
168 initfunc = "set_irn_pinned"
170 initfunc = "set_" + nodename + "_" + attr["name"]
171 initargs.append((attr["name"], initfunc))
173 arguments.append(attr["name"])
175 for arg in node["constructor_args"]:
176 prepare_attr(nodename, arg)
177 arguments.append(arg["name"])
179 node["arguments"] = arguments
180 node["initargs"] = initargs
181 node["special_constructors"] = specialconstrs
183 export_attrs_template = env.from_string('''
184 case iro_{{nodename}}:
185 {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
186 {% for attr in node.attrs %}{{attr.exportcmd}}
188 {% for attr in node.constructor_args %}{{attr.exportcmd}}
189 {% endfor %}break;''')
191 import_attrs_template = env.from_string('''
192 case iro_{{nodename}}:
194 {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
195 {% for attr in node.attrs %}{{attr.importcmd}}
197 {% for attr in node.constructor_args %}{{attr.importcmd}}
199 {% for special in node.special_constructors %}if({{special.attrname}} == {{special.value}})
200 newnode = new_r_{{special.constrname}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
202 newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
203 {% for (initarg, initfunc) in node.initargs %}{{initfunc}}(newnode, {{initarg}});
210 """the main function"""
213 print "usage: %s specname(ignored) destdirectory" % argv[0]
218 sortednodes = do_dictsort(ir_spec.nodes)
220 file = open(gendir + "/gen_irio_export.inl", "w");
221 for nodename, node in sortednodes:
222 preprocess_node(nodename, node)
223 if not "abstract" in node:
224 file.write(export_attrs_template.render(vars()))
228 file = open(gendir + "/gen_irio_import.inl", "w");
229 for nodename, node in sortednodes:
230 if not "abstract" in node and nodename != "Start" and nodename != "End" and nodename != "Anchor" and nodename != "SymConst" and nodename != "Block":
231 file.write(import_attrs_template.render(vars()))
236 file = open(gendir + "/gen_irio_lex.inl", "w");
237 for nodename, node in sortednodes:
238 if not "abstract" in node:
239 file.write("\tINSERT(\"" + nodename + "\", tt_iro, iro_" + nodename + ");\n");
242 if __name__ == "__main__":