#!/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, isAbstract, setdefault
+from ir_spec import nodes
def format_argdecls(node, first = False, voidwhenempty = False):
- if not node.has_key("args") or len(node["args"]) == 0:
+ if len(node.arguments) == 0:
if voidwhenempty:
return "void"
else:
return ""
+ arguments = map(lambda arg: arg["type"] + " " + arg["name"], node.arguments)
res = ""
if not first:
- comma = ", "
- else:
- comma = ""
- for arg in node["args"]:
- res = res + (comma + arg["type"] + " " + arg["name"])
- comma = ", "
+ res = ", "
+ res += ", ".join(arguments)
return res
def format_args(node, first = False):
- if not node.has_key("args"):
- return ""
-
res = ""
- if not first:
- comma = ", "
- else:
- comma = ""
- for arg in node["args"]:
- res = res + (comma + arg["name"])
- comma = ", "
+ if not first and node.arguments != []:
+ res = ", "
+
+ arguments = map(lambda arg: arg["name"], node.arguments)
+ res += ", ".join(arguments)
return res
def format_blockdecl(node):
- if node.get("knownBlock"):
+ if hasattr(node, "knownBlock"):
+ return "ir_graph *irg"
+ else:
+ return "ir_node *block"
+
+def format_irgassign(node):
+ if hasattr(node, "knownBlock"):
return ""
else:
- return ", ir_node *block"
+ return "ir_graph *irg = get_Block_irg(block);\n"
def format_block(node):
- if node.get("knownBlock"):
- return ""
+ if hasattr(node, "knownBlock"):
+ return "irg"
else:
- return ", block"
+ return "block"
def format_curblock(node):
- if node.get("knownBlock"):
- return ""
+ if hasattr(node, "knownBlock"):
+ return "current_ir_graph"
else:
- return ", current_ir_graph->current_block"
+ return "current_ir_graph->current_block"
def format_insdecl(node):
- arity = node["arity"]
- if arity == "variable" and len(node["ins"]) == 0 or arity == "dynamic" or arity == 0:
+ arity = node.arity
+ if arity == "variable" and len(node.ins) == 0 or arity == "dynamic" or arity == 0:
return ""
if arity == "variable":
- insarity = len(node["ins"])
+ insarity = len(node.ins)
res = "int r_arity = arity + " + `insarity` + ";\n\tir_node **r_in;\n\t" \
+ "NEW_ARR_A(ir_node *, r_in, r_arity);\n\t"
i = 0
- for input in node["ins"]:
+ for input in node.ins:
res += "r_in[" + `i` + "] = irn_" + input + ";\n\t"
i += 1
res += "memcpy(&r_in[" + `insarity` + "], in, sizeof(ir_node *) * arity);\n\t"
else:
res = "ir_node *in[" + `arity` + "];\n\t"
i = 0
- for input in node["ins"]:
+ for input in node.ins:
res += "in[" + `i` + "] = irn_" + input + ";\n\t"
i += 1
return res
def format_arity_and_ins(node):
- arity = node["arity"]
+ arity = node.arity
if arity == "dynamic":
return "-1, NULL"
elif arity == "variable":
- if len(node["ins"]) == 0:
+ if len(node.ins) == 0:
return "arity, in"
else:
return "r_arity, r_in"
else:
return `arity` + ", in"
+def format_arity(node):
+ if hasattr(node, "arity_override"):
+ 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 = map(lambda x : "irop_flag_" + x, node.flags)
+ if flags == []:
+ flags = [ "irop_flag_none" ]
+ return " | ".join(flags)
+
+def format_attr_size(node):
+ if not hasattr(node, "attr_struct"):
+ return "0"
+ return "sizeof(%s)" % node.attr_struct
+
+def format_opindex(node):
+ if hasattr(node, "op_index"):
+ return node.op_index
+ return "-1"
+
+def filter_isnot(list, flag):
+ result = []
+ for node in list:
+ if hasattr(node, flag):
+ continue
+ result.append(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['irgassign'] = format_irgassign
+env.filters['block'] = format_block
+env.filters['curblock'] = format_curblock
env.filters['insdecl'] = format_insdecl
env.filters['arity_and_ins'] = format_arity_and_ins
-
-def add_attr(list, type, name, init = None, initname = None):
- if initname == None:
- initname = "." + name
- if init != None:
- list.append(dict(type = type, name = name, init = init, initname = initname))
- else:
- list.append(dict(type = type, name = name, initname = initname))
+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 prepare_attr(attr):
if "init" in attr:
else:
return dict(type = attr["type"], name = attr["name"])
-def preprocess_node(nodename, node):
- # set default attributes
- 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 "outs" in node:
- node["mode"] = "mode_T"
- 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"
+def preprocess_node(node):
+ verify_node(node)
- node.setdefault("ins", [])
- node.setdefault("arity", len(node["ins"]))
- node.setdefault("attrs", [])
- node.setdefault("constructor_args", [])
- node.setdefault("attrs_name", nodename.lower())
- node.setdefault("block", "block")
+ setdefault(node, "attrs_name", node.name.lower())
+ setdefault(node, "block", "block")
# construct node arguments
arguments = [ ]
- initargs = [ ]
initattrs = [ ]
specialconstrs = [ ]
- for input in node["ins"]:
+ for input in node.ins:
arguments.append(dict(type = "ir_node *", name = "irn_" + input))
- # 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"))
- if "mode" not in node:
+ if not hasattr(node, "mode"):
arguments.append(dict(type = "ir_mode *", name = "mode"))
- node["mode"] = "mode"
+ node.mode = "mode"
attrs_with_special = 0
- for attr in node["attrs"]:
- if nodename == "Builtin" and attr["name"] == "kind":
- continue
-
+ for attr in node.attrs:
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
+ print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % node.name
sys.exit(1)
if attrs_with_special != 0:
- print "Node type %s has more than one attribute with a \"special\" entry" % nodename
+ print "Node type %s has more than one attribute with a \"special\" entry" % node.name
sys.exit(1)
attrs_with_special += 1
if "prefix" in attr["special"]:
- specialname = attr["special"]["prefix"] + nodename
+ specialname = attr["special"]["prefix"] + node.name
elif "suffix" in attr["special"]:
- specialname = nodename + attr["special"]["suffix"]
+ specialname = node.name + attr["special"]["suffix"]
else:
- print "Unknown special constructor type for node type %s" % nodename
+ print "Unknown special constructor type for node type %s" % node.name
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))
- for arg in node["constructor_args"]:
+ # dynamic pin state means more constructor arguments
+ if is_dynamic_pinned(node):
+ if hasattr(node, "pinned_init"):
+ 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":
name = arg["name"]
initattrs.append(dict(initname = ".aligned",
init = name + " & cons_unaligned ? align_non_aligned : align_is_aligned"))
- node["args"] = arguments
- node["initargs"] = initargs
- node["initattrs"] = initattrs
- node["special_constructors"] = specialconstrs
+ node.arguments = arguments
+ 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}}(dbg_info *dbgi, {{node|blockdecl}}{{node|argdecls}})
{
ir_node *res;
ir_graph *rem = current_ir_graph;
+ {{node|irgassign}}
{{node|insdecl}}
current_ir_graph = irg;
- res = new_ir_node({{node["db"]}}, irg, {{node["block"]}}, op_{{nodename}}, {{node["mode"]}}, {{node|arity_and_ins}});
- {% for attr in node["attrs"] -%}
- res->attr.{{node["attrs_name"]}}{{attr["initname"]}} =
+ res = new_ir_node(dbgi, irg, {{node.block}}, op_{{node.name}}, {{node.mode}}, {{node|arity_and_ins}});
+ {% for attr in node.attrs -%}
+ res->attr.{{node.attrs_name}}{{attr["initname"]}} =
{%- if "init" in attr %} {{ attr["init"] -}};
{%- else %} {{ attr["name"] -}};
{% endif %}
{% endfor %}
- {%- for attr in node["initattrs"] -%}
- res->attr.{{node["attrs_name"]}}{{attr["initname"]}} = {{ attr["init"] -}};
- {% endfor %}
- {{- node["init"] }}
- {% if node["optimize"] != False -%}
+ {%- for attr in node.initattrs -%}
+ res->attr.{{node.attrs_name}}{{attr["initname"]}} = {{ attr["init"] -}};
+ {%- endfor %}
+ {{- node.init }}
+ {% if node.optimize != False -%}
res = optimize_node(res);
{% endif -%}
IRN_VRFY_IRG(res, irg);
return res;
}
-ir_node *new_r_{{nodename}}(ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
+ir_node *new_r_{{node.constrname}}({{node|blockdecl}}{{node|argdecls}})
{
- {% if node["nodbginfo"] -%}
- return new_rd_{{nodename}}(irg{{node|block}}{{node|args}});
- {%- else -%}
- return new_rd_{{nodename}}(NULL, irg{{node|block}}{{node|args}});
- {%- endif %}
+ return new_rd_{{node.constrname}}(NULL, {{node|block}}{{node|args}});
}
-ir_node *new_d_{{nodename}}({{node["dbdeclnocomma"]}}{{node|argdecls(node["nodbginfo"])}})
+ir_node *new_d_{{node.constrname}}(dbg_info *dbgi{{node|argdecls}})
{
ir_node *res;
- {{ node["d_pre"] }}
- {% if node["nodbginfo"] -%}
- res = new_rd_{{nodename}}(current_ir_graph{{node|curblock}}{{node|args}});
- {%- else -%}
- res = new_rd_{{nodename}}(db, current_ir_graph{{node|curblock}}{{node|args}});
- {%- endif %}
- {{ node["d_post"] }}
+ {{ node.d_pre }}
+ res = new_rd_{{node.constrname}}(dbgi, {{node|curblock}}{{node|args}});
+ {{ node.d_post }}
return res;
}
-ir_node *new_{{nodename}}({{node|argdecls(True, True)}})
+ir_node *new_{{node.constrname}}({{node|argdecls(True, True)}})
+{
+ return new_d_{{node.constrname}}(NULL{{node|args}});
+}
+''')
+
+irnode_h_template = env.from_string('''
+/* Warning: automatically generated code */
+
+{% for node in nodes|isnot('custom_is') %}
+static inline int _is_{{node.name}}(const ir_node *node)
+{
+ assert(node != NULL);
+ return _get_irn_op(node) == op_{{node.name}};
+}
+{% endfor %}
+
+{% for node in nodes %}
+#define is_{{node.name}}(node) _is_{{node.name}}(node)
+{%- endfor %}
+
+''')
+
+irnode_template = env.from_string('''
+/* Warning: automatically generated code */
+{% for node in nodes %}
+int (is_{{node.name}})(const ir_node *node)
+{
+ return _is_{{node.name}}(node);
+}
+{% endfor %}
+''')
+
+irop_template = env.from_string('''
+/* Warning: automatically generated code */
+{% for node in nodes %}
+ir_op *op_{{node.name}}; ir_op *get_op_{{node.name}}(void) { return op_{{node.name}}; }
+{%- endfor %}
+
+void init_op(void)
+{
+ {% for node in nodes %}
+ op_{{node.name}} = new_ir_op(iro_{{node.name}}, "{{node.name}}", {{node|pinned}}, {{node|flags}}, {{node|arity}}, {{node|opindex}}, {{node|attr_size}}, NULL);
+ {%- endfor %}
+
+ be_init_op();
+}
+
+void finish_op(void)
{
- {% if node["nodbginfo"] -%}
- return new_d_{{nodename}}({{node|args(True)}});
- {%- else -%}
- return new_d_{{nodename}}(NULL{{node|args}});
- {%- endif %}
+ {% for node in nodes %}
+ free_ir_op(op_{{node.name}}); op_{{node.name}} = NULL;
+ {%- endfor %}
}
''')
#############################
def main(argv):
- """the main function"""
-
if len(argv) < 3:
print "usage: %s specname(ignored) destdirectory" % argv[0]
sys.exit(1)
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"]
+ niymap = [ "ASM", "Const", "Phi", "SymConst", "Sync"]
+
+ real_nodes = []
+ for node in nodes:
+ if isAbstract(node):
+ continue
+ real_nodes.append(node)
file = open(gendir + "/gen_ir_cons.c.inl", "w")
- for nodename, node in do_dictsort(ir_spec.nodes):
- if nodename in niymap:
+ for node in real_nodes:
+ preprocess_node(node)
+
+ if node.name in niymap:
continue
- preprocess_node(nodename, node)
- if not "abstract" in node:
- file.write(node_template.render(vars()))
+
+ if not isAbstract(node) and not hasattr(node, "singleton"):
+ file.write(constructor_template.render(vars()))
+
+ if hasattr(node, "special_constructors"):
+ 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()
-if __name__ == "__main__":
- main(sys.argv)
+ 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()
+
+main(sys.argv)