3 from jinja2 import Environment, Template
4 from jinja2.filters import do_dictsort
5 from spec_util import is_dynamic_pinned, verify_node
9 """writes an error message to stderr"""
10 sys.stderr.write("Error: " + msg + "\n");
13 """writes a warning message to stderr"""
14 sys.stderr.write("Warning: " + msg + "\n");
16 def format_args(arglist):
17 #argstrings = map(lambda arg : arg["name"], arglist)
18 #return ", ".join(argstrings)
19 s = ", ".join(arglist)
24 def format_ifnset(string, node, key):
29 def format_block(node):
30 if node.get("knownBlock"):
33 return ", get_node(env, preds[0])"
36 env.filters['args'] = format_args
37 env.filters['ifnset'] = format_ifnset
38 env.filters['block'] = format_block
40 def get_io_type(type, attrname, nodename):
42 importcmd = "tarval *%s = read_tv(env);" % attrname
43 exportcmd = "write_tarval(env, %(val)s);";
44 elif type == "ir_mode*":
45 importcmd = "ir_mode *%s = read_mode(env);" % attrname
46 exportcmd = "write_mode(env, %(val)s);"
47 elif type == "ir_entity*":
48 importcmd = "ir_entity *%s = read_entity(env);" % attrname
49 exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));"""
50 elif type == "ir_type*":
51 importcmd = "ir_type *%s = read_type(env);" % attrname
52 exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));"""
53 elif type == "long" and nodename == "Proj":
54 importcmd = "long %s = read_long(env);" % attrname
55 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
56 elif type == "pn_Cmp" or type == "ir_where_alloc":
57 importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
58 exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
59 elif type == "ir_cons_flags" and nodename == "Store":
60 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
61 exportcmd = """write_pin_state(env, irn);
62 write_volatility(env, irn);
63 write_align(env, irn);"""
64 elif type == "ir_cons_flags" and nodename == "Load":
65 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
66 exportcmd = """write_pin_state(env, irn);
67 write_volatility(env, irn);
68 write_align(env, irn);"""
69 elif type == "op_pin_state":
70 importcmd = "op_pin_state %s = read_pin_state(env);" % attrname
71 exportcmd = "write_pin_state(env, irn);"
72 elif type == "ir_builtin_kind":
73 importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
74 exportcmd = "write_builtin_kind(env, irn);"
75 elif type == "cond_kind":
76 importcmd = "cond_kind %s = read_cond_kind(env);" % attrname
77 exportcmd = "write_cond_kind(env, irn);"
78 elif type == "cond_jmp_predicate":
79 importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname
80 exportcmd = "write_cond_jmp_predicate(env, irn);"
82 importcmd = "int %s = (int) read_long(env);" % attrname
83 exportcmd = """fprintf(env->file, "%%d ", %(val)s);"""
85 importcmd = "long %s = read_long(env);" % attrname
86 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
88 error("cannot generate import/export for node %s: unsupported attribute type: %s" % (nodename, type))
89 importcmd = """// BAD: %s %s
90 %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
91 exportcmd = "// BAD: %s" % type
92 return (importcmd, exportcmd)
94 def prepare_attr(nodename, attr):
95 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], nodename)
96 attr["importcmd"] = importcmd
97 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (nodename, attr["name"])}
99 def preprocess_node(nodename, node):
101 parent = ir_spec.nodes[node["is_a"]]
102 node["ins"] = parent["ins"]
104 node["outs"] = parent["outs"]
105 if "ins" not in node:
108 node["mode"] = "mode_T"
109 if "arity" not in node:
110 node["arity"] = len(node["ins"])
111 if "attrs" not in node:
113 if "constructor_args" not in node:
114 node["constructor_args"] = []
115 if "pinned" not in node:
116 node["pinned"] = "no"
117 # dynamic pin state means, we have to im/export that
118 if is_dynamic_pinned(node):
121 type = "op_pin_state"
123 if "pinned_init" in node:
124 newattr["init"] = node["pinned_init"]
125 node["attrs"].append(newattr)
127 verify_node(nodename, node)
129 # construct node arguments
134 for input in node["ins"]:
135 arguments.append("prednodes[%i]" % i)
138 if node["arity"] == "variable" or node["arity"] == "dynamic":
139 arguments.append("numpreds - %i" % (i + 1))
140 arguments.append("prednodes + %i" % i)
142 if "mode" not in node:
143 arguments.append("mode")
145 attrs_with_special = 0
146 for attr in node["attrs"]:
147 prepare_attr(nodename, attr)
148 if "special" in attr:
149 if not "init" in attr:
150 warning("Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename)
153 if attrs_with_special != 0:
154 warning("Node type %s has more than one attribute with a \"special\" entry" % nodename)
157 attrs_with_special += 1
159 if "prefix" in attr["special"]:
160 specialname = attr["special"]["prefix"] + nodename
161 elif "suffix" in attr["special"]:
162 specialname = nodename + attr["special"]["suffix"]
164 error("Unknown special constructor type for node type %s" % nodename)
167 specialconstrs.append(
169 constrname = specialname,
170 attrname = attr["name"],
171 value = attr["special"]["init"]
175 if attr["type"] == "op_pin_state":
176 initfunc = "set_irn_pinned"
178 initfunc = "set_" + nodename + "_" + attr["name"]
179 initargs.append((attr["name"], initfunc))
181 arguments.append(attr["name"])
183 for arg in node["constructor_args"]:
184 prepare_attr(nodename, arg)
185 arguments.append(arg["name"])
187 node["arguments"] = arguments
188 node["initargs"] = initargs
189 node["special_constructors"] = specialconstrs
191 export_attrs_template = env.from_string('''
192 case iro_{{nodename}}:
193 {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
194 {% for attr in node.attrs %}{{attr.exportcmd}}
196 {% for attr in node.constructor_args %}{{attr.exportcmd}}
197 {% endfor %}break;''')
199 import_attrs_template = env.from_string('''
200 case iro_{{nodename}}:
202 {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
203 {% for attr in node.attrs %}{{attr.importcmd}}
205 {% for attr in node.constructor_args %}{{attr.importcmd}}
207 {% for special in node.special_constructors %}if({{special.attrname}} == {{special.value}})
208 newnode = new_r_{{special.constrname}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
210 newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
211 {% for (initarg, initfunc) in node.initargs %}{{initfunc}}(newnode, {{initarg}});
218 """the main function"""
221 print "usage: %s specname(ignored) destdirectory" % argv[0]
225 sortednodes = do_dictsort(ir_spec.nodes)
226 # these nodes don't work correctly yet for some reasons...
227 niynodes = [ "EndExcept", "EndReg", "ASM" ]
228 # these have custom im-/export code
229 customcode = [ "Start", "End", "Anchor", "SymConst", "Block" ]
231 file = open(gendir + "/gen_irio_export.inl", "w");
232 for nodename, node in sortednodes:
233 if nodename in niynodes:
236 preprocess_node(nodename, node)
237 if "abstract" not in node:
238 file.write(export_attrs_template.render(vars()))
242 file = open(gendir + "/gen_irio_import.inl", "w");
243 for nodename, node in sortednodes:
244 if "abstract" in node or nodename in customcode or nodename in niynodes:
246 file.write(import_attrs_template.render(vars()))
250 file = open(gendir + "/gen_irio_lex.inl", "w");
251 for nodename, node in sortednodes:
252 if "abstract" not in node and nodename not in niynodes:
253 file.write("\tINSERT(\"" + nodename + "\", tt_iro, iro_" + nodename + ");\n");
256 if __name__ == "__main__":