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_block(node):
21 if hasattr(node, "knownBlock"):
22 if hasattr(node, "knownGraph"):
28 def format_arguments(string):
29 args = re.split('\s*\n\s*', string)
32 if len(args) > 0 and args[-1] == '':
34 return ", ".join(args)
36 def filter_isnot(list, flag):
37 return filter(lambda x: not hasattr(x, flag), list)
39 def filter_notset(list, flag):
40 return filter(lambda x: not getattr(x,flag), list)
42 def filter_hasnot(list, flag):
43 return filter(lambda x: flag not in x, list)
46 env.filters['args'] = format_args
47 env.filters['block'] = format_block
48 env.filters['arguments'] = format_arguments
49 env.filters['isnot'] = filter_isnot
50 env.filters['notset'] = filter_notset
51 env.filters['hasnot'] = filter_hasnot
53 def get_io_type(type, attrname, node):
54 if type == "ir_tarval*":
55 importcmd = "read_tarval(env)"
56 exportcmd = "write_tarval(env, %(val)s);"
57 elif type == "ir_mode*":
58 importcmd = "read_mode_ref(env)"
59 exportcmd = "write_mode_ref(env, %(val)s);"
60 elif type == "ir_entity*":
61 importcmd = "read_entity_ref(env)"
62 exportcmd = "write_entity_ref(env, %(val)s);"
63 elif type == "ir_type*":
64 importcmd = "read_type_ref(env)"
65 exportcmd = "write_type_ref(env, %(val)s);"
67 importcmd = "read_long(env)"
68 exportcmd = "write_long(env, %(val)s);"
69 elif type == "ir_relation":
70 importcmd = "read_relation(env)"
71 exportcmd = "write_relation(env, %(val)s);"
72 elif type == "ir_where_alloc":
73 importcmd = "read_where_alloc(env)"
74 exportcmd = "write_where_alloc(env, %(val)s);"
75 elif type == "ir_align":
76 importcmd = "read_align(env)"
77 exportcmd = "write_align(env, %(val)s);"
78 elif type == "ir_volatility":
79 importcmd = "read_volatility(env)"
80 exportcmd = "write_volatility(env, %(val)s);"
81 elif type == "ir_cons_flags":
82 importcmd = "cons_none"
83 exportcmd = "" # can't really export cons_flags
84 elif type == "op_pin_state":
85 importcmd = "read_pin_state(env)"
86 exportcmd = "write_pin_state(env, node);"
87 elif type == "ir_builtin_kind":
88 importcmd = "read_builtin_kind(env)"
89 exportcmd = "write_builtin_kind(env, node);"
90 elif type == "cond_kind":
91 importcmd = "read_cond_kind(env)"
92 exportcmd = "write_cond_kind(env, node);"
93 elif type == "cond_jmp_predicate":
94 importcmd = "read_cond_jmp_predicate(env)"
95 exportcmd = "write_cond_jmp_predicate(env, node);"
97 importcmd = "read_int(env)"
98 exportcmd = "write_int(env, %(val)s);"
99 elif type == "unsigned":
100 importcmd = "read_unsigned(env)"
101 exportcmd = "write_unsigned(env, %(val)s);"
103 importcmd = "read_long(env)"
104 exportcmd = "write_long(env, %(val)s);"
105 elif type == "ir_switch_table*":
106 importcmd = "read_switch_table(env)"
107 exportcmd = "write_switch_table(env, %(val)s);"
109 warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
110 importcmd = "/* BAD: %s %s */ (%s)0" % (type, attrname, type)
111 exportcmd = "// BAD: %s" % type
112 return (importcmd, exportcmd)
114 def prepare_attr(node, attr):
115 (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
116 attr["importcmd"] = importcmd
117 attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(node)" % (node.name, attr["name"])}
120 def preprocess_node(node):
123 if node.customSerializer:
126 # construct node arguments
129 for input in node.ins:
130 arguments.append("in_%s" % input[0])
132 if node.arity == "variable" or node.arity == "dynamic":
133 arguments.append("n_preds")
134 arguments.append("preds")
136 if not hasattr(node, "mode"):
137 arguments.append("mode")
139 for attr in node.attrs:
140 prepare_attr(node, attr)
141 if "to_flags" in attr:
142 node.constructorFlags = True
143 attr['to_flags'] = attr['to_flags'] % (attr["name"])
145 extraattrs.append(attr)
147 arguments.append(attr["name"])
149 for arg in node.constructor_args:
150 if arg['type'] != "ir_cons_flags" and arg['name'] != "flags":
151 error("only ir_cons_flags constructor arg supported in irio")
153 node.constructorFlags = True
154 arguments.append("flags")
156 node.arguments = arguments
157 node.extraattrs = extraattrs
158 node.dynamic_pinned = is_dynamic_pinned(node)
160 io_template = env.from_string('''/* Warning: automatically generated code */
161 {%- for node in nodes|notset('customSerializer') %}
162 static ir_node *read_{{node.name}}(read_env_t *env)
164 {%- if not node.knownBlock %}
165 ir_node *block = read_node_ref(env);
167 {%- for input in node.ins %}
168 ir_node *in_{{input[0]}} = read_node_ref(env);
170 {%- if not hasattr(node, "mode") %}
171 ir_mode *mode = read_mode_ref(env);
173 {%- for attr in node.attrs %}
174 {{attr.type}} {{attr.name}} = {{attr.importcmd}};
176 {%- if node.dynamic_pinned %}
177 op_pin_state pin_state = read_pin_state(env);
179 {%- if "fragile" in node.flags %}
180 bool throws = read_throws(env);
182 {%- if node.arity == "dynamic" or node.arity == "variable" %}
183 int n_preds = read_preds(env);
184 ir_node **preds = (ir_node**)obstack_finish(&env->preds_obst);
186 {%- if node.constructorFlags %}
187 ir_cons_flags flags = cons_none;
190 {%- if node.constructorFlags %}
191 {%- for attr in node.attrs %}
192 {%- if "to_flags" in attr %}
193 flags |= {{attr.to_flags}};
196 {%- if node.dynamic_pinned %}
197 flags |= pin_state == op_pin_state_floats ? cons_floats : cons_none;
199 {%- if "fragile" in node.flags %}
200 flags |= throws ? cons_throws_exception : cons_none;
203 res = new_r_{{node.name}}(
204 {%- filter arguments %}
206 {{node.arguments|args}}
207 {%- if node.dynamic_pinned and not hasattr(node, "pinned_init") %}
212 {%- if node.arity == "dynamic" or node.arity == "variable" %}
213 obstack_free(&env->preds_obst, preds);
215 {%- for attr in node.extraattrs %}
216 set_{{node.name}}_{{attr.name}}(res, {{attr.name}});
218 {%- if not node.constructorFlags %}
219 {%- if node.dynamic_pinned and hasattr(node, "pinned_init") %}
220 set_irn_pinned(res, pin_state);
222 {%- if "fragile" in node.flags and hasattr(node, "throws_init") %}
223 ir_set_throws_exception(res, throws);
230 {%- for node in nodes|notset('customSerializer') %}
231 static void write_{{node.name}}(write_env_t *env, const ir_node *node)
233 write_symbol(env, "{{node.name}}");
234 write_node_nr(env, node);
235 {%- if not node.knownBlock %}
236 write_node_ref(env, get_nodes_block(node));
238 {%- for input in node.ins %}
239 write_node_ref(env, get_{{node.name}}_{{input[0]}}(node));
241 {%- if not hasattr(node, "mode") %}
242 write_mode_ref(env, get_irn_mode(node));
244 {%- for attr in node.attrs %}
247 {%- if node.dynamic_pinned %}
248 write_pin_state(env, get_irn_pinned(node));
250 {%- if "fragile" in node.flags %}
251 write_throws(env, ir_throws_exception(node));
253 {%- if node.arity == "dynamic" or node.arity == "variable" %}
254 write_pred_refs(env, node, {% if node.ins %}n_{{node.name}}_max+1{% else %}0{%endif%});
259 static void register_generated_node_readers(void)
261 {%- for node in nodes|notset('customSerializer') %}
262 register_node_reader(new_id_from_str("{{node.name}}"), read_{{node.name}});
266 static void register_generated_node_writers(void)
268 {%- for node in nodes|notset('customSerializer') %}
269 register_node_writer(op_{{node.name}}, write_{{node.name}});
276 print "usage: %s specname(ignored) destdirectory" % argv[0]
282 for node in ir_spec.nodes:
285 preprocess_node(node)
286 real_nodes.append(node)
288 file = open(gendir + "/gen_irio.inl", "w");
289 file.write(io_template.render(nodes = real_nodes, hasattr=hasattr))