e897533187645b8f54e206d09235e3c3acd8f29e
[libfirm] / ir / ir / irio.c
1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Write textual representation of firm to file.
23  * @author  Moritz Kroll
24  */
25 #include "config.h"
26
27 #include <string.h>
28 #include <ctype.h>
29 #include <stdbool.h>
30 #include <stdarg.h>
31
32 #include "irio.h"
33
34 #include "irnode_t.h"
35 #include "irprog.h"
36 #include "irgraph_t.h"
37 #include "irprintf.h"
38 #include "ircons.h"
39 #include "irgmod.h"
40 #include "irflag_t.h"
41 #include "irgwalk.h"
42 #include "tv.h"
43 #include "array.h"
44 #include "error.h"
45 #include "typerep.h"
46 #include "adt/set.h"
47 #include "adt/obst.h"
48
49 #define SYMERROR ((unsigned) ~0)
50
51 typedef struct io_env_t
52 {
53         int c;                /**< currently read char */
54         FILE *file;
55         set *idset;           /**< id_entry set, which maps from file ids to new Firm elements */
56         int ignoreblocks;
57         const char *inputname;
58         int line;
59         ir_type **fixedtypes;
60         struct obstack obst;
61         ir_graph *irg;
62 } io_env_t;
63
64 typedef enum typetag_t
65 {
66         tt_align,
67         tt_allocation,
68         tt_builtin,
69         tt_cond_jmp_predicate,
70         tt_initializer,
71         tt_iro,
72         tt_keyword,
73         tt_mode_arithmetic,
74         tt_pin_state,
75         tt_tpo,
76         tt_type_state,
77         tt_volatility,
78         tt_linkage,
79         tt_segment,
80         tt_visibility
81 } typetag_t;
82
83 typedef enum keyword_t
84 {
85         kw_constirg,
86         kw_entity,
87         kw_irg,
88         kw_int_mode,
89         kw_reference_mode,
90         kw_float_mode,
91         kw_modes,
92         kw_type,
93         kw_typegraph,
94         kw_program,
95         kw_segment_type
96 } keyword_t;
97
98 typedef struct symbol_t
99 {
100         const char *str;      /**< The name of this symbol. */
101         typetag_t   typetag;  /**< The type tag of this symbol. */
102         unsigned    code;     /**< The value of this symbol. */
103 } symbol_t;
104
105 typedef struct id_entry
106 {
107         long id;
108         void *elem;
109 } id_entry;
110
111 /** The symbol table, a set of symbol_t elements. */
112 static set *symtbl;
113
114 /**
115  * Compare two symbol table entries.
116  */
117 static int symbol_cmp(const void *elt, const void *key, size_t size)
118 {
119         int res;
120         const symbol_t *entry = (const symbol_t *) elt;
121         const symbol_t *keyentry = (const symbol_t *) key;
122         (void) size;
123         res = entry->typetag - keyentry->typetag;
124         if (res) return res;
125         return strcmp(entry->str, keyentry->str);
126 }
127
128 static int id_cmp(const void *elt, const void *key, size_t size)
129 {
130         const id_entry *entry = (const id_entry *) elt;
131         const id_entry *keyentry = (const id_entry *) key;
132         (void) size;
133         return entry->id - keyentry->id;
134 }
135
136 static void __attribute__((format(printf, 2, 3)))
137 parse_error(io_env_t *env, const char *fmt, ...)
138 {
139         va_list ap;
140         int     line = env->line;
141
142         /* workaround read_c "feature" that a '\n' triggers the line++
143          * instead of the character after the '\n' */
144         if (env->c == '\n') {
145                 line--;
146         }
147
148         fprintf(stderr, "%s:%d: error ", env->inputname, line);
149
150         va_start(ap, fmt);
151         vfprintf(stderr, fmt, ap);
152         va_end(ap);
153 }
154
155 /** Initializes the symbol table. May be called more than once without problems. */
156 static void symtbl_init(void)
157 {
158         symbol_t key;
159
160         /* Only initialize once */
161         if (symtbl != NULL)
162                 return;
163
164         symtbl = new_set(symbol_cmp, 256);
165
166 #define INSERT(tt, s, cod)                                       \
167         key.str = (s);                                               \
168         key.typetag = (tt);                                          \
169         key.code = (cod);                                            \
170         set_insert(symtbl, &key, sizeof(key), firm_fnv_hash_str(s) + tt * 17)
171
172 #define INSERTENUM(tt, e) INSERT(tt, #e, e)
173 #define INSERTKEYWORD(k) INSERT(tt_keyword, #k, kw_##k)
174
175         INSERT(tt_tpo, "array", tpo_array);
176         INSERT(tt_tpo, "class", tpo_class);
177         INSERT(tt_tpo, "method", tpo_method);
178         INSERT(tt_tpo, "pointer", tpo_pointer);
179         INSERT(tt_tpo, "primitive", tpo_primitive);
180         INSERT(tt_tpo, "struct", tpo_struct);
181         INSERT(tt_tpo, "union", tpo_union);
182         INSERT(tt_tpo, "Unknown", tpo_unknown);
183
184         INSERT(tt_segment, "global", IR_SEGMENT_GLOBAL);
185         INSERT(tt_segment, "thread_local", IR_SEGMENT_THREAD_LOCAL);
186         INSERT(tt_segment, "constructors", IR_SEGMENT_CONSTRUCTORS);
187         INSERT(tt_segment, "destructors", IR_SEGMENT_DESTRUCTORS);
188
189         INSERT(tt_linkage, "constant", IR_LINKAGE_CONSTANT);
190         INSERT(tt_linkage, "weak", IR_LINKAGE_WEAK);
191         INSERT(tt_linkage, "garbage_collect", IR_LINKAGE_GARBAGE_COLLECT);
192         INSERT(tt_linkage, "merge", IR_LINKAGE_MERGE);
193         INSERT(tt_linkage, "hidden_user", IR_LINKAGE_HIDDEN_USER);
194
195         INSERT(tt_visibility, "local", ir_visibility_local);
196         INSERT(tt_visibility, "external", ir_visibility_external);
197         INSERT(tt_visibility, "default", ir_visibility_default);
198         INSERT(tt_visibility, "private", ir_visibility_private);
199
200         INSERTKEYWORD(constirg);
201         INSERTKEYWORD(entity);
202         INSERTKEYWORD(irg);
203         INSERTKEYWORD(int_mode);
204         INSERTKEYWORD(float_mode);
205         INSERTKEYWORD(reference_mode);
206         INSERTKEYWORD(modes);
207         INSERTKEYWORD(type);
208         INSERTKEYWORD(typegraph);
209         INSERTKEYWORD(program);
210         INSERTKEYWORD(segment_type);
211
212 #include "gen_irio_lex.inl"
213
214         INSERTENUM(tt_align, align_non_aligned);
215         INSERTENUM(tt_align, align_is_aligned);
216
217         INSERTENUM(tt_builtin, ir_bk_trap);
218         INSERTENUM(tt_builtin, ir_bk_debugbreak);
219         INSERTENUM(tt_builtin, ir_bk_return_address);
220         INSERTENUM(tt_builtin, ir_bk_frame_address);
221         INSERTENUM(tt_builtin, ir_bk_prefetch);
222         INSERTENUM(tt_builtin, ir_bk_ffs);
223         INSERTENUM(tt_builtin, ir_bk_clz);
224         INSERTENUM(tt_builtin, ir_bk_ctz);
225         INSERTENUM(tt_builtin, ir_bk_popcount);
226         INSERTENUM(tt_builtin, ir_bk_parity);
227         INSERTENUM(tt_builtin, ir_bk_bswap);
228         INSERTENUM(tt_builtin, ir_bk_inport);
229         INSERTENUM(tt_builtin, ir_bk_outport);
230         INSERTENUM(tt_builtin, ir_bk_inner_trampoline);
231
232         INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_NONE);
233         INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_TRUE);
234         INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_FALSE);
235
236         INSERTENUM(tt_initializer, IR_INITIALIZER_CONST);
237         INSERTENUM(tt_initializer, IR_INITIALIZER_TARVAL);
238         INSERTENUM(tt_initializer, IR_INITIALIZER_NULL);
239         INSERTENUM(tt_initializer, IR_INITIALIZER_COMPOUND);
240
241         INSERTENUM(tt_mode_arithmetic, irma_uninitialized);
242         INSERTENUM(tt_mode_arithmetic, irma_none);
243         INSERTENUM(tt_mode_arithmetic, irma_twos_complement);
244         INSERTENUM(tt_mode_arithmetic, irma_ieee754);
245
246         INSERTENUM(tt_pin_state, op_pin_state_floats);
247         INSERTENUM(tt_pin_state, op_pin_state_pinned);
248         INSERTENUM(tt_pin_state, op_pin_state_exc_pinned);
249         INSERTENUM(tt_pin_state, op_pin_state_mem_pinned);
250
251         INSERTENUM(tt_type_state, layout_undefined);
252         INSERTENUM(tt_type_state, layout_fixed);
253
254         INSERTENUM(tt_volatility, volatility_non_volatile);
255         INSERTENUM(tt_volatility, volatility_is_volatile);
256
257 #undef INSERTKEYWORD
258 #undef INSERTENUM
259 #undef INSERT
260 }
261
262 static const char *get_segment_name(ir_segment_t segment)
263 {
264         switch (segment) {
265         case IR_SEGMENT_GLOBAL:       return "global";
266         case IR_SEGMENT_THREAD_LOCAL: return "thread_local";
267         case IR_SEGMENT_CONSTRUCTORS: return "constructors";
268         case IR_SEGMENT_DESTRUCTORS:  return "destructors";
269         }
270         return "INVALID_SEGMENT";
271 }
272
273 static const char *get_visibility_name(ir_visibility visibility)
274 {
275         switch (visibility) {
276         case ir_visibility_local:    return "local";
277         case ir_visibility_external: return "external";
278         case ir_visibility_default:  return "default";
279         case ir_visibility_private:  return "private";
280         }
281         return "INVALID_VISIBILITY";
282 }
283
284 /** Returns the according symbol value for the given string and tag, or SYMERROR if none was found. */
285 static unsigned symbol(const char *str, typetag_t typetag)
286 {
287         symbol_t key, *entry;
288
289         key.str = str;
290         key.typetag = typetag;
291
292         entry = (symbol_t*)set_find(symtbl, &key, sizeof(key), firm_fnv_hash_str(str) + typetag * 17);
293         return entry ? entry->code : SYMERROR;
294 }
295
296 static void *get_id(io_env_t *env, long id)
297 {
298         id_entry key, *entry;
299         key.id = id;
300
301         entry = (id_entry*)set_find(env->idset, &key, sizeof(key), (unsigned) id);
302         return entry ? entry->elem : NULL;
303 }
304
305 static void set_id(io_env_t *env, long id, void *elem)
306 {
307         id_entry key;
308         key.id = id;
309         key.elem = elem;
310         set_insert(env->idset, &key, sizeof(key), (unsigned) id);
311 }
312
313 static void write_long(io_env_t *env, long value)
314 {
315         fprintf(env->file, "%ld ", value);
316 }
317
318 static void write_int(io_env_t *env, int value)
319 {
320         fprintf(env->file, "%d ", value);
321 }
322
323 static void write_unsigned(io_env_t *env, unsigned value)
324 {
325         fprintf(env->file, "%u ", value);
326 }
327
328 static void write_entity_ref(io_env_t *env, ir_entity *entity)
329 {
330         write_long(env, get_entity_nr(entity));
331 }
332
333 static void write_type_ref(io_env_t *env, ir_type *type)
334 {
335         write_long(env, get_type_nr(type));
336 }
337
338 static void write_string(io_env_t *env, const char *string)
339 {
340         const char *c;
341         fputc('"', env->file);
342         for (c = string; *c != '\0'; ++c) {
343                 switch (*c) {
344                 case '\n':
345                         fputc('\\', env->file);
346                         fputc('n', env->file);
347                         break;
348                 case '"':
349                 case '\\':
350                         fputc('\\', env->file);
351                         /* FALLTHROUGH */
352                 default:
353                         fputc(*c, env->file);
354                         break;
355                 }
356         }
357         fputc('"', env->file);
358 }
359
360 static void write_ident(io_env_t *env, ident *id)
361 {
362         write_string(env, get_id_str(id));
363         fputc(' ', env->file);
364 }
365
366 static void write_ident_null(io_env_t *env, ident *id)
367 {
368         if (id == NULL) {
369                 fputs("NULL ", env->file);
370         } else {
371                 write_ident(env, id);
372         }
373 }
374
375 static void write_mode(io_env_t *env, ir_mode *mode)
376 {
377         write_string(env, get_mode_name(mode));
378         fputc(' ', env->file);
379 }
380
381 static void write_tarval(io_env_t *env, ir_tarval *tv)
382 {
383         char buf[1024];
384         write_mode(env, get_tarval_mode(tv));
385         tarval_snprintf(buf, sizeof(buf), tv);
386         fputs(buf, env->file);
387         fputc(' ', env->file);
388 }
389
390 static void write_align(io_env_t *env, ir_align align)
391 {
392         fputs(get_align_name(align), env->file);
393         fputc(' ', env->file);
394 }
395
396 static void write_builtin_kind(io_env_t *env, ir_node *irn)
397 {
398         fputs(get_builtin_kind_name(get_Builtin_kind(irn)), env->file);
399         fputc(' ', env->file);
400 }
401
402 static void write_cond_jmp_predicate(io_env_t *env, ir_node *irn)
403 {
404         fputs(get_cond_jmp_predicate_name(get_Cond_jmp_pred(irn)), env->file);
405         fputc(' ', env->file);
406 }
407
408 static void write_list_begin(io_env_t *env)
409 {
410         fputs("[", env->file);
411 }
412
413 static void write_list_end(io_env_t *env)
414 {
415         fputs("] ", env->file);
416 }
417
418 static void write_initializer(io_env_t *env, ir_initializer_t *ini)
419 {
420         FILE *f = env->file;
421         ir_initializer_kind_t ini_kind = get_initializer_kind(ini);
422
423         fputs(get_initializer_kind_name(ini_kind), f);
424         fputc(' ', f);
425
426         switch (ini_kind) {
427         case IR_INITIALIZER_CONST:
428                 write_long(env, get_irn_node_nr(get_initializer_const_value(ini)));
429                 break;
430
431         case IR_INITIALIZER_TARVAL:
432                 write_tarval(env, get_initializer_tarval_value(ini));
433                 break;
434
435         case IR_INITIALIZER_NULL:
436                 break;
437
438         case IR_INITIALIZER_COMPOUND: {
439                 size_t i, n = get_initializer_compound_n_entries(ini);
440                 ir_fprintf(f, "%zu ", n);
441                 for (i = 0; i < n; ++i)
442                         write_initializer(env, get_initializer_compound_value(ini, i));
443                 break;
444         }
445
446         default:
447                 panic("Unknown initializer kind");
448         }
449 }
450
451 static void write_pin_state(io_env_t *env, ir_node *irn)
452 {
453         fputs(get_op_pin_state_name(get_irn_pinned(irn)), env->file);
454         fputc(' ', env->file);
455 }
456
457 static void write_volatility(io_env_t *env, ir_volatility vol)
458 {
459         fputs(get_volatility_name(vol), env->file);
460         fputc(' ', env->file);
461 }
462
463 static void export_type_common(io_env_t *env, ir_type *tp)
464 {
465         fprintf(env->file, "\ttype %ld %s %u %u %s %u ",
466                 get_type_nr(tp),
467                 get_type_tpop_name(tp),
468                 get_type_size_bytes(tp),
469                 get_type_alignment_bytes(tp),
470                 get_type_state_name(get_type_state(tp)),
471                 tp->flags);
472 }
473
474 static void export_type_pre(io_env_t *env, ir_type *tp)
475 {
476         FILE *f = env->file;
477
478         /* skip types to be handled by post walker */
479         switch (get_type_tpop_code(tp)) {
480         case tpo_array:
481         case tpo_method:
482         case tpo_pointer:
483                 return;
484         default:
485                 break;
486         }
487
488         export_type_common(env, tp);
489
490         switch (get_type_tpop_code(tp)) {
491         case tpo_uninitialized:
492                 panic("invalid type found");
493
494         case tpo_class:
495                 write_ident_null(env, get_compound_ident(tp));
496                 break;
497
498         case tpo_primitive:
499                 write_mode(env, get_type_mode(tp));
500                 break;
501
502         case tpo_union:
503         case tpo_struct:
504         case tpo_enumeration:
505                 write_ident_null(env, get_compound_ident(tp));
506                 break;
507
508         case tpo_array:
509         case tpo_method:
510         case tpo_pointer:
511         case tpo_code:
512         case tpo_none:
513         case tpo_unknown:
514                 break;
515         }
516         fputc('\n', f);
517 }
518
519 static void export_type_post(io_env_t *env, ir_type *tp)
520 {
521         FILE *f = env->file;
522         size_t i;
523
524         /* skip types already handled by pre walker */
525         switch (get_type_tpop_code(tp)) {
526         case tpo_class:
527         case tpo_primitive:
528         case tpo_struct:
529         case tpo_union:
530         case tpo_unknown:
531         case tpo_uninitialized:
532         case tpo_code:
533         case tpo_none:
534                 return;
535         case tpo_array:
536         case tpo_method:
537         case tpo_pointer:
538         case tpo_enumeration:
539                 break;
540         }
541
542         export_type_common(env, tp);
543
544         switch (get_type_tpop_code(tp)) {
545         case tpo_array: {
546                 size_t n = get_array_n_dimensions(tp);
547                 ir_fprintf(f, "%zu %ld ", n, get_type_nr(get_array_element_type(tp)));
548                 for (i = 0; i < n; i++) {
549                         ir_node *lower = get_array_lower_bound(tp, i);
550                         ir_node *upper = get_array_upper_bound(tp, i);
551
552                         if (is_Const(lower))
553                                 write_long(env, get_tarval_long(get_Const_tarval(lower)));
554                         else
555                                 panic("Lower array bound is not constant");
556
557                         if (is_Const(upper))
558                                 write_long(env, get_tarval_long(get_Const_tarval(upper)));
559                         else if (is_Unknown(upper))
560                                 fputs("unknown ", f);
561                         else
562                                 panic("Upper array bound is not constant");
563                 }
564                 break;
565         }
566
567         case tpo_method: {
568                 size_t nparams  = get_method_n_params(tp);
569                 size_t nresults = get_method_n_ress(tp);
570                 ir_fprintf(f, "%u %u %zu %zu ", get_method_calling_convention(tp),
571                         get_method_additional_properties(tp), nparams, nresults);
572                 for (i = 0; i < nparams; i++)
573                         write_long(env, get_type_nr(get_method_param_type(tp, i)));
574                 for (i = 0; i < nresults; i++)
575                         write_long(env, get_type_nr(get_method_res_type(tp, i)));
576                 ir_fprintf(f, "%u ", get_method_variadicity(tp));
577                 break;
578         }
579
580         case tpo_pointer:
581                 write_mode(env, get_type_mode(tp));
582                 write_long(env, get_type_nr(get_pointer_points_to_type(tp)));
583                 break;
584
585         case tpo_enumeration:
586                 fprintf(stderr, "Enumeration type not handled yet by exporter\n");
587                 break;
588
589         default:
590                 printf("export_type: Unknown type code \"%s\".\n",
591                        get_type_tpop_name(tp));
592                 break;
593         }
594         fputc('\n', f);
595 }
596
597 static void export_entity(io_env_t *env, ir_entity *ent)
598 {
599         FILE          *file       = env->file;
600         ir_type       *owner      = get_entity_owner(ent);
601         ir_visibility  visibility = get_entity_visibility(ent);
602         ir_linkage     linkage    = get_entity_linkage(ent);
603
604         /* we don't dump array_element_ent entities. They're a strange concept
605          * and lead to cycles in type_graph.
606          */
607         if (is_Array_type(owner))
608                 return;
609
610         fprintf(env->file, "\tentity ");
611         write_long(env, get_entity_nr(ent));
612         write_ident_null(env, get_entity_ident(ent));
613         if (!entity_has_ld_ident(ent)) {
614                 write_ident_null(env, NULL);
615         } else {
616                 write_ident_null(env, get_entity_ld_ident(ent));
617         }
618
619         /* visibility + linkage */
620         if (visibility != ir_visibility_default) {
621                 fprintf(file, "%s ", get_visibility_name(visibility));
622         }
623         if (linkage & IR_LINKAGE_CONSTANT)
624                 fputs("constant ", file);
625         if (linkage & IR_LINKAGE_WEAK)
626                 fputs("weak ", file);
627         if (linkage & IR_LINKAGE_GARBAGE_COLLECT)
628                 fputs("garbage_collect ", file);
629         if (linkage & IR_LINKAGE_MERGE)
630                 fputs("merge ", file);
631         if (linkage & IR_LINKAGE_HIDDEN_USER)
632                 fputs("hidden_user ", file);
633
634         fprintf(file, "%ld %ld %d %u %d %s ",
635                         get_type_nr(get_entity_type(ent)),
636                         get_type_nr(owner),
637                         get_entity_offset(ent),
638                         (unsigned) get_entity_offset_bits_remainder(ent),
639                         is_entity_compiler_generated(ent),
640                         get_volatility_name(get_entity_volatility(ent)));
641
642         if (ent->initializer != NULL) {
643                 fputs("initializer ", env->file);
644                 write_initializer(env, get_entity_initializer(ent));
645         } else if (entity_has_compound_ent_values(ent)) {
646                 size_t i, n = get_compound_ent_n_values(ent);
647                 fputs("compoundgraph ", env->file);
648                 ir_fprintf(env->file, "%zu ", n);
649                 for (i = 0; i < n; i++) {
650                         ir_entity *member = get_compound_ent_value_member(ent, i);
651                         ir_node   *irn    = get_compound_ent_value(ent, i);
652                         fprintf(env->file, "%ld %ld ", get_entity_nr(member), get_irn_node_nr(irn));
653                 }
654         } else {
655                 fputs("none", env->file);
656         }
657
658         fputc('\n', env->file);
659 }
660
661 static void export_type_or_ent_pre(type_or_ent tore, void *ctx)
662 {
663         io_env_t *env = (io_env_t *) ctx;
664         if (get_kind(tore.typ) == k_type)
665                 export_type_pre(env, tore.typ);
666 }
667
668 static void export_type_or_ent_post(type_or_ent tore, void *ctx)
669 {
670         io_env_t *env = (io_env_t *) ctx;
671
672         switch (get_kind(tore.ent)) {
673         case k_entity:
674                 export_entity(env, tore.ent);
675                 break;
676
677         case k_type:
678                 export_type_post(env, tore.typ);
679                 break;
680
681         default:
682                 panic("export_type_or_ent_post: Unknown type or entity.");
683         }
684 }
685
686 static void export_ASM(io_env_t *env, ir_node *node)
687 {
688         ir_asm_constraint *input_constraints    = get_ASM_input_constraints(node);
689         ir_asm_constraint *output_constraints   = get_ASM_output_constraints(node);
690         ident            **clobbers             = get_ASM_clobbers(node);
691         int                n_input_constraints  = get_ASM_n_input_constraints(node);
692         int                n_output_constraints = get_ASM_n_output_constraints(node);
693         int                n_clobbers           = get_ASM_n_clobbers(node);
694         int i;
695
696         write_ident(env, get_ASM_text(node));
697         write_list_begin(env);
698         for (i = 0; i < n_input_constraints; ++i) {
699                 const ir_asm_constraint *constraint = &input_constraints[i];
700                 write_unsigned(env, constraint->pos);
701                 write_ident(env, constraint->constraint);
702                 write_mode(env, constraint->mode);
703         }
704         write_list_end(env);
705
706         write_list_begin(env);
707         for (i = 0; i < n_output_constraints; ++i) {
708                 const ir_asm_constraint *constraint = &output_constraints[i];
709                 write_unsigned(env, constraint->pos);
710                 write_ident(env, constraint->constraint);
711                 write_mode(env, constraint->mode);
712         }
713         write_list_end(env);
714
715         write_list_begin(env);
716         for (i = 0; i < n_clobbers; ++i) {
717                 ident *clobber = clobbers[i];
718                 write_ident(env, clobber);
719         }
720         write_list_end(env);
721 }
722
723 /**
724  * Walker: exports every node.
725  */
726 static void export_node(ir_node *irn, void *ctx)
727 {
728         io_env_t *env = (io_env_t *) ctx;
729         int i, n;
730         unsigned opcode = get_irn_opcode(irn);
731
732         if (env->ignoreblocks && opcode == iro_Block)
733                 return;
734
735         fprintf(env->file, "\t%s ", get_irn_opname(irn));
736         write_long(env, get_irn_node_nr(irn));
737
738         write_list_begin(env);
739         n = get_irn_arity(irn);
740         if (!is_Block(irn)) {
741                 ir_node *block = get_nodes_block(irn);
742                 write_long(env, get_irn_node_nr(block));
743         }
744
745         for (i = 0; i < n; i++) {
746                 ir_node *pred = get_irn_n(irn, i);
747                 if (pred == NULL) {
748                         /* Anchor node may have NULL predecessors */
749                         assert(is_Anchor(irn));
750                         fputs("-1 ", env->file);
751                 } else {
752                         write_long(env, get_irn_node_nr(pred));
753                 }
754         }
755         write_list_end(env);
756
757         fputs("{ ", env->file);
758
759         switch (opcode) {
760         case iro_Start:
761         case iro_End:
762         case iro_Block:
763         case iro_Anchor:
764                 break;
765         case iro_SymConst:
766                 /* TODO: only symconst_addr_ent implemented yet */
767                 assert(get_SymConst_kind(irn) == symconst_addr_ent);
768                 fprintf(env->file, "%ld ", get_entity_nr(get_SymConst_entity(irn)));
769                 write_mode(env, get_irn_mode(irn));
770                 break;
771         case iro_Proj:
772                 write_mode(env, get_irn_mode(irn));
773                 fprintf(env->file, "%ld ", get_Proj_proj(irn));
774                 break;
775         case iro_ASM:
776                 export_ASM(env, irn);
777                 break;
778 #include "gen_irio_export.inl"
779         default:
780                 panic("no export code for node %+F\n", irn);
781         }
782         fputs("}\n", env->file);
783 }
784
785 static void export_modes(io_env_t *env)
786 {
787         size_t i, n_modes = get_irp_n_modes();
788
789         fputs("modes {\n", env->file);
790
791         for (i = 0; i < n_modes; i++) {
792                 ir_mode *mode = get_irp_mode(i);
793
794                 if (mode_is_int(mode)) {
795                         fprintf(env->file, "\tint_mode ");
796                         write_string(env, get_mode_name(mode));
797                         fprintf(env->file, "%s %u %d %u ",
798                                 get_mode_arithmetic_name(get_mode_arithmetic(mode)),
799                                 get_mode_size_bits(mode), get_mode_sign(mode),
800                                 get_mode_modulo_shift(mode));
801                 } else if (mode_is_reference(mode)) {
802                         fprintf(env->file, "\treference_mode ");
803                         write_string(env, get_mode_name(mode));
804                         fprintf(env->file, "%s %u %u ",
805                                         get_mode_arithmetic_name(get_mode_arithmetic(mode)),
806                                         get_mode_size_bits(mode),
807                                         get_mode_modulo_shift(mode));
808                         write_mode(env, get_reference_mode_signed_eq(mode));
809                         write_mode(env, get_reference_mode_unsigned_eq(mode));
810                         write_int(env, (mode == mode_P ? 1 : 0));
811                 } else if (mode_is_float(mode)) {
812                         fprintf(env->file, "\tfloat_mode ");
813                         write_string(env, get_mode_name(mode));
814                         fprintf(env->file, "%s %u %u ",
815                                 get_mode_arithmetic_name(get_mode_arithmetic(mode)),
816                                 get_mode_exponent_size(mode),
817                                 get_mode_mantissa_size(mode));
818                 } else {
819                         /* skip "internal" modes */
820                 }
821                 fputc('\n', env->file);
822         }
823
824         fputs("}\n", env->file);
825 }
826
827 static void export_program(io_env_t *env)
828 {
829         FILE         *f = env->file;
830         ir_segment_t  s;
831
832         fputs("\nprogram {\n", f);
833         if (irp_prog_name_is_set()) {
834                 fprintf(f, "\tname ");
835                 write_string(env, get_irp_name());
836                 fputc('\n', f);
837         }
838
839         for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
840                 ir_type *segment_type = get_segment_type(s);
841                 fprintf(f, "\tsegment_type %s ", get_segment_name(s));
842                 if (segment_type == NULL) {
843                         fputs(" NULL\n", f);
844                 } else {
845                         write_long(env, get_type_nr(segment_type));
846                         fputc('\n', f);
847                 }
848         }
849         fputs("}\n", f);
850 }
851
852 void ir_export(const char *filename)
853 {
854         FILE *file = fopen(filename, "wt");
855         if (file == NULL) {
856                 perror(filename);
857                 return;
858         }
859
860         ir_export_file(file, filename);
861         fclose(file);
862 }
863
864 /* Exports the whole irp to the given file in a textual form. */
865 void ir_export_file(FILE *file, const char *outputname)
866 {
867         io_env_t env;
868         size_t i, n_irgs = get_irp_n_irgs();
869
870         (void) outputname;
871         env.file = file;
872
873         export_modes(&env);
874
875         fputs("\ntypegraph {\n", env.file);
876         type_walk_prog(export_type_or_ent_pre, export_type_or_ent_post, &env);
877         fputs("}\n", env.file);
878
879         for (i = 0; i < n_irgs; i++) {
880                 ir_graph *irg       = get_irp_irg(i);
881
882                 fprintf(env.file, "\nirg %ld %ld {\n",
883                         get_entity_nr(get_irg_entity(irg)),
884                         get_type_nr(get_irg_frame_type(irg)));
885
886                 env.ignoreblocks = 0;
887                 irg_block_walk_graph(irg, NULL, export_node, &env);
888
889                 env.ignoreblocks = 1;
890                 irg_walk_anchors(irg, NULL, export_node, &env);
891
892                 fputs("}\n", env.file);
893         }
894
895         fprintf(env.file, "\nconstirg %ld {\n", get_irn_node_nr(get_const_code_irg()->current_block));
896
897         walk_const_code(NULL, export_node, &env);
898         fputs("}\n", env.file);
899
900         export_program(&env);
901 }
902
903 /* Exports the given irg to the given file. */
904 void ir_export_irg(ir_graph *irg, FILE *file, const char *outputname)
905 {
906         io_env_t env;
907
908         (void) outputname;
909         env.file = file;
910
911         export_modes(&env);
912
913         fputs("typegraph {\n", env.file);
914
915         type_walk_irg(irg, export_type_or_ent_pre, export_type_or_ent_post, &env);
916
917         fprintf(env.file, "}\n\nirg %ld {\n", get_entity_nr(get_irg_entity(irg)));
918
919         env.ignoreblocks = 0;
920         irg_block_walk_graph(irg, NULL, export_node, &env);
921
922         env.ignoreblocks = 1;
923         irg_walk_anchors(irg, NULL, export_node, &env);
924
925         /* TODO: Only output needed constants */
926         fprintf(env.file, "}\n\nconstirg %ld {\n", get_irn_node_nr(get_const_code_irg()->current_block));
927         walk_const_code(NULL, export_node, &env);
928         fputs("}\n", env.file);
929 }
930
931 static void read_c(io_env_t *env)
932 {
933         int c = fgetc(env->file);
934         env->c = c;
935         if (c == '\n')
936                 env->line++;
937 }
938
939 /** Returns the first non-whitespace character or EOF. **/
940 static void skip_ws(io_env_t *env)
941 {
942         while (true) {
943                 switch (env->c) {
944                 case ' ':
945                 case '\t':
946                 case '\n':
947                 case '\r':
948                         read_c(env);
949                         continue;
950
951                 default:
952                         return;
953                 }
954         }
955 }
956
957 static void skip_to(io_env_t *env, char to_ch)
958 {
959         while (env->c != to_ch && env->c != EOF) {
960                 read_c(env);
961         }
962 }
963
964 static int expect_char(io_env_t *env, char ch)
965 {
966         skip_ws(env);
967         if (env->c != ch) {
968                 parse_error(env, "Unexpected char '%c', expected '%c'\n",
969                             env->c, ch);
970                 return 0;
971         }
972         read_c(env);
973         return 1;
974 }
975
976 #define EXPECT(c) if (expect_char(env, (c))) {} else return 0
977
978 static char *read_word(io_env_t *env)
979 {
980         skip_ws(env);
981
982         assert(obstack_object_size(&env->obst) == 0);
983         while (true) {
984                 int c = env->c;
985                 switch (c) {
986                 case EOF:
987                 case ' ':
988                 case '\t':
989                 case '\n':
990                 case '\r':
991                         goto endofword;
992
993                 default:
994                         obstack_1grow(&env->obst, c);
995                         break;
996                 }
997                 read_c(env);
998         }
999
1000 endofword:
1001         obstack_1grow(&env->obst, '\0');
1002         return (char*)obstack_finish(&env->obst);
1003 }
1004
1005 static char *read_string(io_env_t *env)
1006 {
1007         skip_ws(env);
1008         if (env->c != '"') {
1009                 parse_error(env, "Expected string, got '%c'\n", env->c);
1010                 exit(1);
1011         }
1012         read_c(env);
1013
1014         assert(obstack_object_size(&env->obst) == 0);
1015         while (env->c != '"') {
1016                 if (env->c == EOF) {
1017                         parse_error(env, "Unexpected EOF while parsing string\n");
1018                         exit(1);
1019                 }
1020
1021                 if (env->c == '\\') {
1022                         read_c(env);
1023                         switch (env->c) {
1024                         case 'n':
1025                                 obstack_1grow(&env->obst, '\n');
1026                                 break;
1027                         case '"':
1028                         case '\\':
1029                                 obstack_1grow(&env->obst, env->c);
1030                                 break;
1031                         default:
1032                                 parse_error(env, "Unknown escape sequence '\\%c'\n", env->c);
1033                                 exit(1);
1034                         }
1035                 } else {
1036                         obstack_1grow(&env->obst, env->c);
1037                 }
1038                 read_c(env);
1039         }
1040         read_c(env);
1041         obstack_1grow(&env->obst, 0);
1042
1043         return (char*)obstack_finish(&env->obst);
1044 }
1045
1046 static ident *read_ident(io_env_t *env)
1047 {
1048         char  *str = read_string(env);
1049         ident *res = new_id_from_str(str);
1050         obstack_free(&env->obst, str);
1051         return res;
1052 }
1053
1054 /*
1055  * reads a "quoted string" or alternatively the token NULL
1056  */
1057 static char *read_string_null(io_env_t *env)
1058 {
1059         skip_ws(env);
1060         if (env->c == 'N') {
1061                 char *str = read_word(env);
1062                 if (strcmp(str, "NULL") == 0) {
1063                         obstack_free(&env->obst, str);
1064                         return NULL;
1065                 }
1066         } else if (env->c == '"') {
1067                 return read_string(env);
1068         }
1069
1070         parse_error(env, "Expected \"string\" or NULL\n");
1071         exit(1);
1072 }
1073
1074 static ident *read_ident_null(io_env_t *env)
1075 {
1076         ident *res;
1077         char  *str = read_string_null(env);
1078         if (str == NULL)
1079                 return NULL;
1080
1081         res = new_id_from_str(str);
1082         obstack_free(&env->obst, str);
1083         return res;
1084 }
1085
1086 static long read_long(io_env_t *env)
1087 {
1088         long  result;
1089         char *str;
1090
1091         skip_ws(env);
1092         if (!isdigit(env->c) && env->c != '-') {
1093                 parse_error(env, "Expected number, got '%c'\n", env->c);
1094                 exit(1);
1095         }
1096
1097         assert(obstack_object_size(&env->obst) == 0);
1098         do {
1099                 obstack_1grow(&env->obst, env->c);
1100                 read_c(env);
1101         } while (isdigit(env->c));
1102         obstack_1grow(&env->obst, 0);
1103
1104         str = (char*)obstack_finish(&env->obst);
1105         result = atol(str);
1106         obstack_free(&env->obst, str);
1107
1108         return result;
1109 }
1110
1111 static int read_int(io_env_t *env)
1112 {
1113         return (int) read_long(env);
1114 }
1115
1116 static unsigned read_unsigned(io_env_t *env)
1117 {
1118         return (unsigned) read_long(env);
1119 }
1120
1121 static size_t read_size_t(io_env_t *env)
1122 {
1123         /* FIXME */
1124         return (size_t) read_unsigned(env);
1125 }
1126
1127 static void expect_list_begin(io_env_t *env)
1128 {
1129         skip_ws(env);
1130         if (env->c != '[') {
1131                 parse_error(env, "Expected list, got '%c'\n", env->c);
1132                 exit(1);
1133         }
1134         read_c(env);
1135 }
1136
1137 static bool list_has_next(io_env_t *env)
1138 {
1139         if (feof(env->file)) {
1140                 parse_error(env, "Unexpected EOF while reading list");
1141                 exit(1);
1142         }
1143         skip_ws(env);
1144         if (env->c == ']') {
1145                 read_c(env);
1146                 return false;
1147         }
1148
1149         return true;
1150 }
1151
1152 static ir_node *get_node_or_null(io_env_t *env, long nodenr)
1153 {
1154         ir_node *node = (ir_node *) get_id(env, nodenr);
1155         if (node && node->kind != k_ir_node) {
1156                 panic("Irn ID %ld collides with something else in line %d\n",
1157                       nodenr, env->line);
1158         }
1159         return node;
1160 }
1161
1162 static ir_node *get_node_or_dummy(io_env_t *env, long nodenr)
1163 {
1164         ir_node *node = get_node_or_null(env, nodenr);
1165         if (node == NULL) {
1166                 node = new_r_Dummy(env->irg, mode_X);
1167                 set_id(env, nodenr, node);
1168         }
1169         return node;
1170 }
1171
1172 static ir_type *get_type(io_env_t *env, long typenr)
1173 {
1174         ir_type *type = (ir_type *) get_id(env, typenr);
1175         if (type == NULL)
1176                 panic("unknown type: %ld in line %d\n", typenr, env->line);
1177         else if (type->kind != k_type)
1178                 panic("type ID %ld collides with something else in line %d\n",
1179                       typenr, env->line);
1180         return type;
1181 }
1182
1183 static ir_type *read_type(io_env_t *env)
1184 {
1185         return get_type(env, read_long(env));
1186 }
1187
1188 static ir_entity *get_entity(io_env_t *env, long entnr)
1189 {
1190         ir_entity *entity = (ir_entity *) get_id(env, entnr);
1191         if (entity == NULL) {
1192                 parse_error(env, "unknown entity: %ld\n", entnr);
1193                 exit(1);
1194         } else if (entity->kind != k_entity) {
1195                 panic("Entity ID %ld collides with something else in line %d\n",
1196                       entnr, env->line);
1197         }
1198
1199         return entity;
1200 }
1201
1202 static ir_entity *read_entity(io_env_t *env)
1203 {
1204         return get_entity(env, read_long(env));
1205 }
1206
1207 static ir_mode *read_mode(io_env_t *env)
1208 {
1209         char *str = read_string(env);
1210         size_t i, n;
1211
1212         n = get_irp_n_modes();
1213         for (i = 0; i < n; i++) {
1214                 ir_mode *mode = get_irp_mode(i);
1215                 if (strcmp(str, get_mode_name(mode)) == 0) {
1216                         obstack_free(&env->obst, str);
1217                         return mode;
1218                 }
1219         }
1220
1221         parse_error(env, "unknown mode \"%s\"\n", str);
1222         exit(1);
1223 }
1224
1225 static const char *get_typetag_name(typetag_t typetag)
1226 {
1227         switch (typetag) {
1228         case tt_align:              return "align";
1229         case tt_allocation:         return "allocation";
1230         case tt_builtin:            return "builtin kind";
1231         case tt_cond_jmp_predicate: return "cond_jmp_predicate";
1232         case tt_initializer:        return "initializer kind";
1233         case tt_iro:                return "opcode";
1234         case tt_keyword:            return "keyword";
1235         case tt_linkage:            return "linkage";
1236         case tt_mode_arithmetic:    return "mode_arithmetic";
1237         case tt_pin_state:          return "pin state";
1238         case tt_segment:            return "segment";
1239         case tt_tpo:                return "type";
1240         case tt_type_state:         return "type state";
1241         case tt_volatility:         return "volatility";
1242         case tt_visibility:         return "visibility";
1243         }
1244         return "<UNKNOWN>";
1245 }
1246
1247 /**
1248  * Read and decode an enum constant.
1249  */
1250 static unsigned read_enum(io_env_t *env, typetag_t typetag)
1251 {
1252         char     *str  = read_word(env);
1253         unsigned  code = symbol(str, typetag);
1254
1255         if (code != SYMERROR) {
1256                 obstack_free(&env->obst, str);
1257                 return code;
1258         }
1259
1260         parse_error(env, "invalid %s: \"%s\"\n", get_typetag_name(typetag), str);
1261         return 0;
1262 }
1263
1264 #define read_align(env)              ((ir_align)              read_enum(env, tt_align))
1265 #define read_allocation(env)         ((ir_allocation)         read_enum(env, tt_allocation))
1266 #define read_builtin_kind(env)       ((ir_builtin_kind)       read_enum(env, tt_builtin))
1267 #define read_cond_jmp_predicate(env) ((cond_jmp_predicate)    read_enum(env, tt_cond_jmp_predicate))
1268 #define read_initializer_kind(env)   ((ir_initializer_kind_t) read_enum(env, tt_initializer))
1269 #define read_mode_arithmetic(env)    ((ir_mode_arithmetic)    read_enum(env, tt_mode_arithmetic))
1270 #define read_peculiarity(env)        ((ir_peculiarity)        read_enum(env, tt_peculiarity))
1271 #define read_pin_state(env)          ((op_pin_state)          read_enum(env, tt_pin_state))
1272 #define read_type_state(env)         ((ir_type_state)         read_enum(env, tt_type_state))
1273 #define read_variability(env)        ((ir_variability)        read_enum(env, tt_variability))
1274 #define read_volatility(env)         ((ir_volatility)         read_enum(env, tt_volatility))
1275
1276 static ir_tarval *read_tv(io_env_t *env)
1277 {
1278         ir_mode   *tvmode = read_mode(env);
1279         char      *str    = read_word(env);
1280         ir_tarval *tv     = new_tarval_from_str(str, strlen(str), tvmode);
1281         obstack_free(&env->obst, str);
1282
1283         return tv;
1284 }
1285
1286 static ir_initializer_t *read_initializer(io_env_t *env)
1287 {
1288         ir_initializer_kind_t ini_kind = read_initializer_kind(env);
1289
1290         switch (ini_kind) {
1291         case IR_INITIALIZER_CONST: {
1292                 ir_node *irn = get_node_or_dummy(env, read_long(env));
1293                 return create_initializer_const(irn);
1294         }
1295
1296         case IR_INITIALIZER_TARVAL:
1297                 return create_initializer_tarval(read_tv(env));
1298
1299         case IR_INITIALIZER_NULL:
1300                 return get_initializer_null();
1301
1302         case IR_INITIALIZER_COMPOUND: {
1303                 size_t i, n = read_size_t(env);
1304                 ir_initializer_t *ini = create_initializer_compound(n);
1305                 for (i = 0; i < n; i++) {
1306                         ir_initializer_t *curini = read_initializer(env);
1307                         set_initializer_compound_value(ini, i, curini);
1308                 }
1309                 return ini;
1310         }
1311
1312         default:
1313                 panic("Unknown initializer kind");
1314         }
1315 }
1316
1317
1318 /** Reads a type description and remembers it by its id. */
1319 static void import_type(io_env_t *env)
1320 {
1321         int            i;
1322         ir_type       *type;
1323         long           typenr = read_long(env);
1324         tp_opcode      tpop   = (tp_opcode) read_enum(env, tt_tpo);
1325         unsigned       size   = (unsigned) read_long(env);
1326         unsigned       align  = (unsigned) read_long(env);
1327         ir_type_state  state  = read_type_state(env);
1328         unsigned       flags  = (unsigned) read_long(env);
1329
1330         switch (tpop) {
1331         case tpo_array: {
1332                 int ndims = (int) read_long(env);
1333                 long elemtypenr = read_long(env);
1334                 ir_type *elemtype = get_type(env, elemtypenr);
1335
1336                 type = new_type_array(ndims, elemtype);
1337                 for (i = 0; i < ndims; i++) {
1338                         char *str = read_word(env);
1339                         if (strcmp(str, "unknown") != 0) {
1340                                 long lowerbound = atol(str);
1341                                 set_array_lower_bound_int(type, i, lowerbound);
1342                         }
1343                         obstack_free(&env->obst, str);
1344
1345                         str = read_word(env);
1346                         if (strcmp(str, "unknown") != 0) {
1347                                 long upperbound = atol(str);
1348                                 set_array_upper_bound_int(type, i, upperbound);
1349                         }
1350                         obstack_free(&env->obst, str);
1351                 }
1352                 set_type_size_bytes(type, size);
1353                 break;
1354         }
1355
1356         case tpo_class: {
1357                 ident *id = read_ident_null(env);
1358
1359                 if (typenr == (long) IR_SEGMENT_GLOBAL)
1360                         type = get_glob_type();
1361                 else
1362                         type = new_type_class(id);
1363                 set_type_size_bytes(type, size);
1364                 break;
1365         }
1366
1367         case tpo_method: {
1368                 unsigned                  callingconv = (unsigned) read_long(env);
1369                 mtp_additional_properties addprops    = (mtp_additional_properties) read_long(env);
1370                 int nparams          = (int)      read_long(env);
1371                 int nresults         = (int)      read_long(env);
1372                 int variadicity;
1373
1374                 type = new_type_method(nparams, nresults);
1375
1376                 for (i = 0; i < nparams; i++) {
1377                         long ptypenr = read_long(env);
1378                         ir_type *paramtype = get_type(env, ptypenr);
1379
1380                         set_method_param_type(type, i, paramtype);
1381                 }
1382                 for (i = 0; i < nresults; i++) {
1383                         long ptypenr = read_long(env);
1384                         ir_type *restype = get_type(env, ptypenr);
1385
1386                         set_method_res_type(type, i, restype);
1387                 }
1388
1389                 variadicity = (int) read_long(env);
1390                 set_method_variadicity(type, variadicity);
1391
1392                 set_method_calling_convention(type, callingconv);
1393                 set_method_additional_properties(type, addprops);
1394                 break;
1395         }
1396
1397         case tpo_pointer: {
1398                 ir_mode *mode     = read_mode(env);
1399                 ir_type *pointsto = get_type(env, read_long(env));
1400                 type = new_type_pointer(pointsto);
1401                 set_type_mode(type, mode);
1402                 break;
1403         }
1404
1405         case tpo_primitive: {
1406                 ir_mode *mode = read_mode(env);
1407                 type = new_type_primitive(mode);
1408                 break;
1409         }
1410
1411         case tpo_struct: {
1412                 ident *id = read_ident_null(env);
1413                 type = new_type_struct(id);
1414                 set_type_size_bytes(type, size);
1415                 break;
1416         }
1417
1418         case tpo_union: {
1419                 ident *id = read_ident_null(env);
1420                 type = new_type_union(id);
1421                 set_type_size_bytes(type, size);
1422                 break;
1423         }
1424
1425         case tpo_unknown:
1426                 return;   /* ignore unknown type */
1427
1428         default:
1429                 parse_error(env, "unknown type kind: \"%d\"\n", tpop);
1430                 skip_to(env, '\n');
1431                 return;
1432         }
1433
1434         set_type_alignment_bytes(type, align);
1435         type->flags = flags;
1436
1437         if (state == layout_fixed)
1438                 ARR_APP1(ir_type *, env->fixedtypes, type);
1439
1440         set_id(env, typenr, type);
1441 }
1442
1443 /** Reads an entity description and remembers it by its id. */
1444 static void import_entity(io_env_t *env)
1445 {
1446         long           entnr      = read_long(env);
1447         ident         *name       = read_ident(env);
1448         ident         *ld_name    = read_ident_null(env);
1449         ir_visibility  visibility = ir_visibility_default;
1450         ir_linkage     linkage    = IR_LINKAGE_DEFAULT;
1451         long           typenr;
1452         long           ownertypenr;
1453         const char    *str;
1454         ir_type       *type;
1455         ir_type       *ownertype;
1456         ir_entity     *entity;
1457
1458         skip_ws(env);
1459         while (!isdigit(env->c)) {
1460                 char     *vstr = read_word(env);
1461                 unsigned  v;
1462
1463                 skip_ws(env);
1464
1465                 v = symbol(vstr, tt_visibility);
1466                 if (v != SYMERROR) {
1467                         visibility = (ir_visibility)v;
1468                         continue;
1469                 }
1470                 v = symbol(vstr, tt_linkage);
1471                 if (v != SYMERROR) {
1472                         linkage |= (ir_linkage)v;
1473                         continue;
1474                 }
1475                 printf("Parser error, expected visibility or linkage, got '%s'\n",
1476                        vstr);
1477                 break;
1478         }
1479
1480         typenr      = read_long(env);
1481         ownertypenr = read_long(env);
1482
1483         type      = get_type(env, typenr);
1484         ownertype = !ownertypenr ? get_glob_type() : get_type(env, ownertypenr);
1485         entity    = new_entity(ownertype, name, type);
1486
1487         if (ld_name != NULL)
1488                 set_entity_ld_ident(entity, ld_name);
1489         set_entity_offset(entity, (int) read_long(env));
1490         set_entity_offset_bits_remainder(entity, (unsigned char) read_long(env));
1491         set_entity_compiler_generated(entity, (int) read_long(env));
1492         set_entity_volatility(entity, read_volatility(env));
1493         set_entity_visibility(entity, visibility);
1494         set_entity_linkage(entity, linkage);
1495
1496         str = read_word(env);
1497         if (strcmp(str, "initializer") == 0) {
1498                 set_entity_initializer(entity, read_initializer(env));
1499         } else if (strcmp(str, "compoundgraph") == 0) {
1500                 int n = (int) read_long(env);
1501                 int i;
1502                 for (i = 0; i < n; i++) {
1503                         ir_entity *member = get_entity(env, read_long(env));
1504                         ir_node   *irn    = get_node_or_dummy(env, read_long(env));
1505                         add_compound_ent_value(entity, irn, member);
1506                 }
1507         } else if (strcmp(str, "none") == 0) {
1508                 /* do nothing */
1509         } else {
1510                 parse_error(env, "expected 'initializer', 'compoundgraph' or 'none' got '%s'\n", str);
1511                 exit(1);
1512         }
1513
1514         set_id(env, entnr, entity);
1515 }
1516
1517 /** Parses the whole type graph. */
1518 static int parse_typegraph(io_env_t *env)
1519 {
1520         ir_graph *old_irg = env->irg;
1521         keyword_t kwkind;
1522
1523         EXPECT('{');
1524
1525         env->irg = get_const_code_irg();
1526
1527         /* parse all types first */
1528         while (true) {
1529                 skip_ws(env);
1530                 if (env->c == '}') {
1531                         read_c(env);
1532                         break;
1533                 }
1534
1535                 kwkind = (keyword_t) read_enum(env, tt_keyword);
1536                 switch (kwkind) {
1537                 case kw_type:
1538                         import_type(env);
1539                         break;
1540
1541                 case kw_entity:
1542                         import_entity(env);
1543                         break;
1544
1545                 default:
1546                         parse_error(env, "type graph element not supported yet: %d\n", kwkind);
1547                         skip_to(env, '\n');
1548                         break;
1549                 }
1550         }
1551         env->irg = old_irg;
1552         return 1;
1553 }
1554
1555 static int read_node_header(io_env_t *env, long *nodenr, ir_node ***preds,
1556                             const char **nodename)
1557 {
1558         int numpreds;
1559
1560         *nodename = read_word(env);
1561         *nodenr   = read_long(env);
1562
1563         ARR_RESIZE(ir_node*, *preds, 0);
1564
1565         expect_list_begin(env);
1566         for (numpreds = 0; list_has_next(env); numpreds++) {
1567                 long     val  = read_long(env);
1568                 ir_node *pred = get_node_or_dummy(env, val);
1569                 ARR_APP1(ir_node*, *preds, pred);
1570         }
1571
1572         return numpreds;
1573 }
1574
1575 static ir_node *read_ASM(io_env_t *env, int numpreds, ir_node **preds)
1576 {
1577         ir_node *newnode;
1578         ir_asm_constraint *input_constraints  = NEW_ARR_F(ir_asm_constraint, 0);
1579         ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0);
1580         ident            **clobbers           = NEW_ARR_F(ident*, 0);
1581
1582         ident *asm_text = read_ident(env);
1583
1584         expect_list_begin(env);
1585         while (list_has_next(env)) {
1586                 ir_asm_constraint constraint;
1587                 constraint.pos        = read_unsigned(env);
1588                 constraint.constraint = read_ident(env);
1589                 constraint.mode       = read_mode(env);
1590                 ARR_APP1(ir_asm_constraint, input_constraints, constraint);
1591         }
1592
1593         expect_list_begin(env);
1594         while (list_has_next(env)) {
1595                 ir_asm_constraint constraint;
1596                 constraint.pos        = read_unsigned(env);
1597                 constraint.constraint = read_ident(env);
1598                 constraint.mode       = read_mode(env);
1599                 ARR_APP1(ir_asm_constraint, output_constraints, constraint);
1600         }
1601
1602         expect_list_begin(env);
1603         while (list_has_next(env)) {
1604                 ident *clobber = read_ident(env);
1605                 ARR_APP1(ident*, clobbers, clobber);
1606         }
1607
1608         assert(ARR_LEN(input_constraints) == (size_t)numpreds-1);
1609
1610         newnode = new_r_ASM(preds[0], numpreds-1, preds+1,
1611                         input_constraints,
1612                         ARR_LEN(output_constraints),
1613                         output_constraints,
1614                         ARR_LEN(clobbers),
1615                         clobbers,
1616                         asm_text);
1617         DEL_ARR_F(clobbers);
1618         DEL_ARR_F(output_constraints);
1619         DEL_ARR_F(input_constraints);
1620         return newnode;
1621 }
1622
1623 /** Parses an IRG. */
1624 static int parse_graph(io_env_t *env, ir_graph *irg)
1625 {
1626         ir_node   **preds = NEW_ARR_F(ir_node*,0);
1627         int         i, numpreds, ret = 1;
1628         long        nodenr;
1629         const char *nodename;
1630         ir_node    *node, *newnode;
1631
1632         env->irg = irg;
1633
1634         EXPECT('{');
1635
1636         while (true) {
1637                 skip_ws(env);
1638                 if (env->c == '}') {
1639                         read_c(env);
1640                         break;
1641                 }
1642
1643                 numpreds = read_node_header(env, &nodenr, &preds, &nodename);
1644
1645                 node = get_node_or_null(env, nodenr);
1646                 newnode = NULL;
1647
1648                 EXPECT('{');
1649
1650                 switch (symbol(nodename, tt_iro)) {
1651                 case iro_End: {
1652                         ir_node *newendblock = preds[0];
1653                         newnode = get_irg_end(irg);
1654                         exchange(get_nodes_block(newnode), newendblock);
1655                         for (i = 1; i < numpreds; i++)
1656                                 add_irn_n(newnode, preds[i]);
1657                         break;
1658                 }
1659
1660                 case iro_Start: {
1661                         ir_node *newstartblock = preds[0];
1662                         newnode = get_irg_start(irg);
1663                         exchange(get_nodes_block(newnode), newstartblock);
1664                         break;
1665                 }
1666
1667                 case iro_Block:
1668                         newnode = new_r_Block(irg, numpreds, preds);
1669                         break;
1670
1671                 case iro_Anchor:
1672                         newnode = irg->anchor;
1673                         for (i = 1; i < numpreds; i++)
1674                                 set_irn_n(newnode, i-1, preds[i]);
1675                         set_nodes_block(newnode, preds[0]);
1676                         break;
1677
1678                 case iro_SymConst: {
1679                         long entnr = read_long(env);
1680                         union symconst_symbol sym;
1681                         sym.entity_p = get_entity(env, entnr);
1682                         ir_mode *mode = read_mode(env);
1683                         newnode = new_r_SymConst(irg, mode, sym, symconst_addr_ent);
1684                         break;
1685                 }
1686
1687                 case iro_Proj: {
1688                         ir_mode *mode = read_mode(env);
1689                         long     pn   = read_long(env);
1690                         newnode = new_r_Proj(preds[1], mode, pn);
1691                         /* explicitely set block, since preds[1] might be a dummy node
1692                          * which is always in the startblock */
1693                         set_nodes_block(newnode, preds[0]);
1694                         break;
1695                 }
1696
1697                 case iro_ASM:
1698                         newnode = read_ASM(env, numpreds, preds);
1699                         break;
1700
1701                 #include "gen_irio_import.inl"
1702
1703                 default:
1704                         goto notsupported;
1705                 }
1706
1707                 EXPECT('}');
1708
1709                 if (!newnode) {
1710 notsupported:
1711                         parse_error(env, "node type not supported yet: %s\n", nodename);
1712                         abort();
1713                 }
1714
1715                 if (node)
1716                         exchange(node, newnode);
1717                 /* Always update hash entry to avoid more uses of id nodes */
1718                 set_id(env, nodenr, newnode);
1719         }
1720
1721         DEL_ARR_F(preds);
1722
1723         return ret;
1724 }
1725
1726 static int parse_modes(io_env_t *env)
1727 {
1728         EXPECT('{');
1729
1730         while (true) {
1731                 keyword_t kwkind;
1732
1733                 skip_ws(env);
1734                 if (env->c == '}') {
1735                         read_c(env);
1736                         break;
1737                 }
1738
1739                 kwkind = (keyword_t) read_enum(env, tt_keyword);
1740                 switch (kwkind) {
1741                 case kw_int_mode: {
1742                         const char *name = read_string(env);
1743                         ir_mode_arithmetic arith = read_mode_arithmetic(env);
1744                         int size = read_long(env);
1745                         int sign = read_long(env);
1746                         unsigned modulo_shift = read_long(env);
1747                         new_int_mode(name, arith, size, sign, modulo_shift);
1748                         break;
1749                 }
1750                 case kw_reference_mode: {
1751                         const char *name = read_string(env);
1752                         ir_mode_arithmetic arith = read_mode_arithmetic(env);
1753                         int size = read_long(env);
1754                         unsigned modulo_shift = read_long(env);
1755                         ir_mode *mode = new_reference_mode(name, arith, size, modulo_shift);
1756                         set_reference_mode_signed_eq(mode, read_mode(env));
1757                         set_reference_mode_unsigned_eq(mode, read_mode(env));
1758                         int is_mode_P = read_int(env);
1759                         if (is_mode_P) {
1760                                 set_modeP_data(mode);
1761                                 set_modeP_code(mode);
1762                         }
1763                         break;
1764                 }
1765                 case kw_float_mode: {
1766                         const char *name = read_string(env);
1767                         ir_mode_arithmetic arith = read_mode_arithmetic(env);
1768                         int exponent_size = read_long(env);
1769                         int mantissa_size = read_long(env);
1770                         new_float_mode(name, arith, exponent_size, mantissa_size);
1771                         break;
1772                 }
1773
1774                 default:
1775                         skip_to(env, '\n');
1776                         break;
1777                 }
1778         }
1779         return 1;
1780 }
1781
1782 static int parse_program(io_env_t *env)
1783 {
1784         EXPECT('{');
1785
1786         while (true) {
1787                 keyword_t kwkind;
1788
1789                 skip_ws(env);
1790                 if (env->c == '}') {
1791                         read_c(env);
1792                         break;
1793                 }
1794
1795                 kwkind = (keyword_t) read_enum(env, tt_keyword);
1796                 switch (kwkind) {
1797                 case kw_segment_type: {
1798                         ir_segment_t  segment = (ir_segment_t) read_enum(env, tt_segment);
1799                         ir_type      *type    = read_type(env);
1800                         set_segment_type(segment, type);
1801                         break;
1802                 }
1803                 default:
1804                         parse_error(env, "unexpected keyword %d\n", kwkind);
1805                         skip_to(env, '\n');
1806                 }
1807         }
1808         return 1;
1809 }
1810
1811 void ir_import(const char *filename)
1812 {
1813         FILE *file = fopen(filename, "rt");
1814         if (file == NULL) {
1815                 perror(filename);
1816                 exit(1);
1817         }
1818
1819         ir_import_file(file, filename);
1820
1821         fclose(file);
1822 }
1823
1824 void ir_import_file(FILE *input, const char *inputname)
1825 {
1826         int oldoptimize = get_optimize();
1827         firm_verification_t oldver = get_node_verification_mode();
1828         io_env_t ioenv;
1829         io_env_t *env = &ioenv;
1830         size_t i, n;
1831
1832         symtbl_init();
1833
1834         memset(env, 0, sizeof(*env));
1835         obstack_init(&env->obst);
1836         env->idset      = new_set(id_cmp, 128);
1837         env->fixedtypes = NEW_ARR_F(ir_type *, 0);
1838         env->inputname  = inputname;
1839         env->file       = input;
1840         env->line       = 1;
1841
1842         /* read first character */
1843         read_c(env);
1844
1845         set_optimize(0);
1846         do_node_verification(FIRM_VERIFICATION_OFF);
1847
1848         while (true) {
1849                 keyword_t kw;
1850
1851                 skip_ws(env);
1852                 if (env->c == EOF)
1853                         break;
1854
1855                 kw = (keyword_t)read_enum(env, tt_keyword);
1856                 switch (kw) {
1857                 case kw_modes:
1858                         if (!parse_modes(env)) goto end;
1859                         break;
1860
1861                 case kw_typegraph:
1862                         if (!parse_typegraph(env)) goto end;
1863                         break;
1864
1865                 case kw_irg:
1866                 {
1867                         ir_entity *irgent = get_entity(env, read_long(env));
1868                         ir_graph *irg = new_ir_graph(irgent, 0);
1869                         set_irg_frame_type(irg, get_type(env, read_long(env)));
1870                         if (!parse_graph(env, irg)) goto end;
1871                         break;
1872                 }
1873
1874                 case kw_constirg: {
1875                         ir_graph *constirg = get_const_code_irg();
1876                         long bodyblockid = read_long(env);
1877                         set_id(env, bodyblockid, constirg->current_block);
1878                         if (!parse_graph(env, constirg)) goto end;
1879                         break;
1880                 }
1881
1882                 case kw_program:
1883                         parse_program(env);
1884                         break;
1885
1886                 default: {
1887                         parse_error(env, "Unexpected keyword %d at toplevel\n", kw);
1888                         exit(1);
1889                 }
1890                 }
1891         }
1892
1893 end:
1894         n = ARR_LEN(env->fixedtypes);
1895         for (i = 0; i < n; i++)
1896                 set_type_state(env->fixedtypes[i], layout_fixed);
1897
1898         DEL_ARR_F(env->fixedtypes);
1899
1900         del_set(env->idset);
1901
1902         irp_finalize_cons();
1903
1904         do_node_verification(oldver);
1905         set_optimize(oldoptimize);
1906
1907         obstack_free(&env->obst, NULL);
1908 }