3 from jinja2 import Environment, Template
4 from jinja2.filters import do_dictsort
5 from spec_util import is_dynamic_pinned, verify_node, isAbstract
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 s = ", ".join(arglist)
22 def format_ifnset(string, node, key):
23 if hasattr(node, key):
27 def format_block(node):
28 if hasattr(node, "knownBlock"):
29 return "current_ir_graph"
31 return "get_node(env, preds[0])"
34 env.filters['args'] = format_args
35 env.filters['ifnset'] = format_ifnset
36 env.filters['block'] = format_block
38 def get_io_type(type, attrname, node):
40 importcmd = "tarval *%s = read_tv(env);" % attrname
41 exportcmd = "write_tarval(env, %(val)s);";
42 elif type == "ir_mode*":
43 importcmd = "ir_mode *%s = read_mode(env);" % attrname
44 exportcmd = "write_mode(env, %(val)s);"
45 elif type == "ir_entity*":
46 importcmd = "ir_entity *%s = read_entity(env);" % attrname
47 exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));"""
48 elif type == "ir_type*":
49 importcmd = "ir_type *%s = read_type(env);" % attrname
50 exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));"""
51 elif type == "long" and node.name == "Proj":
52 importcmd = "long %s = read_long(env);" % attrname
53 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
54 elif type == "pn_Cmp" or type == "ir_where_alloc":
55 importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
56 exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
57 elif type == "ir_cons_flags" and node.name == "Store":
58 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
59 exportcmd = """write_pin_state(env, irn);
60 write_volatility(env, irn);
61 write_align(env, irn);"""
62 elif type == "ir_cons_flags" and node.name == "Load":
63 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
64 exportcmd = """write_pin_state(env, irn);
65 write_volatility(env, irn);
66 write_align(env, irn);"""
67 elif type == "op_pin_state":
68 importcmd = "op_pin_state %s = read_pin_state(env);" % attrname
69 exportcmd = "write_pin_state(env, irn);"
70 elif type == "ir_builtin_kind":
71 importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
72 exportcmd = "write_builtin_kind(env, irn);"
73 elif type == "cond_kind":
74 importcmd = "cond_kind %s = read_cond_kind(env);" % attrname
75 exportcmd = "write_cond_kind(env, irn);"
76 elif type == "cond_jmp_predicate":
77 importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname
78 exportcmd = "write_cond_jmp_predicate(env, irn);"
80 importcmd = "int %s = (int) read_long(env);" % attrname
81 exportcmd = """fprintf(env->file, "%%d ", %(val)s);"""
83 importcmd = "long %s = read_long(env);" % attrname
84 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
86 error("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
87 importcmd = """// BAD: %s %s
88 %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
89 exportcmd = "// BAD: %s" % type
90 return (importcmd, exportcmd)
92 def prepare_attr(node, attr):
93 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
94 attr["importcmd"] = importcmd
95 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (node.name, attr["name"])}
98 def preprocess_node(node):
99 # dynamic pin state means, we have to im/export that
100 if is_dynamic_pinned(node):
103 type = "op_pin_state"
105 if hasattr(node, "pinned_init"):
106 newattr["init"] = node.pinned_init
107 node.attrs.append(newattr)
111 # construct node arguments
116 for input in node.ins:
117 arguments.append("prednodes[%i]" % i)
120 if node.arity == "variable" or node.arity == "dynamic":
121 arguments.append("numpreds - %i" % (i + 1))
122 arguments.append("prednodes + %i" % i)
124 if not hasattr(node, "mode"):
125 arguments.append("mode")
127 attrs_with_special = 0
128 for attr in node.attrs:
129 prepare_attr(node, attr)
130 if "special" in attr:
131 if not "init" in attr:
132 warning("Node type %s has an attribute with a \"special\" entry but without \"init\"" % node.name)
135 if attrs_with_special != 0:
136 warning("Node type %s has more than one attribute with a \"special\" entry" % node.name)
139 attrs_with_special += 1
141 if "prefix" in attr["special"]:
142 specialname = attr["special"]["prefix"] + node.name
143 elif "suffix" in attr["special"]:
144 specialname = node.name + attr["special"]["suffix"]
146 error("Unknown special constructor type for node type %s" % node.name)
149 specialconstrs.append(
151 constrname = specialname,
152 attrname = attr["name"],
153 value = attr["special"]["init"]
157 if attr["type"] == "op_pin_state":
158 initfunc = "set_irn_pinned"
160 initfunc = "set_" + node.name + "_" + attr["name"]
161 initargs.append((attr["name"], initfunc))
163 arguments.append(attr["name"])
165 for arg in node.constructor_args:
166 prepare_attr(node, arg)
167 arguments.append(arg["name"])
169 node.arguments = arguments
170 node.initargs = initargs
171 node.special_constructors = specialconstrs
173 export_attrs_template = env.from_string('''
174 case iro_{{node.name}}:
175 {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
176 {% for attr in node.attrs %}{{attr.exportcmd}}
178 {% for attr in node.constructor_args %}{{attr.exportcmd}}
179 {% endfor %}break;''')
181 import_attrs_template = env.from_string('''
182 case iro_{{node.name}}:
184 {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
185 {% for attr in node.attrs %}{{attr.importcmd}}
187 {% for attr in node.constructor_args %}{{attr.importcmd}}
189 {% for special in node.special_constructors %}if({{special.attrname}} == {{special.value}})
190 newnode = new_r_{{special.constrname}}({{node|block}}{{node.arguments|args}});
192 newnode = new_r_{{node.name}}({{node|block}}{{node.arguments|args}});
193 {% for (initarg, initfunc) in node.initargs %}{{initfunc}}(newnode, {{initarg}});
200 """the main function"""
203 print "usage: %s specname(ignored) destdirectory" % argv[0]
207 # these nodes don't work correctly yet for some reasons...
208 niynodes = [ "EndExcept", "EndReg", "ASM" ]
209 # these have custom im-/export code
210 customcode = [ "Start", "End", "Anchor", "SymConst", "Block" ]
213 for node in ir_spec.nodes:
216 real_nodes.append(node)
218 file = open(gendir + "/gen_irio_export.inl", "w");
219 for node in real_nodes:
220 if node.__name__ in niynodes:
223 preprocess_node(node)
224 file.write(export_attrs_template.render(vars()))
228 file = open(gendir + "/gen_irio_import.inl", "w");
229 for node in real_nodes:
230 if node.name in customcode or node.name in niynodes:
232 file.write(import_attrs_template.render(vars()))
236 file = open(gendir + "/gen_irio_lex.inl", "w");
237 for node in real_nodes:
238 if node.name in niynodes:
240 file.write("\tINSERT(\"" + node.name + "\", tt_iro, iro_" + node.name + ");\n");