654e9216ee451feb16a8ccb64cc767ed3e165612
[libfirm] / ir / ir / irio.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   Write textual representation of firm to file.
9  * @author  Moritz Kroll, Matthias Braun
10  */
11 #include "config.h"
12
13 #include <string.h>
14 #include <ctype.h>
15 #include <stdbool.h>
16 #include <stdarg.h>
17
18 #include "irio.h"
19
20 #include "irnode_t.h"
21 #include "irprog.h"
22 #include "irgraph_t.h"
23 #include "irprintf.h"
24 #include "ircons_t.h"
25 #include "irgmod.h"
26 #include "irflag_t.h"
27 #include "irgwalk.h"
28 #include "tv.h"
29 #include "array.h"
30 #include "error.h"
31 #include "typerep.h"
32 #include "set.h"
33 #include "obst.h"
34 #include "pmap.h"
35 #include "pdeq.h"
36
37 #define SYMERROR ((unsigned) ~0)
38
39 static void register_generated_node_readers(void);
40 static void register_generated_node_writers(void);
41
42 typedef struct delayed_initializer_t {
43         ir_initializer_t *initializer;
44         long              node_nr;
45 } delayed_initializer_t;
46
47 typedef struct delayed_pred_t {
48         ir_node *node;
49         int      n_preds;
50         long     preds[];
51 } delayed_pred_t;
52
53 typedef struct read_env_t {
54         int            c;           /**< currently read char */
55         FILE          *file;
56         const char    *inputname;
57         unsigned       line;
58
59         ir_graph      *irg;
60         set           *idset;       /**< id_entry set, which maps from file ids to
61                                          new Firm elements */
62         ir_type      **fixedtypes;
63         bool           read_errors;
64         struct obstack obst;
65         struct obstack preds_obst;
66         delayed_initializer_t *delayed_initializers;
67         const delayed_pred_t **delayed_preds;
68 } read_env_t;
69
70 typedef struct write_env_t {
71         FILE *file;
72         pdeq *write_queue;
73 } write_env_t;
74
75 typedef enum typetag_t {
76         tt_align,
77         tt_builtin_kind,
78         tt_cond_jmp_predicate,
79         tt_initializer,
80         tt_keyword,
81         tt_linkage,
82         tt_mode_arithmetic,
83         tt_pin_state,
84         tt_segment,
85         tt_throws,
86         tt_tpo,
87         tt_type_state,
88         tt_visibility,
89         tt_volatility,
90         tt_where_alloc,
91 } typetag_t;
92
93 typedef enum keyword_t {
94         kw_asm,
95         kw_compound_member,
96         kw_constirg,
97         kw_entity,
98         kw_float_mode,
99         kw_int_mode,
100         kw_irg,
101         kw_label,
102         kw_method,
103         kw_modes,
104         kw_parameter,
105         kw_program,
106         kw_reference_mode,
107         kw_segment_type,
108         kw_type,
109         kw_typegraph,
110         kw_unknown,
111 } keyword_t;
112
113 typedef struct symbol_t {
114         const char *str;      /**< The name of this symbol. */
115         typetag_t   typetag;  /**< The type tag of this symbol. */
116         unsigned    code;     /**< The value of this symbol. */
117 } symbol_t;
118
119 typedef struct id_entry {
120         long id;
121         void *elem;
122 } id_entry;
123
124 /** The symbol table, a set of symbol_t elements. */
125 static set *symtbl;
126
127 /**
128  * Compare two symbol table entries.
129  */
130 static int symbol_cmp(const void *elt, const void *key, size_t size)
131 {
132         int res;
133         const symbol_t *entry = (const symbol_t *) elt;
134         const symbol_t *keyentry = (const symbol_t *) key;
135         (void) size;
136         res = entry->typetag - keyentry->typetag;
137         if (res) return res;
138         return strcmp(entry->str, keyentry->str);
139 }
140
141 static int id_cmp(const void *elt, const void *key, size_t size)
142 {
143         const id_entry *entry = (const id_entry *) elt;
144         const id_entry *keyentry = (const id_entry *) key;
145         (void) size;
146         return entry->id - keyentry->id;
147 }
148
149 static void __attribute__((format(printf, 2, 3)))
150 parse_error(read_env_t *env, const char *fmt, ...)
151 {
152         va_list  ap;
153         unsigned line = env->line;
154
155         /* workaround read_c "feature" that a '\n' triggers the line++
156          * instead of the character after the '\n' */
157         if (env->c == '\n') {
158                 line--;
159         }
160
161         fprintf(stderr, "%s:%u: error ", env->inputname, line);
162         env->read_errors = true;
163
164         /* let's hope firm doesn't die on further errors */
165         do_node_verification(FIRM_VERIFICATION_OFF);
166
167         va_start(ap, fmt);
168         vfprintf(stderr, fmt, ap);
169         va_end(ap);
170 }
171
172 /** Initializes the symbol table. May be called more than once without problems. */
173 static void symtbl_init(void)
174 {
175         symbol_t key;
176
177         /* Only initialize once */
178         if (symtbl != NULL)
179                 return;
180
181         symtbl = new_set(symbol_cmp, 256);
182
183 #define INSERT(tt, s, cod)                                       \
184         key.str = (s);                                               \
185         key.typetag = (tt);                                          \
186         key.code = (cod);                                            \
187         (void)set_insert(symbol_t, symtbl, &key, sizeof(key), hash_str(s) + tt * 17)
188
189 #define INSERTENUM(tt, e) INSERT(tt, #e, e)
190 #define INSERTKEYWORD(k) INSERT(tt_keyword, #k, kw_##k)
191
192         INSERT(tt_tpo, "array", tpo_array);
193         INSERT(tt_tpo, "class", tpo_class);
194         INSERT(tt_tpo, "method", tpo_method);
195         INSERT(tt_tpo, "pointer", tpo_pointer);
196         INSERT(tt_tpo, "primitive", tpo_primitive);
197         INSERT(tt_tpo, "struct", tpo_struct);
198         INSERT(tt_tpo, "union", tpo_union);
199         INSERT(tt_tpo, "Unknown", tpo_unknown);
200
201         INSERT(tt_segment, "global", IR_SEGMENT_GLOBAL);
202         INSERT(tt_segment, "thread_local", IR_SEGMENT_THREAD_LOCAL);
203         INSERT(tt_segment, "constructors", IR_SEGMENT_CONSTRUCTORS);
204         INSERT(tt_segment, "destructors", IR_SEGMENT_DESTRUCTORS);
205
206         INSERT(tt_linkage, "constant", IR_LINKAGE_CONSTANT);
207         INSERT(tt_linkage, "weak", IR_LINKAGE_WEAK);
208         INSERT(tt_linkage, "garbage_collect", IR_LINKAGE_GARBAGE_COLLECT);
209         INSERT(tt_linkage, "merge", IR_LINKAGE_MERGE);
210         INSERT(tt_linkage, "hidden_user", IR_LINKAGE_HIDDEN_USER);
211
212         INSERT(tt_visibility, "local", ir_visibility_local);
213         INSERT(tt_visibility, "external", ir_visibility_external);
214         INSERT(tt_visibility, "private", ir_visibility_private);
215
216         INSERT(tt_throws, "throw",   true);
217         INSERT(tt_throws, "nothrow", false);
218
219         INSERTKEYWORD(asm);
220         INSERTKEYWORD(compound_member);
221         INSERTKEYWORD(constirg);
222         INSERTKEYWORD(entity);
223         INSERTKEYWORD(float_mode);
224         INSERTKEYWORD(int_mode);
225         INSERTKEYWORD(irg);
226         INSERTKEYWORD(label);
227         INSERTKEYWORD(method);
228         INSERTKEYWORD(modes);
229         INSERTKEYWORD(parameter);
230         INSERTKEYWORD(program);
231         INSERTKEYWORD(reference_mode);
232         INSERTKEYWORD(segment_type);
233         INSERTKEYWORD(type);
234         INSERTKEYWORD(typegraph);
235         INSERTKEYWORD(unknown);
236
237         INSERTENUM(tt_align, align_non_aligned);
238         INSERTENUM(tt_align, align_is_aligned);
239
240         INSERTENUM(tt_builtin_kind, ir_bk_trap);
241         INSERTENUM(tt_builtin_kind, ir_bk_debugbreak);
242         INSERTENUM(tt_builtin_kind, ir_bk_return_address);
243         INSERTENUM(tt_builtin_kind, ir_bk_frame_address);
244         INSERTENUM(tt_builtin_kind, ir_bk_prefetch);
245         INSERTENUM(tt_builtin_kind, ir_bk_ffs);
246         INSERTENUM(tt_builtin_kind, ir_bk_clz);
247         INSERTENUM(tt_builtin_kind, ir_bk_ctz);
248         INSERTENUM(tt_builtin_kind, ir_bk_popcount);
249         INSERTENUM(tt_builtin_kind, ir_bk_parity);
250         INSERTENUM(tt_builtin_kind, ir_bk_bswap);
251         INSERTENUM(tt_builtin_kind, ir_bk_inport);
252         INSERTENUM(tt_builtin_kind, ir_bk_outport);
253         INSERTENUM(tt_builtin_kind, ir_bk_inner_trampoline);
254
255         INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_NONE);
256         INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_TRUE);
257         INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_FALSE);
258
259         INSERTENUM(tt_initializer, IR_INITIALIZER_CONST);
260         INSERTENUM(tt_initializer, IR_INITIALIZER_TARVAL);
261         INSERTENUM(tt_initializer, IR_INITIALIZER_NULL);
262         INSERTENUM(tt_initializer, IR_INITIALIZER_COMPOUND);
263
264         INSERT(tt_mode_arithmetic, "none",               irma_none);
265         INSERT(tt_mode_arithmetic, "twos_complement",    irma_twos_complement);
266         INSERT(tt_mode_arithmetic, "ieee754",            irma_ieee754);
267         INSERT(tt_mode_arithmetic, "x86_extended_float", irma_x86_extended_float);
268
269         INSERTENUM(tt_pin_state, op_pin_state_floats);
270         INSERTENUM(tt_pin_state, op_pin_state_pinned);
271         INSERTENUM(tt_pin_state, op_pin_state_exc_pinned);
272         INSERTENUM(tt_pin_state, op_pin_state_mem_pinned);
273
274         INSERTENUM(tt_type_state, layout_undefined);
275         INSERTENUM(tt_type_state, layout_fixed);
276
277         INSERTENUM(tt_volatility, volatility_non_volatile);
278         INSERTENUM(tt_volatility, volatility_is_volatile);
279
280         INSERTENUM(tt_where_alloc, stack_alloc);
281         INSERTENUM(tt_where_alloc, heap_alloc);
282
283 #undef INSERTKEYWORD
284 #undef INSERTENUM
285 #undef INSERT
286 }
287
288 static const char *get_segment_name(ir_segment_t segment)
289 {
290         switch (segment) {
291         case IR_SEGMENT_GLOBAL:       return "global";
292         case IR_SEGMENT_THREAD_LOCAL: return "thread_local";
293         case IR_SEGMENT_CONSTRUCTORS: return "constructors";
294         case IR_SEGMENT_DESTRUCTORS:  return "destructors";
295         }
296         panic("INVALID_SEGMENT");
297 }
298
299 static const char *get_visibility_name(ir_visibility visibility)
300 {
301         switch (visibility) {
302         case ir_visibility_local:    return "local";
303         case ir_visibility_external: return "external";
304         case ir_visibility_private:  return "private";
305         }
306         panic("INVALID_VISIBILITY");
307 }
308
309 static const char *get_mode_arithmetic_name(ir_mode_arithmetic arithmetic)
310 {
311         switch (arithmetic) {
312         case irma_none:               return "none";
313         case irma_twos_complement:    return "twos_complement";
314         case irma_ieee754:            return "ieee754";
315         case irma_x86_extended_float: return "x86_extended_float";
316         }
317         panic("invalid mode_arithmetic");
318 }
319
320 /** Returns the according symbol value for the given string and tag, or SYMERROR if none was found. */
321 static unsigned symbol(const char *str, typetag_t typetag)
322 {
323         symbol_t key, *entry;
324
325         key.str = str;
326         key.typetag = typetag;
327
328         entry = set_find(symbol_t, symtbl, &key, sizeof(key), hash_str(str) + typetag * 17);
329         return entry ? entry->code : SYMERROR;
330 }
331
332 static void write_long(write_env_t *env, long value)
333 {
334         fprintf(env->file, "%ld ", value);
335 }
336
337 static void write_int(write_env_t *env, int value)
338 {
339         fprintf(env->file, "%d ", value);
340 }
341
342 static void write_unsigned(write_env_t *env, unsigned value)
343 {
344         fprintf(env->file, "%u ", value);
345 }
346
347 static void write_size_t(write_env_t *env, size_t value)
348 {
349         ir_fprintf(env->file, "%zu ", value);
350 }
351
352 static void write_symbol(write_env_t *env, const char *symbol)
353 {
354         fputs(symbol, env->file);
355         fputc(' ', env->file);
356 }
357
358 static void write_entity_ref(write_env_t *env, ir_entity *entity)
359 {
360         write_long(env, get_entity_nr(entity));
361 }
362
363 static void write_type_ref(write_env_t *env, ir_type *type)
364 {
365         switch (get_type_tpop_code(type)) {
366         case tpo_unknown:
367                 write_symbol(env, "unknown");
368                 return;
369         case tpo_none:
370                 write_symbol(env, "none");
371                 return;
372         case tpo_code:
373                 write_symbol(env, "code");
374                 return;
375         default:
376                 break;
377         }
378         write_long(env, get_type_nr(type));
379 }
380
381 static void write_string(write_env_t *env, const char *string)
382 {
383         const char *c;
384         fputc('"', env->file);
385         for (c = string; *c != '\0'; ++c) {
386                 switch (*c) {
387                 case '\n':
388                         fputc('\\', env->file);
389                         fputc('n', env->file);
390                         break;
391                 case '"':
392                 case '\\':
393                         fputc('\\', env->file);
394                         /* FALLTHROUGH */
395                 default:
396                         fputc(*c, env->file);
397                         break;
398                 }
399         }
400         fputc('"', env->file);
401         fputc(' ', env->file);
402 }
403
404 static void write_ident(write_env_t *env, ident *id)
405 {
406         write_string(env, get_id_str(id));
407 }
408
409 static void write_ident_null(write_env_t *env, ident *id)
410 {
411         if (id == NULL) {
412                 fputs("NULL ", env->file);
413         } else {
414                 write_ident(env, id);
415         }
416 }
417
418 static void write_mode_ref(write_env_t *env, ir_mode *mode)
419 {
420         write_string(env, get_mode_name(mode));
421 }
422
423 static void write_tarval(write_env_t *env, ir_tarval *tv)
424 {
425         write_mode_ref(env, get_tarval_mode(tv));
426         if (tv == tarval_bad) {
427                 write_symbol(env, "bad");
428         } else {
429                 char buf[1024];
430                 tarval_snprintf(buf, sizeof(buf), tv);
431                 fputs(buf, env->file);
432                 fputc(' ', env->file);
433         }
434 }
435
436 static void write_align(write_env_t *env, ir_align align)
437 {
438         fputs(get_align_name(align), env->file);
439         fputc(' ', env->file);
440 }
441
442 static void write_builtin_kind(write_env_t *env, const ir_node *node)
443 {
444         fputs(get_builtin_kind_name(get_Builtin_kind(node)), env->file);
445         fputc(' ', env->file);
446 }
447
448 static void write_cond_jmp_predicate(write_env_t *env, const ir_node *node)
449 {
450         fputs(get_cond_jmp_predicate_name(get_Cond_jmp_pred(node)), env->file);
451         fputc(' ', env->file);
452 }
453
454 static void write_relation(write_env_t *env, ir_relation relation)
455 {
456         write_long(env, (long)relation);
457 }
458
459 static void write_where_alloc(write_env_t *env, ir_where_alloc where_alloc)
460 {
461         switch (where_alloc) {
462         case stack_alloc: write_symbol(env, "stack_alloc"); return;
463         case heap_alloc:  write_symbol(env, "heap_alloc");  return;
464         }
465         panic("invalid where_alloc value");
466 }
467
468 static void write_throws(write_env_t *env, bool throws)
469 {
470         write_symbol(env, throws ? "throw" : "nothrow");
471 }
472
473 static void write_list_begin(write_env_t *env)
474 {
475         fputs("[", env->file);
476 }
477
478 static void write_list_end(write_env_t *env)
479 {
480         fputs("] ", env->file);
481 }
482
483 static void write_scope_begin(write_env_t *env)
484 {
485         fputs("{\n", env->file);
486 }
487
488 static void write_scope_end(write_env_t *env)
489 {
490         fputs("}\n\n", env->file);
491 }
492
493 static void write_node_ref(write_env_t *env, const ir_node *node)
494 {
495         write_long(env, get_irn_node_nr(node));
496 }
497
498 static void write_initializer(write_env_t *env, ir_initializer_t *ini)
499 {
500         FILE *f = env->file;
501         ir_initializer_kind_t ini_kind = get_initializer_kind(ini);
502
503         fputs(get_initializer_kind_name(ini_kind), f);
504         fputc(' ', f);
505
506         switch (ini_kind) {
507         case IR_INITIALIZER_CONST:
508                 write_node_ref(env, get_initializer_const_value(ini));
509                 return;
510
511         case IR_INITIALIZER_TARVAL:
512                 write_tarval(env, get_initializer_tarval_value(ini));
513                 return;
514
515         case IR_INITIALIZER_NULL:
516                 return;
517
518         case IR_INITIALIZER_COMPOUND: {
519                 size_t i, n = get_initializer_compound_n_entries(ini);
520                 write_size_t(env, n);
521                 for (i = 0; i < n; ++i)
522                         write_initializer(env, get_initializer_compound_value(ini, i));
523                 return;
524         }
525         }
526         panic("Unknown initializer kind");
527 }
528
529 static void write_pin_state(write_env_t *env, op_pin_state state)
530 {
531         fputs(get_op_pin_state_name(state), env->file);
532         fputc(' ', env->file);
533 }
534
535 static void write_volatility(write_env_t *env, ir_volatility vol)
536 {
537         fputs(get_volatility_name(vol), env->file);
538         fputc(' ', env->file);
539 }
540
541 static void write_type_state(write_env_t *env, ir_type_state state)
542 {
543         fputs(get_type_state_name(state), env->file);
544         fputc(' ', env->file);
545 }
546
547 static void write_visibility(write_env_t *env, ir_visibility visibility)
548 {
549         fputs(get_visibility_name(visibility), env->file);
550         fputc(' ', env->file);
551 }
552
553 static void write_mode_arithmetic(write_env_t *env, ir_mode_arithmetic arithmetic)
554 {
555         fputs(get_mode_arithmetic_name(arithmetic), env->file);
556         fputc(' ', env->file);
557 }
558
559 static void write_type(write_env_t *env, ir_type *tp);
560 static void write_entity(write_env_t *env, ir_entity *entity);
561
562 static void write_type_common(write_env_t *env, ir_type *tp)
563 {
564         fputc('\t', env->file);
565         write_symbol(env, "type");
566         write_long(env, get_type_nr(tp));
567         write_symbol(env, get_type_tpop_name(tp));
568         write_unsigned(env, get_type_size_bytes(tp));
569         write_unsigned(env, get_type_alignment_bytes(tp));
570         write_type_state(env, get_type_state(tp));
571         write_unsigned(env, tp->flags);
572 }
573
574 static void write_type_primitive(write_env_t *env, ir_type *tp)
575 {
576         ir_type *base_type = get_primitive_base_type(tp);
577
578         if (base_type != NULL)
579                 write_type(env, base_type);
580
581         write_type_common(env, tp);
582         write_mode_ref(env, get_type_mode(tp));
583         if (base_type == NULL)
584                 base_type = get_none_type();
585         write_type_ref(env, base_type);
586         fputc('\n', env->file);
587 }
588
589 static void write_type_compound(write_env_t *env, ir_type *tp)
590 {
591         size_t n_members = get_compound_n_members(tp);
592         size_t i;
593
594         if (is_Class_type(tp)) {
595                 if (get_class_n_subtypes(tp) > 0 || get_class_n_supertypes(tp) > 0 || get_class_vtable_size(tp) > 0) {
596                         /* sub/superclass export not implemented yet, it's unclear whether
597                          * class types will stay in libfirm anyway */
598                         panic("can't export class types yet");
599                 }
600         }
601         write_type_common(env, tp);
602         write_ident_null(env, get_compound_ident(tp));
603         fputc('\n', env->file);
604
605         for (i = 0; i < n_members; ++i) {
606                 ir_entity *member = get_compound_member(tp, i);
607                 write_entity(env, member);
608         }
609 }
610
611 static void write_type_array(write_env_t *env, ir_type *tp)
612 {
613         size_t     n_dimensions   = get_array_n_dimensions(tp);
614         ir_type   *element_type   = get_array_element_type(tp);
615         ir_entity *element_entity = get_array_element_entity(tp);
616         size_t   i;
617
618         write_type(env, element_type);
619
620         write_type_common(env, tp);
621         write_size_t(env, n_dimensions);
622         write_type_ref(env, get_array_element_type(tp));
623         for (i = 0; i < n_dimensions; i++) {
624                 ir_node *lower = get_array_lower_bound(tp, i);
625                 ir_node *upper = get_array_upper_bound(tp, i);
626
627                 if (is_Const(lower))
628                         write_long(env, get_tarval_long(get_Const_tarval(lower)));
629                 else
630                         panic("Lower array bound is not constant");
631
632                 if (is_Const(upper))
633                         write_long(env, get_tarval_long(get_Const_tarval(upper)));
634                 else if (is_Unknown(upper))
635                         write_symbol(env, "unknown");
636                 else
637                         panic("Upper array bound is not constant");
638         }
639         /* note that we just write a reference to the element entity
640          * but never the entity itself */
641         write_entity_ref(env, element_entity);
642         fputc('\n', env->file);
643 }
644
645 static void write_type_method(write_env_t *env, ir_type *tp)
646 {
647         size_t nparams  = get_method_n_params(tp);
648         size_t nresults = get_method_n_ress(tp);
649         size_t i;
650
651         for (i = 0; i < nparams; i++)
652                 write_type(env, get_method_param_type(tp, i));
653         for (i = 0; i < nresults; i++)
654                 write_type(env, get_method_res_type(tp, i));
655
656         write_type_common(env, tp);
657         write_unsigned(env, get_method_calling_convention(tp));
658         write_unsigned(env, get_method_additional_properties(tp));
659         write_size_t(env, nparams);
660         write_size_t(env, nresults);
661         for (i = 0; i < nparams; i++)
662                 write_type_ref(env, get_method_param_type(tp, i));
663         for (i = 0; i < nresults; i++)
664                 write_type_ref(env, get_method_res_type(tp, i));
665         write_unsigned(env, get_method_variadicity(tp));
666         fputc('\n', env->file);
667 }
668
669 static void write_type_pointer(write_env_t *env, ir_type *tp)
670 {
671         ir_type *points_to = get_pointer_points_to_type(tp);
672
673         write_type(env, points_to);
674
675         write_type_common(env, tp);
676         write_mode_ref(env, get_type_mode(tp));
677         write_type_ref(env, points_to);
678         fputc('\n', env->file);
679 }
680
681 static void write_type_enumeration(write_env_t *env, ir_type *tp)
682 {
683         write_type_common(env, tp);
684         write_ident_null(env, get_enumeration_ident(tp));
685         fputc('\n', env->file);
686 }
687
688 static void write_type(write_env_t *env, ir_type *tp)
689 {
690         if (type_visited(tp))
691                 return;
692         mark_type_visited(tp);
693
694         switch ((tp_opcode)get_type_tpop_code(tp)) {
695         case tpo_none:
696         case tpo_unknown:
697         case tpo_code:
698         case tpo_uninitialized:
699                 /* no need to write special builtin types */
700                 return;
701
702         case tpo_union:
703         case tpo_struct:
704         case tpo_class:
705                 write_type_compound(env, tp);
706                 return;
707
708         case tpo_primitive:    write_type_primitive(env, tp);   return;
709         case tpo_enumeration:  write_type_enumeration(env, tp); return;
710         case tpo_method:       write_type_method(env, tp);      return;
711         case tpo_pointer:      write_type_pointer(env, tp);     return;
712         case tpo_array:        write_type_array(env, tp);       return;
713         }
714         panic("can't write invalid type %+F\n", tp);
715 }
716
717 static void write_entity(write_env_t *env, ir_entity *ent)
718 {
719         ir_type       *type       = get_entity_type(ent);
720         ir_type       *owner      = get_entity_owner(ent);
721         ir_visibility  visibility = get_entity_visibility(ent);
722         ir_linkage     linkage    = get_entity_linkage(ent);
723
724         if (entity_visited(ent))
725                 return;
726         mark_entity_visited(ent);
727
728         write_type(env, type);
729         write_type(env, owner);
730
731         fputc('\t', env->file);
732         switch ((ir_entity_kind)ent->entity_kind) {
733         case IR_ENTITY_NORMAL:          write_symbol(env, "entity");          break;
734         case IR_ENTITY_METHOD:          write_symbol(env, "method");          break;
735         case IR_ENTITY_LABEL:           write_symbol(env, "label");           break;
736         case IR_ENTITY_COMPOUND_MEMBER: write_symbol(env, "compound_member"); break;
737         case IR_ENTITY_PARAMETER:       write_symbol(env, "parameter");       break;
738         case IR_ENTITY_UNKNOWN:
739                 write_symbol(env, "unknown");
740                 write_long(env, get_entity_nr(ent));
741                 return;
742         }
743         write_long(env, get_entity_nr(ent));
744
745         if (ent->entity_kind != IR_ENTITY_LABEL
746             && ent->entity_kind != IR_ENTITY_PARAMETER) {
747                 write_ident_null(env, get_entity_ident(ent));
748                 if (!entity_has_ld_ident(ent)) {
749                         write_ident_null(env, NULL);
750                 } else {
751                         write_ident_null(env, get_entity_ld_ident(ent));
752                 }
753         }
754
755         write_visibility(env, visibility);
756         write_list_begin(env);
757         if (linkage & IR_LINKAGE_CONSTANT)
758                 write_symbol(env, "constant");
759         if (linkage & IR_LINKAGE_WEAK)
760                 write_symbol(env, "weak");
761         if (linkage & IR_LINKAGE_GARBAGE_COLLECT)
762                 write_symbol(env, "garbage_collect");
763         if (linkage & IR_LINKAGE_MERGE)
764                 write_symbol(env, "merge");
765         if (linkage & IR_LINKAGE_HIDDEN_USER)
766                 write_symbol(env, "hidden_user");
767         write_list_end(env);
768
769         write_type_ref(env, type);
770         if (ent->entity_kind != IR_ENTITY_LABEL)
771                 write_type_ref(env, owner);
772         write_long(env, is_entity_compiler_generated(ent));
773         write_volatility(env, get_entity_volatility(ent));
774
775         switch ((ir_entity_kind)ent->entity_kind) {
776         case IR_ENTITY_NORMAL:
777                 if (ent->initializer != NULL) {
778                         write_symbol(env, "initializer");
779                         write_initializer(env, get_entity_initializer(ent));
780                 } else {
781                         write_symbol(env, "none");
782                 }
783                 break;
784         case IR_ENTITY_COMPOUND_MEMBER:
785                 write_long(env, get_entity_offset(ent));
786                 write_unsigned(env, get_entity_offset_bits_remainder(ent));
787                 break;
788         case IR_ENTITY_PARAMETER: {
789                 size_t num = get_entity_parameter_number(ent);
790                 if (num == IR_VA_START_PARAMETER_NUMBER) {
791                         write_symbol(env, "va_start");
792                 } else {
793                         write_size_t(env, num);
794                 }
795                 break;
796         }
797         case IR_ENTITY_UNKNOWN:
798         case IR_ENTITY_LABEL:
799         case IR_ENTITY_METHOD:
800                 break;
801         }
802
803         fputc('\n', env->file);
804 }
805
806 static void write_switch_table(write_env_t *env, const ir_switch_table *table)
807 {
808         size_t n_entries = ir_switch_table_get_n_entries(table);
809         size_t i;
810
811         write_size_t(env, n_entries);
812         for (i = 0; i < n_entries; ++i) {
813                 long       pn  = ir_switch_table_get_pn(table, i);
814                 ir_tarval *min = ir_switch_table_get_min(table, i);
815                 ir_tarval *max = ir_switch_table_get_max(table, i);
816                 write_long(env, pn);
817                 write_tarval(env, min);
818                 write_tarval(env, max);
819         }
820 }
821
822 static void write_pred_refs(write_env_t *env, const ir_node *node, int from)
823 {
824         int arity = get_irn_arity(node);
825         int i;
826         write_list_begin(env);
827         assert(from <= arity);
828         for (i = from; i < arity; ++i) {
829                 ir_node *pred = get_irn_n(node, i);
830                 write_node_ref(env, pred);
831         }
832         write_list_end(env);
833 }
834
835 static void write_node_nr(write_env_t *env, const ir_node *node)
836 {
837         write_long(env, get_irn_node_nr(node));
838 }
839
840 static void write_ASM(write_env_t *env, const ir_node *node)
841 {
842         write_symbol(env, "ASM");
843         write_node_nr(env, node);
844         write_node_nr(env, get_nodes_block(node));
845         write_node_nr(env, get_ASM_mem(node));
846
847         write_ident(env, get_ASM_text(node));
848         write_list_begin(env);
849         ir_asm_constraint *input_constraints = get_ASM_input_constraints(node);
850         int                n_inputs          = get_ASM_n_inputs(node);
851         for (int i = 0; i < n_inputs; ++i) {
852                 const ir_asm_constraint *constraint = &input_constraints[i];
853                 write_unsigned(env, constraint->pos);
854                 write_ident(env, constraint->constraint);
855                 write_mode_ref(env, constraint->mode);
856         }
857         write_list_end(env);
858
859         write_list_begin(env);
860         ir_asm_constraint *output_constraints  = get_ASM_output_constraints(node);
861         size_t            n_output_constraints = get_ASM_n_output_constraints(node);
862         for (size_t i = 0; i < n_output_constraints; ++i) {
863                 const ir_asm_constraint *constraint = &output_constraints[i];
864                 write_unsigned(env, constraint->pos);
865                 write_ident(env, constraint->constraint);
866                 write_mode_ref(env, constraint->mode);
867         }
868         write_list_end(env);
869
870         write_list_begin(env);
871         ident **clobbers   = get_ASM_clobbers(node);
872         size_t  n_clobbers = get_ASM_n_clobbers(node);
873         for (size_t i = 0; i < n_clobbers; ++i) {
874                 ident *clobber = clobbers[i];
875                 write_ident(env, clobber);
876         }
877         write_list_end(env);
878
879         write_pin_state(env, get_irn_pinned(node));
880         write_pred_refs(env, node, n_ASM_max+1);
881 }
882
883 static void write_Phi(write_env_t *env, const ir_node *node)
884 {
885         write_symbol(env, "Phi");
886         write_node_nr(env, node);
887         write_node_ref(env, get_nodes_block(node));
888         write_mode_ref(env, get_irn_mode(node));
889         write_pred_refs(env, node, 0);
890 }
891
892 static void write_Block(write_env_t *env, const ir_node *node)
893 {
894         ir_entity *entity = get_Block_entity(node);
895
896         if (entity != NULL) {
897                 write_symbol(env, "BlockL");
898                 write_node_nr(env, node);
899                 write_entity_ref(env, entity);
900         } else {
901                 write_symbol(env, "Block");
902                 write_node_nr(env, node);
903         }
904         write_pred_refs(env, node, 0);
905 }
906
907 static void write_Anchor(write_env_t *env, const ir_node *node)
908 {
909         write_symbol(env, "Anchor");
910         write_node_nr(env, node);
911         write_pred_refs(env, node, 0);
912 }
913
914 static void write_SymConst(write_env_t *env, const ir_node *node)
915 {
916         /* TODO: only symconst_addr_ent implemented yet */
917         if (get_SymConst_kind(node) != symconst_addr_ent)
918                 panic("Can't export %+F (only symconst_addr_ent supported)", node);
919
920         write_symbol(env, "SymConst");
921         write_node_nr(env, node);
922         write_mode_ref(env, get_irn_mode(node));
923         write_entity_ref(env, get_SymConst_entity(node));
924 }
925
926 typedef void write_node_func(write_env_t *env, ir_node const *node);
927
928 static void register_node_writer(ir_op *op, write_node_func *func)
929 {
930         set_generic_function_ptr(op, func);
931 }
932
933 static void writers_init(void)
934 {
935         ir_clear_opcodes_generic_func();
936         register_node_writer(op_Anchor,   write_Anchor);
937         register_node_writer(op_ASM,      write_ASM);
938         register_node_writer(op_Block,    write_Block);
939         register_node_writer(op_Phi,      write_Phi);
940         register_node_writer(op_SymConst, write_SymConst);
941         register_generated_node_writers();
942 }
943
944 static void write_node(const ir_node *node, write_env_t *env)
945 {
946         ir_op           *const op   = get_irn_op(node);
947         write_node_func *const func = get_generic_function_ptr(write_node_func, op);
948
949         fputc('\t', env->file);
950         if (func == NULL)
951                 panic("No write_node_func for %+F", node);
952         func(env, node);
953         fputc('\n', env->file);
954 }
955
956 static void write_node_recursive(ir_node *node, write_env_t *env);
957
958 static void write_preds(ir_node *node, write_env_t *env)
959 {
960         int arity = get_irn_arity(node);
961         int i;
962         for (i = 0; i < arity; ++i) {
963                 ir_node *pred = get_irn_n(node, i);
964                 write_node_recursive(pred, env);
965         }
966 }
967
968 /**
969  * Recursively write nodes.
970  * The reader expects nodes in a way that except for block/phi/anchor nodes
971  * all predecessors are already defined when we reach them. So usually we
972  * recurse to all our predecessors except for block/phi/anchor nodes where
973  * we put the predecessors into a queue for later processing.
974  */
975 static void write_node_recursive(ir_node *node, write_env_t *env)
976 {
977         if (irn_visited_else_mark(node))
978                 return;
979
980         if (!is_Block(node)) {
981                 write_node_recursive(get_nodes_block(node), env);
982         }
983         /* write predecessors */
984         if (!is_Phi(node) && !is_Block(node) && !is_Anchor(node)) {
985                 write_preds(node, env);
986         } else {
987                 int arity = get_irn_arity(node);
988                 int i;
989                 for (i = 0; i < arity; ++i) {
990                         ir_node *pred = get_irn_n(node, i);
991                         pdeq_putr(env->write_queue, pred);
992                 }
993         }
994         write_node(node, env);
995 }
996
997 static void write_mode(write_env_t *env, ir_mode *mode)
998 {
999         if (mode_is_int(mode)) {
1000                 write_symbol(env, "int_mode");
1001                 write_string(env, get_mode_name(mode));
1002                 write_mode_arithmetic(env, get_mode_arithmetic(mode));
1003                 write_unsigned(env, get_mode_size_bits(mode));
1004                 write_int(env, get_mode_sign(mode));
1005                 write_unsigned(env, get_mode_modulo_shift(mode));
1006         } else if (mode_is_reference(mode)) {
1007                 write_symbol(env, "reference_mode");
1008                 write_string(env, get_mode_name(mode));
1009                 write_mode_arithmetic(env, get_mode_arithmetic(mode));
1010                 write_unsigned(env, get_mode_size_bits(mode));
1011                 write_unsigned(env, get_mode_modulo_shift(mode));
1012
1013                 write_mode_ref(env, get_reference_mode_signed_eq(mode));
1014                 write_mode_ref(env, get_reference_mode_unsigned_eq(mode));
1015                 write_int(env, (mode == mode_P ? 1 : 0));
1016         } else if (mode_is_float(mode)) {
1017                 write_symbol(env, "float_mode");
1018                 write_string(env, get_mode_name(mode));
1019                 write_mode_arithmetic(env, get_mode_arithmetic(mode));
1020                 write_unsigned(env, get_mode_exponent_size(mode));
1021                 write_unsigned(env, get_mode_mantissa_size(mode));
1022         } else {
1023                 panic("Can't write internal modes");
1024         }
1025 }
1026
1027 static void write_modes(write_env_t *env)
1028 {
1029         size_t n_modes = ir_get_n_modes();
1030         size_t i;
1031
1032         write_symbol(env, "modes");
1033         fputs("{\n", env->file);
1034
1035         for (i = 0; i < n_modes; i++) {
1036                 ir_mode *mode = ir_get_mode(i);
1037                 if (!mode_is_int(mode) && !mode_is_reference(mode)
1038                     && !mode_is_float(mode)) {
1039                     /* skip internal modes */
1040                     continue;
1041                 }
1042                 fputc('\t', env->file);
1043                 write_mode(env, mode);
1044                 fputc('\n', env->file);
1045         }
1046
1047         fputs("}\n\n", env->file);
1048 }
1049
1050 static void write_program(write_env_t *env)
1051 {
1052         ir_segment_t s;
1053         size_t n_asms = get_irp_n_asms();
1054         size_t i;
1055
1056         write_symbol(env, "program");
1057         write_scope_begin(env);
1058         if (irp_prog_name_is_set()) {
1059                 fputc('\t', env->file);
1060                 write_symbol(env, "name");
1061                 write_string(env, get_irp_name());
1062                 fputc('\n', env->file);
1063         }
1064
1065         for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
1066                 ir_type *segment_type = get_segment_type(s);
1067                 fputc('\t', env->file);
1068                 write_symbol(env, "segment_type");
1069                 write_symbol(env, get_segment_name(s));
1070                 if (segment_type == NULL) {
1071                         write_symbol(env, "NULL");
1072                 } else {
1073                         write_type_ref(env, segment_type);
1074                 }
1075                 fputc('\n', env->file);
1076         }
1077
1078         for (i = 0; i < n_asms; ++i) {
1079                 ident *asm_text = get_irp_asm(i);
1080                 fputc('\t', env->file);
1081                 write_symbol(env, "asm");
1082                 write_ident(env, asm_text);
1083                 fputc('\n', env->file);
1084         }
1085         write_scope_end(env);
1086 }
1087
1088 int ir_export(const char *filename)
1089 {
1090         FILE *file = fopen(filename, "wt");
1091         int   res  = 0;
1092         if (file == NULL) {
1093                 perror(filename);
1094                 return 1;
1095         }
1096
1097         ir_export_file(file);
1098         res = ferror(file);
1099         fclose(file);
1100         return res;
1101 }
1102
1103 static void write_node_cb(ir_node *node, void *ctx)
1104 {
1105         write_env_t *env = (write_env_t*)ctx;
1106         write_node(node, env);
1107 }
1108
1109 static void write_typegraph(write_env_t *env)
1110 {
1111         size_t n_types = get_irp_n_types();
1112         size_t i;
1113
1114         write_symbol(env, "typegraph");
1115         write_scope_begin(env);
1116         irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
1117         inc_master_type_visited();
1118         for (i = 0; i < n_types; ++i) {
1119                 ir_type *type = get_irp_type(i);
1120                 write_type(env, type);
1121         }
1122         irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
1123         write_scope_end(env);
1124 }
1125
1126 static void write_irg(write_env_t *env, ir_graph *irg)
1127 {
1128         write_symbol(env, "irg");
1129         write_entity_ref(env, get_irg_entity(irg));
1130         write_type_ref(env, get_irg_frame_type(irg));
1131         write_scope_begin(env);
1132         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
1133         inc_irg_visited(irg);
1134         assert(pdeq_empty(env->write_queue));
1135         pdeq_putr(env->write_queue, irg->anchor);
1136         do {
1137                 ir_node *node = (ir_node*) pdeq_getl(env->write_queue);
1138                 write_node_recursive(node, env);
1139         } while (!pdeq_empty(env->write_queue));
1140         ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
1141         write_scope_end(env);
1142 }
1143
1144 /* Exports the whole irp to the given file in a textual form. */
1145 void ir_export_file(FILE *file)
1146 {
1147         write_env_t my_env;
1148         write_env_t *env = &my_env;
1149         size_t i, n_irgs = get_irp_n_irgs();
1150
1151         memset(env, 0, sizeof(*env));
1152         env->file        = file;
1153         env->write_queue = new_pdeq();
1154
1155         writers_init();
1156         write_modes(env);
1157
1158         write_typegraph(env);
1159
1160         for (i = 0; i < n_irgs; i++) {
1161                 ir_graph *irg = get_irp_irg(i);
1162                 write_irg(env, irg);
1163         }
1164
1165         write_symbol(env, "constirg");
1166         write_node_ref(env, get_const_code_irg()->current_block);
1167         write_scope_begin(env);
1168         walk_const_code(NULL, write_node_cb, env);
1169         write_scope_end(env);
1170
1171         write_program(env);
1172
1173         del_pdeq(env->write_queue);
1174 }
1175
1176
1177
1178 static void read_c(read_env_t *env)
1179 {
1180         int c = fgetc(env->file);
1181         env->c = c;
1182         if (c == '\n')
1183                 env->line++;
1184 }
1185
1186 /** Returns the first non-whitespace character or EOF. **/
1187 static void skip_ws(read_env_t *env)
1188 {
1189         while (true) {
1190                 switch (env->c) {
1191                 case ' ':
1192                 case '\t':
1193                 case '\n':
1194                 case '\r':
1195                         read_c(env);
1196                         continue;
1197
1198                 default:
1199                         return;
1200                 }
1201         }
1202 }
1203
1204 static void skip_to(read_env_t *env, char to_ch)
1205 {
1206         while (env->c != to_ch && env->c != EOF) {
1207                 read_c(env);
1208         }
1209 }
1210
1211 static bool expect_char(read_env_t *env, char ch)
1212 {
1213         skip_ws(env);
1214         if (env->c != ch) {
1215                 parse_error(env, "Unexpected char '%c', expected '%c'\n",
1216                             env->c, ch);
1217                 return false;
1218         }
1219         read_c(env);
1220         return true;
1221 }
1222
1223 #define EXPECT(c) if (expect_char(env, (c))) {} else return
1224
1225 static char *read_word(read_env_t *env)
1226 {
1227         skip_ws(env);
1228
1229         assert(obstack_object_size(&env->obst) == 0);
1230         while (true) {
1231                 int c = env->c;
1232                 switch (c) {
1233                 case EOF:
1234                 case ' ':
1235                 case '\t':
1236                 case '\n':
1237                 case '\r':
1238                         goto endofword;
1239
1240                 default:
1241                         obstack_1grow(&env->obst, c);
1242                         break;
1243                 }
1244                 read_c(env);
1245         }
1246
1247 endofword:
1248         obstack_1grow(&env->obst, '\0');
1249         return (char*)obstack_finish(&env->obst);
1250 }
1251
1252 static char *read_string(read_env_t *env)
1253 {
1254         skip_ws(env);
1255         if (env->c != '"') {
1256                 parse_error(env, "Expected string, got '%c'\n", env->c);
1257                 exit(1);
1258         }
1259         read_c(env);
1260
1261         assert(obstack_object_size(&env->obst) == 0);
1262         while (env->c != '"') {
1263                 if (env->c == EOF) {
1264                         parse_error(env, "Unexpected EOF while parsing string\n");
1265                         exit(1);
1266                 }
1267
1268                 if (env->c == '\\') {
1269                         read_c(env);
1270                         switch (env->c) {
1271                         case 'n':
1272                                 obstack_1grow(&env->obst, '\n');
1273                                 break;
1274                         case '"':
1275                         case '\\':
1276                                 obstack_1grow(&env->obst, env->c);
1277                                 break;
1278                         default:
1279                                 parse_error(env, "Unknown escape sequence '\\%c'\n", env->c);
1280                                 exit(1);
1281                         }
1282                 } else {
1283                         obstack_1grow(&env->obst, env->c);
1284                 }
1285                 read_c(env);
1286         }
1287         read_c(env);
1288         obstack_1grow(&env->obst, 0);
1289
1290         return (char*)obstack_finish(&env->obst);
1291 }
1292
1293 static ident *read_ident(read_env_t *env)
1294 {
1295         char  *str = read_string(env);
1296         ident *res = new_id_from_str(str);
1297         obstack_free(&env->obst, str);
1298         return res;
1299 }
1300
1301 static ident *read_symbol(read_env_t *env)
1302 {
1303         char  *str = read_word(env);
1304         ident *res = new_id_from_str(str);
1305         obstack_free(&env->obst, str);
1306         return res;
1307 }
1308
1309 /*
1310  * reads a "quoted string" or alternatively the token NULL
1311  */
1312 static char *read_string_null(read_env_t *env)
1313 {
1314         skip_ws(env);
1315         if (env->c == 'N') {
1316                 char *str = read_word(env);
1317                 if (strcmp(str, "NULL") == 0) {
1318                         obstack_free(&env->obst, str);
1319                         return NULL;
1320                 }
1321         } else if (env->c == '"') {
1322                 return read_string(env);
1323         }
1324
1325         parse_error(env, "Expected \"string\" or NULL\n");
1326         exit(1);
1327 }
1328
1329 static ident *read_ident_null(read_env_t *env)
1330 {
1331         ident *res;
1332         char  *str = read_string_null(env);
1333         if (str == NULL)
1334                 return NULL;
1335
1336         res = new_id_from_str(str);
1337         obstack_free(&env->obst, str);
1338         return res;
1339 }
1340
1341 static long read_long(read_env_t *env)
1342 {
1343         long  result;
1344         char *str;
1345
1346         skip_ws(env);
1347         if (!isdigit(env->c) && env->c != '-') {
1348                 parse_error(env, "Expected number, got '%c'\n", env->c);
1349                 exit(1);
1350         }
1351
1352         assert(obstack_object_size(&env->obst) == 0);
1353         do {
1354                 obstack_1grow(&env->obst, env->c);
1355                 read_c(env);
1356         } while (isdigit(env->c));
1357         obstack_1grow(&env->obst, 0);
1358
1359         str = (char*)obstack_finish(&env->obst);
1360         result = atol(str);
1361         obstack_free(&env->obst, str);
1362
1363         return result;
1364 }
1365
1366 static int read_int(read_env_t *env)
1367 {
1368         return (int) read_long(env);
1369 }
1370
1371 static unsigned read_unsigned(read_env_t *env)
1372 {
1373         return (unsigned) read_long(env);
1374 }
1375
1376 static size_t read_size_t(read_env_t *env)
1377 {
1378         /* FIXME */
1379         return (size_t) read_unsigned(env);
1380 }
1381
1382 static void expect_list_begin(read_env_t *env)
1383 {
1384         skip_ws(env);
1385         if (env->c != '[') {
1386                 parse_error(env, "Expected list, got '%c'\n", env->c);
1387                 exit(1);
1388         }
1389         read_c(env);
1390 }
1391
1392 static bool list_has_next(read_env_t *env)
1393 {
1394         if (feof(env->file)) {
1395                 parse_error(env, "Unexpected EOF while reading list");
1396                 exit(1);
1397         }
1398         skip_ws(env);
1399         if (env->c == ']') {
1400                 read_c(env);
1401                 return false;
1402         }
1403
1404         return true;
1405 }
1406
1407 static void *get_id(read_env_t *env, long id)
1408 {
1409         id_entry key, *entry;
1410         key.id = id;
1411
1412         entry = set_find(id_entry, env->idset, &key, sizeof(key), (unsigned) id);
1413         return entry ? entry->elem : NULL;
1414 }
1415
1416 static void set_id(read_env_t *env, long id, void *elem)
1417 {
1418         id_entry key;
1419         key.id = id;
1420         key.elem = elem;
1421         (void)set_insert(id_entry, env->idset, &key, sizeof(key), (unsigned) id);
1422 }
1423
1424 static ir_node *get_node_or_null(read_env_t *env, long nodenr)
1425 {
1426         ir_node *node = (ir_node *) get_id(env, nodenr);
1427         if (node && node->kind != k_ir_node) {
1428                 parse_error(env, "Irn ID %ld collides with something else\n",
1429                             nodenr);
1430                 return NULL;
1431         }
1432         return node;
1433 }
1434
1435 static ir_type *get_type(read_env_t *env, long typenr)
1436 {
1437         ir_type *type = (ir_type *) get_id(env, typenr);
1438         if (type == NULL) {
1439                 parse_error(env, "Type %ld not defined (yet?)\n", typenr);
1440                 return get_unknown_type();
1441         }
1442         if (type->kind != k_type) {
1443                 parse_error(env, "Object %ld is not a type (but should be)\n", typenr);
1444                 return get_unknown_type();
1445         }
1446         return type;
1447 }
1448
1449 static ir_type *read_type_ref(read_env_t *env)
1450 {
1451         char *str = read_word(env);
1452         if (strcmp(str, "none") == 0) {
1453                 obstack_free(&env->obst, str);
1454                 return get_none_type();
1455         }
1456         if (strcmp(str, "unknown") == 0) {
1457                 obstack_free(&env->obst, str);
1458                 return get_unknown_type();
1459         }
1460         if (strcmp(str, "code") == 0) {
1461                 obstack_free(&env->obst, str);
1462                 return get_code_type();
1463         }
1464         long nr = atol(str);
1465         obstack_free(&env->obst, str);
1466
1467         return get_type(env, nr);
1468 }
1469
1470 static ir_entity *create_error_entity(void)
1471 {
1472         ir_entity *res = new_entity(get_glob_type(), new_id_from_str("error"),
1473                                     get_unknown_type());
1474         return res;
1475 }
1476
1477 static ir_entity *get_entity(read_env_t *env, long entnr)
1478 {
1479         ir_entity *entity = (ir_entity *) get_id(env, entnr);
1480         if (entity == NULL) {
1481                 parse_error(env, "unknown entity: %ld\n", entnr);
1482                 return create_error_entity();
1483         }
1484         if (entity->kind != k_entity) {
1485                 parse_error(env, "Object %ld is not an entity (but should be)\n",
1486                             entnr);
1487                 return create_error_entity();
1488         }
1489
1490         return entity;
1491 }
1492
1493 static ir_entity *read_entity_ref(read_env_t *env)
1494 {
1495         long nr = read_long(env);
1496         return get_entity(env, nr);
1497 }
1498
1499 static ir_mode *read_mode_ref(read_env_t *env)
1500 {
1501         char  *str = read_string(env);
1502         size_t n   = ir_get_n_modes();
1503         size_t i;
1504
1505         for (i = 0; i < n; i++) {
1506                 ir_mode *mode = ir_get_mode(i);
1507                 if (strcmp(str, get_mode_name(mode)) == 0) {
1508                         obstack_free(&env->obst, str);
1509                         return mode;
1510                 }
1511         }
1512
1513         parse_error(env, "unknown mode \"%s\"\n", str);
1514         return mode_ANY;
1515 }
1516
1517 static const char *get_typetag_name(typetag_t typetag)
1518 {
1519         switch (typetag) {
1520         case tt_align:               return "align";
1521         case tt_builtin_kind:        return "builtin kind";
1522         case tt_cond_jmp_predicate:  return "cond_jmp_predicate";
1523         case tt_initializer:         return "initializer kind";
1524         case tt_keyword:             return "keyword";
1525         case tt_linkage:             return "linkage";
1526         case tt_mode_arithmetic:     return "mode_arithmetic";
1527         case tt_pin_state:           return "pin state";
1528         case tt_segment:             return "segment";
1529         case tt_throws:              return "throws";
1530         case tt_tpo:                 return "type";
1531         case tt_type_state:          return "type state";
1532         case tt_visibility:          return "visibility";
1533         case tt_volatility:          return "volatility";
1534         case tt_where_alloc:         return "where alloc";
1535         }
1536         return "<UNKNOWN>";
1537 }
1538
1539 /**
1540  * Read and decode an enum constant.
1541  */
1542 static unsigned read_enum(read_env_t *env, typetag_t typetag)
1543 {
1544         char     *str  = read_word(env);
1545         unsigned  code = symbol(str, typetag);
1546
1547         if (code != SYMERROR) {
1548                 obstack_free(&env->obst, str);
1549                 return code;
1550         }
1551
1552         parse_error(env, "invalid %s: \"%s\"\n", get_typetag_name(typetag), str);
1553         return 0;
1554 }
1555
1556 static ir_align read_align(read_env_t *env)
1557 {
1558         return (ir_align)read_enum(env, tt_align);
1559 }
1560
1561 static ir_builtin_kind read_builtin_kind(read_env_t *env)
1562 {
1563         return (ir_builtin_kind)read_enum(env, tt_builtin_kind);
1564 }
1565
1566 static cond_jmp_predicate read_cond_jmp_predicate(read_env_t *env)
1567 {
1568         return (cond_jmp_predicate)read_enum(env, tt_cond_jmp_predicate);
1569 }
1570
1571 static ir_initializer_kind_t read_initializer_kind(read_env_t *env)
1572 {
1573         return (ir_initializer_kind_t)read_enum(env, tt_initializer);
1574 }
1575
1576 static ir_mode_arithmetic read_mode_arithmetic(read_env_t *env)
1577 {
1578         return (ir_mode_arithmetic)read_enum(env, tt_mode_arithmetic);
1579 }
1580
1581 static op_pin_state read_pin_state(read_env_t *env)
1582 {
1583         return (op_pin_state)read_enum(env, tt_pin_state);
1584 }
1585
1586 static ir_type_state read_type_state(read_env_t *env)
1587 {
1588         return (ir_type_state)read_enum(env, tt_type_state);
1589 }
1590
1591 static ir_visibility read_visibility(read_env_t *env)
1592 {
1593         return (ir_visibility)read_enum(env, tt_visibility);
1594 }
1595
1596 static ir_linkage read_linkage(read_env_t *env)
1597 {
1598         return (ir_linkage)read_enum(env, tt_linkage);
1599 }
1600
1601 static ir_volatility read_volatility(read_env_t *env)
1602 {
1603         return (ir_volatility)read_enum(env, tt_volatility);
1604 }
1605
1606 static ir_where_alloc read_where_alloc(read_env_t *env)
1607 {
1608         return (ir_where_alloc)read_enum(env, tt_where_alloc);
1609 }
1610
1611 static bool read_throws(read_env_t *env)
1612 {
1613         return (bool)read_enum(env, tt_throws);
1614 }
1615
1616 static keyword_t read_keyword(read_env_t *env)
1617 {
1618         return (keyword_t)read_enum(env, tt_keyword);
1619 }
1620
1621 static ir_relation read_relation(read_env_t *env)
1622 {
1623         return (ir_relation)read_long(env);
1624 }
1625
1626 static ir_tarval *read_tarval(read_env_t *env)
1627 {
1628         ir_mode   *tvmode = read_mode_ref(env);
1629         char      *str    = read_word(env);
1630         ir_tarval *tv;
1631         if (strcmp(str, "bad") == 0)
1632                 return tarval_bad;
1633         tv = new_tarval_from_str(str, strlen(str), tvmode);
1634         if (tv == tarval_bad)
1635                 parse_error(env, "problem while parsing tarval '%s'\n", str);
1636         obstack_free(&env->obst, str);
1637
1638         return tv;
1639 }
1640
1641 static ir_switch_table *read_switch_table(read_env_t *env)
1642 {
1643         size_t           n_entries = read_size_t(env);
1644         ir_switch_table *table     = ir_new_switch_table(env->irg, n_entries);
1645         size_t           i;
1646
1647         for (i = 0; i < n_entries; ++i) {
1648                 long       pn  = read_long(env);
1649                 ir_tarval *min = read_tarval(env);
1650                 ir_tarval *max = read_tarval(env);
1651                 ir_switch_table_set(table, i, min, max, pn);
1652         }
1653         return table;
1654 }
1655
1656 static ir_initializer_t *read_initializer(read_env_t *env)
1657 {
1658         ir_initializer_kind_t ini_kind = read_initializer_kind(env);
1659
1660         switch (ini_kind) {
1661         case IR_INITIALIZER_CONST: {
1662                 long nr = read_long(env);
1663                 ir_node *node = get_node_or_null(env, nr);
1664                 ir_initializer_t *initializer = create_initializer_const(node);
1665                 if (node == NULL) {
1666                         delayed_initializer_t di;
1667                         di.initializer = initializer;
1668                         di.node_nr     = nr;
1669                         ARR_APP1(delayed_initializer_t, env->delayed_initializers, di);
1670                 }
1671                 return initializer;
1672         }
1673
1674         case IR_INITIALIZER_TARVAL:
1675                 return create_initializer_tarval(read_tarval(env));
1676
1677         case IR_INITIALIZER_NULL:
1678                 return get_initializer_null();
1679
1680         case IR_INITIALIZER_COMPOUND: {
1681                 size_t i, n = read_size_t(env);
1682                 ir_initializer_t *ini = create_initializer_compound(n);
1683                 for (i = 0; i < n; i++) {
1684                         ir_initializer_t *curini = read_initializer(env);
1685                         set_initializer_compound_value(ini, i, curini);
1686                 }
1687                 return ini;
1688         }
1689         }
1690
1691         panic("Unknown initializer kind");
1692 }
1693
1694 /** Reads a type description and remembers it by its id. */
1695 static void read_type(read_env_t *env)
1696 {
1697         long           typenr = read_long(env);
1698         tp_opcode      tpop   = (tp_opcode) read_enum(env, tt_tpo);
1699         unsigned       size   = (unsigned) read_long(env);
1700         unsigned       align  = (unsigned) read_long(env);
1701         ir_type_state  state  = read_type_state(env);
1702         unsigned       flags  = (unsigned) read_long(env);
1703         ir_type       *type;
1704
1705         switch (tpop) {
1706         case tpo_array: {
1707                 size_t     n_dimensions = read_size_t(env);
1708                 ir_type   *elemtype     = read_type_ref(env);
1709                 size_t     i;
1710                 ir_entity *element_entity;
1711                 long       element_entity_nr;
1712
1713                 type = new_type_array(n_dimensions, elemtype);
1714                 for (i = 0; i < n_dimensions; i++) {
1715                         char *str = read_word(env);
1716                         if (strcmp(str, "unknown") != 0) {
1717                                 long lowerbound = atol(str);
1718                                 set_array_lower_bound_int(type, i, lowerbound);
1719                         }
1720                         obstack_free(&env->obst, str);
1721
1722                         str = read_word(env);
1723                         if (strcmp(str, "unknown") != 0) {
1724                                 long upperbound = atol(str);
1725                                 set_array_upper_bound_int(type, i, upperbound);
1726                         }
1727                         obstack_free(&env->obst, str);
1728                 }
1729
1730                 element_entity_nr = read_long(env);
1731                 element_entity = get_array_element_entity(type);
1732                 set_id(env, element_entity_nr, element_entity);
1733
1734                 set_type_size_bytes(type, size);
1735                 goto finish_type;
1736         }
1737
1738         case tpo_class: {
1739                 ident *id = read_ident_null(env);
1740
1741                 if (typenr == (long) IR_SEGMENT_GLOBAL)
1742                         type = get_glob_type();
1743                 else
1744                         type = new_type_class(id);
1745                 set_type_size_bytes(type, size);
1746                 goto finish_type;
1747         }
1748
1749         case tpo_method: {
1750                 unsigned                  callingconv = read_unsigned(env);
1751                 mtp_additional_properties addprops
1752                         = (mtp_additional_properties) read_long(env);
1753                 size_t nparams  = read_size_t(env);
1754                 size_t nresults = read_size_t(env);
1755                 size_t i;
1756                 ir_variadicity variadicity;
1757
1758                 type = new_type_method(nparams, nresults);
1759
1760                 for (i = 0; i < nparams; i++) {
1761                         long ptypenr = read_long(env);
1762                         ir_type *paramtype = get_type(env, ptypenr);
1763
1764                         set_method_param_type(type, i, paramtype);
1765                 }
1766                 for (i = 0; i < nresults; i++) {
1767                         long ptypenr = read_long(env);
1768                         ir_type *restype = get_type(env, ptypenr);
1769
1770                         set_method_res_type(type, i, restype);
1771                 }
1772
1773                 variadicity = (ir_variadicity) read_long(env);
1774                 set_method_variadicity(type, variadicity);
1775
1776                 set_method_calling_convention(type, callingconv);
1777                 set_method_additional_properties(type, addprops);
1778                 goto finish_type;
1779         }
1780
1781         case tpo_pointer: {
1782                 ir_mode *mode     = read_mode_ref(env);
1783                 ir_type *pointsto = get_type(env, read_long(env));
1784                 type = new_type_pointer(pointsto);
1785                 set_type_mode(type, mode);
1786                 goto finish_type;
1787         }
1788
1789         case tpo_primitive: {
1790                 ir_mode *mode = read_mode_ref(env);
1791                 ir_type *base_type = read_type_ref(env);
1792                 type = new_type_primitive(mode);
1793                 if (base_type != get_none_type()) {
1794                         set_primitive_base_type(type, base_type);
1795                 }
1796                 goto finish_type;
1797         }
1798
1799         case tpo_struct: {
1800                 ident *id = read_ident_null(env);
1801                 type = new_type_struct(id);
1802                 set_type_size_bytes(type, size);
1803                 goto finish_type;
1804         }
1805
1806         case tpo_union: {
1807                 ident *id = read_ident_null(env);
1808                 type = new_type_union(id);
1809                 set_type_size_bytes(type, size);
1810                 goto finish_type;
1811         }
1812
1813         case tpo_none:
1814         case tpo_code:
1815         case tpo_unknown:
1816         case tpo_enumeration:
1817         case tpo_uninitialized:
1818                 parse_error(env, "can't import this type kind (%d)", tpop);
1819                 return;
1820         }
1821         parse_error(env, "unknown type kind: \"%d\"\n", tpop);
1822         skip_to(env, '\n');
1823         return;
1824
1825 finish_type:
1826         set_type_alignment_bytes(type, align);
1827         type->flags = flags;
1828
1829         if (state == layout_fixed)
1830                 ARR_APP1(ir_type *, env->fixedtypes, type);
1831
1832         set_id(env, typenr, type);
1833 }
1834
1835 static void read_unknown_entity(read_env_t *env)
1836 {
1837         long       entnr  = read_long(env);
1838         ir_entity *entity = get_unknown_entity();
1839         set_id(env, entnr, entity);
1840 }
1841
1842 /** Reads an entity description and remembers it by its id. */
1843 static void read_entity(read_env_t *env, ir_entity_kind kind)
1844 {
1845         long           entnr      = read_long(env);
1846         ident         *name       = NULL;
1847         ident         *ld_name    = NULL;
1848         ir_visibility  visibility = ir_visibility_external;
1849         ir_linkage     linkage    = IR_LINKAGE_DEFAULT;
1850         ir_type       *owner      = NULL;
1851         ir_entity     *entity     = NULL;
1852         int            compiler_generated;
1853         ir_volatility  volatility;
1854         const char    *str;
1855         ir_type       *type;
1856
1857         if (kind != IR_ENTITY_LABEL && kind != IR_ENTITY_PARAMETER) {
1858                 name    = read_ident(env);
1859                 ld_name = read_ident_null(env);
1860         }
1861
1862         visibility = read_visibility(env);
1863         expect_list_begin(env);
1864         while (list_has_next(env)) {
1865                 linkage |= read_linkage(env);
1866         }
1867
1868         type = read_type_ref(env);
1869         if (kind != IR_ENTITY_LABEL)
1870                 owner = read_type_ref(env);
1871
1872         compiler_generated = read_long(env) != 0;
1873         volatility         = read_volatility(env);
1874
1875         switch (kind) {
1876         case IR_ENTITY_NORMAL:
1877                 entity = new_entity(owner, name, type);
1878                 if (ld_name != NULL)
1879                         set_entity_ld_ident(entity, ld_name);
1880                 str = read_word(env);
1881                 if (strcmp(str, "initializer") == 0) {
1882                         ir_initializer_t *initializer = read_initializer(env);
1883                         if (initializer != NULL)
1884                                 set_entity_initializer(entity, initializer);
1885                 } else if (strcmp(str, "none") == 0) {
1886                         /* do nothing */
1887                 } else {
1888                         parse_error(env, "expected 'initializer' or 'none' got '%s'\n", str);
1889                 }
1890                 break;
1891         case IR_ENTITY_COMPOUND_MEMBER:
1892                 entity = new_entity(owner, name, type);
1893                 if (ld_name != NULL)
1894                         set_entity_ld_ident(entity, ld_name);
1895                 set_entity_offset(entity, (int) read_long(env));
1896                 set_entity_offset_bits_remainder(entity, (unsigned char) read_long(env));
1897                 break;
1898         case IR_ENTITY_METHOD:
1899                 entity = new_entity(owner, name, type);
1900                 if (ld_name != NULL)
1901                         set_entity_ld_ident(entity, ld_name);
1902                 break;
1903         case IR_ENTITY_PARAMETER: {
1904                 char  *str = read_word(env);
1905                 size_t parameter_number;
1906                 if (strcmp(str, "va_start") == 0) {
1907                         parameter_number = IR_VA_START_PARAMETER_NUMBER;
1908                 } else {
1909                         parameter_number = atol(str);
1910                 }
1911                 obstack_free(&env->obst, str);
1912                 entity = new_parameter_entity(owner, parameter_number, type);
1913                 break;
1914         }
1915         case IR_ENTITY_LABEL: {
1916                 ir_label_t nr = get_irp_next_label_nr();
1917                 entity = new_label_entity(nr);
1918                 break;
1919         }
1920         case IR_ENTITY_UNKNOWN:
1921                 panic("read_entity with IR_ENTITY_UNKNOWN?");
1922         }
1923
1924         set_entity_compiler_generated(entity, compiler_generated);
1925         set_entity_volatility(entity, volatility);
1926         set_entity_visibility(entity, visibility);
1927         set_entity_linkage(entity, linkage);
1928
1929         if (owner != NULL && is_Array_type(owner)) {
1930                 set_array_element_entity(owner, entity);
1931         }
1932
1933         set_id(env, entnr, entity);
1934 }
1935
1936 /** Parses the whole type graph. */
1937 static void read_typegraph(read_env_t *env)
1938 {
1939         ir_graph *old_irg = env->irg;
1940
1941         EXPECT('{');
1942
1943         env->irg = get_const_code_irg();
1944
1945         /* parse all types first */
1946         while (true) {
1947                 keyword_t kwkind;
1948                 skip_ws(env);
1949                 if (env->c == '}') {
1950                         read_c(env);
1951                         break;
1952                 }
1953
1954                 kwkind = read_keyword(env);
1955                 switch (kwkind) {
1956                 case kw_type:
1957                         read_type(env);
1958                         break;
1959
1960                 case kw_entity:
1961                         read_entity(env, IR_ENTITY_NORMAL);
1962                         break;
1963                 case kw_label:
1964                         read_entity(env, IR_ENTITY_LABEL);
1965                         break;
1966                 case kw_method:
1967                         read_entity(env, IR_ENTITY_METHOD);
1968                         break;
1969                 case kw_compound_member:
1970                         read_entity(env, IR_ENTITY_COMPOUND_MEMBER);
1971                         break;
1972                 case kw_parameter:
1973                         read_entity(env, IR_ENTITY_PARAMETER);
1974                         break;
1975                 case kw_unknown:
1976                         read_unknown_entity(env);
1977                         break;
1978                 default:
1979                         parse_error(env, "type graph element not supported yet: %d\n", kwkind);
1980                         skip_to(env, '\n');
1981                         break;
1982                 }
1983         }
1984         env->irg = old_irg;
1985 }
1986
1987 /**
1988  * Read a node reference and return the node for it. This assumes that the node
1989  * was previously read. This is fine for all normal nodes.
1990  * (Note: that we "break" loops by having special code for phi, block or anchor
1991  *  nodes in place, firm guarantees us that a loop in the graph always contains
1992  *  a phi, block or anchor node)
1993  */
1994 static ir_node *read_node_ref(read_env_t *env)
1995 {
1996         long     nr   = read_long(env);
1997         ir_node *node = get_node_or_null(env, nr);
1998         if (node == NULL) {
1999                 parse_error(env, "node %ld not defined (yet?)\n", nr);
2000                 return new_r_Bad(env->irg, mode_ANY);
2001         }
2002         return node;
2003 }
2004
2005 static int read_preds(read_env_t *env)
2006 {
2007         expect_list_begin(env);
2008         assert(obstack_object_size(&env->preds_obst) == 0);
2009         while (list_has_next(env)) {
2010                 ir_node *pred = read_node_ref(env);
2011                 obstack_grow(&env->preds_obst, &pred, sizeof(pred));
2012         }
2013         return obstack_object_size(&env->preds_obst) / sizeof(ir_node*);
2014 }
2015
2016 static void read_preds_delayed(read_env_t *env, ir_node *node)
2017 {
2018         int             n_preds = 0;
2019         delayed_pred_t *d;
2020
2021         expect_list_begin(env);
2022         assert(obstack_object_size(&env->preds_obst) == 0);
2023         obstack_blank(&env->preds_obst, sizeof(delayed_pred_t));
2024         while (list_has_next(env)) {
2025                 long pred_nr = read_long(env);
2026                 obstack_grow(&env->preds_obst, &pred_nr, sizeof(pred_nr));
2027                 ++n_preds;
2028         }
2029         d          = (delayed_pred_t*) obstack_finish(&env->preds_obst);
2030         d->node    = node;
2031         d->n_preds = n_preds;
2032
2033         ARR_APP1(const delayed_pred_t*, env->delayed_preds, d);
2034 }
2035
2036 static ir_node *read_ASM(read_env_t *env)
2037 {
2038         int                n_in;
2039         ir_node          **in;
2040         ir_node           *newnode;
2041         ir_asm_constraint *input_constraints  = NEW_ARR_F(ir_asm_constraint, 0);
2042         ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0);
2043         ident            **clobbers           = NEW_ARR_F(ident*, 0);
2044         ir_node           *block              = read_node_ref(env);
2045         ir_node           *mem                = read_node_ref(env);
2046         op_pin_state       pin_state;
2047
2048         ident *asm_text = read_ident(env);
2049
2050         expect_list_begin(env);
2051         while (list_has_next(env)) {
2052                 ir_asm_constraint constraint;
2053                 constraint.pos        = read_unsigned(env);
2054                 constraint.constraint = read_ident(env);
2055                 constraint.mode       = read_mode_ref(env);
2056                 ARR_APP1(ir_asm_constraint, input_constraints, constraint);
2057         }
2058
2059         expect_list_begin(env);
2060         while (list_has_next(env)) {
2061                 ir_asm_constraint constraint;
2062                 constraint.pos        = read_unsigned(env);
2063                 constraint.constraint = read_ident(env);
2064                 constraint.mode       = read_mode_ref(env);
2065                 ARR_APP1(ir_asm_constraint, output_constraints, constraint);
2066         }
2067
2068         expect_list_begin(env);
2069         while (list_has_next(env)) {
2070                 ident *clobber = read_ident(env);
2071                 ARR_APP1(ident*, clobbers, clobber);
2072         }
2073
2074         pin_state = read_pin_state(env);
2075
2076         n_in = read_preds(env);
2077         in   = (ir_node**)obstack_finish(&env->preds_obst);
2078
2079         if (ARR_LEN(input_constraints) != (size_t)n_in) {
2080                 parse_error(env, "input_constraints != n_in in ir file");
2081                 return new_r_Bad(env->irg, mode_T);
2082         }
2083
2084         newnode = new_r_ASM(block, mem, n_in, in,
2085                 input_constraints, ARR_LEN(output_constraints),
2086                 output_constraints, ARR_LEN(clobbers),
2087                 clobbers, asm_text);
2088         set_irn_pinned(newnode, pin_state);
2089         obstack_free(&env->preds_obst, in);
2090         DEL_ARR_F(clobbers);
2091         DEL_ARR_F(output_constraints);
2092         DEL_ARR_F(input_constraints);
2093         return newnode;
2094 }
2095
2096 static ir_node *read_Phi(read_env_t *env)
2097 {
2098         ir_node *block = read_node_ref(env);
2099         ir_mode *mode  = read_mode_ref(env);
2100         ir_node *res   = new_r_Phi(block, 0, NULL, mode);
2101         read_preds_delayed(env, res);
2102         return res;
2103 }
2104
2105 static ir_node *read_Block(read_env_t *env)
2106 {
2107         ir_node *res = new_r_Block(env->irg, 0, NULL);
2108         read_preds_delayed(env, res);
2109         return res;
2110 }
2111
2112 static ir_node *read_labeled_Block(read_env_t *env)
2113 {
2114         ir_node   *res    = new_r_Block(env->irg, 0, NULL);
2115         ir_entity *entity = read_entity_ref(env);
2116         read_preds_delayed(env, res);
2117         set_Block_entity(res, entity);
2118         return res;
2119 }
2120
2121 static ir_node *read_SymConst(read_env_t *env)
2122 {
2123         ir_mode   *mode   = read_mode_ref(env);
2124         ir_entity *entity = read_entity_ref(env);
2125         ir_node   *res;
2126         symconst_symbol sym;
2127
2128         sym.entity_p = entity;
2129         res = new_r_SymConst(env->irg, mode, sym, symconst_addr_ent);
2130         return res;
2131 }
2132
2133 static ir_node *read_Anchor(read_env_t *env)
2134 {
2135         ir_node *res = new_r_Anchor(env->irg);
2136         read_preds_delayed(env, res);
2137         return res;
2138 }
2139
2140 typedef ir_node* read_node_func(read_env_t *env);
2141 static pmap *node_readers;
2142
2143 static void register_node_reader(ident *ident, read_node_func* func)
2144 {
2145         pmap_insert(node_readers, ident, (void*)func);
2146 }
2147
2148 static ir_node *read_node(read_env_t *env)
2149 {
2150         ident          *id   = read_symbol(env);
2151         read_node_func *func = pmap_get(read_node_func, node_readers, id);
2152         long            nr   = read_long(env);
2153         ir_node        *res;
2154         if (func == NULL) {
2155                 parse_error(env, "Unknown nodetype '%s'", get_id_str(id));
2156                 skip_to(env, '\n');
2157                 res = new_r_Bad(env->irg, mode_ANY);
2158         } else {
2159                 res = func(env);
2160         }
2161         set_id(env, nr, res);
2162         return res;
2163 }
2164
2165 static void readers_init(void)
2166 {
2167         assert(node_readers == NULL);
2168         node_readers = pmap_create();
2169         register_node_reader(new_id_from_str("Anchor"),   read_Anchor);
2170         register_node_reader(new_id_from_str("ASM"),      read_ASM);
2171         register_node_reader(new_id_from_str("Block"),    read_Block);
2172         register_node_reader(new_id_from_str("BlockL"),   read_labeled_Block);
2173         register_node_reader(new_id_from_str("Phi"),      read_Phi);
2174         register_node_reader(new_id_from_str("SymConst"), read_SymConst);
2175         register_generated_node_readers();
2176 }
2177
2178 static void read_graph(read_env_t *env, ir_graph *irg)
2179 {
2180         size_t n_delayed_preds;
2181         size_t i;
2182         env->irg = irg;
2183
2184         env->delayed_preds = NEW_ARR_F(const delayed_pred_t*, 0);
2185
2186         EXPECT('{');
2187         while (true) {
2188                 skip_ws(env);
2189                 if (env->c == '}' || env->c == EOF) {
2190                         read_c(env);
2191                         break;
2192                 }
2193
2194                 read_node(env);
2195         }
2196
2197         /* resolve delayed preds */
2198         n_delayed_preds = ARR_LEN(env->delayed_preds);
2199         for (i = 0; i < n_delayed_preds; ++i) {
2200                 const delayed_pred_t *dp  = env->delayed_preds[i];
2201                 ir_node             **ins = ALLOCAN(ir_node*, dp->n_preds);
2202                 int                   i;
2203                 for (i = 0; i < dp->n_preds; ++i) {
2204                         long     pred_nr = dp->preds[i];
2205                         ir_node *pred    = get_node_or_null(env, pred_nr);
2206                         if (pred == NULL) {
2207                                 parse_error(env, "predecessor %ld of a node not defined\n",
2208                                             pred_nr);
2209                                 goto next_delayed_pred;
2210                         }
2211                         ins[i] = pred;
2212                 }
2213                 set_irn_in(dp->node, dp->n_preds, ins);
2214                 if (is_Anchor(dp->node)) {
2215                         irg_anchors a;
2216                         for (a = anchor_first; a <= anchor_last; ++a) {
2217                                 ir_node *old_anchor = get_irg_anchor(irg, a);
2218                                 ir_node *new_anchor = ins[a];
2219                                 exchange(old_anchor, new_anchor);
2220                         }
2221                 }
2222 next_delayed_pred: ;
2223         }
2224         DEL_ARR_F(env->delayed_preds);
2225         env->delayed_preds = NULL;
2226 }
2227
2228 static ir_graph *read_irg(read_env_t *env)
2229 {
2230         ir_entity *irgent = get_entity(env, read_long(env));
2231         ir_graph  *irg    = new_ir_graph(irgent, 0);
2232         ir_type   *frame  = read_type_ref(env);
2233         set_irg_frame_type(irg, frame);
2234         read_graph(env, irg);
2235         irg_finalize_cons(irg);
2236         return irg;
2237 }
2238
2239 static void read_modes(read_env_t *env)
2240 {
2241         EXPECT('{');
2242
2243         while (true) {
2244                 keyword_t kwkind;
2245
2246                 skip_ws(env);
2247                 if (env->c == '}' || env->c == EOF) {
2248                         read_c(env);
2249                         break;
2250                 }
2251
2252                 kwkind = read_keyword(env);
2253                 switch (kwkind) {
2254                 case kw_int_mode: {
2255                         const char *name = read_string(env);
2256                         ir_mode_arithmetic arith = read_mode_arithmetic(env);
2257                         int size = read_long(env);
2258                         int sign = read_long(env);
2259                         unsigned modulo_shift = read_long(env);
2260                         new_int_mode(name, arith, size, sign, modulo_shift);
2261                         break;
2262                 }
2263                 case kw_reference_mode: {
2264                         const char *name = read_string(env);
2265                         ir_mode_arithmetic arith = read_mode_arithmetic(env);
2266                         int size = read_long(env);
2267                         unsigned modulo_shift = read_long(env);
2268                         ir_mode *mode = new_reference_mode(name, arith, size, modulo_shift);
2269                         set_reference_mode_signed_eq(mode, read_mode_ref(env));
2270                         set_reference_mode_unsigned_eq(mode, read_mode_ref(env));
2271                         int is_mode_P = read_int(env);
2272                         if (is_mode_P) {
2273                                 set_modeP_data(mode);
2274                                 set_modeP_code(mode);
2275                         }
2276                         break;
2277                 }
2278                 case kw_float_mode: {
2279                         const char *name = read_string(env);
2280                         ir_mode_arithmetic arith = read_mode_arithmetic(env);
2281                         int exponent_size = read_long(env);
2282                         int mantissa_size = read_long(env);
2283                         new_float_mode(name, arith, exponent_size, mantissa_size);
2284                         break;
2285                 }
2286
2287                 default:
2288                         skip_to(env, '\n');
2289                         break;
2290                 }
2291         }
2292 }
2293
2294 static void read_program(read_env_t *env)
2295 {
2296         EXPECT('{');
2297
2298         while (true) {
2299                 keyword_t kwkind;
2300
2301                 skip_ws(env);
2302                 if (env->c == '}') {
2303                         read_c(env);
2304                         break;
2305                 }
2306
2307                 kwkind = read_keyword(env);
2308                 switch (kwkind) {
2309                 case kw_segment_type: {
2310                         ir_segment_t  segment = (ir_segment_t) read_enum(env, tt_segment);
2311                         ir_type      *type    = read_type_ref(env);
2312                         set_segment_type(segment, type);
2313                         break;
2314                 }
2315                 case kw_asm: {
2316                         ident *text = read_ident(env);
2317                         add_irp_asm(text);
2318                         break;
2319                 }
2320                 default:
2321                         parse_error(env, "unexpected keyword %d\n", kwkind);
2322                         skip_to(env, '\n');
2323                 }
2324         }
2325 }
2326
2327 int ir_import(const char *filename)
2328 {
2329         FILE *file = fopen(filename, "rt");
2330         int   res;
2331         if (file == NULL) {
2332                 perror(filename);
2333                 return 1;
2334         }
2335
2336         res = ir_import_file(file, filename);
2337         fclose(file);
2338
2339         return res;
2340 }
2341
2342 int ir_import_file(FILE *input, const char *inputname)
2343 {
2344         read_env_t          myenv;
2345         int                 oldoptimize = get_optimize();
2346         read_env_t         *env         = &myenv;
2347         size_t              i;
2348         size_t              n;
2349         size_t              n_delayed_initializers;
2350
2351         readers_init();
2352         symtbl_init();
2353
2354         memset(env, 0, sizeof(*env));
2355         obstack_init(&env->obst);
2356         obstack_init(&env->preds_obst);
2357         env->idset      = new_set(id_cmp, 128);
2358         env->fixedtypes = NEW_ARR_F(ir_type *, 0);
2359         env->inputname  = inputname;
2360         env->file       = input;
2361         env->line       = 1;
2362         env->delayed_initializers = NEW_ARR_F(delayed_initializer_t, 0);
2363
2364         /* read first character */
2365         read_c(env);
2366
2367         /* if the first line starts with '#', it contains a comment. */
2368         if (env->c == '#')
2369                 skip_to(env, '\n');
2370
2371         set_optimize(0);
2372
2373         while (true) {
2374                 keyword_t kw;
2375
2376                 skip_ws(env);
2377                 if (env->c == EOF)
2378                         break;
2379
2380                 kw = read_keyword(env);
2381                 switch (kw) {
2382                 case kw_modes:
2383                         read_modes(env);
2384                         break;
2385
2386                 case kw_typegraph:
2387                         read_typegraph(env);
2388                         break;
2389
2390                 case kw_irg:
2391                         read_irg(env);
2392                         break;
2393
2394                 case kw_constirg: {
2395                         ir_graph *constirg = get_const_code_irg();
2396                         long bodyblockid = read_long(env);
2397                         set_id(env, bodyblockid, constirg->current_block);
2398                         read_graph(env, constirg);
2399                         break;
2400                 }
2401
2402                 case kw_program:
2403                         read_program(env);
2404                         break;
2405
2406                 default: {
2407                         parse_error(env, "Unexpected keyword %d at toplevel\n", kw);
2408                         exit(1);
2409                 }
2410                 }
2411         }
2412
2413         n = ARR_LEN(env->fixedtypes);
2414         for (i = 0; i < n; i++)
2415                 set_type_state(env->fixedtypes[i], layout_fixed);
2416
2417         DEL_ARR_F(env->fixedtypes);
2418
2419         /* resolve delayed initializers */
2420         n_delayed_initializers = ARR_LEN(env->delayed_initializers);
2421         for (i = 0; i < n_delayed_initializers; ++i) {
2422                 const delayed_initializer_t *di   = &env->delayed_initializers[i];
2423                 ir_node                     *node = get_node_or_null(env, di->node_nr);
2424                 if (node == NULL) {
2425                         parse_error(env, "node %ld mentioned in an initializer was never defined\n",
2426                                     di->node_nr);
2427                         continue;
2428                 }
2429                 assert(di->initializer->kind == IR_INITIALIZER_CONST);
2430                 di->initializer->consti.value = node;
2431         }
2432         DEL_ARR_F(env->delayed_initializers);
2433         env->delayed_initializers = NULL;
2434
2435         del_set(env->idset);
2436
2437         irp_finalize_cons();
2438
2439         set_optimize(oldoptimize);
2440
2441         obstack_free(&env->preds_obst, NULL);
2442         obstack_free(&env->obst, NULL);
2443
2444         pmap_destroy(node_readers);
2445         node_readers = NULL;
2446
2447         return env->read_errors;
2448 }
2449
2450 #include "gen_irio.inl"