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