3 from jinja2 import Environment, Template
4 from spec_util import is_dynamic_pinned, isAbstract, load_spec
5 from filters import format_arguments, filter_isnot, filter_hasnot, filter_notset
8 """writes an error message to stderr"""
9 sys.stderr.write("Error: " + msg + "\n");
12 """writes a warning message to stderr"""
13 sys.stderr.write("Warning: " + msg + "\n");
15 def format_args(arglist):
16 return "\n".join(arglist)
18 def format_block(node):
19 if hasattr(node, "knownBlock"):
20 if hasattr(node, "knownGraph"):
27 env.filters['args'] = format_args
28 env.filters['block'] = format_block
29 env.filters['arguments'] = format_arguments
30 env.filters['isnot'] = filter_isnot
31 env.filters['notset'] = filter_notset
32 env.filters['hasnot'] = filter_hasnot
34 def get_io_type(type, attrname, node):
35 if type == "ir_tarval*":
36 importcmd = "read_tarval(env)"
37 exportcmd = "write_tarval(env, %(val)s);"
38 elif type == "ir_mode*":
39 importcmd = "read_mode_ref(env)"
40 exportcmd = "write_mode_ref(env, %(val)s);"
41 elif type == "ir_entity*":
42 importcmd = "read_entity_ref(env)"
43 exportcmd = "write_entity_ref(env, %(val)s);"
44 elif type == "ir_type*":
45 importcmd = "read_type_ref(env)"
46 exportcmd = "write_type_ref(env, %(val)s);"
48 importcmd = "read_long(env)"
49 exportcmd = "write_long(env, %(val)s);"
50 elif type == "ir_relation":
51 importcmd = "read_relation(env)"
52 exportcmd = "write_relation(env, %(val)s);"
53 elif type == "ir_where_alloc":
54 importcmd = "read_where_alloc(env)"
55 exportcmd = "write_where_alloc(env, %(val)s);"
56 elif type == "ir_align":
57 importcmd = "read_align(env)"
58 exportcmd = "write_align(env, %(val)s);"
59 elif type == "ir_volatility":
60 importcmd = "read_volatility(env)"
61 exportcmd = "write_volatility(env, %(val)s);"
62 elif type == "ir_cons_flags":
63 importcmd = "cons_none"
64 exportcmd = "" # can't really export cons_flags
65 elif type == "op_pin_state":
66 importcmd = "read_pin_state(env)"
67 exportcmd = "write_pin_state(env, node);"
68 elif type == "ir_builtin_kind":
69 importcmd = "read_builtin_kind(env)"
70 exportcmd = "write_builtin_kind(env, node);"
71 elif type == "cond_kind":
72 importcmd = "read_cond_kind(env)"
73 exportcmd = "write_cond_kind(env, node);"
74 elif type == "cond_jmp_predicate":
75 importcmd = "read_cond_jmp_predicate(env)"
76 exportcmd = "write_cond_jmp_predicate(env, node);"
78 importcmd = "read_int(env)"
79 exportcmd = "write_int(env, %(val)s);"
80 elif type == "unsigned":
81 importcmd = "read_unsigned(env)"
82 exportcmd = "write_unsigned(env, %(val)s);"
84 importcmd = "read_long(env)"
85 exportcmd = "write_long(env, %(val)s);"
86 elif type == "ir_switch_table*":
87 importcmd = "read_switch_table(env)"
88 exportcmd = "write_switch_table(env, %(val)s);"
90 warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
91 importcmd = "/* BAD: %s %s */ (%s)0" % (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(node)" % (node.name, attr["name"])}
101 def preprocess_node(node):
102 if node.customSerializer:
105 # construct node arguments
108 for input in node.ins:
109 arguments.append("in_%s" % input[0])
111 if node.arity == "variable" or node.arity == "dynamic":
112 arguments.append("n_preds")
113 arguments.append("preds")
115 if not hasattr(node, "mode"):
116 arguments.append("mode")
118 for attr in node.attrs:
119 prepare_attr(node, attr)
120 if "to_flags" in attr:
121 node.constructorFlags = True
122 attr['to_flags'] = attr['to_flags'] % (attr["name"])
124 extraattrs.append(attr)
126 arguments.append(attr["name"])
128 for arg in node.constructor_args:
129 if arg['type'] != "ir_cons_flags" and arg['name'] != "flags":
130 error("only ir_cons_flags constructor arg supported in irio")
132 node.constructorFlags = True
133 arguments.append("flags")
135 node.arguments = arguments
136 node.extraattrs = extraattrs
137 node.dynamic_pinned = is_dynamic_pinned(node)
139 io_template = env.from_string('''/* Warning: automatically generated code */
140 {%- for node in nodes|notset('customSerializer') %}
141 static ir_node *read_{{node.name}}(read_env_t *env)
143 {%- if not node.knownBlock %}
144 ir_node *block = read_node_ref(env);
146 {%- for input in node.ins %}
147 ir_node *in_{{input[0]}} = read_node_ref(env);
149 {%- if not hasattr(node, "mode") %}
150 ir_mode *mode = read_mode_ref(env);
152 {%- for attr in node.attrs %}
153 {{attr.type}} {{attr.name}} = {{attr.importcmd}};
155 {%- if node.dynamic_pinned %}
156 op_pin_state pin_state = read_pin_state(env);
158 {%- if "fragile" in node.flags %}
159 bool throws = read_throws(env);
161 {%- if node.arity == "dynamic" or node.arity == "variable" %}
162 int n_preds = read_preds(env);
163 ir_node **preds = (ir_node**)obstack_finish(&env->preds_obst);
165 {%- if node.constructorFlags %}
166 ir_cons_flags flags = cons_none;
169 {%- if node.constructorFlags %}
170 {%- for attr in node.attrs %}
171 {%- if "to_flags" in attr %}
172 flags |= {{attr.to_flags}};
175 {%- if node.dynamic_pinned %}
176 flags |= pin_state == op_pin_state_floats ? cons_floats : cons_none;
178 {%- if "fragile" in node.flags %}
179 flags |= throws ? cons_throws_exception : cons_none;
182 res = new_r_{{node.name}}(
183 {%- filter arguments %}
185 {{node.arguments|args}}
186 {%- if node.dynamic_pinned and not hasattr(node, "pinned_init") %}
191 {%- if node.arity == "dynamic" or node.arity == "variable" %}
192 obstack_free(&env->preds_obst, preds);
194 {%- for attr in node.extraattrs %}
195 set_{{node.name}}_{{attr.name}}(res, {{attr.name}});
197 {%- if not node.constructorFlags %}
198 {%- if node.dynamic_pinned and hasattr(node, "pinned_init") %}
199 set_irn_pinned(res, pin_state);
201 {%- if "fragile" in node.flags and hasattr(node, "throws_init") %}
202 ir_set_throws_exception(res, throws);
209 {%- for node in nodes|notset('customSerializer') %}
210 static void write_{{node.name}}(write_env_t *env, const ir_node *node)
212 write_symbol(env, "{{node.name}}");
213 write_node_nr(env, node);
214 {%- if not node.knownBlock %}
215 write_node_ref(env, get_nodes_block(node));
217 {%- for input in node.ins %}
218 write_node_ref(env, get_{{node.name}}_{{input[0]}}(node));
220 {%- if not hasattr(node, "mode") %}
221 write_mode_ref(env, get_irn_mode(node));
223 {%- for attr in node.attrs %}
226 {%- if node.dynamic_pinned %}
227 write_pin_state(env, get_irn_pinned(node));
229 {%- if "fragile" in node.flags %}
230 write_throws(env, ir_throws_exception(node));
232 {%- if node.arity == "dynamic" or node.arity == "variable" %}
233 write_pred_refs(env, node, {% if node.ins %}n_{{node.name}}_max+1{% else %}0{%endif%});
238 static void register_generated_node_readers(void)
240 {%- for node in nodes|notset('customSerializer') %}
241 register_node_reader(new_id_from_str("{{node.name}}"), read_{{node.name}});
245 static void register_generated_node_writers(void)
247 {%- for node in nodes|notset('customSerializer') %}
248 register_node_writer(op_{{node.name}}, write_{{node.name}});
255 print "usage: %s specname(ignored) destdirectory" % argv[0]
261 spec = load_spec(specfile)
267 preprocess_node(node)
268 real_nodes.append(node)
270 file = open(gendir + "/gen_irio.inl", "w");
271 file.write(io_template.render(nodes = real_nodes, hasattr=hasattr))