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