-#!/usr/bin/python
+#!/usr/bin/env python
import sys
from jinja2 import Environment, Template
-import ir_spec
+from spec_util import is_dynamic_pinned, isAbstract, load_spec
+from filters import format_arguments, filter_isnot, filter_hasnot, filter_notset
+
+def error(msg):
+ """writes an error message to stderr"""
+ sys.stderr.write("Error: " + msg + "\n");
+
+def warning(msg):
+ """writes a warning message to stderr"""
+ sys.stderr.write("Warning: " + msg + "\n");
def format_args(arglist):
- #argstrings = map(lambda arg : arg["name"], arglist)
- #return ", ".join(argstrings)
- s = ", ".join(arglist)
- if len(s) == 0:
- return "";
- return ", " + s;
-
-def format_ifnset(string, node, key):
- if key in node:
- return ""
- return string
+ return "\n".join(arglist)
def format_block(node):
- if node.get("knownBlock"):
- return ""
+ if hasattr(node, "knownBlock"):
+ if hasattr(node, "knownGraph"):
+ return ""
+ return "env->irg"
else:
- return ", get_node(env, preds[0])"
+ return "block"
env = Environment()
-env.filters['args'] = format_args
-env.filters['ifnset'] = format_ifnset
-env.filters['block'] = format_block
-
-def get_io_type(type, attrname, nodename):
- if type == "tarval*":
- importcmd = "tarval *%s = read_tv(env);" % attrname
- exportcmd = "write_tarval(env, %(val)s);";
+env.filters['args'] = format_args
+env.filters['block'] = format_block
+env.filters['arguments'] = format_arguments
+env.filters['isnot'] = filter_isnot
+env.filters['notset'] = filter_notset
+env.filters['hasnot'] = filter_hasnot
+
+def get_io_type(type, attrname, node):
+ if type == "ir_tarval*":
+ importcmd = "read_tarval(env)"
+ exportcmd = "write_tarval(env, %(val)s);"
elif type == "ir_mode*":
- importcmd = "ir_mode *%s = read_mode(env);" % attrname
- exportcmd = "write_mode(env, %(val)s);"
+ importcmd = "read_mode_ref(env)"
+ exportcmd = "write_mode_ref(env, %(val)s);"
elif type == "ir_entity*":
- importcmd = "ir_entity *%s = read_entity(env);" % attrname
- exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));"""
+ importcmd = "read_entity_ref(env)"
+ exportcmd = "write_entity_ref(env, %(val)s);"
elif type == "ir_type*":
- importcmd = "ir_type *%s = read_type(env);" % attrname
- exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));"""
- elif type == "long" and nodename == "Proj":
- importcmd = "long %s = read_long(env);" % attrname
- exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
- elif type == "pn_Cmp" or type == "ir_where_alloc":
- importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
- exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
- elif type == "cons_flags" and nodename == "Store":
- importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
- exportcmd = """write_pin_state(env, irn);
- write_volatility(env, irn);
- write_align(env, irn);"""
- elif type == "cons_flags" and nodename == "Load":
- importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
- exportcmd = """write_pin_state(env, irn);
- write_volatility(env, irn);
- write_align(env, irn);"""
+ importcmd = "read_type_ref(env)"
+ exportcmd = "write_type_ref(env, %(val)s);"
+ elif type == "long":
+ importcmd = "read_long(env)"
+ exportcmd = "write_long(env, %(val)s);"
+ elif type == "ir_relation":
+ importcmd = "read_relation(env)"
+ exportcmd = "write_relation(env, %(val)s);"
+ elif type == "ir_where_alloc":
+ importcmd = "read_where_alloc(env)"
+ exportcmd = "write_where_alloc(env, %(val)s);"
+ elif type == "ir_align":
+ importcmd = "read_align(env)"
+ exportcmd = "write_align(env, %(val)s);"
+ elif type == "ir_volatility":
+ importcmd = "read_volatility(env)"
+ exportcmd = "write_volatility(env, %(val)s);"
+ elif type == "ir_cons_flags":
+ importcmd = "cons_none"
+ exportcmd = "" # can't really export cons_flags
elif type == "op_pin_state":
- importcmd = "op_pin_state %s = read_pin_state(env);" % attrname
- exportcmd = "write_pin_state(env, irn);"
+ importcmd = "read_pin_state(env)"
+ exportcmd = "write_pin_state(env, node);"
elif type == "ir_builtin_kind":
- importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
- exportcmd = "write_builtin_kind(env, irn);"
+ importcmd = "read_builtin_kind(env)"
+ exportcmd = "write_builtin_kind(env, node);"
+ elif type == "cond_kind":
+ importcmd = "read_cond_kind(env)"
+ exportcmd = "write_cond_kind(env, node);"
+ elif type == "cond_jmp_predicate":
+ importcmd = "read_cond_jmp_predicate(env)"
+ exportcmd = "write_cond_jmp_predicate(env, node);"
elif type == "int":
- importcmd = "int %s = (int) read_long(env);" % attrname
- exportcmd = """fprintf(env->file, "%%d ", %(val)s);"""
+ importcmd = "read_int(env)"
+ exportcmd = "write_int(env, %(val)s);"
+ elif type == "unsigned":
+ importcmd = "read_unsigned(env)"
+ exportcmd = "write_unsigned(env, %(val)s);"
+ elif type == "long":
+ importcmd = "read_long(env)"
+ exportcmd = "write_long(env, %(val)s);"
+ elif type == "ir_switch_table*":
+ importcmd = "read_switch_table(env)"
+ exportcmd = "write_switch_table(env, %(val)s);"
else:
- print "UNKNOWN TYPE: %s" % type
- importcmd = """// BAD: %s %s
- %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
+ warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
+ importcmd = "/* BAD: %s %s */ (%s)0" % (type, attrname, type)
exportcmd = "// BAD: %s" % type
return (importcmd, exportcmd)
-""" if type == "ir_type*":
- java_type = "firm.Type"
- wrap_type = "Pointer"
- to_wrapper = "%s.ptr"
- from_wrapper = "firm.Type.createWrapper(%s)"
- elif type == "ir_mode*":
- java_type = "firm.Mode"
- wrap_type = "Pointer"
- to_wrapper = "%s.ptr"
- from_wrapper = "new firm.Mode(%s)"
- elif type == "tarval*":
- java_type = "firm.TargetValue"
- wrap_type = "Pointer"
- to_wrapper = "%s.ptr"
- from_wrapper = "new firm.TargetValue(%s)"
- elif type == "pn_Cmp":
- java_type = "int"
- wrap_type = "int"
- to_wrapper = "%s"
- from_wrapper = "%s"
- elif type == "long":
- java_type = "int"
- wrap_type = "com.sun.jna.NativeLong"
- to_wrapper = "new com.sun.jna.NativeLong(%s)"
- from_wrapper = "%s.intValue()"
- elif type == "cons_flags":
- java_type = "firm.bindings.binding_ircons.ir_cons_flags"
- wrap_type = "int"
- to_wrapper = "%s.val"
- from_wrapper = "firm.bindings.binding_ircons.ir_cons_flags.getEnum(%s)"
- elif type == "ir_where_alloc":
- java_type = "firm.bindings.binding_ircons.ir_where_alloc"
- wrap_type = "int"
- to_wrapper = "%s.val"
- from_wrapper = "firm.bindings.binding_ircons.ir_where_alloc.getEnum(%s)"
- elif type == "ir_entity*":
- java_type = "firm.Entity"
- wrap_type = "Pointer"
- to_wrapper = "%s.ptr"
- from_wrapper = "new firm.Entity(%s)"
- else:
- print "UNKNOWN TYPE"
- java_type = "BAD"
- wrap_type = "BAD"
- to_wrapper = "BAD"
- from_wrapper = "BAD"
- return (java_type,wrap_type,to_wrapper,from_wrapper)"""
-
-def prepare_attr(nodename, attr):
- (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], nodename)
+def prepare_attr(node, attr):
+ (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
attr["importcmd"] = importcmd
- attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (nodename, attr["name"])}
-
-def preprocess_node(nodename, node):
- if "is_a" in node:
- parent = ir_spec.nodes[node["is_a"]]
- node["ins"] = parent["ins"]
- if "outs" in parent:
- node["outs"] = parent["outs"]
- if "ins" not in node:
- node["ins"] = []
- if "outs" in node:
- node["mode"] = "mode_T"
- if "arity" not in node:
- node["arity"] = len(node["ins"])
- if "attrs" not in node:
- node["attrs"] = []
- if "constructor_args" not in node:
- node["constructor_args"] = []
+ attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(node)" % (node.name, attr["name"])}
+
+
+def preprocess_node(node):
+ if node.customSerializer:
+ return
# construct node arguments
arguments = [ ]
- i = 0
- for input in node["ins"]:
- arguments.append("prednodes[%i]" % i)
- i += 1
-
- # Special case for Builtin...
- if nodename == "Builtin":
- for attr in node["attrs"]:
- if attr["name"] == "kind":
- prepare_attr(nodename, attr)
- arguments.append(attr["name"])
-
- if node["arity"] == "variable" or node["arity"] == "dynamic":
- arguments.append("numpreds - %i" % (i + 1))
- arguments.append("prednodes + %i" % i)
-
- if "mode" not in node:
+ extraattrs = [ ]
+ for input in node.ins:
+ arguments.append("in_%s" % input[0])
+
+ if node.arity == "variable" or node.arity == "dynamic":
+ arguments.append("n_preds")
+ arguments.append("preds")
+
+ if not hasattr(node, "mode"):
arguments.append("mode")
- for attr in node["attrs"]:
- if nodename == "Builtin" and attr["name"] == "kind":
+ for attr in node.attrs:
+ prepare_attr(node, attr)
+ if "to_flags" in attr:
+ node.constructorFlags = True
+ attr['to_flags'] = attr['to_flags'] % (attr["name"])
+ elif "init" in attr:
+ extraattrs.append(attr)
+ else:
+ arguments.append(attr["name"])
+
+ for arg in node.constructor_args:
+ if arg['type'] != "ir_cons_flags" and arg['name'] != "flags":
+ error("only ir_cons_flags constructor arg supported in irio")
continue
- prepare_attr(nodename, attr)
- arguments.append(attr["name"])
-
- for arg in node["constructor_args"]:
- prepare_attr(nodename, arg)
- arguments.append(arg["name"])
-
- node["arguments"] = arguments
-
-export_attrs_template = env.from_string('''
- case iro_{{nodename}}:
- {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
- {% for attr in node.attrs %}{{attr.exportcmd}}
- {% endfor %}
- {% for attr in node.constructor_args %}{{attr.exportcmd}}
- {% endfor %}break;''')
-
-import_attrs_template = env.from_string('''
- case iro_{{nodename}}:
- {
- {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
- {% for attr in node.attrs %}{{attr.importcmd}}
- {% endfor %}
- {% for attr in node.constructor_args %}{{attr.importcmd}}
- {% endfor %}newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
- break;
- }
+ node.constructorFlags = True
+ arguments.append("flags")
+
+ node.arguments = arguments
+ node.extraattrs = extraattrs
+ node.dynamic_pinned = is_dynamic_pinned(node)
+
+io_template = env.from_string('''/* Warning: automatically generated code */
+{%- for node in nodes|notset('customSerializer') %}
+static ir_node *read_{{node.name}}(read_env_t *env)
+{
+ {%- if not node.knownBlock %}
+ ir_node *block = read_node_ref(env);
+ {%- endif %}
+ {%- for input in node.ins %}
+ ir_node *in_{{input[0]}} = read_node_ref(env);
+ {%- endfor %}
+ {%- if not hasattr(node, "mode") %}
+ ir_mode *mode = read_mode_ref(env);
+ {%- endif %}
+ {%- for attr in node.attrs %}
+ {{attr.type}} {{attr.name}} = {{attr.importcmd}};
+ {%- endfor %}
+ {%- if node.dynamic_pinned %}
+ op_pin_state pin_state = read_pin_state(env);
+ {%- endif %}
+ {%- if "fragile" in node.flags %}
+ bool throws = read_throws(env);
+ {%- endif %}
+ {%- if node.arity == "dynamic" or node.arity == "variable" %}
+ int n_preds = read_preds(env);
+ ir_node **preds = (ir_node**)obstack_finish(&env->preds_obst);
+ {%- endif %}
+ {%- if node.constructorFlags %}
+ ir_cons_flags flags = cons_none;
+ {%- endif %}
+ ir_node *res;
+ {%- if node.constructorFlags %}
+ {%- for attr in node.attrs %}
+ {%- if "to_flags" in attr %}
+ flags |= {{attr.to_flags}};
+ {%- endif %}
+ {%- endfor %}
+ {%- if node.dynamic_pinned %}
+ flags |= pin_state == op_pin_state_floats ? cons_floats : cons_none;
+ {%- endif %}
+ {%- if "fragile" in node.flags %}
+ flags |= throws ? cons_throws_exception : cons_none;
+ {%- endif %}
+ {%- endif %}
+ res = new_r_{{node.name}}(
+ {%- filter arguments %}
+{{node|block}}
+{{node.arguments|args}}
+ {%- if node.dynamic_pinned and not hasattr(node, "pinned_init") %}
+pin_state
+ {%- endif %}
+{% endfilter %});
+
+ {%- if node.arity == "dynamic" or node.arity == "variable" %}
+ obstack_free(&env->preds_obst, preds);
+ {%- endif %}
+ {%- for attr in node.extraattrs %}
+ set_{{node.name}}_{{attr.name}}(res, {{attr.name}});
+ {%- endfor %}
+ {%- if not node.constructorFlags %}
+ {%- if node.dynamic_pinned and hasattr(node, "pinned_init") %}
+ set_irn_pinned(res, pin_state);
+ {%- endif %}
+ {%- if "fragile" in node.flags and hasattr(node, "throws_init") %}
+ ir_set_throws_exception(res, throws);
+ {%- endif %}
+ {%- endif %}
+ return res;
+}
+{% endfor %}
+
+{%- for node in nodes|notset('customSerializer') %}
+static void write_{{node.name}}(write_env_t *env, const ir_node *node)
+{
+ write_symbol(env, "{{node.name}}");
+ write_node_nr(env, node);
+ {%- if not node.knownBlock %}
+ write_node_ref(env, get_nodes_block(node));
+ {%- endif %}
+ {%- for input in node.ins %}
+ write_node_ref(env, get_{{node.name}}_{{input[0]}}(node));
+ {%- endfor %}
+ {%- if not hasattr(node, "mode") %}
+ write_mode_ref(env, get_irn_mode(node));
+ {%- endif %}
+ {%- for attr in node.attrs %}
+ {{attr.exportcmd}}
+ {%- endfor %}
+ {%- if node.dynamic_pinned %}
+ write_pin_state(env, get_irn_pinned(node));
+ {%- endif %}
+ {%- if "fragile" in node.flags %}
+ write_throws(env, ir_throws_exception(node));
+ {%- endif %}
+ {%- if node.arity == "dynamic" or node.arity == "variable" %}
+ write_pred_refs(env, node, {% if node.ins %}n_{{node.name}}_max+1{% else %}0{%endif%});
+ {%- endif %}
+}
+{% endfor %}
+
+static void register_generated_node_readers(void)
+{
+ {%- for node in nodes|notset('customSerializer') %}
+ register_node_reader(new_id_from_str("{{node.name}}"), read_{{node.name}});
+ {%- endfor %}
+}
+
+static void register_generated_node_writers(void)
+{
+ {%- for node in nodes|notset('customSerializer') %}
+ register_node_writer(op_{{node.name}}, write_{{node.name}});
+ {%- endfor %}
+}
+
''')
def main(argv):
- """the main function"""
-
if len(argv) < 3:
print "usage: %s specname(ignored) destdirectory" % argv[0]
sys.exit(1)
+ specfile = argv[1]
gendir = argv[2]
- file = open(gendir + "/gen_irio_export.inl", "w");
- for nodename, node in ir_spec.nodes.iteritems():
- preprocess_node(nodename, node)
- if not "abstract" in node:
- file.write(export_attrs_template.render(vars()))
- file.write("\n")
- file.close()
-
- file = open(gendir + "/gen_irio_import.inl", "w");
- for nodename, node in ir_spec.nodes.iteritems():
- if not "abstract" in node and nodename != "Start" and nodename != "End" and nodename != "Anchor" and nodename != "SymConst" and nodename != "Block":
- file.write(import_attrs_template.render(vars()))
- # TODO: SymConst
- file.write("\n")
- file.close()
+ spec = load_spec(specfile)
+ nodes = spec.nodes
+ real_nodes = []
+ for node in nodes:
+ if isAbstract(node):
+ continue
+ preprocess_node(node)
+ real_nodes.append(node)
- file = open(gendir + "/gen_irio_lex.inl", "w");
- for nodename, node in ir_spec.nodes.iteritems():
- if not "abstract" in node:
- file.write("\tINSERT(\"" + nodename + "\", tt_iro, iro_" + nodename + ");\n");
+ file = open(gendir + "/gen_irio.inl", "w");
+ file.write(io_template.render(nodes = real_nodes, hasattr=hasattr))
file.close()
-if __name__ == "__main__":
- main(sys.argv)
+main(sys.argv)