6ace69fffaff4ada0c532fe0b3dd35408edda23b
[libfirm] / scripts / gen_ir_io.py
1 #!/usr/bin/python
2 import sys
3 from jinja2 import Environment, Template
4 import ir_spec
5
6 def format_args(arglist):
7         #argstrings = map(lambda arg : arg["name"], arglist)
8         #return ", ".join(argstrings)
9         s = ", ".join(arglist)
10         if len(s) == 0:
11           return "";
12         return ", " + s;
13
14 def format_ifnset(string, node, key):
15         if key in node:
16                 return ""
17         return string
18
19 def format_block(node):
20         if node.get("knownBlock"):
21                 return ""
22         else:
23                 return ", get_node(env, preds[0])"
24
25 env = Environment()
26 env.filters['args']   = format_args
27 env.filters['ifnset'] = format_ifnset
28 env.filters['block']  = format_block
29
30 def get_io_type(type, attrname, nodename):
31         if type == "tarval*":
32                 importcmd = "tarval *%s = read_tv(env);" % attrname
33                 exportcmd = """
34                         write_mode(env, get_tarval_mode(%(val)s));
35                         tarval_snprintf(buf, sizeof(buf), %(val)s);
36                         fprintf(env->file, "%%s ", buf);"""
37         elif type == "ir_mode*":
38                 importcmd = "ir_mode *%s = read_mode(env);" % attrname
39                 exportcmd = "write_mode(env, %(val)s);"
40         elif type == "ir_entity*":
41                 importcmd = "ir_entity *%s = read_entity(env);" % attrname
42                 exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));"""
43         elif type == "ir_type*":
44                 importcmd = "ir_type *%s = read_type(env);" % attrname
45                 exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));"""
46         elif type == "long" and nodename == "Proj":
47                 importcmd = "long %s = read_long(env);" % attrname
48                 exportcmd = """fprintf(env->file, "%%ld ", %(val)s);"""
49         elif type == "pn_Cmp" or type == "ir_where_alloc":
50                 importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
51                 exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);"""
52         elif type == "cons_flags" and nodename == "Store":
53                 importcmd = """ir_cons_flags %s = read_pinned(env)
54                                 | read_volatility(env)
55                                 | read_align(env);""" % attrname
56                 exportcmd = """write_pinned(env, irn);
57                         write_volatility(env, irn);
58                         write_align(env, irn);"""
59         elif type == "cons_flags" and nodename == "Load":
60                 importcmd = """ir_cons_flags %s = read_pinned(env)
61                                 | read_volatility(env)
62                                 | read_align(env);""" % attrname
63                 exportcmd = """write_pinned(env, irn);
64                         write_volatility(env, irn);
65                         write_align(env, irn);"""
66         else:
67                 print "UNKNOWN TYPE: %s" % type
68                 importcmd = """// BAD: %s %s
69                         %s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
70                 exportcmd = "// BAD: %s" % type
71         return (importcmd, exportcmd)
72
73 """     if type == "ir_type*":
74                 java_type    = "firm.Type"
75                 wrap_type    = "Pointer"
76                 to_wrapper   = "%s.ptr"
77                 from_wrapper = "firm.Type.createWrapper(%s)"
78         elif type == "ir_mode*":
79                 java_type    = "firm.Mode"
80                 wrap_type    = "Pointer"
81                 to_wrapper   = "%s.ptr"
82                 from_wrapper = "new firm.Mode(%s)"
83         elif type == "tarval*":
84                 java_type    = "firm.TargetValue"
85                 wrap_type    = "Pointer"
86                 to_wrapper   = "%s.ptr"
87                 from_wrapper = "new firm.TargetValue(%s)"
88         elif type == "pn_Cmp":
89                 java_type    = "int"
90                 wrap_type    = "int"
91                 to_wrapper   = "%s"
92                 from_wrapper = "%s"
93         elif type == "long":
94                 java_type    = "int"
95                 wrap_type    = "com.sun.jna.NativeLong"
96                 to_wrapper   = "new com.sun.jna.NativeLong(%s)"
97                 from_wrapper = "%s.intValue()"
98         elif type == "cons_flags":
99                 java_type    = "firm.bindings.binding_ircons.ir_cons_flags"
100                 wrap_type    = "int"
101                 to_wrapper   = "%s.val"
102                 from_wrapper = "firm.bindings.binding_ircons.ir_cons_flags.getEnum(%s)"
103         elif type == "ir_where_alloc":
104                 java_type    = "firm.bindings.binding_ircons.ir_where_alloc"
105                 wrap_type    = "int"
106                 to_wrapper   = "%s.val"
107                 from_wrapper = "firm.bindings.binding_ircons.ir_where_alloc.getEnum(%s)"
108         elif type == "ir_entity*":
109                 java_type    = "firm.Entity"
110                 wrap_type    = "Pointer"
111                 to_wrapper   = "%s.ptr"
112                 from_wrapper = "new firm.Entity(%s)"
113         else:
114                 print "UNKNOWN TYPE"
115                 java_type    = "BAD"
116                 wrap_type    = "BAD"
117                 to_wrapper   = "BAD"
118                 from_wrapper = "BAD"
119         return (java_type,wrap_type,to_wrapper,from_wrapper)"""
120
121 def prepare_attr(nodename, attr):
122         (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], nodename)
123         attr["importcmd"] = importcmd
124         attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (nodename, attr["name"])}
125
126 def preprocess_node(nodename, node):
127         if "is_a" in node:
128                 parent = ir_spec.nodes[node["is_a"]]
129                 node["ins"] = parent["ins"]
130                 if "outs" in parent:
131                         node["outs"] = parent["outs"]
132         if "ins" not in node:
133                 node["ins"] = []
134         if "outs" in node:
135                 node["mode"] = "mode_T"
136         if "arity" not in node:
137                 node["arity"] = len(node["ins"])
138         if "attrs" not in node:
139                 node["attrs"] = []
140         if "constructor_args" not in node:
141                 node["constructor_args"] = []
142
143         # construct node arguments
144         arguments = [ ]
145         i = 0
146         for input in node["ins"]:
147                 arguments.append("prednodes[%i]" % i)
148                 i += 1
149
150         if node["arity"] == "variable" or node["arity"] == "dynamic":
151                 arguments.append("numpreds - %i" % (i + 1))
152                 arguments.append("prednodes + %i" % i)
153
154         if "mode" not in node:
155                 arguments.append("mode")
156
157         for attr in node["attrs"]:
158                 prepare_attr(nodename, attr)
159                 arguments.append(attr["name"])
160
161         for arg in node["constructor_args"]:
162                 prepare_attr(nodename, arg)
163                 arguments.append(arg["name"])
164
165         node["arguments"] = arguments
166
167 export_attrs_template = env.from_string('''
168         case iro_{{nodename}}:
169                 {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
170                 {% for attr in node.attrs %}{{attr.exportcmd}}
171                 {% endfor %}
172                 {% for attr in node.constructor_args %}{{attr.exportcmd}}
173                 {% endfor %}break;''')
174
175 import_attrs_template = env.from_string('''
176         case iro_{{nodename}}:
177         {
178                 {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
179                 {% for attr in node.attrs %}{{attr.importcmd}}
180                 {% endfor %}
181                 {% for attr in node.constructor_args %}{{attr.importcmd}}
182                 {% endfor %}newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
183                 break;
184         }
185 ''')
186
187 def main(argv):
188         """the main function"""
189
190         if len(argv) < 2:
191                 print "usage: %s destdirectory" % argv[0]
192                 sys.exit(1)
193
194         gendir = argv[1]
195
196         file = open(gendir + "/gen_irio_export.inl", "w");
197         for nodename, node in ir_spec.nodes.iteritems():
198                 preprocess_node(nodename, node)
199                 if not "abstract" in node:
200                         file.write(export_attrs_template.render(vars()))
201         file.write("\n")
202         file.close()
203
204         file = open(gendir + "/gen_irio_import.inl", "w");
205         for nodename, node in ir_spec.nodes.iteritems():
206                 if not "abstract" in node and nodename != "Start" and nodename != "End" and nodename != "Anchor" and nodename != "SymConst" and nodename != "Block":
207                         file.write(import_attrs_template.render(vars()))
208         # TODO: SymConst
209         file.write("\n")
210         file.close()
211
212         file = open(gendir + "/gen_irio_lex.inl", "w");
213         for nodename, node in ir_spec.nodes.iteritems():
214                 if not "abstract" in node:
215                         file.write("\tINSERT(\"" + nodename + "\", tt_iro, iro_" + nodename + ");\n");
216         file.close()
217
218 if __name__ == "__main__":
219         main(sys.argv)