#!/usr/bin/env python
import sys
+import re
from jinja2 import Environment, Template
from jinja2.filters import do_dictsort
-import ir_spec
+from spec_util import is_dynamic_pinned, verify_node
+from ir_spec import nodes
def format_argdecls(node, first = False, voidwhenempty = False):
if not node.has_key("args") or len(node["args"]) == 0:
else:
return `arity` + ", in"
+def format_arity(node):
+ if "arity_override" in node:
+ return node["arity_override"]
+ arity = node['arity']
+ if arity == "dynamic":
+ return "oparity_dynamic"
+ if arity == "variable":
+ return "oparity_variable"
+ if arity == 0:
+ return "oparity_zero"
+ if arity == 1:
+ return "oparity_unary"
+ if arity == 2:
+ return "oparity_binary"
+ if arity == 3:
+ return "oparity_trinary"
+ return "oparity_any"
+
+def format_pinned(node):
+ pinned = node["pinned"]
+ if pinned == "yes":
+ return "op_pin_state_pinned"
+ if pinned == "no":
+ return "op_pin_state_floats"
+ if pinned == "exception":
+ return "op_pin_state_exc_pinned"
+ if pinned == "memory":
+ return "op_pin_state_mem_pinned"
+ print "WARNING: Unknown pinned state %s in format pined" % pinned
+ return ""
+
+def format_flags(node):
+ flags = node['flags']
+ flags = re.split("\s*,\s*", flags)
+ flags = map(lambda x : "irop_flag_" + x, flags)
+ return " | ".join(flags)
+
+def format_attr_size(node):
+ if "attr_struct" not in node:
+ return "0"
+ return "sizeof(%s)" % node['attr_struct']
+
+def format_opindex(node):
+ if "op_index" in node:
+ return node["op_index"]
+ return "-1"
+
+def filter_isnot(list, flag):
+ result = []
+ for nodename, node in list:
+ if flag in node:
+ continue
+ result.append((nodename, node))
+ return result
+
env = Environment()
-env.filters['argdecls'] = format_argdecls
-env.filters['args'] = format_args
-env.filters['blockdecl'] = format_blockdecl
-env.filters['block'] = format_block
-env.filters['curblock'] = format_curblock
+env.filters['argdecls'] = format_argdecls
+env.filters['args'] = format_args
+env.filters['blockdecl'] = format_blockdecl
+env.filters['block'] = format_block
+env.filters['curblock'] = format_curblock
env.filters['insdecl'] = format_insdecl
env.filters['arity_and_ins'] = format_arity_and_ins
+env.filters['arity'] = format_arity
+env.filters['pinned'] = format_pinned
+env.filters['flags'] = format_flags
+env.filters['attr_size'] = format_attr_size
+env.filters['isnot'] = filter_isnot
+env.filters['opindex'] = format_opindex
def add_attr(list, type, name, init = None, initname = None):
if initname == None:
return dict(type = attr["type"], name = attr["name"])
def preprocess_node(nodename, node):
- print "nodename: " + nodename
+ # set default attributes
if "is_a" in node:
- parent = ir_spec.nodes[node["is_a"]]
+ parent = nodes[node["is_a"]]
node["ins"] = parent["ins"]
+ if "op_index" in parent:
+ node["op_index"] = parent["op_index"]
+ if "pinned" in parent:
+ node["pinned"] = parent["pinned"]
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"] = []
- if "attrs_name" not in node:
- node["attrs_name"] = nodename.lower()
- if "block" not in node:
- node["block"] = "block"
- if "nodbginfo" in node:
- node["db"] = "NULL"
- node["dbdecl"] = ""
- node["dbdeclnocomma"] = ""
- else:
- node["db"] = "db"
- node["dbdecl"] = "dbg_info *db, "
- node["dbdeclnocomma"] = "dbg_info *db"
+ node["db"] = "db"
+ node["dbdecl"] = "dbg_info *db, "
+ node["dbdeclnocomma"] = "dbg_info *db"
+
+ if "flags" not in node and "abstract" not in node:
+ print "WARNING: no flags specified for %s (you should say at least 'none')\n" % nodename
+
+ node.setdefault("ins", [])
+ node.setdefault("arity", len(node["ins"]))
+ node.setdefault("attrs", [])
+ node.setdefault("constrname", nodename);
+ node.setdefault("constructor_args", [])
+ node.setdefault("attrs_name", nodename.lower())
+ node.setdefault("block", "block")
+ node.setdefault("flags", "none")
+
+ verify_node(nodename, node)
# construct node arguments
arguments = [ ]
- initargs = [ ]
initattrs = [ ]
specialconstrs = [ ]
- i = 0
for input in node["ins"]:
- print "ins: " + input
arguments.append(dict(type = "ir_node *", name = "irn_" + input))
- i += 1
-
- # Special case for Builtin...
- if nodename == "Builtin":
- for attr in node["attrs"]:
- if attr["name"] == "kind":
- arguments.append(prepare_attr(attr))
- if node["arity"] == "variable":
+ if node["arity"] == "variable" or node["arity"] == "dynamic":
arguments.append(dict(type = "int", name = "arity"))
arguments.append(dict(type = "ir_node **", name = "in"))
attrs_with_special = 0
for attr in node["attrs"]:
- print "attr: " + attr["name"]
- if nodename == "Builtin" and attr["name"] == "kind":
- continue
-
- if "initname" not in attr:
- attr["initname"] = "." + attr["name"]
+ attr.setdefault("initname", "." + attr["name"])
- # "special" stuff does not work at all, yet
if "special" in attr:
if not "init" in attr:
print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename
elif "suffix" in attr["special"]:
specialname = nodename + attr["special"]["suffix"]
else:
- print "Unknown special constructor type for node type %s" %nodename
+ print "Unknown special constructor type for node type %s" % nodename
sys.exit(1)
specialconstrs.append(
dict(
constrname = specialname,
- attrname = attr["name"],
- value = attr["special"]["init"]
+ attr = attr
)
)
- elif "init" in attr:
- initargs.append(attr["name"])
- else:
+ elif not "init" in attr:
arguments.append(prepare_attr(attr))
+ # dynamic pin state means more constructor arguments
+ if is_dynamic_pinned(node):
+ if "pinned_init" in node:
+ initattrs.append(dict(
+ initname = ".exc.pin_state",
+ init = node["pinned_init"]
+ ))
+ else:
+ node["constructor_args"].append(
+ dict(
+ name = "pin_state",
+ type = "op_pin_state"
+ )
+ )
+ initattrs.append(dict(
+ initname = ".exc.pin_state",
+ init = "pin_state"
+ ))
+
for arg in node["constructor_args"]:
arguments.append(prepare_attr(arg))
if arg["type"] == "ir_cons_flags":
init = name + " & cons_unaligned ? align_non_aligned : align_is_aligned"))
node["args"] = arguments
- node["initargs"] = initargs
node["initattrs"] = initattrs
node["special_constructors"] = specialconstrs
#############################
-node_template = env.from_string('''
-ir_node *new_rd_{{nodename}}({{node["dbdecl"]}}ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
+constructor_template = env.from_string('''
+
+ir_node *new_rd_{{node["constrname"]}}({{node["dbdecl"]}}ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
{
ir_node *res;
ir_graph *rem = current_ir_graph;
{% endfor %}
{%- for attr in node["initattrs"] -%}
res->attr.{{node["attrs_name"]}}{{attr["initname"]}} = {{ attr["init"] -}};
- {% endfor %}
+ {%- endfor %}
{{- node["init"] }}
{% if node["optimize"] != False -%}
res = optimize_node(res);
return res;
}
-ir_node *new_r_{{nodename}}(ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
+ir_node *new_r_{{node["constrname"]}}(ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
{
{% if node["nodbginfo"] -%}
- return new_rd_{{nodename}}(irg{{node|block}}{{node|args}});
+ return new_rd_{{node["constrname"]}}(irg{{node|block}}{{node|args}});
{%- else -%}
- return new_rd_{{nodename}}(NULL, irg{{node|block}}{{node|args}});
+ return new_rd_{{node["constrname"]}}(NULL, irg{{node|block}}{{node|args}});
{%- endif %}
}
-ir_node *new_d_{{nodename}}({{node["dbdeclnocomma"]}}{{node|argdecls(node["nodbginfo"])}})
+ir_node *new_d_{{node["constrname"]}}({{node["dbdeclnocomma"]}}{{node|argdecls(node["nodbginfo"])}})
{
ir_node *res;
{{ node["d_pre"] }}
{% if node["nodbginfo"] -%}
- res = new_rd_{{nodename}}(current_ir_graph{{node|curblock}}{{node|args}});
+ res = new_rd_{{node["constrname"]}}(current_ir_graph{{node|curblock}}{{node|args}});
{%- else -%}
- res = new_rd_{{nodename}}(db, current_ir_graph{{node|curblock}}{{node|args}});
+ res = new_rd_{{node["constrname"]}}(db, current_ir_graph{{node|curblock}}{{node|args}});
{%- endif %}
{{ node["d_post"] }}
return res;
}
-ir_node *new_{{nodename}}({{node|argdecls(True, True)}})
+ir_node *new_{{node["constrname"]}}({{node|argdecls(True, True)}})
{
{% if node["nodbginfo"] -%}
- return new_d_{{nodename}}({{node|args(True)}});
+ return new_d_{{node["constrname"]}}({{node|args(True)}});
{%- else -%}
- return new_d_{{nodename}}(NULL{{node|args}});
+ return new_d_{{node["constrname"]}}(NULL{{node|args}});
{%- endif %}
}
+''')
+
+irnode_h_template = env.from_string('''
+/* Warning: automatically generated code */
+
+{% for nodename, node in nodes|isnot('custom_is') %}
+static inline int _is_{{nodename}}(const ir_node *node)
+{
+ assert(node != NULL);
+ return _get_irn_op(node) == op_{{nodename}};
+}
+{% endfor %}
+
+{% for nodename, node in nodes %}
+#define is_{{nodename}}(node) _is_{{nodename}}(node)
+{%- endfor %}
''')
+irnode_template = env.from_string('''
+/* Warning: automatically generated code */
+{% for nodename, node in nodes %}
+int (is_{{nodename}})(const ir_node *node)
+{
+ return _is_{{nodename}}(node);
+}
+{% endfor %}
+''')
+
+irop_template = env.from_string('''
+/* Warning: automatically generated code */
+{% for nodename, node in nodes %}
+ir_op *op_{{nodename}}; ir_op *get_op_{{nodename}}(void) { return op_{{nodename}}; }
+{%- endfor %}
+
+void init_op(void)
+{
+ {% for nodename, node in nodes %}
+ op_{{nodename}} = new_ir_op(iro_{{nodename}}, "{{nodename}}", {{node|pinned}}, {{node|flags}}, {{node|arity}}, {{node|opindex}}, {{node|attr_size}}, NULL);
+ {%- endfor %}
+
+ be_init_op();
+}
+
+void finish_op(void)
+{
+ {% for nodename, node in nodes %}
+ free_ir_op(op_{{nodename}}); op_{{nodename}} = NULL;
+ {%- endfor %}
+}
+''')
+
#############################
def main(argv):
gendir = argv[2]
# List of TODOs
- niymap = ["Alloc", "Anchor", "ASM", "Bad", "Bound", "Break", "Builtin",
- "Call", "CallBegin", "Cast", "Const", "Const_type", "Const_long", "CopyB",
- "defaultProj", "Div", "DivRL", "DivMod", "Dummy", "EndReg", "EndExcept",
- "Filter", "InstOf", "Mod", "NoMem", "Phi", "Quot", "Raise",
- "simpleSel", "strictConv", "SymConst", "SymConst_type", "Sync"]
-
- file = open(gendir + "/gen_ir_cons_py.c.inl", "w")
- for nodename, node in do_dictsort(ir_spec.nodes):
+ niymap = [ "ASM", "Const", "Phi", "SymConst", "Sync"]
+
+ file = open(gendir + "/gen_ir_cons.c.inl", "w")
+ for nodename, node in do_dictsort(nodes):
+ preprocess_node(nodename, node)
if nodename in niymap:
continue
- preprocess_node(nodename, node)
- if not "abstract" in node:
- file.write(node_template.render(vars()))
+ if "abstract" not in node and "singleton" not in node:
+ file.write(constructor_template.render(vars()))
+
+ if "special_constructors" in node:
+ for special in node["special_constructors"]:
+ node["constrname"] = special["constrname"]
+ special["attr"]["init"] = special["attr"]["special"]["init"]
+ file.write(constructor_template.render(vars()))
file.write("\n")
file.close()
+ real_nodes = dict()
+ for nodename, node in nodes.iteritems():
+ if "abstract" in node:
+ continue
+ real_nodes[nodename] = node
+ real_nodes = do_dictsort(real_nodes)
+
+ file = open(gendir + "/gen_irnode.h", "w")
+ file.write(irnode_h_template.render(nodes = real_nodes))
+ file.close()
+
+ file = open(gendir + "/gen_irnode.c.inl", "w")
+ file.write(irnode_template.render(nodes = real_nodes))
+ file.close()
+
+ file = open(gendir + "/gen_irop.c.inl", "w")
+ file.write(irop_template.render(nodes = real_nodes))
+ file.close()
+
if __name__ == "__main__":
main(sys.argv)