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);"""
82 elif type == "unsigned":
83 importcmd = "unsigned %s = (unsigned) read_long(env);" % attrname
84 exportcmd = """fprintf(env->file, "%%u ", %(val)s);"""
86 importcmd = "long %s = read_long(env);" % attrname
87 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
89 error("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
90 importcmd = """// BAD: %s %s
91 %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
92 exportcmd = "// BAD: %s" % type
93 return (importcmd, exportcmd)
95 def prepare_attr(node, attr):
96 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
97 attr["importcmd"] = importcmd
98 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (node.name, attr["name"])}
101 def preprocess_node(node):
102 # dynamic pin state means, we have to im/export that
103 if is_dynamic_pinned(node):
106 type = "op_pin_state"
108 if hasattr(node, "pinned_init"):
109 newattr["init"] = node.pinned_init
110 node.attrs.append(newattr)
114 # construct node arguments
119 for input in node.ins:
120 arguments.append("prednodes[%i]" % i)
123 if node.arity == "variable" or node.arity == "dynamic":
124 arguments.append("numpreds - %i" % (i + 1))
125 arguments.append("prednodes + %i" % i)
127 if not hasattr(node, "mode"):
128 arguments.append("mode")
130 attrs_with_special = 0
131 for attr in node.attrs:
132 prepare_attr(node, attr)
133 if "special" in attr:
134 if not "init" in attr:
135 warning("Node type %s has an attribute with a \"special\" entry but without \"init\"" % node.name)
138 if attrs_with_special != 0:
139 warning("Node type %s has more than one attribute with a \"special\" entry" % node.name)
142 attrs_with_special += 1
144 if "prefix" in attr["special"]:
145 specialname = attr["special"]["prefix"] + node.name
146 elif "suffix" in attr["special"]:
147 specialname = node.name + attr["special"]["suffix"]
149 error("Unknown special constructor type for node type %s" % node.name)
152 specialconstrs.append(
154 constrname = specialname,
155 attrname = attr["name"],
156 value = attr["special"]["init"]
160 if attr["type"] == "op_pin_state":
161 initfunc = "set_irn_pinned"
163 initfunc = "set_" + node.name + "_" + attr["name"]
164 initargs.append((attr["name"], initfunc))
166 arguments.append(attr["name"])
168 for arg in node.constructor_args:
169 prepare_attr(node, arg)
170 arguments.append(arg["name"])
172 node.arguments = arguments
173 node.initargs = initargs
174 node.special_constructors = specialconstrs
176 export_attrs_template = env.from_string('''
177 case iro_{{node.name}}:
178 {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
179 {% for attr in node.attrs %}{{attr.exportcmd}}
181 {% for attr in node.constructor_args %}{{attr.exportcmd}}
182 {% endfor %}break;''')
184 import_attrs_template = env.from_string('''
185 case iro_{{node.name}}:
187 {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
188 {% for attr in node.attrs %}{{attr.importcmd}}
190 {% for attr in node.constructor_args %}{{attr.importcmd}}
192 {% for special in node.special_constructors %}if({{special.attrname}} == {{special.value}})
193 newnode = new_r_{{special.constrname}}({{node|block}}{{node.arguments|args}});
195 newnode = new_r_{{node.name}}({{node|block}}{{node.arguments|args}});
196 {% for (initarg, initfunc) in node.initargs %}{{initfunc}}(newnode, {{initarg}});
203 """the main function"""
206 print "usage: %s specname(ignored) destdirectory" % argv[0]
210 # these nodes don't work correctly yet for some reasons...
211 niynodes = [ "EndExcept", "EndReg", "ASM" ]
212 # these have custom im-/export code
213 customcode = [ "Start", "End", "Anchor", "SymConst", "Block" ]
216 for node in ir_spec.nodes:
219 real_nodes.append(node)
221 file = open(gendir + "/gen_irio_export.inl", "w");
222 for node in real_nodes:
223 if node.__name__ in niynodes:
226 preprocess_node(node)
227 file.write(export_attrs_template.render(vars()))
231 file = open(gendir + "/gen_irio_import.inl", "w");
232 for node in real_nodes:
233 if node.name in customcode or node.name in niynodes:
235 file.write(import_attrs_template.render(vars()))
239 file = open(gendir + "/gen_irio_lex.inl", "w");
240 for node in real_nodes:
241 if node.name in niynodes:
243 file.write("\tINSERT(\"" + node.name + "\", tt_iro, iro_" + node.name + ");\n");