4 from jinja2 import Environment, Template
5 from jinja2.filters import do_dictsort
6 from spec_util import is_dynamic_pinned, verify_node, isAbstract
10 """writes an error message to stderr"""
11 sys.stderr.write("Error: " + msg + "\n");
14 """writes a warning message to stderr"""
15 sys.stderr.write("Warning: " + msg + "\n");
17 def format_args(arglist):
18 return "\n".join(arglist)
20 def format_ifnset(string, node, key):
21 if hasattr(node, key):
25 def format_block(node):
26 if hasattr(node, "knownBlock"):
27 if hasattr(node, "knownGraph"):
29 return "current_ir_graph"
31 return "get_node(env, preds[0])"
33 def format_arguments(string):
34 args = re.split('\s*\n\s*', string)
37 if len(args) > 0 and args[-1] == '':
39 return ", ".join(args)
42 env.filters['args'] = format_args
43 env.filters['ifnset'] = format_ifnset
44 env.filters['block'] = format_block
45 env.filters['arguments'] = format_arguments
47 def get_io_type(type, attrname, node):
48 if type == "ir_tarval*":
49 importcmd = "ir_tarval *%s = read_tv(env);" % attrname
50 exportcmd = "write_tarval(env, %(val)s);";
51 elif type == "ir_mode*":
52 importcmd = "ir_mode *%s = read_mode(env);" % attrname
53 exportcmd = "write_mode(env, %(val)s);"
54 elif type == "ir_entity*":
55 importcmd = "ir_entity *%s = read_entity(env);" % attrname
56 exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));"""
57 elif type == "ir_type*":
58 importcmd = "ir_type *%s = read_type(env);" % attrname
59 exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));"""
60 elif type == "long" and node.name == "Proj":
61 importcmd = "long %s = read_long(env);" % attrname
62 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
63 elif type == "pn_Cmp" or type == "ir_where_alloc":
64 importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
65 exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
66 elif type == "ir_cons_flags" and node.name == "Store":
67 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
68 exportcmd = """write_pin_state(env, irn);
69 write_volatility(env, irn);
70 write_align(env, irn);"""
71 elif type == "ir_cons_flags" and node.name == "Load":
72 importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
73 exportcmd = """write_pin_state(env, irn);
74 write_volatility(env, irn);
75 write_align(env, irn);"""
76 elif type == "op_pin_state":
77 importcmd = "op_pin_state %s = read_pin_state(env);" % attrname
78 exportcmd = "write_pin_state(env, irn);"
79 elif type == "ir_builtin_kind":
80 importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
81 exportcmd = "write_builtin_kind(env, irn);"
82 elif type == "cond_kind":
83 importcmd = "cond_kind %s = read_cond_kind(env);" % attrname
84 exportcmd = "write_cond_kind(env, irn);"
85 elif type == "cond_jmp_predicate":
86 importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname
87 exportcmd = "write_cond_jmp_predicate(env, irn);"
89 importcmd = "int %s = (int) read_long(env);" % attrname
90 exportcmd = """fprintf(env->file, "%%d ", %(val)s);"""
91 elif type == "unsigned":
92 importcmd = "unsigned %s = (unsigned) read_long(env);" % attrname
93 exportcmd = """fprintf(env->file, "%%u ", %(val)s);"""
95 importcmd = "long %s = read_long(env);" % attrname
96 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
98 warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
99 importcmd = """// BAD: %s %s
100 %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
101 exportcmd = "// BAD: %s" % type
102 return (importcmd, exportcmd)
104 def prepare_attr(node, attr):
105 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
106 attr["importcmd"] = importcmd
107 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (node.name, attr["name"])}
110 def preprocess_node(node):
111 # dynamic pin state means, we have to im/export that
112 if is_dynamic_pinned(node):
115 type = "op_pin_state"
117 if hasattr(node, "pinned_init"):
118 newattr["init"] = node.pinned_init
119 node.attrs.append(newattr)
123 # construct node arguments
128 for input in node.ins:
129 arguments.append("prednodes[%i]" % i)
132 if node.arity == "variable" or node.arity == "dynamic":
133 arguments.append("numpreds - %i" % (i + 1))
134 arguments.append("prednodes + %i" % i)
136 if not hasattr(node, "mode"):
137 arguments.append("mode")
139 attrs_with_special = 0
140 for attr in node.attrs:
141 prepare_attr(node, attr)
142 if "special" in attr:
143 if not "init" in attr:
144 warning("Node type %s has an attribute with a \"special\" entry but without \"init\"" % node.name)
147 if attrs_with_special != 0:
148 warning("Node type %s has more than one attribute with a \"special\" entry" % node.name)
151 attrs_with_special += 1
153 if "prefix" in attr["special"]:
154 specialname = attr["special"]["prefix"] + node.name
155 elif "suffix" in attr["special"]:
156 specialname = node.name + attr["special"]["suffix"]
158 error("Unknown special constructor type for node type %s" % node.name)
161 specialconstrs.append(
163 constrname = specialname,
164 attrname = attr["name"],
165 value = attr["special"]["init"]
169 if attr["type"] == "op_pin_state":
170 initfunc = "set_irn_pinned"
172 initfunc = "set_" + node.name + "_" + attr["name"]
173 initargs.append((attr["name"], initfunc))
175 arguments.append(attr["name"])
177 for arg in node.constructor_args:
178 prepare_attr(node, arg)
179 arguments.append(arg["name"])
181 node.arguments = arguments
182 node.initargs = initargs
183 node.special_constructors = specialconstrs
185 export_attrs_template = env.from_string('''
186 case iro_{{node.name}}:
187 {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
188 {% for attr in node.attrs %}{{attr.exportcmd}}
190 {% for attr in node.constructor_args %}{{attr.exportcmd}}
191 {% endfor %}break;''')
193 import_attrs_template = env.from_string('''
194 case iro_{{node.name}}: {
195 {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
196 {% for attr in node.attrs %}
199 {% for attr in node.constructor_args %}
202 {% for special in node.special_constructors %}
203 if ({{special.attrname}} == {{special.value}})
204 newnode = new_r_{{special.constrname}}(
205 {%- filter arguments %}
207 {{node.arguments|args}}
211 newnode = new_r_{{node.name}}(
212 {%- filter arguments %}
214 {{node.arguments|args}}
216 {% for (initarg, initfunc) in node.initargs %}
217 {{initfunc}}(newnode, {{initarg}});
224 """the main function"""
227 print "usage: %s specname(ignored) destdirectory" % argv[0]
231 # these nodes don't work correctly yet for some reasons...
233 # these have custom im-/export code
234 customcode = [ "Start", "End", "Anchor", "SymConst", "Block", "Deleted" ]
237 for node in ir_spec.nodes:
240 real_nodes.append(node)
242 file = open(gendir + "/gen_irio_export.inl", "w");
243 for node in real_nodes:
244 if node.__name__ in niynodes:
247 preprocess_node(node)
248 file.write(export_attrs_template.render(vars()))
252 file = open(gendir + "/gen_irio_import.inl", "w");
253 for node in real_nodes:
254 if node.name in customcode or node.name in niynodes:
256 file.write(import_attrs_template.render(vars()))
260 file = open(gendir + "/gen_irio_lex.inl", "w");
261 for node in real_nodes:
262 if node.name in niynodes:
264 file.write("\tINSERT(tt_iro, \"%s\", iro_%s);\n" % (node.name, node.name));