2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Write textual representation of firm to file.
23 * @author Moritz Kroll, Matthias Braun
36 #include "irgraph_t.h"
51 #define SYMERROR ((unsigned) ~0)
53 static void register_generated_node_readers(void);
54 static void register_generated_node_writers(void);
56 typedef struct delayed_initializer_t {
57 ir_initializer_t *initializer;
59 } delayed_initializer_t;
61 typedef struct delayed_pred_t {
67 typedef struct read_env_t {
68 int c; /**< currently read char */
70 const char *inputname;
74 set *idset; /**< id_entry set, which maps from file ids to
79 struct obstack preds_obst;
80 delayed_initializer_t *delayed_initializers;
81 const delayed_pred_t **delayed_preds;
84 typedef struct write_env_t {
89 typedef enum typetag_t {
92 tt_cond_jmp_predicate,
94 tt_irg_inline_property,
108 typedef enum keyword_t {
128 typedef struct symbol_t {
129 const char *str; /**< The name of this symbol. */
130 typetag_t typetag; /**< The type tag of this symbol. */
131 unsigned code; /**< The value of this symbol. */
134 typedef struct id_entry {
139 /** The symbol table, a set of symbol_t elements. */
143 * Compare two symbol table entries.
145 static int symbol_cmp(const void *elt, const void *key, size_t size)
148 const symbol_t *entry = (const symbol_t *) elt;
149 const symbol_t *keyentry = (const symbol_t *) key;
151 res = entry->typetag - keyentry->typetag;
153 return strcmp(entry->str, keyentry->str);
156 static int id_cmp(const void *elt, const void *key, size_t size)
158 const id_entry *entry = (const id_entry *) elt;
159 const id_entry *keyentry = (const id_entry *) key;
161 return entry->id - keyentry->id;
164 static void __attribute__((format(printf, 2, 3)))
165 parse_error(read_env_t *env, const char *fmt, ...)
168 unsigned line = env->line;
170 /* workaround read_c "feature" that a '\n' triggers the line++
171 * instead of the character after the '\n' */
172 if (env->c == '\n') {
176 fprintf(stderr, "%s:%u: error ", env->inputname, line);
177 env->read_errors = true;
179 /* let's hope firm doesn't die on further errors */
180 do_node_verification(0);
183 vfprintf(stderr, fmt, ap);
187 /** Initializes the symbol table. May be called more than once without problems. */
188 static void symtbl_init(void)
192 /* Only initialize once */
196 symtbl = new_set(symbol_cmp, 256);
198 #define INSERT(tt, s, cod) \
200 key.typetag = (tt); \
202 set_insert(symtbl, &key, sizeof(key), hash_str(s) + tt * 17)
204 #define INSERTENUM(tt, e) INSERT(tt, #e, e)
205 #define INSERTKEYWORD(k) INSERT(tt_keyword, #k, kw_##k)
207 INSERT(tt_tpo, "array", tpo_array);
208 INSERT(tt_tpo, "class", tpo_class);
209 INSERT(tt_tpo, "method", tpo_method);
210 INSERT(tt_tpo, "pointer", tpo_pointer);
211 INSERT(tt_tpo, "primitive", tpo_primitive);
212 INSERT(tt_tpo, "struct", tpo_struct);
213 INSERT(tt_tpo, "union", tpo_union);
214 INSERT(tt_tpo, "Unknown", tpo_unknown);
216 INSERT(tt_segment, "global", IR_SEGMENT_GLOBAL);
217 INSERT(tt_segment, "thread_local", IR_SEGMENT_THREAD_LOCAL);
218 INSERT(tt_segment, "constructors", IR_SEGMENT_CONSTRUCTORS);
219 INSERT(tt_segment, "destructors", IR_SEGMENT_DESTRUCTORS);
221 INSERT(tt_linkage, "constant", IR_LINKAGE_CONSTANT);
222 INSERT(tt_linkage, "weak", IR_LINKAGE_WEAK);
223 INSERT(tt_linkage, "garbage_collect", IR_LINKAGE_GARBAGE_COLLECT);
224 INSERT(tt_linkage, "merge", IR_LINKAGE_MERGE);
225 INSERT(tt_linkage, "hidden_user", IR_LINKAGE_HIDDEN_USER);
227 INSERT(tt_visibility, "local", ir_visibility_local);
228 INSERT(tt_visibility, "external", ir_visibility_external);
229 INSERT(tt_visibility, "default", ir_visibility_default);
230 INSERT(tt_visibility, "private", ir_visibility_private);
232 INSERT(tt_throws, "throw", true);
233 INSERT(tt_throws, "nothrow", false);
236 INSERTKEYWORD(compound_member);
237 INSERTKEYWORD(constirg);
238 INSERTKEYWORD(entity);
239 INSERTKEYWORD(float_mode);
240 INSERTKEYWORD(int_mode);
242 INSERTKEYWORD(label);
243 INSERTKEYWORD(method);
244 INSERTKEYWORD(modes);
245 INSERTKEYWORD(parameter);
246 INSERTKEYWORD(program);
247 INSERTKEYWORD(reference_mode);
248 INSERTKEYWORD(segment_type);
250 INSERTKEYWORD(typegraph);
251 INSERTKEYWORD(unknown);
253 INSERTENUM(tt_align, align_non_aligned);
254 INSERTENUM(tt_align, align_is_aligned);
256 INSERTENUM(tt_builtin_kind, ir_bk_trap);
257 INSERTENUM(tt_builtin_kind, ir_bk_debugbreak);
258 INSERTENUM(tt_builtin_kind, ir_bk_return_address);
259 INSERTENUM(tt_builtin_kind, ir_bk_frame_address);
260 INSERTENUM(tt_builtin_kind, ir_bk_prefetch);
261 INSERTENUM(tt_builtin_kind, ir_bk_ffs);
262 INSERTENUM(tt_builtin_kind, ir_bk_clz);
263 INSERTENUM(tt_builtin_kind, ir_bk_ctz);
264 INSERTENUM(tt_builtin_kind, ir_bk_popcount);
265 INSERTENUM(tt_builtin_kind, ir_bk_parity);
266 INSERTENUM(tt_builtin_kind, ir_bk_bswap);
267 INSERTENUM(tt_builtin_kind, ir_bk_inport);
268 INSERTENUM(tt_builtin_kind, ir_bk_outport);
269 INSERTENUM(tt_builtin_kind, ir_bk_inner_trampoline);
271 INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_NONE);
272 INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_TRUE);
273 INSERTENUM(tt_cond_jmp_predicate, COND_JMP_PRED_FALSE);
275 INSERTENUM(tt_initializer, IR_INITIALIZER_CONST);
276 INSERTENUM(tt_initializer, IR_INITIALIZER_TARVAL);
277 INSERTENUM(tt_initializer, IR_INITIALIZER_NULL);
278 INSERTENUM(tt_initializer, IR_INITIALIZER_COMPOUND);
280 INSERT(tt_mode_arithmetic, "uninitialized", irma_uninitialized);
281 INSERT(tt_mode_arithmetic, "none", irma_none);
282 INSERT(tt_mode_arithmetic, "twos_complement", irma_twos_complement);
283 INSERT(tt_mode_arithmetic, "ieee754", irma_ieee754);
284 INSERT(tt_mode_arithmetic, "x86_extended_float", irma_x86_extended_float);
286 INSERT(tt_irg_inline_property, "any", irg_inline_any);
287 INSERT(tt_irg_inline_property, "recommended", irg_inline_recomended);
288 INSERT(tt_irg_inline_property, "forbidden", irg_inline_forbidden);
289 INSERT(tt_irg_inline_property, "forced", irg_inline_forced);
290 INSERT(tt_irg_inline_property, "forced_no_body", irg_inline_forced_no_body);
292 INSERTENUM(tt_pin_state, op_pin_state_floats);
293 INSERTENUM(tt_pin_state, op_pin_state_pinned);
294 INSERTENUM(tt_pin_state, op_pin_state_exc_pinned);
295 INSERTENUM(tt_pin_state, op_pin_state_mem_pinned);
297 INSERTENUM(tt_type_state, layout_undefined);
298 INSERTENUM(tt_type_state, layout_fixed);
300 INSERTENUM(tt_volatility, volatility_non_volatile);
301 INSERTENUM(tt_volatility, volatility_is_volatile);
303 INSERTENUM(tt_where_alloc, stack_alloc);
304 INSERTENUM(tt_where_alloc, heap_alloc);
311 static const char *get_segment_name(ir_segment_t segment)
314 case IR_SEGMENT_GLOBAL: return "global";
315 case IR_SEGMENT_THREAD_LOCAL: return "thread_local";
316 case IR_SEGMENT_CONSTRUCTORS: return "constructors";
317 case IR_SEGMENT_DESTRUCTORS: return "destructors";
319 panic("INVALID_SEGMENT");
322 static const char *get_visibility_name(ir_visibility visibility)
324 switch (visibility) {
325 case ir_visibility_local: return "local";
326 case ir_visibility_external: return "external";
327 case ir_visibility_default: return "default";
328 case ir_visibility_private: return "private";
330 panic("INVALID_VISIBILITY");
333 static const char *get_mode_arithmetic_name(ir_mode_arithmetic arithmetic)
335 switch (arithmetic) {
336 case irma_uninitialized: return "uninitialized";
337 case irma_none: return "none";
338 case irma_twos_complement: return "twos_complement";
339 case irma_ieee754: return "ieee754";
340 case irma_x86_extended_float: return "x86_extended_float";
342 panic("invalid mode_arithmetic");
345 static const char *get_irg_inline_property_name(irg_inline_property prop)
348 case irg_inline_any: return "any";
349 case irg_inline_recomended: return "recommended";
350 case irg_inline_forbidden: return "forbidden";
351 case irg_inline_forced: return "forced";
352 case irg_inline_forced_no_body: return "forced_no_body";
354 panic("invalid irg_inline_property");
357 /** Returns the according symbol value for the given string and tag, or SYMERROR if none was found. */
358 static unsigned symbol(const char *str, typetag_t typetag)
360 symbol_t key, *entry;
363 key.typetag = typetag;
365 entry = (symbol_t*)set_find(symtbl, &key, sizeof(key), hash_str(str) + typetag * 17);
366 return entry ? entry->code : SYMERROR;
369 static void write_long(write_env_t *env, long value)
371 fprintf(env->file, "%ld ", value);
374 static void write_int(write_env_t *env, int value)
376 fprintf(env->file, "%d ", value);
379 static void write_unsigned(write_env_t *env, unsigned value)
381 fprintf(env->file, "%u ", value);
384 static void write_size_t(write_env_t *env, size_t value)
386 ir_fprintf(env->file, "%zu ", value);
389 static void write_symbol(write_env_t *env, const char *symbol)
391 fputs(symbol, env->file);
392 fputc(' ', env->file);
395 static void write_entity_ref(write_env_t *env, ir_entity *entity)
397 write_long(env, get_entity_nr(entity));
400 static void write_type_ref(write_env_t *env, ir_type *type)
402 switch (get_type_tpop_code(type)) {
404 write_symbol(env, "unknown");
407 write_symbol(env, "none");
410 write_symbol(env, "code");
415 write_long(env, get_type_nr(type));
418 static void write_string(write_env_t *env, const char *string)
421 fputc('"', env->file);
422 for (c = string; *c != '\0'; ++c) {
425 fputc('\\', env->file);
426 fputc('n', env->file);
430 fputc('\\', env->file);
433 fputc(*c, env->file);
437 fputc('"', env->file);
438 fputc(' ', env->file);
441 static void write_ident(write_env_t *env, ident *id)
443 write_string(env, get_id_str(id));
446 static void write_ident_null(write_env_t *env, ident *id)
449 fputs("NULL ", env->file);
451 write_ident(env, id);
455 static void write_mode_ref(write_env_t *env, ir_mode *mode)
457 write_string(env, get_mode_name(mode));
460 static void write_tarval(write_env_t *env, ir_tarval *tv)
462 write_mode_ref(env, get_tarval_mode(tv));
463 if (tv == tarval_bad) {
464 write_symbol(env, "bad");
467 tarval_snprintf(buf, sizeof(buf), tv);
468 fputs(buf, env->file);
469 fputc(' ', env->file);
473 static void write_align(write_env_t *env, ir_align align)
475 fputs(get_align_name(align), env->file);
476 fputc(' ', env->file);
479 static void write_builtin_kind(write_env_t *env, const ir_node *node)
481 fputs(get_builtin_kind_name(get_Builtin_kind(node)), env->file);
482 fputc(' ', env->file);
485 static void write_cond_jmp_predicate(write_env_t *env, const ir_node *node)
487 fputs(get_cond_jmp_predicate_name(get_Cond_jmp_pred(node)), env->file);
488 fputc(' ', env->file);
491 static void write_relation(write_env_t *env, ir_relation relation)
493 write_long(env, (long)relation);
496 static void write_where_alloc(write_env_t *env, ir_where_alloc where_alloc)
498 switch (where_alloc) {
499 case stack_alloc: write_symbol(env, "stack_alloc"); return;
500 case heap_alloc: write_symbol(env, "heap_alloc"); return;
502 panic("invalid where_alloc value");
505 static void write_throws(write_env_t *env, bool throws)
507 write_symbol(env, throws ? "throw" : "nothrow");
510 static void write_list_begin(write_env_t *env)
512 fputs("[", env->file);
515 static void write_list_end(write_env_t *env)
517 fputs("] ", env->file);
520 static void write_scope_begin(write_env_t *env)
522 fputs("{\n", env->file);
525 static void write_scope_end(write_env_t *env)
527 fputs("}\n\n", env->file);
530 static void write_node_ref(write_env_t *env, const ir_node *node)
532 write_long(env, get_irn_node_nr(node));
535 static void write_initializer(write_env_t *env, ir_initializer_t *ini)
538 ir_initializer_kind_t ini_kind = get_initializer_kind(ini);
540 fputs(get_initializer_kind_name(ini_kind), f);
544 case IR_INITIALIZER_CONST:
545 write_node_ref(env, get_initializer_const_value(ini));
548 case IR_INITIALIZER_TARVAL:
549 write_tarval(env, get_initializer_tarval_value(ini));
552 case IR_INITIALIZER_NULL:
555 case IR_INITIALIZER_COMPOUND: {
556 size_t i, n = get_initializer_compound_n_entries(ini);
557 write_size_t(env, n);
558 for (i = 0; i < n; ++i)
559 write_initializer(env, get_initializer_compound_value(ini, i));
563 panic("Unknown initializer kind");
566 static void write_pin_state(write_env_t *env, op_pin_state state)
568 fputs(get_op_pin_state_name(state), env->file);
569 fputc(' ', env->file);
572 static void write_volatility(write_env_t *env, ir_volatility vol)
574 fputs(get_volatility_name(vol), env->file);
575 fputc(' ', env->file);
578 static void write_inline_property(write_env_t *env, irg_inline_property prop)
580 fputs(get_irg_inline_property_name(prop), env->file);
581 fputc(' ', env->file);
584 static void write_type_state(write_env_t *env, ir_type_state state)
586 fputs(get_type_state_name(state), env->file);
587 fputc(' ', env->file);
590 static void write_visibility(write_env_t *env, ir_visibility visibility)
592 fputs(get_visibility_name(visibility), env->file);
593 fputc(' ', env->file);
596 static void write_mode_arithmetic(write_env_t *env, ir_mode_arithmetic arithmetic)
598 fputs(get_mode_arithmetic_name(arithmetic), env->file);
599 fputc(' ', env->file);
602 static void write_type(write_env_t *env, ir_type *tp);
603 static void write_entity(write_env_t *env, ir_entity *entity);
605 static void write_type_common(write_env_t *env, ir_type *tp)
607 fputc('\t', env->file);
608 write_symbol(env, "type");
609 write_long(env, get_type_nr(tp));
610 write_symbol(env, get_type_tpop_name(tp));
611 write_unsigned(env, get_type_size_bytes(tp));
612 write_unsigned(env, get_type_alignment_bytes(tp));
613 write_type_state(env, get_type_state(tp));
614 write_unsigned(env, tp->flags);
617 static void write_type_primitive(write_env_t *env, ir_type *tp)
619 ir_type *base_type = get_primitive_base_type(tp);
621 if (base_type != NULL)
622 write_type(env, base_type);
624 write_type_common(env, tp);
625 write_mode_ref(env, get_type_mode(tp));
626 if (base_type == NULL)
627 base_type = get_none_type();
628 write_type_ref(env, base_type);
629 fputc('\n', env->file);
632 static void write_type_compound(write_env_t *env, ir_type *tp)
634 size_t n_members = get_compound_n_members(tp);
637 if (is_Class_type(tp)) {
638 if (get_class_n_subtypes(tp) > 0 || get_class_n_supertypes(tp) > 0
639 || get_class_type_info(tp) != NULL || get_class_vtable_size(tp) > 0) {
640 /* sub/superclass export not implemented yet, it's unclear wether
641 * class types will stay in libfirm anyway */
642 panic("can't export class types yet");
645 write_type_common(env, tp);
646 write_ident_null(env, get_compound_ident(tp));
647 fputc('\n', env->file);
649 for (i = 0; i < n_members; ++i) {
650 ir_entity *member = get_compound_member(tp, i);
651 write_entity(env, member);
655 static void write_type_array(write_env_t *env, ir_type *tp)
657 size_t n_dimensions = get_array_n_dimensions(tp);
658 ir_type *element_type = get_array_element_type(tp);
659 ir_entity *element_entity = get_array_element_entity(tp);
662 write_type(env, element_type);
664 write_type_common(env, tp);
665 write_size_t(env, n_dimensions);
666 write_type_ref(env, get_array_element_type(tp));
667 for (i = 0; i < n_dimensions; i++) {
668 ir_node *lower = get_array_lower_bound(tp, i);
669 ir_node *upper = get_array_upper_bound(tp, i);
672 write_long(env, get_tarval_long(get_Const_tarval(lower)));
674 panic("Lower array bound is not constant");
677 write_long(env, get_tarval_long(get_Const_tarval(upper)));
678 else if (is_Unknown(upper))
679 write_symbol(env, "unknown");
681 panic("Upper array bound is not constant");
683 /* note that we just write a reference to the element entity
684 * but never the entity itself */
685 write_entity_ref(env, element_entity);
686 fputc('\n', env->file);
689 static void write_type_method(write_env_t *env, ir_type *tp)
691 size_t nparams = get_method_n_params(tp);
692 size_t nresults = get_method_n_ress(tp);
695 for (i = 0; i < nparams; i++)
696 write_type(env, get_method_param_type(tp, i));
697 for (i = 0; i < nresults; i++)
698 write_type(env, get_method_res_type(tp, i));
700 write_type_common(env, tp);
701 write_unsigned(env, get_method_calling_convention(tp));
702 write_unsigned(env, get_method_additional_properties(tp));
703 write_size_t(env, nparams);
704 write_size_t(env, nresults);
705 for (i = 0; i < nparams; i++)
706 write_type_ref(env, get_method_param_type(tp, i));
707 for (i = 0; i < nresults; i++)
708 write_type_ref(env, get_method_res_type(tp, i));
709 write_unsigned(env, get_method_variadicity(tp));
710 fputc('\n', env->file);
713 static void write_type_pointer(write_env_t *env, ir_type *tp)
715 ir_type *points_to = get_pointer_points_to_type(tp);
717 write_type(env, points_to);
719 write_type_common(env, tp);
720 write_mode_ref(env, get_type_mode(tp));
721 write_type_ref(env, points_to);
722 fputc('\n', env->file);
725 static void write_type_enumeration(write_env_t *env, ir_type *tp)
727 write_type_common(env, tp);
728 write_ident_null(env, get_enumeration_ident(tp));
729 fputc('\n', env->file);
732 static void write_type(write_env_t *env, ir_type *tp)
734 if (type_visited(tp))
736 mark_type_visited(tp);
738 switch ((tp_opcode)get_type_tpop_code(tp)) {
742 case tpo_uninitialized:
743 /* no need to write special builtin types */
749 write_type_compound(env, tp);
752 case tpo_primitive: write_type_primitive(env, tp); return;
753 case tpo_enumeration: write_type_enumeration(env, tp); return;
754 case tpo_method: write_type_method(env, tp); return;
755 case tpo_pointer: write_type_pointer(env, tp); return;
756 case tpo_array: write_type_array(env, tp); return;
758 panic("can't write invalid type %+F\n", tp);
761 static void write_entity(write_env_t *env, ir_entity *ent)
763 ir_type *type = get_entity_type(ent);
764 ir_type *owner = get_entity_owner(ent);
765 ir_visibility visibility = get_entity_visibility(ent);
766 ir_linkage linkage = get_entity_linkage(ent);
768 if (entity_visited(ent))
770 mark_entity_visited(ent);
772 write_type(env, type);
773 write_type(env, owner);
775 fputc('\t', env->file);
776 switch ((ir_entity_kind)ent->entity_kind) {
777 case IR_ENTITY_NORMAL: write_symbol(env, "entity"); break;
778 case IR_ENTITY_METHOD: write_symbol(env, "method"); break;
779 case IR_ENTITY_LABEL: write_symbol(env, "label"); break;
780 case IR_ENTITY_COMPOUND_MEMBER: write_symbol(env, "compound_member"); break;
781 case IR_ENTITY_PARAMETER: write_symbol(env, "parameter"); break;
782 case IR_ENTITY_UNKNOWN:
783 write_symbol(env, "unknown");
784 write_long(env, get_entity_nr(ent));
787 write_long(env, get_entity_nr(ent));
789 if (ent->entity_kind != IR_ENTITY_LABEL
790 && ent->entity_kind != IR_ENTITY_PARAMETER) {
791 write_ident_null(env, get_entity_ident(ent));
792 if (!entity_has_ld_ident(ent)) {
793 write_ident_null(env, NULL);
795 write_ident_null(env, get_entity_ld_ident(ent));
799 write_visibility(env, visibility);
800 write_list_begin(env);
801 if (linkage & IR_LINKAGE_CONSTANT)
802 write_symbol(env, "constant");
803 if (linkage & IR_LINKAGE_WEAK)
804 write_symbol(env, "weak");
805 if (linkage & IR_LINKAGE_GARBAGE_COLLECT)
806 write_symbol(env, "garbage_collect");
807 if (linkage & IR_LINKAGE_MERGE)
808 write_symbol(env, "merge");
809 if (linkage & IR_LINKAGE_HIDDEN_USER)
810 write_symbol(env, "hidden_user");
813 write_type_ref(env, type);
814 if (ent->entity_kind != IR_ENTITY_LABEL)
815 write_type_ref(env, owner);
816 write_long(env, is_entity_compiler_generated(ent));
817 write_volatility(env, get_entity_volatility(ent));
819 switch ((ir_entity_kind)ent->entity_kind) {
820 case IR_ENTITY_NORMAL:
821 if (ent->initializer != NULL) {
822 write_symbol(env, "initializer");
823 write_initializer(env, get_entity_initializer(ent));
824 } else if (entity_has_compound_ent_values(ent)) {
825 /* compound graph API is deprecated */
826 panic("exporting compound_graph initializers not supported");
828 write_symbol(env, "none");
831 case IR_ENTITY_COMPOUND_MEMBER:
832 write_long(env, get_entity_offset(ent));
833 write_unsigned(env, get_entity_offset_bits_remainder(ent));
835 case IR_ENTITY_PARAMETER: {
836 size_t num = get_entity_parameter_number(ent);
837 if (num == IR_VA_START_PARAMETER_NUMBER) {
838 write_symbol(env, "va_start");
840 write_size_t(env, num);
844 case IR_ENTITY_UNKNOWN:
845 case IR_ENTITY_LABEL:
846 case IR_ENTITY_METHOD:
850 fputc('\n', env->file);
853 static void write_switch_table(write_env_t *env, const ir_switch_table *table)
855 size_t n_entries = ir_switch_table_get_n_entries(table);
858 write_size_t(env, n_entries);
859 for (i = 0; i < n_entries; ++i) {
860 long pn = ir_switch_table_get_pn(table, i);
861 ir_tarval *min = ir_switch_table_get_min(table, i);
862 ir_tarval *max = ir_switch_table_get_max(table, i);
864 write_tarval(env, min);
865 write_tarval(env, max);
869 static void write_pred_refs(write_env_t *env, const ir_node *node, int from)
871 int arity = get_irn_arity(node);
873 write_list_begin(env);
874 assert(from <= arity);
875 for (i = from; i < arity; ++i) {
876 ir_node *pred = get_irn_n(node, i);
877 write_node_ref(env, pred);
882 static void write_node_nr(write_env_t *env, const ir_node *node)
884 write_long(env, get_irn_node_nr(node));
887 static void write_ASM(write_env_t *env, const ir_node *node)
889 ir_asm_constraint *input_constraints = get_ASM_input_constraints(node);
890 ir_asm_constraint *output_constraints = get_ASM_output_constraints(node);
891 ident **clobbers = get_ASM_clobbers(node);
892 size_t n_input_constraints = get_ASM_n_input_constraints(node);
893 size_t n_output_constraints = get_ASM_n_output_constraints(node);
894 size_t n_clobbers = get_ASM_n_clobbers(node);
897 write_symbol(env, "ASM");
898 write_node_nr(env, node);
899 write_node_nr(env, get_nodes_block(node));
901 write_ident(env, get_ASM_text(node));
902 write_list_begin(env);
903 for (i = 0; i < n_input_constraints; ++i) {
904 const ir_asm_constraint *constraint = &input_constraints[i];
905 write_unsigned(env, constraint->pos);
906 write_ident(env, constraint->constraint);
907 write_mode_ref(env, constraint->mode);
911 write_list_begin(env);
912 for (i = 0; i < n_output_constraints; ++i) {
913 const ir_asm_constraint *constraint = &output_constraints[i];
914 write_unsigned(env, constraint->pos);
915 write_ident(env, constraint->constraint);
916 write_mode_ref(env, constraint->mode);
920 write_list_begin(env);
921 for (i = 0; i < n_clobbers; ++i) {
922 ident *clobber = clobbers[i];
923 write_ident(env, clobber);
927 write_pin_state(env, get_irn_pinned(node));
928 write_pred_refs(env, node, 0);
931 static void write_Phi(write_env_t *env, const ir_node *node)
933 write_symbol(env, "Phi");
934 write_node_nr(env, node);
935 write_node_ref(env, get_nodes_block(node));
936 write_mode_ref(env, get_irn_mode(node));
937 write_pred_refs(env, node, 0);
940 static void write_Block(write_env_t *env, const ir_node *node)
942 ir_entity *entity = get_Block_entity(node);
944 if (entity != NULL) {
945 write_symbol(env, "BlockL");
946 write_node_nr(env, node);
947 write_entity_ref(env, entity);
949 write_symbol(env, "Block");
950 write_node_nr(env, node);
952 write_pred_refs(env, node, 0);
955 static void write_Anchor(write_env_t *env, const ir_node *node)
957 write_symbol(env, "Anchor");
958 write_node_nr(env, node);
959 write_pred_refs(env, node, 0);
962 static void write_SymConst(write_env_t *env, const ir_node *node)
964 /* TODO: only symconst_addr_ent implemented yet */
965 if (get_SymConst_kind(node) != symconst_addr_ent)
966 panic("Can't export %+F (only symconst_addr_ent supported)", node);
968 write_symbol(env, "SymConst");
969 write_node_nr(env, node);
970 write_mode_ref(env, get_irn_mode(node));
971 write_entity_ref(env, get_SymConst_entity(node));
974 typedef void (*write_node_func)(write_env_t *env, const ir_node *node);
976 static void register_node_writer(ir_op *op, write_node_func func)
978 set_generic_function_ptr(op, (op_func)func);
981 static void writers_init(void)
983 ir_clear_opcodes_generic_func();
984 register_node_writer(op_Anchor, write_Anchor);
985 register_node_writer(op_ASM, write_ASM);
986 register_node_writer(op_Block, write_Block);
987 register_node_writer(op_Phi, write_Phi);
988 register_node_writer(op_SymConst, write_SymConst);
989 register_generated_node_writers();
992 static void write_node(const ir_node *node, write_env_t *env)
994 ir_op *op = get_irn_op(node);
995 write_node_func func = (write_node_func) get_generic_function_ptr(op);
997 fputc('\t', env->file);
999 panic("No write_node_func for %+F", node);
1001 fputc('\n', env->file);
1004 static void write_node_recursive(ir_node *node, write_env_t *env);
1006 static void write_preds(ir_node *node, write_env_t *env)
1008 int arity = get_irn_arity(node);
1010 for (i = 0; i < arity; ++i) {
1011 ir_node *pred = get_irn_n(node, i);
1012 write_node_recursive(pred, env);
1017 * Recursively write nodes.
1018 * The reader expects nodes in a way that except for block/phi/anchor nodes
1019 * all predecessors are already defined when we reach them. So usually we
1020 * recurse to all our predecessors except for block/phi/anchor nodes where
1021 * we put the predecessors into a queue for later processing.
1023 static void write_node_recursive(ir_node *node, write_env_t *env)
1025 if (irn_visited_else_mark(node))
1028 if (!is_Block(node)) {
1029 write_node_recursive(get_nodes_block(node), env);
1031 /* write predecessors */
1032 if (!is_Phi(node) && !is_Block(node) && !is_Anchor(node)) {
1033 write_preds(node, env);
1035 int arity = get_irn_arity(node);
1037 for (i = 0; i < arity; ++i) {
1038 ir_node *pred = get_irn_n(node, i);
1039 pdeq_putr(env->write_queue, pred);
1042 write_node(node, env);
1045 static void write_mode(write_env_t *env, ir_mode *mode)
1047 if (mode_is_int(mode)) {
1048 write_symbol(env, "int_mode");
1049 write_string(env, get_mode_name(mode));
1050 write_mode_arithmetic(env, get_mode_arithmetic(mode));
1051 write_unsigned(env, get_mode_size_bits(mode));
1052 write_int(env, get_mode_sign(mode));
1053 write_unsigned(env, get_mode_modulo_shift(mode));
1054 } else if (mode_is_reference(mode)) {
1055 write_symbol(env, "reference_mode");
1056 write_string(env, get_mode_name(mode));
1057 write_mode_arithmetic(env, get_mode_arithmetic(mode));
1058 write_unsigned(env, get_mode_size_bits(mode));
1059 write_unsigned(env, get_mode_modulo_shift(mode));
1061 write_mode_ref(env, get_reference_mode_signed_eq(mode));
1062 write_mode_ref(env, get_reference_mode_unsigned_eq(mode));
1063 write_int(env, (mode == mode_P ? 1 : 0));
1064 } else if (mode_is_float(mode)) {
1065 write_symbol(env, "float_mode");
1066 write_string(env, get_mode_name(mode));
1067 write_mode_arithmetic(env, get_mode_arithmetic(mode));
1068 write_unsigned(env, get_mode_exponent_size(mode));
1069 write_unsigned(env, get_mode_mantissa_size(mode));
1071 panic("Can't write internal modes");
1075 static void write_modes(write_env_t *env)
1077 size_t i, n_modes = get_irp_n_modes();
1079 write_symbol(env, "modes");
1080 fputs("{\n", env->file);
1082 for (i = 0; i < n_modes; i++) {
1083 ir_mode *mode = get_irp_mode(i);
1084 if (!mode_is_int(mode) && !mode_is_reference(mode)
1085 && !mode_is_float(mode)) {
1086 /* skip internal modes */
1089 fputc('\t', env->file);
1090 write_mode(env, mode);
1091 fputc('\n', env->file);
1094 fputs("}\n\n", env->file);
1097 static void write_program(write_env_t *env)
1100 size_t n_asms = get_irp_n_asms();
1103 write_symbol(env, "program");
1104 write_scope_begin(env);
1105 if (irp_prog_name_is_set()) {
1106 fputc('\t', env->file);
1107 write_symbol(env, "name");
1108 write_string(env, get_irp_name());
1109 fputc('\n', env->file);
1112 for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) {
1113 ir_type *segment_type = get_segment_type(s);
1114 fputc('\t', env->file);
1115 write_symbol(env, "segment_type");
1116 write_symbol(env, get_segment_name(s));
1117 if (segment_type == NULL) {
1118 write_symbol(env, "NULL");
1120 write_type_ref(env, segment_type);
1122 fputc('\n', env->file);
1125 for (i = 0; i < n_asms; ++i) {
1126 ident *asm_text = get_irp_asm(i);
1127 fputc('\t', env->file);
1128 write_symbol(env, "asm");
1129 write_ident(env, asm_text);
1130 fputc('\n', env->file);
1132 write_scope_end(env);
1135 int ir_export(const char *filename)
1137 FILE *file = fopen(filename, "wt");
1144 ir_export_file(file);
1150 static void write_node_cb(ir_node *node, void *ctx)
1152 write_env_t *env = (write_env_t*)ctx;
1153 write_node(node, env);
1156 static void write_typegraph(write_env_t *env)
1158 size_t n_types = get_irp_n_types();
1161 write_symbol(env, "typegraph");
1162 write_scope_begin(env);
1163 irp_reserve_resources(irp, IRP_RESOURCE_TYPE_VISITED);
1164 inc_master_type_visited();
1165 for (i = 0; i < n_types; ++i) {
1166 ir_type *type = get_irp_type(i);
1167 write_type(env, type);
1169 irp_free_resources(irp, IRP_RESOURCE_TYPE_VISITED);
1170 write_scope_end(env);
1173 static void write_irg(write_env_t *env, ir_graph *irg)
1175 write_symbol(env, "irg");
1176 write_entity_ref(env, get_irg_entity(irg));
1177 write_type_ref(env, get_irg_frame_type(irg));
1178 write_inline_property(env, get_irg_inline_property(irg));
1179 write_unsigned(env, get_irg_additional_properties(irg));
1180 write_scope_begin(env);
1181 ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
1182 inc_irg_visited(irg);
1183 assert(pdeq_empty(env->write_queue));
1184 pdeq_putr(env->write_queue, irg->anchor);
1186 ir_node *node = (ir_node*) pdeq_getl(env->write_queue);
1187 write_node_recursive(node, env);
1188 } while (!pdeq_empty(env->write_queue));
1189 ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
1190 write_scope_end(env);
1193 /* Exports the whole irp to the given file in a textual form. */
1194 void ir_export_file(FILE *file)
1197 write_env_t *env = &my_env;
1198 size_t i, n_irgs = get_irp_n_irgs();
1200 memset(env, 0, sizeof(*env));
1202 env->write_queue = new_pdeq();
1207 write_typegraph(env);
1209 for (i = 0; i < n_irgs; i++) {
1210 ir_graph *irg = get_irp_irg(i);
1211 write_irg(env, irg);
1214 write_symbol(env, "constirg");
1215 write_node_ref(env, get_const_code_irg()->current_block);
1216 write_scope_begin(env);
1217 walk_const_code(NULL, write_node_cb, env);
1218 write_scope_end(env);
1222 del_pdeq(env->write_queue);
1227 static void read_c(read_env_t *env)
1229 int c = fgetc(env->file);
1235 /** Returns the first non-whitespace character or EOF. **/
1236 static void skip_ws(read_env_t *env)
1253 static void skip_to(read_env_t *env, char to_ch)
1255 while (env->c != to_ch && env->c != EOF) {
1260 static bool expect_char(read_env_t *env, char ch)
1264 parse_error(env, "Unexpected char '%c', expected '%c'\n",
1272 #define EXPECT(c) if (expect_char(env, (c))) {} else return
1274 static char *read_word(read_env_t *env)
1278 assert(obstack_object_size(&env->obst) == 0);
1290 obstack_1grow(&env->obst, c);
1297 obstack_1grow(&env->obst, '\0');
1298 return (char*)obstack_finish(&env->obst);
1301 static char *read_string(read_env_t *env)
1304 if (env->c != '"') {
1305 parse_error(env, "Expected string, got '%c'\n", env->c);
1310 assert(obstack_object_size(&env->obst) == 0);
1311 while (env->c != '"') {
1312 if (env->c == EOF) {
1313 parse_error(env, "Unexpected EOF while parsing string\n");
1317 if (env->c == '\\') {
1321 obstack_1grow(&env->obst, '\n');
1325 obstack_1grow(&env->obst, env->c);
1328 parse_error(env, "Unknown escape sequence '\\%c'\n", env->c);
1332 obstack_1grow(&env->obst, env->c);
1337 obstack_1grow(&env->obst, 0);
1339 return (char*)obstack_finish(&env->obst);
1342 static ident *read_ident(read_env_t *env)
1344 char *str = read_string(env);
1345 ident *res = new_id_from_str(str);
1346 obstack_free(&env->obst, str);
1350 static ident *read_symbol(read_env_t *env)
1352 char *str = read_word(env);
1353 ident *res = new_id_from_str(str);
1354 obstack_free(&env->obst, str);
1359 * reads a "quoted string" or alternatively the token NULL
1361 static char *read_string_null(read_env_t *env)
1364 if (env->c == 'N') {
1365 char *str = read_word(env);
1366 if (strcmp(str, "NULL") == 0) {
1367 obstack_free(&env->obst, str);
1370 } else if (env->c == '"') {
1371 return read_string(env);
1374 parse_error(env, "Expected \"string\" or NULL\n");
1378 static ident *read_ident_null(read_env_t *env)
1381 char *str = read_string_null(env);
1385 res = new_id_from_str(str);
1386 obstack_free(&env->obst, str);
1390 static long read_long(read_env_t *env)
1396 if (!isdigit(env->c) && env->c != '-') {
1397 parse_error(env, "Expected number, got '%c'\n", env->c);
1401 assert(obstack_object_size(&env->obst) == 0);
1403 obstack_1grow(&env->obst, env->c);
1405 } while (isdigit(env->c));
1406 obstack_1grow(&env->obst, 0);
1408 str = (char*)obstack_finish(&env->obst);
1410 obstack_free(&env->obst, str);
1415 static int read_int(read_env_t *env)
1417 return (int) read_long(env);
1420 static unsigned read_unsigned(read_env_t *env)
1422 return (unsigned) read_long(env);
1425 static size_t read_size_t(read_env_t *env)
1428 return (size_t) read_unsigned(env);
1431 static void expect_list_begin(read_env_t *env)
1434 if (env->c != '[') {
1435 parse_error(env, "Expected list, got '%c'\n", env->c);
1441 static bool list_has_next(read_env_t *env)
1443 if (feof(env->file)) {
1444 parse_error(env, "Unexpected EOF while reading list");
1448 if (env->c == ']') {
1456 static void *get_id(read_env_t *env, long id)
1458 id_entry key, *entry;
1461 entry = (id_entry*)set_find(env->idset, &key, sizeof(key), (unsigned) id);
1462 return entry ? entry->elem : NULL;
1465 static void set_id(read_env_t *env, long id, void *elem)
1470 set_insert(env->idset, &key, sizeof(key), (unsigned) id);
1473 static ir_node *get_node_or_null(read_env_t *env, long nodenr)
1475 ir_node *node = (ir_node *) get_id(env, nodenr);
1476 if (node && node->kind != k_ir_node) {
1477 parse_error(env, "Irn ID %ld collides with something else\n",
1484 static ir_type *get_type(read_env_t *env, long typenr)
1486 ir_type *type = (ir_type *) get_id(env, typenr);
1488 parse_error(env, "Type %ld not defined (yet?)\n", typenr);
1489 return get_unknown_type();
1491 if (type->kind != k_type) {
1492 parse_error(env, "Object %ld is not a type (but should be)\n", typenr);
1493 return get_unknown_type();
1498 static ir_type *read_type_ref(read_env_t *env)
1500 char *str = read_word(env);
1501 if (strcmp(str, "none") == 0) {
1502 obstack_free(&env->obst, str);
1503 return get_none_type();
1505 if (strcmp(str, "unknown") == 0) {
1506 obstack_free(&env->obst, str);
1507 return get_unknown_type();
1509 if (strcmp(str, "code") == 0) {
1510 obstack_free(&env->obst, str);
1511 return get_code_type();
1513 long nr = atol(str);
1514 obstack_free(&env->obst, str);
1516 return get_type(env, nr);
1519 static ir_entity *create_error_entity(void)
1521 ir_entity *res = new_entity(get_glob_type(), new_id_from_str("error"),
1522 get_unknown_type());
1526 static ir_entity *get_entity(read_env_t *env, long entnr)
1528 ir_entity *entity = (ir_entity *) get_id(env, entnr);
1529 if (entity == NULL) {
1530 parse_error(env, "unknown entity: %ld\n", entnr);
1531 return create_error_entity();
1533 if (entity->kind != k_entity) {
1534 parse_error(env, "Object %ld is not an entity (but should be)\n",
1536 return create_error_entity();
1542 static ir_entity *read_entity_ref(read_env_t *env)
1544 long nr = read_long(env);
1545 return get_entity(env, nr);
1548 static ir_mode *read_mode_ref(read_env_t *env)
1550 char *str = read_string(env);
1551 size_t n = get_irp_n_modes();
1554 for (i = 0; i < n; i++) {
1555 ir_mode *mode = get_irp_mode(i);
1556 if (strcmp(str, get_mode_name(mode)) == 0) {
1557 obstack_free(&env->obst, str);
1562 parse_error(env, "unknown mode \"%s\"\n", str);
1566 static const char *get_typetag_name(typetag_t typetag)
1569 case tt_align: return "align";
1570 case tt_builtin_kind: return "builtin kind";
1571 case tt_cond_jmp_predicate: return "cond_jmp_predicate";
1572 case tt_initializer: return "initializer kind";
1573 case tt_irg_inline_property: return "irg_inline_property";
1574 case tt_keyword: return "keyword";
1575 case tt_linkage: return "linkage";
1576 case tt_mode_arithmetic: return "mode_arithmetic";
1577 case tt_pin_state: return "pin state";
1578 case tt_segment: return "segment";
1579 case tt_throws: return "throws";
1580 case tt_tpo: return "type";
1581 case tt_type_state: return "type state";
1582 case tt_visibility: return "visibility";
1583 case tt_volatility: return "volatility";
1584 case tt_where_alloc: return "where alloc";
1590 * Read and decode an enum constant.
1592 static unsigned read_enum(read_env_t *env, typetag_t typetag)
1594 char *str = read_word(env);
1595 unsigned code = symbol(str, typetag);
1597 if (code != SYMERROR) {
1598 obstack_free(&env->obst, str);
1602 parse_error(env, "invalid %s: \"%s\"\n", get_typetag_name(typetag), str);
1606 static ir_align read_align(read_env_t *env)
1608 return (ir_align)read_enum(env, tt_align);
1611 static ir_builtin_kind read_builtin_kind(read_env_t *env)
1613 return (ir_builtin_kind)read_enum(env, tt_builtin_kind);
1616 static cond_jmp_predicate read_cond_jmp_predicate(read_env_t *env)
1618 return (cond_jmp_predicate)read_enum(env, tt_cond_jmp_predicate);
1621 static ir_initializer_kind_t read_initializer_kind(read_env_t *env)
1623 return (ir_initializer_kind_t)read_enum(env, tt_initializer);
1626 static ir_mode_arithmetic read_mode_arithmetic(read_env_t *env)
1628 return (ir_mode_arithmetic)read_enum(env, tt_mode_arithmetic);
1631 static op_pin_state read_pin_state(read_env_t *env)
1633 return (op_pin_state)read_enum(env, tt_pin_state);
1636 static ir_type_state read_type_state(read_env_t *env)
1638 return (ir_type_state)read_enum(env, tt_type_state);
1641 static ir_visibility read_visibility(read_env_t *env)
1643 return (ir_visibility)read_enum(env, tt_visibility);
1646 static ir_linkage read_linkage(read_env_t *env)
1648 return (ir_linkage)read_enum(env, tt_linkage);
1651 static ir_volatility read_volatility(read_env_t *env)
1653 return (ir_volatility)read_enum(env, tt_volatility);
1656 static ir_where_alloc read_where_alloc(read_env_t *env)
1658 return (ir_where_alloc)read_enum(env, tt_where_alloc);
1661 static bool read_throws(read_env_t *env)
1663 return (bool)read_enum(env, tt_throws);
1666 static keyword_t read_keyword(read_env_t *env)
1668 return (keyword_t)read_enum(env, tt_keyword);
1671 static irg_inline_property read_inline_property(read_env_t *env)
1673 return (irg_inline_property)read_enum(env, tt_irg_inline_property);
1676 static ir_relation read_relation(read_env_t *env)
1678 return (ir_relation)read_long(env);
1681 static ir_tarval *read_tarval(read_env_t *env)
1683 ir_mode *tvmode = read_mode_ref(env);
1684 char *str = read_word(env);
1686 if (strcmp(str, "bad") == 0)
1688 tv = new_tarval_from_str(str, strlen(str), tvmode);
1689 if (tv == tarval_bad)
1690 parse_error(env, "problem while parsing tarval '%s'\n", str);
1691 obstack_free(&env->obst, str);
1696 static ir_switch_table *read_switch_table(read_env_t *env)
1698 size_t n_entries = read_size_t(env);
1699 ir_switch_table *table = ir_new_switch_table(env->irg, n_entries);
1702 for (i = 0; i < n_entries; ++i) {
1703 long pn = read_long(env);
1704 ir_tarval *min = read_tarval(env);
1705 ir_tarval *max = read_tarval(env);
1706 ir_switch_table_set(table, i, min, max, pn);
1711 static ir_initializer_t *read_initializer(read_env_t *env)
1713 ir_initializer_kind_t ini_kind = read_initializer_kind(env);
1716 case IR_INITIALIZER_CONST: {
1717 long nr = read_long(env);
1718 ir_node *node = get_node_or_null(env, nr);
1719 ir_initializer_t *initializer = create_initializer_const(node);
1721 delayed_initializer_t di;
1722 di.initializer = initializer;
1724 ARR_APP1(delayed_initializer_t, env->delayed_initializers, di);
1729 case IR_INITIALIZER_TARVAL:
1730 return create_initializer_tarval(read_tarval(env));
1732 case IR_INITIALIZER_NULL:
1733 return get_initializer_null();
1735 case IR_INITIALIZER_COMPOUND: {
1736 size_t i, n = read_size_t(env);
1737 ir_initializer_t *ini = create_initializer_compound(n);
1738 for (i = 0; i < n; i++) {
1739 ir_initializer_t *curini = read_initializer(env);
1740 set_initializer_compound_value(ini, i, curini);
1746 panic("Unknown initializer kind");
1749 /** Reads a type description and remembers it by its id. */
1750 static void read_type(read_env_t *env)
1752 long typenr = read_long(env);
1753 tp_opcode tpop = (tp_opcode) read_enum(env, tt_tpo);
1754 unsigned size = (unsigned) read_long(env);
1755 unsigned align = (unsigned) read_long(env);
1756 ir_type_state state = read_type_state(env);
1757 unsigned flags = (unsigned) read_long(env);
1762 size_t n_dimensions = read_size_t(env);
1763 ir_type *elemtype = read_type_ref(env);
1765 ir_entity *element_entity;
1766 long element_entity_nr;
1768 type = new_type_array(n_dimensions, elemtype);
1769 for (i = 0; i < n_dimensions; i++) {
1770 char *str = read_word(env);
1771 if (strcmp(str, "unknown") != 0) {
1772 long lowerbound = atol(str);
1773 set_array_lower_bound_int(type, i, lowerbound);
1775 obstack_free(&env->obst, str);
1777 str = read_word(env);
1778 if (strcmp(str, "unknown") != 0) {
1779 long upperbound = atol(str);
1780 set_array_upper_bound_int(type, i, upperbound);
1782 obstack_free(&env->obst, str);
1785 element_entity_nr = read_long(env);
1786 element_entity = get_array_element_entity(type);
1787 set_id(env, element_entity_nr, element_entity);
1789 set_type_size_bytes(type, size);
1794 ident *id = read_ident_null(env);
1796 if (typenr == (long) IR_SEGMENT_GLOBAL)
1797 type = get_glob_type();
1799 type = new_type_class(id);
1800 set_type_size_bytes(type, size);
1805 unsigned callingconv = read_unsigned(env);
1806 mtp_additional_properties addprops
1807 = (mtp_additional_properties) read_long(env);
1808 size_t nparams = read_size_t(env);
1809 size_t nresults = read_size_t(env);
1813 type = new_type_method(nparams, nresults);
1815 for (i = 0; i < nparams; i++) {
1816 long ptypenr = read_long(env);
1817 ir_type *paramtype = get_type(env, ptypenr);
1819 set_method_param_type(type, i, paramtype);
1821 for (i = 0; i < nresults; i++) {
1822 long ptypenr = read_long(env);
1823 ir_type *restype = get_type(env, ptypenr);
1825 set_method_res_type(type, i, restype);
1828 variadicity = (int) read_long(env);
1829 set_method_variadicity(type, variadicity);
1831 set_method_calling_convention(type, callingconv);
1832 set_method_additional_properties(type, addprops);
1837 ir_mode *mode = read_mode_ref(env);
1838 ir_type *pointsto = get_type(env, read_long(env));
1839 type = new_type_pointer(pointsto);
1840 set_type_mode(type, mode);
1844 case tpo_primitive: {
1845 ir_mode *mode = read_mode_ref(env);
1846 ir_type *base_type = read_type_ref(env);
1847 type = new_type_primitive(mode);
1848 if (base_type != get_none_type()) {
1849 set_primitive_base_type(type, base_type);
1855 ident *id = read_ident_null(env);
1856 type = new_type_struct(id);
1857 set_type_size_bytes(type, size);
1862 ident *id = read_ident_null(env);
1863 type = new_type_union(id);
1864 set_type_size_bytes(type, size);
1871 case tpo_enumeration:
1872 case tpo_uninitialized:
1873 parse_error(env, "can't import this type kind (%d)", tpop);
1876 parse_error(env, "unknown type kind: \"%d\"\n", tpop);
1881 set_type_alignment_bytes(type, align);
1882 type->flags = flags;
1884 if (state == layout_fixed)
1885 ARR_APP1(ir_type *, env->fixedtypes, type);
1887 set_id(env, typenr, type);
1890 static void read_unknown_entity(read_env_t *env)
1892 long entnr = read_long(env);
1893 ir_entity *entity = get_unknown_entity();
1894 set_id(env, entnr, entity);
1897 /** Reads an entity description and remembers it by its id. */
1898 static void read_entity(read_env_t *env, ir_entity_kind kind)
1900 long entnr = read_long(env);
1902 ident *ld_name = NULL;
1903 ir_visibility visibility = ir_visibility_default;
1904 ir_linkage linkage = IR_LINKAGE_DEFAULT;
1905 ir_type *owner = NULL;
1906 ir_entity *entity = NULL;
1907 int compiler_generated;
1908 ir_volatility volatility;
1912 if (kind != IR_ENTITY_LABEL && kind != IR_ENTITY_PARAMETER) {
1913 name = read_ident(env);
1914 ld_name = read_ident_null(env);
1917 visibility = read_visibility(env);
1918 expect_list_begin(env);
1919 while (list_has_next(env)) {
1920 linkage |= read_linkage(env);
1923 type = read_type_ref(env);
1924 if (kind != IR_ENTITY_LABEL)
1925 owner = read_type_ref(env);
1927 compiler_generated = read_long(env) != 0;
1928 volatility = read_volatility(env);
1931 case IR_ENTITY_NORMAL:
1932 entity = new_entity(owner, name, type);
1933 if (ld_name != NULL)
1934 set_entity_ld_ident(entity, ld_name);
1935 str = read_word(env);
1936 if (strcmp(str, "initializer") == 0) {
1937 ir_initializer_t *initializer = read_initializer(env);
1938 if (initializer != NULL)
1939 set_entity_initializer(entity, initializer);
1940 } else if (strcmp(str, "none") == 0) {
1943 parse_error(env, "expected 'initializer' or 'none' got '%s'\n", str);
1946 case IR_ENTITY_COMPOUND_MEMBER:
1947 entity = new_entity(owner, name, type);
1948 if (ld_name != NULL)
1949 set_entity_ld_ident(entity, ld_name);
1950 set_entity_offset(entity, (int) read_long(env));
1951 set_entity_offset_bits_remainder(entity, (unsigned char) read_long(env));
1953 case IR_ENTITY_METHOD:
1954 entity = new_entity(owner, name, type);
1955 if (ld_name != NULL)
1956 set_entity_ld_ident(entity, ld_name);
1958 case IR_ENTITY_PARAMETER: {
1959 char *str = read_word(env);
1960 size_t parameter_number;
1961 if (strcmp(str, "va_start") == 0) {
1962 parameter_number = IR_VA_START_PARAMETER_NUMBER;
1964 parameter_number = atol(str);
1966 obstack_free(&env->obst, str);
1967 entity = new_parameter_entity(owner, parameter_number, type);
1970 case IR_ENTITY_LABEL: {
1971 ir_label_t nr = get_irp_next_label_nr();
1972 entity = new_label_entity(nr);
1974 case IR_ENTITY_UNKNOWN:
1975 panic("read_entity with IR_ENTITY_UNKNOWN?");
1979 set_entity_compiler_generated(entity, compiler_generated);
1980 set_entity_volatility(entity, volatility);
1981 set_entity_visibility(entity, visibility);
1982 set_entity_linkage(entity, linkage);
1984 if (owner != NULL && is_Array_type(owner)) {
1985 set_array_element_entity(owner, entity);
1988 set_id(env, entnr, entity);
1991 /** Parses the whole type graph. */
1992 static void read_typegraph(read_env_t *env)
1994 ir_graph *old_irg = env->irg;
1998 env->irg = get_const_code_irg();
2000 /* parse all types first */
2004 if (env->c == '}') {
2009 kwkind = read_keyword(env);
2016 read_entity(env, IR_ENTITY_NORMAL);
2019 read_entity(env, IR_ENTITY_LABEL);
2022 read_entity(env, IR_ENTITY_METHOD);
2024 case kw_compound_member:
2025 read_entity(env, IR_ENTITY_COMPOUND_MEMBER);
2028 read_entity(env, IR_ENTITY_PARAMETER);
2031 read_unknown_entity(env);
2034 parse_error(env, "type graph element not supported yet: %d\n", kwkind);
2043 * Read a node reference and return the node for it. This assumes that the node
2044 * was previously read. This is fine for all normal nodes.
2045 * (Note: that we "break" loops by having special code for phi, block or anchor
2046 * nodes in place, firm guarantees us that a loop in the graph always contains
2047 * a phi, block or anchor node)
2049 static ir_node *read_node_ref(read_env_t *env)
2051 long nr = read_long(env);
2052 ir_node *node = get_node_or_null(env, nr);
2054 parse_error(env, "node %ld not defined (yet?)\n", nr);
2055 return new_r_Bad(env->irg, mode_ANY);
2060 static int read_preds(read_env_t *env)
2062 expect_list_begin(env);
2063 assert(obstack_object_size(&env->preds_obst) == 0);
2064 while (list_has_next(env)) {
2065 ir_node *pred = read_node_ref(env);
2066 obstack_grow(&env->preds_obst, &pred, sizeof(pred));
2068 return obstack_object_size(&env->preds_obst) / sizeof(ir_node*);
2071 static void read_preds_delayed(read_env_t *env, ir_node *node)
2076 expect_list_begin(env);
2077 assert(obstack_object_size(&env->preds_obst) == 0);
2078 obstack_blank(&env->preds_obst, sizeof(delayed_pred_t));
2079 while (list_has_next(env)) {
2080 long pred_nr = read_long(env);
2081 obstack_grow(&env->preds_obst, &pred_nr, sizeof(pred_nr));
2084 d = (delayed_pred_t*) obstack_finish(&env->preds_obst);
2086 d->n_preds = n_preds;
2088 ARR_APP1(const delayed_pred_t*, env->delayed_preds, d);
2091 static ir_node *read_ASM(read_env_t *env)
2096 ir_asm_constraint *input_constraints = NEW_ARR_F(ir_asm_constraint, 0);
2097 ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0);
2098 ident **clobbers = NEW_ARR_F(ident*, 0);
2099 ir_node *block = read_node_ref(env);
2100 op_pin_state pin_state;
2102 ident *asm_text = read_ident(env);
2104 expect_list_begin(env);
2105 while (list_has_next(env)) {
2106 ir_asm_constraint constraint;
2107 constraint.pos = read_unsigned(env);
2108 constraint.constraint = read_ident(env);
2109 constraint.mode = read_mode_ref(env);
2110 ARR_APP1(ir_asm_constraint, input_constraints, constraint);
2113 expect_list_begin(env);
2114 while (list_has_next(env)) {
2115 ir_asm_constraint constraint;
2116 constraint.pos = read_unsigned(env);
2117 constraint.constraint = read_ident(env);
2118 constraint.mode = read_mode_ref(env);
2119 ARR_APP1(ir_asm_constraint, output_constraints, constraint);
2122 expect_list_begin(env);
2123 while (list_has_next(env)) {
2124 ident *clobber = read_ident(env);
2125 ARR_APP1(ident*, clobbers, clobber);
2128 pin_state = read_pin_state(env);
2130 n_in = read_preds(env);
2131 in = obstack_finish(&env->preds_obst);
2133 if (ARR_LEN(input_constraints) != (size_t)n_in) {
2134 parse_error(env, "input_constraints != n_in in ir file");
2135 return new_r_Bad(env->irg, mode_T);
2138 newnode = new_r_ASM(block, n_in, in,
2139 input_constraints, ARR_LEN(output_constraints),
2140 output_constraints, ARR_LEN(clobbers),
2141 clobbers, asm_text);
2142 set_irn_pinned(newnode, pin_state);
2143 obstack_free(&env->preds_obst, in);
2144 DEL_ARR_F(clobbers);
2145 DEL_ARR_F(output_constraints);
2146 DEL_ARR_F(input_constraints);
2150 static ir_node *read_Phi(read_env_t *env)
2152 ir_node *block = read_node_ref(env);
2153 ir_mode *mode = read_mode_ref(env);
2154 ir_node *res = new_r_Phi(block, 0, NULL, mode);
2155 read_preds_delayed(env, res);
2159 static ir_node *read_Block(read_env_t *env)
2161 ir_node *res = new_r_Block(env->irg, 0, NULL);
2162 read_preds_delayed(env, res);
2166 static ir_node *read_labeled_Block(read_env_t *env)
2168 ir_node *res = new_r_Block(env->irg, 0, NULL);
2169 ir_entity *entity = read_entity_ref(env);
2170 read_preds_delayed(env, res);
2171 set_Block_entity(res, entity);
2175 static ir_node *read_SymConst(read_env_t *env)
2177 ir_mode *mode = read_mode_ref(env);
2178 ir_entity *entity = read_entity_ref(env);
2180 symconst_symbol sym;
2182 sym.entity_p = entity;
2183 res = new_r_SymConst(env->irg, mode, sym, symconst_addr_ent);
2187 static ir_node *read_Anchor(read_env_t *env)
2189 ir_node *res = new_r_Anchor(env->irg);
2190 read_preds_delayed(env, res);
2194 typedef ir_node* (*read_node_func)(read_env_t *env);
2195 static pmap *node_readers;
2197 static void register_node_reader(ident *ident, read_node_func func)
2199 pmap_insert(node_readers, ident, func);
2202 static ir_node *read_node(read_env_t *env)
2204 ident *id = read_symbol(env);
2205 read_node_func func = pmap_get(node_readers, id);
2206 long nr = read_long(env);
2209 parse_error(env, "Unknown nodetype '%s'", get_id_str(id));
2211 res = new_r_Bad(env->irg, mode_ANY);
2215 set_id(env, nr, res);
2219 static void readers_init(void)
2221 assert(node_readers == NULL);
2222 node_readers = pmap_create();
2223 register_node_reader(new_id_from_str("Anchor"), read_Anchor);
2224 register_node_reader(new_id_from_str("ASM"), read_ASM);
2225 register_node_reader(new_id_from_str("Block"), read_Block);
2226 register_node_reader(new_id_from_str("BlockL"), read_labeled_Block);
2227 register_node_reader(new_id_from_str("Phi"), read_Phi);
2228 register_node_reader(new_id_from_str("SymConst"), read_SymConst);
2229 register_generated_node_readers();
2232 static void read_graph(read_env_t *env, ir_graph *irg)
2234 size_t n_delayed_preds;
2238 env->delayed_preds = NEW_ARR_F(const delayed_pred_t*, 0);
2243 if (env->c == '}' || env->c == EOF) {
2251 /* resolve delayed preds */
2252 n_delayed_preds = ARR_LEN(env->delayed_preds);
2253 for (i = 0; i < n_delayed_preds; ++i) {
2254 const delayed_pred_t *dp = env->delayed_preds[i];
2255 ir_node **ins = ALLOCAN(ir_node*, dp->n_preds);
2257 for (i = 0; i < dp->n_preds; ++i) {
2258 long pred_nr = dp->preds[i];
2259 ir_node *pred = get_node_or_null(env, pred_nr);
2261 parse_error(env, "predecessor %ld of a node not defined\n",
2263 goto next_delayed_pred;
2267 set_irn_in(dp->node, dp->n_preds, ins);
2268 if (is_Anchor(dp->node)) {
2270 for (a = anchor_first; a <= anchor_last; ++a) {
2271 ir_node *old_anchor = get_irg_anchor(irg, a);
2272 ir_node *new_anchor = ins[a];
2273 exchange(old_anchor, new_anchor);
2276 next_delayed_pred: ;
2278 DEL_ARR_F(env->delayed_preds);
2279 env->delayed_preds = NULL;
2282 static ir_graph *read_irg(read_env_t *env)
2284 ir_entity *irgent = get_entity(env, read_long(env));
2285 ir_graph *irg = new_ir_graph(irgent, 0);
2286 ir_type *frame = read_type_ref(env);
2287 irg_inline_property prop = read_inline_property(env);
2288 unsigned props = read_unsigned(env);
2289 irg_finalize_cons(irg);
2290 set_irg_frame_type(irg, frame);
2291 set_irg_inline_property(irg, prop);
2292 set_irg_additional_properties(irg, (mtp_additional_properties)props);
2293 read_graph(env, irg);
2297 static void read_modes(read_env_t *env)
2305 if (env->c == '}' || env->c == EOF) {
2310 kwkind = read_keyword(env);
2313 const char *name = read_string(env);
2314 ir_mode_arithmetic arith = read_mode_arithmetic(env);
2315 int size = read_long(env);
2316 int sign = read_long(env);
2317 unsigned modulo_shift = read_long(env);
2318 new_int_mode(name, arith, size, sign, modulo_shift);
2321 case kw_reference_mode: {
2322 const char *name = read_string(env);
2323 ir_mode_arithmetic arith = read_mode_arithmetic(env);
2324 int size = read_long(env);
2325 unsigned modulo_shift = read_long(env);
2326 ir_mode *mode = new_reference_mode(name, arith, size, modulo_shift);
2327 set_reference_mode_signed_eq(mode, read_mode_ref(env));
2328 set_reference_mode_unsigned_eq(mode, read_mode_ref(env));
2329 int is_mode_P = read_int(env);
2331 set_modeP_data(mode);
2332 set_modeP_code(mode);
2336 case kw_float_mode: {
2337 const char *name = read_string(env);
2338 ir_mode_arithmetic arith = read_mode_arithmetic(env);
2339 int exponent_size = read_long(env);
2340 int mantissa_size = read_long(env);
2341 new_float_mode(name, arith, exponent_size, mantissa_size);
2352 static void read_program(read_env_t *env)
2360 if (env->c == '}') {
2365 kwkind = read_keyword(env);
2367 case kw_segment_type: {
2368 ir_segment_t segment = (ir_segment_t) read_enum(env, tt_segment);
2369 ir_type *type = read_type_ref(env);
2370 set_segment_type(segment, type);
2374 ident *text = read_ident(env);
2379 parse_error(env, "unexpected keyword %d\n", kwkind);
2385 int ir_import(const char *filename)
2387 FILE *file = fopen(filename, "rt");
2394 res = ir_import_file(file, filename);
2400 int ir_import_file(FILE *input, const char *inputname)
2403 int oldoptimize = get_optimize();
2404 read_env_t *env = &myenv;
2407 size_t n_delayed_initializers;
2412 memset(env, 0, sizeof(*env));
2413 obstack_init(&env->obst);
2414 obstack_init(&env->preds_obst);
2415 env->idset = new_set(id_cmp, 128);
2416 env->fixedtypes = NEW_ARR_F(ir_type *, 0);
2417 env->inputname = inputname;
2420 env->delayed_initializers = NEW_ARR_F(delayed_initializer_t, 0);
2422 /* read first character */
2434 kw = read_keyword(env);
2441 read_typegraph(env);
2449 ir_graph *constirg = get_const_code_irg();
2450 long bodyblockid = read_long(env);
2451 set_id(env, bodyblockid, constirg->current_block);
2452 read_graph(env, constirg);
2461 parse_error(env, "Unexpected keyword %d at toplevel\n", kw);
2467 n = ARR_LEN(env->fixedtypes);
2468 for (i = 0; i < n; i++)
2469 set_type_state(env->fixedtypes[i], layout_fixed);
2471 DEL_ARR_F(env->fixedtypes);
2473 /* resolve delayed initializers */
2474 n_delayed_initializers = ARR_LEN(env->delayed_initializers);
2475 for (i = 0; i < n_delayed_initializers; ++i) {
2476 const delayed_initializer_t *di = &env->delayed_initializers[i];
2477 ir_node *node = get_node_or_null(env, di->node_nr);
2479 parse_error(env, "node %ld mentioned in an initializer was never defined\n",
2483 assert(di->initializer->kind == IR_INITIALIZER_CONST);
2484 di->initializer->consti.value = node;
2486 DEL_ARR_F(env->delayed_initializers);
2487 env->delayed_initializers = NULL;
2489 del_set(env->idset);
2491 irp_finalize_cons();
2493 set_optimize(oldoptimize);
2495 obstack_free(&env->preds_obst, NULL);
2496 obstack_free(&env->obst, NULL);
2498 pmap_destroy(node_readers);
2499 node_readers = NULL;
2501 return env->read_errors;
2504 #include "gen_irio.inl"