X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firio.c;h=311e3bd2cdefa0cf88263ea0adeeb82f00be880b;hb=5ab45bb586d934d46c6739452ffdde2f3278156b;hp=6f4483ab2b6630858a48089c20fe713dcbf018a8;hpb=a6e674f74ea93c3661f100088db520acb701571f;p=libfirm diff --git a/ir/ir/irio.c b/ir/ir/irio.c index 6f4483ab2..311e3bd2c 100644 --- a/ir/ir/irio.c +++ b/ir/ir/irio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2009 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -35,6 +35,7 @@ #include "irnode_t.h" #include "irprog.h" #include "irgraph_t.h" +#include "irprintf.h" #include "ircons.h" #include "irgmod.h" #include "irflag_t.h" @@ -58,6 +59,7 @@ typedef struct io_env_t int line; ir_type **fixedtypes; struct obstack obst; + ir_graph *irg; } io_env_t; typedef enum typetag_t @@ -296,7 +298,7 @@ static unsigned symbol(const char *str, typetag_t typetag) key.str = str; key.typetag = typetag; - entry = set_find(symtbl, &key, sizeof(key), firm_fnv_hash_str(str) + typetag * 17); + entry = (symbol_t*)set_find(symtbl, &key, sizeof(key), firm_fnv_hash_str(str) + typetag * 17); return entry ? entry->code : SYMERROR; } @@ -305,7 +307,7 @@ static void *get_id(io_env_t *env, long id) id_entry key, *entry; key.id = id; - entry = set_find(env->idset, &key, sizeof(key), (unsigned) id); + entry = (id_entry*)set_find(env->idset, &key, sizeof(key), (unsigned) id); return entry ? entry->elem : NULL; } @@ -317,13 +319,75 @@ static void set_id(io_env_t *env, long id, void *elem) set_insert(env->idset, &key, sizeof(key), (unsigned) id); } +static void write_long(io_env_t *env, long value) +{ + fprintf(env->file, "%ld ", value); +} + +static void write_int(io_env_t *env, int value) +{ + fprintf(env->file, "%d ", value); +} + +static void write_unsigned(io_env_t *env, unsigned value) +{ + fprintf(env->file, "%u ", value); +} + +static void write_entity_ref(io_env_t *env, ir_entity *entity) +{ + write_long(env, get_entity_nr(entity)); +} + +static void write_type_ref(io_env_t *env, ir_type *type) +{ + write_long(env, get_type_nr(type)); +} + +static void write_string(io_env_t *env, const char *string) +{ + const char *c; + fputc('"', env->file); + for (c = string; *c != '\0'; ++c) { + switch (*c) { + case '\n': + fputc('\\', env->file); + fputc('n', env->file); + break; + case '"': + case '\\': + fputc('\\', env->file); + /* FALLTHROUGH */ + default: + fputc(*c, env->file); + break; + } + } + fputc('"', env->file); +} + +static void write_ident(io_env_t *env, ident *id) +{ + write_string(env, get_id_str(id)); + fputc(' ', env->file); +} + +static void write_ident_null(io_env_t *env, ident *id) +{ + if (id == NULL) { + fputs("NULL ", env->file); + } else { + write_ident(env, id); + } +} + static void write_mode(io_env_t *env, ir_mode *mode) { - fputs(get_mode_name(mode), env->file); + write_string(env, get_mode_name(mode)); fputc(' ', env->file); } -static void write_tarval(io_env_t *env, tarval *tv) +static void write_tarval(io_env_t *env, ir_tarval *tv) { char buf[1024]; write_mode(env, get_tarval_mode(tv)); @@ -332,17 +396,8 @@ static void write_tarval(io_env_t *env, tarval *tv) fputc(' ', env->file); } -static void write_align(io_env_t *env, ir_node *irn) +static void write_align(io_env_t *env, ir_align align) { - ir_align align; - - if (is_Load(irn)) - align = get_Load_align(irn); - else if (is_Store(irn)) - align = get_Store_align(irn); - else - panic("Invalid optype for write_align"); - fputs(get_align_name(align), env->file); fputc(' ', env->file); } @@ -359,6 +414,16 @@ static void write_cond_jmp_predicate(io_env_t *env, ir_node *irn) fputc(' ', env->file); } +static void write_list_begin(io_env_t *env) +{ + fputs("[", env->file); +} + +static void write_list_end(io_env_t *env) +{ + fputs("] ", env->file); +} + static void write_initializer(io_env_t *env, ir_initializer_t *ini) { FILE *f = env->file; @@ -369,7 +434,7 @@ static void write_initializer(io_env_t *env, ir_initializer_t *ini) switch (ini_kind) { case IR_INITIALIZER_CONST: - fprintf(f, "%ld ", get_irn_node_nr(get_initializer_const_value(ini))); + write_long(env, get_irn_node_nr(get_initializer_const_value(ini))); break; case IR_INITIALIZER_TARVAL: @@ -380,9 +445,9 @@ static void write_initializer(io_env_t *env, ir_initializer_t *ini) break; case IR_INITIALIZER_COMPOUND: { - unsigned i, n = get_initializer_compound_n_entries(ini); - fprintf(f, "%u ", n); - for (i = 0; i < n; i++) + size_t i, n = get_initializer_compound_n_entries(ini); + ir_fprintf(f, "%zu ", n); + for (i = 0; i < n; ++i) write_initializer(env, get_initializer_compound_value(ini, i)); break; } @@ -398,17 +463,8 @@ static void write_pin_state(io_env_t *env, ir_node *irn) fputc(' ', env->file); } -static void write_volatility(io_env_t *env, ir_node *irn) +static void write_volatility(io_env_t *env, ir_volatility vol) { - ir_volatility vol; - - if (is_Load(irn)) - vol = get_Load_volatility(irn); - else if (is_Store(irn)) - vol = get_Store_volatility(irn); - else - panic("Invalid optype for write_volatility"); - fputs(get_volatility_name(vol), env->file); fputc(' ', env->file); } @@ -424,16 +480,6 @@ static void export_type_common(io_env_t *env, ir_type *tp) tp->flags); } -static void export_compound_name(FILE *f, const ir_type *tp) -{ - ident *name = get_compound_ident(tp); - if (name == NULL) { - fputs("NULL ", f); - } else { - fprintf(f, "\"%s\" ", get_id_str(name)); - } -} - static void export_type_pre(io_env_t *env, ir_type *tp) { FILE *f = env->file; @@ -455,7 +501,7 @@ static void export_type_pre(io_env_t *env, ir_type *tp) panic("invalid type found"); case tpo_class: - export_compound_name(f, tp); + write_ident_null(env, get_compound_ident(tp)); break; case tpo_primitive: @@ -465,7 +511,7 @@ static void export_type_pre(io_env_t *env, ir_type *tp) case tpo_union: case tpo_struct: case tpo_enumeration: - export_compound_name(f, tp); + write_ident_null(env, get_compound_ident(tp)); break; case tpo_array: @@ -482,7 +528,7 @@ static void export_type_pre(io_env_t *env, ir_type *tp) static void export_type_post(io_env_t *env, ir_type *tp) { FILE *f = env->file; - int i; + size_t i; /* skip types already handled by pre walker */ switch (get_type_tpop_code(tp)) { @@ -506,19 +552,19 @@ static void export_type_post(io_env_t *env, ir_type *tp) switch (get_type_tpop_code(tp)) { case tpo_array: { - int n = get_array_n_dimensions(tp); - fprintf(f, "%d %ld ", n, get_type_nr(get_array_element_type(tp))); + size_t n = get_array_n_dimensions(tp); + ir_fprintf(f, "%zu %ld ", n, get_type_nr(get_array_element_type(tp))); for (i = 0; i < n; i++) { ir_node *lower = get_array_lower_bound(tp, i); ir_node *upper = get_array_upper_bound(tp, i); if (is_Const(lower)) - fprintf(f, "%ld ", get_tarval_long(get_Const_tarval(lower))); + write_long(env, get_tarval_long(get_Const_tarval(lower))); else panic("Lower array bound is not constant"); if (is_Const(upper)) - fprintf(f, "%ld ", get_tarval_long(get_Const_tarval(upper))); + write_long(env, get_tarval_long(get_Const_tarval(upper))); else if (is_Unknown(upper)) fputs("unknown ", f); else @@ -528,21 +574,21 @@ static void export_type_post(io_env_t *env, ir_type *tp) } case tpo_method: { - int nparams = get_method_n_params(tp); - int nresults = get_method_n_ress(tp); - fprintf(f, "%u %u %d %d ", get_method_calling_convention(tp), + size_t nparams = get_method_n_params(tp); + size_t nresults = get_method_n_ress(tp); + ir_fprintf(f, "%u %u %zu %zu ", get_method_calling_convention(tp), get_method_additional_properties(tp), nparams, nresults); for (i = 0; i < nparams; i++) - fprintf(f, "%ld ", get_type_nr(get_method_param_type(tp, i))); + write_long(env, get_type_nr(get_method_param_type(tp, i))); for (i = 0; i < nresults; i++) - fprintf(f, "%ld ", get_type_nr(get_method_res_type(tp, i))); - fprintf(f, "%d ", get_method_first_variadic_param_index(tp)); + write_long(env, get_type_nr(get_method_res_type(tp, i))); + ir_fprintf(f, "%u ", get_method_variadicity(tp)); break; } case tpo_pointer: write_mode(env, get_type_mode(tp)); - fprintf(f, "%ld ", get_type_nr(get_pointer_points_to_type(tp))); + write_long(env, get_type_nr(get_pointer_points_to_type(tp))); break; case tpo_enumeration: @@ -570,12 +616,13 @@ static void export_entity(io_env_t *env, ir_entity *ent) if (is_Array_type(owner)) return; - fprintf(env->file, "\tentity %ld \"%s\" ", - get_entity_nr(ent), get_entity_name(ent)); - if (ent->ld_name != NULL) { - fprintf(env->file, "\"%s\" ", get_entity_ld_name(ent)); + fprintf(env->file, "\tentity "); + write_long(env, get_entity_nr(ent)); + write_ident_null(env, get_entity_ident(ent)); + if (!entity_has_ld_ident(ent)) { + write_ident_null(env, NULL); } else { - fprintf(env->file, "NULL "); + write_ident_null(env, get_entity_ld_ident(ent)); } /* visibility + linkage */ @@ -605,9 +652,9 @@ static void export_entity(io_env_t *env, ir_entity *ent) fputs("initializer ", env->file); write_initializer(env, get_entity_initializer(ent)); } else if (entity_has_compound_ent_values(ent)) { - int i, n = get_compound_ent_n_values(ent); + size_t i, n = get_compound_ent_n_values(ent); fputs("compoundgraph ", env->file); - fprintf(env->file, "%d ", n); + ir_fprintf(env->file, "%zu ", n); for (i = 0; i < n; i++) { ir_entity *member = get_compound_ent_value_member(ent, i); ir_node *irn = get_compound_ent_value(ent, i); @@ -642,10 +689,46 @@ static void export_type_or_ent_post(type_or_ent tore, void *ctx) default: panic("export_type_or_ent_post: Unknown type or entity."); - break; } } +static void export_ASM(io_env_t *env, ir_node *node) +{ + ir_asm_constraint *input_constraints = get_ASM_input_constraints(node); + ir_asm_constraint *output_constraints = get_ASM_output_constraints(node); + ident **clobbers = get_ASM_clobbers(node); + int n_input_constraints = get_ASM_n_input_constraints(node); + int n_output_constraints = get_ASM_n_output_constraints(node); + int n_clobbers = get_ASM_n_clobbers(node); + int i; + + write_ident(env, get_ASM_text(node)); + write_list_begin(env); + for (i = 0; i < n_input_constraints; ++i) { + const ir_asm_constraint *constraint = &input_constraints[i]; + write_unsigned(env, constraint->pos); + write_ident(env, constraint->constraint); + write_mode(env, constraint->mode); + } + write_list_end(env); + + write_list_begin(env); + for (i = 0; i < n_output_constraints; ++i) { + const ir_asm_constraint *constraint = &output_constraints[i]; + write_unsigned(env, constraint->pos); + write_ident(env, constraint->constraint); + write_mode(env, constraint->mode); + } + write_list_end(env); + + write_list_begin(env); + for (i = 0; i < n_clobbers; ++i) { + ident *clobber = clobbers[i]; + write_ident(env, clobber); + } + write_list_end(env); +} + /** * Walker: exports every node. */ @@ -658,24 +741,52 @@ static void export_node(ir_node *irn, void *ctx) if (env->ignoreblocks && opcode == iro_Block) return; - fprintf(env->file, "\t%s %ld [ ", get_irn_opname(irn), get_irn_node_nr(irn)); + fprintf(env->file, "\t%s ", get_irn_opname(irn)); + write_long(env, get_irn_node_nr(irn)); + write_list_begin(env); n = get_irn_arity(irn); - for (i = -1; i < n; i++) { + if (!is_Block(irn)) { + ir_node *block = get_nodes_block(irn); + write_long(env, get_irn_node_nr(block)); + } + + for (i = 0; i < n; i++) { ir_node *pred = get_irn_n(irn, i); if (pred == NULL) { /* Anchor node may have NULL predecessors */ assert(is_Anchor(irn)); fputs("-1 ", env->file); } else { - fprintf(env->file, "%ld ", get_irn_node_nr(pred)); + write_long(env, get_irn_node_nr(pred)); } } + write_list_end(env); - fprintf(env->file, "] { "); + fputs("{ ", env->file); - switch (opcode) { - #include "gen_irio_export.inl" + switch (opcode) { + case iro_Start: + case iro_End: + case iro_Block: + case iro_Anchor: + break; + case iro_SymConst: + /* TODO: only symconst_addr_ent implemented yet */ + assert(get_SymConst_kind(irn) == symconst_addr_ent); + fprintf(env->file, "%ld ", get_entity_nr(get_SymConst_entity(irn))); + write_mode(env, get_irn_mode(irn)); + break; + case iro_Proj: + write_mode(env, get_irn_mode(irn)); + fprintf(env->file, "%ld ", get_Proj_proj(irn)); + break; + case iro_ASM: + export_ASM(env, irn); + break; +#include "gen_irio_export.inl" + default: + panic("no export code for node %+F\n", irn); } fputs("}\n", env->file); } @@ -696,7 +807,7 @@ static const char *get_mode_sort_name(ir_mode_sort sort) static void export_modes(io_env_t *env) { - int i, n_modes = get_irp_n_modes(); + size_t i, n_modes = get_irp_n_modes(); fputs("modes {\n", env->file); @@ -713,8 +824,10 @@ static void export_modes(io_env_t *env) break; } - fprintf(env->file, "\tmode \"%s\" %s %u %d %s %u %u ", - get_mode_name(mode), get_mode_sort_name(get_mode_sort(mode)), + fprintf(env->file, "\tmode "); + write_string(env, get_mode_name(mode)); + fprintf(env->file, "%s %u %d %s %u %u ", + get_mode_sort_name(get_mode_sort(mode)), get_mode_size_bits(mode), get_mode_sign(mode), get_mode_arithmetic_name(get_mode_arithmetic(mode)), get_mode_modulo_shift(mode), @@ -722,6 +835,7 @@ static void export_modes(io_env_t *env) if (mode_is_reference(mode)) { write_mode(env, get_reference_mode_signed_eq(mode)); write_mode(env, get_reference_mode_unsigned_eq(mode)); + write_int(env, (mode == mode_P ? 1 : 0)); } fputc('\n', env->file); } @@ -736,21 +850,19 @@ static void export_program(io_env_t *env) fputs("\nprogram {\n", f); if (irp_prog_name_is_set()) { - fprintf(f, "\tname \"%s\"\n", get_irp_name()); + fprintf(f, "\tname "); + write_string(env, get_irp_name()); + fputc('\n', f); } - /* We need numbers for irgs... */ -#if 0 - if (get_irp_main_irg() != NULL) { - fprintf(f, "\tmain_irg %d\n", get_irp_main_irg -#endif - for (s = 0; s <= IR_SEGMENT_LAST; ++s) { + for (s = IR_SEGMENT_FIRST; s <= IR_SEGMENT_LAST; ++s) { ir_type *segment_type = get_segment_type(s); - fprintf(f, "\tsegment_type %s", get_segment_name(s)); + fprintf(f, "\tsegment_type %s ", get_segment_name(s)); if (segment_type == NULL) { fputs(" NULL\n", f); } else { - fprintf(f, " %ld\n", get_type_nr(segment_type)); + write_long(env, get_type_nr(segment_type)); + fputc('\n', f); } } fputs("}\n", f); @@ -772,7 +884,7 @@ void ir_export(const char *filename) void ir_export_file(FILE *file, const char *outputname) { io_env_t env; - int i, n_irgs = get_irp_n_irgs(); + size_t i, n_irgs = get_irp_n_irgs(); (void) outputname; env.file = file; @@ -785,12 +897,10 @@ void ir_export_file(FILE *file, const char *outputname) for (i = 0; i < n_irgs; i++) { ir_graph *irg = get_irp_irg(i); - ir_type *valuetype = get_irg_value_param_type(irg); - fprintf(env.file, "\nirg %ld %ld %ld {\n", + fprintf(env.file, "\nirg %ld %ld {\n", get_entity_nr(get_irg_entity(irg)), - get_type_nr(get_irg_frame_type(irg)), - valuetype == NULL ? -1 : get_type_nr(valuetype)); + get_type_nr(get_irg_frame_type(irg))); env.ignoreblocks = 0; irg_block_walk_graph(irg, NULL, export_node, &env); @@ -908,50 +1018,62 @@ static char *read_word(io_env_t *env) endofword: obstack_1grow(&env->obst, '\0'); - return obstack_finish(&env->obst); + return (char*)obstack_finish(&env->obst); } -static char *read_quoted_string(io_env_t *env) +static char *read_string(io_env_t *env) { skip_ws(env); - if (env->c != '\"') { - parse_error(env, "Expected '\"', found '%c'\n", env->c); + if (env->c != '"') { + parse_error(env, "Expected string, got '%c'\n", env->c); exit(1); } read_c(env); assert(obstack_object_size(&env->obst) == 0); - while (true) { - int ch = env->c; - if (ch == EOF) { - parse_error(env, "Unexpected end of quoted string!\n"); + while (env->c != '"') { + if (env->c == EOF) { + parse_error(env, "Unexpected EOF while parsing string\n"); exit(1); } - if (ch == '\"') { + + if (env->c == '\\') { read_c(env); - break; + switch (env->c) { + case 'n': + obstack_1grow(&env->obst, '\n'); + break; + case '"': + case '\\': + obstack_1grow(&env->obst, env->c); + break; + default: + parse_error(env, "Unknown escape sequence '\\%c'\n", env->c); + exit(1); + } + } else { + obstack_1grow(&env->obst, env->c); } - obstack_1grow(&env->obst, ch); read_c(env); } - obstack_1grow(&env->obst, '\0'); + read_c(env); + obstack_1grow(&env->obst, 0); - return obstack_finish(&env->obst); + return (char*)obstack_finish(&env->obst); } static ident *read_ident(io_env_t *env) { - char *str = read_quoted_string(env); + char *str = read_string(env); ident *res = new_id_from_str(str); obstack_free(&env->obst, str); - return res; } /* * reads a "quoted string" or alternatively the token NULL */ -static char *read_quoted_string_null(io_env_t *env) +static char *read_string_null(io_env_t *env) { skip_ws(env); if (env->c == 'N') { @@ -961,7 +1083,7 @@ static char *read_quoted_string_null(io_env_t *env) return NULL; } } else if (env->c == '"') { - return read_quoted_string(env); + return read_string(env); } parse_error(env, "Expected \"string\" or NULL\n"); @@ -971,7 +1093,7 @@ static char *read_quoted_string_null(io_env_t *env) static ident *read_ident_null(io_env_t *env) { ident *res; - char *str = read_quoted_string_null(env); + char *str = read_string_null(env); if (str == NULL) return NULL; @@ -998,13 +1120,54 @@ static long read_long(io_env_t *env) } while (isdigit(env->c)); obstack_1grow(&env->obst, 0); - str = obstack_finish(&env->obst); + str = (char*)obstack_finish(&env->obst); result = atol(str); obstack_free(&env->obst, str); return result; } +static int read_int(io_env_t *env) +{ + return (int) read_long(env); +} + +static unsigned read_unsigned(io_env_t *env) +{ + return (unsigned) read_long(env); +} + +static size_t read_size_t(io_env_t *env) +{ + /* FIXME */ + return (size_t) read_unsigned(env); +} + +static void expect_list_begin(io_env_t *env) +{ + skip_ws(env); + if (env->c != '[') { + parse_error(env, "Expected list, got '%c'\n", env->c); + exit(1); + } + read_c(env); +} + +static bool list_has_next(io_env_t *env) +{ + if (feof(env->file)) { + parse_error(env, "Unexpected EOF while reading list"); + exit(1); + } + skip_ws(env); + if (env->c == ']') { + read_c(env); + return false; + } + + return true; +} + static ir_node *get_node_or_null(io_env_t *env, long nodenr) { ir_node *node = (ir_node *) get_id(env, nodenr); @@ -1015,20 +1178,11 @@ static ir_node *get_node_or_null(io_env_t *env, long nodenr) return node; } -static ir_node *get_node(io_env_t *env, long nodenr) -{ - ir_node *node = get_node_or_null(env, nodenr); - if (!node) - panic("Unknown node: %ld in line %d\n", nodenr, env->line); - - return node; -} - static ir_node *get_node_or_dummy(io_env_t *env, long nodenr) { ir_node *node = get_node_or_null(env, nodenr); if (node == NULL) { - node = new_Dummy(mode_X); + node = new_r_Dummy(env->irg, mode_X); set_id(env, nodenr, node); } return node; @@ -1071,8 +1225,8 @@ static ir_entity *read_entity(io_env_t *env) static ir_mode *read_mode(io_env_t *env) { - char *str = read_word(env); - int i, n; + char *str = read_string(env); + size_t i, n; n = get_irp_n_modes(); for (i = 0; i < n; i++) { @@ -1139,32 +1293,11 @@ static unsigned read_enum(io_env_t *env, typetag_t typetag) #define read_variability(env) ((ir_variability) read_enum(env, tt_variability)) #define read_volatility(env) ((ir_volatility) read_enum(env, tt_volatility)) -static ir_cons_flags get_cons_flags(io_env_t *env) +static ir_tarval *read_tv(io_env_t *env) { - ir_cons_flags flags = cons_none; - - op_pin_state pinstate = read_pin_state(env); - switch (pinstate) { - case op_pin_state_floats: flags |= cons_floats; break; - case op_pin_state_pinned: break; - default: - panic("Error in %d: Invalid pinstate: %s", env->line, - get_op_pin_state_name(pinstate)); - } - - if (read_volatility(env) == volatility_is_volatile) - flags |= cons_volatile; - if (read_align(env) == align_non_aligned) - flags |= cons_unaligned; - - return flags; -} - -static tarval *read_tv(io_env_t *env) -{ - ir_mode *tvmode = read_mode(env); - char *str = read_word(env); - tarval *tv = new_tarval_from_str(str, strlen(str), tvmode); + ir_mode *tvmode = read_mode(env); + char *str = read_word(env); + ir_tarval *tv = new_tarval_from_str(str, strlen(str), tvmode); obstack_free(&env->obst, str); return tv; @@ -1187,7 +1320,7 @@ static ir_initializer_t *read_initializer(io_env_t *env) return get_initializer_null(); case IR_INITIALIZER_COMPOUND: { - unsigned i, n = (unsigned) read_long(env); + size_t i, n = read_size_t(env); ir_initializer_t *ini = create_initializer_compound(n); for (i = 0; i < n; i++) { ir_initializer_t *curini = read_initializer(env); @@ -1241,8 +1374,7 @@ static void import_type(io_env_t *env) } case tpo_class: { - const char *name = read_quoted_string_null(env); - ident *id = name != NULL ? new_id_from_str(name) : NULL; + ident *id = read_ident_null(env); if (typenr == (long) IR_SEGMENT_GLOBAL) type = get_glob_type(); @@ -1253,33 +1385,29 @@ static void import_type(io_env_t *env) } case tpo_method: { - unsigned callingconv = (unsigned) read_long(env); - unsigned addprops = (unsigned) read_long(env); + unsigned callingconv = (unsigned) read_long(env); + mtp_additional_properties addprops = (mtp_additional_properties) read_long(env); int nparams = (int) read_long(env); int nresults = (int) read_long(env); - int variaindex; + int variadicity; type = new_type_method(nparams, nresults); for (i = 0; i < nparams; i++) { - long typenr = read_long(env); - ir_type *paramtype = get_type(env, typenr); + long ptypenr = read_long(env); + ir_type *paramtype = get_type(env, ptypenr); set_method_param_type(type, i, paramtype); } for (i = 0; i < nresults; i++) { - long typenr = read_long(env); - ir_type *restype = get_type(env, typenr); + long ptypenr = read_long(env); + ir_type *restype = get_type(env, ptypenr); set_method_res_type(type, i, restype); } - variaindex = (int) read_long(env); - if (variaindex != -1) { - set_method_variadicity(type, variadicity_variadic); - if (variaindex != nparams) - set_method_first_variadic_param_index(type, variaindex); - } + variadicity = (int) read_long(env); + set_method_variadicity(type, variadicity); set_method_calling_convention(type, callingconv); set_method_additional_properties(type, addprops); @@ -1301,17 +1429,14 @@ static void import_type(io_env_t *env) } case tpo_struct: { - const char *name = read_quoted_string_null(env); - ident *id = name != NULL ? new_id_from_str(name) : NULL; + ident *id = read_ident_null(env); type = new_type_struct(id); set_type_size_bytes(type, size); break; } case tpo_union: { - const char *name = read_quoted_string_null(env); - ident *id = name != NULL ? new_id_from_str(name) : NULL; - + ident *id = read_ident_null(env); type = new_type_union(id); set_type_size_bytes(type, size); break; @@ -1352,23 +1477,23 @@ static void import_entity(io_env_t *env) skip_ws(env); while (!isdigit(env->c)) { - char *str = read_word(env); + char *vstr = read_word(env); unsigned v; skip_ws(env); - v = symbol(str, tt_visibility); + v = symbol(vstr, tt_visibility); if (v != SYMERROR) { - visibility = v; + visibility = (ir_visibility)v; continue; } - v = symbol(str, tt_linkage); + v = symbol(vstr, tt_linkage); if (v != SYMERROR) { - linkage |= v; + linkage |= (ir_linkage)v; continue; } printf("Parser error, expected visibility or linkage, got '%s'\n", - str); + vstr); break; } @@ -1412,11 +1537,12 @@ static void import_entity(io_env_t *env) /** Parses the whole type graph. */ static int parse_typegraph(io_env_t *env) { + ir_graph *old_irg = env->irg; keyword_t kwkind; EXPECT('{'); - current_ir_graph = get_const_code_irg(); + env->irg = get_const_code_irg(); /* parse all types first */ while (true) { @@ -1442,10 +1568,11 @@ static int parse_typegraph(io_env_t *env) break; } } + env->irg = old_irg; return 1; } -static int read_node_header(io_env_t *env, long *nodenr, long **preds, +static int read_node_header(io_env_t *env, long *nodenr, ir_node ***preds, const char **nodename) { int numpreds; @@ -1453,35 +1580,76 @@ static int read_node_header(io_env_t *env, long *nodenr, long **preds, *nodename = read_word(env); *nodenr = read_long(env); - ARR_RESIZE(ir_node *, *preds, 0); - - EXPECT('['); - for (numpreds = 0; !feof(env->file); numpreds++) { - long val; + ARR_RESIZE(ir_node*, *preds, 0); - skip_ws(env); - if (env->c == ']') { - read_c(env); - break; - } - val = read_long(env); - ARR_APP1(long, *preds, val); + expect_list_begin(env); + for (numpreds = 0; list_has_next(env); numpreds++) { + long val = read_long(env); + ir_node *pred = get_node_or_dummy(env, val); + ARR_APP1(ir_node*, *preds, pred); } return numpreds; } +static ir_node *read_ASM(io_env_t *env, int numpreds, ir_node **preds) +{ + ir_node *newnode; + ir_asm_constraint *input_constraints = NEW_ARR_F(ir_asm_constraint, 0); + ir_asm_constraint *output_constraints = NEW_ARR_F(ir_asm_constraint, 0); + ident **clobbers = NEW_ARR_F(ident*, 0); + + ident *asm_text = read_ident(env); + + expect_list_begin(env); + while (list_has_next(env)) { + ir_asm_constraint constraint; + constraint.pos = read_unsigned(env); + constraint.constraint = read_ident(env); + constraint.mode = read_mode(env); + ARR_APP1(ir_asm_constraint, input_constraints, constraint); + } + + expect_list_begin(env); + while (list_has_next(env)) { + ir_asm_constraint constraint; + constraint.pos = read_unsigned(env); + constraint.constraint = read_ident(env); + constraint.mode = read_mode(env); + ARR_APP1(ir_asm_constraint, output_constraints, constraint); + } + + expect_list_begin(env); + while (list_has_next(env)) { + ident *clobber = read_ident(env); + ARR_APP1(ident*, clobbers, clobber); + } + + assert(ARR_LEN(input_constraints) == (size_t)numpreds-1); + + newnode = new_r_ASM(preds[0], numpreds-1, preds+1, + input_constraints, + ARR_LEN(output_constraints), + output_constraints, + ARR_LEN(clobbers), + clobbers, + asm_text); + DEL_ARR_F(clobbers); + DEL_ARR_F(output_constraints); + DEL_ARR_F(input_constraints); + return newnode; +} + /** Parses an IRG. */ static int parse_graph(io_env_t *env, ir_graph *irg) { - long *preds = NEW_ARR_F(long, 16); - ir_node **prednodes = NEW_ARR_F(ir_node *, 16); + ir_node **preds = NEW_ARR_F(ir_node*,0); int i, numpreds, ret = 1; long nodenr; const char *nodename; ir_node *node, *newnode; - current_ir_graph = irg; + env->irg = irg; EXPECT('{'); @@ -1493,17 +1661,6 @@ static int parse_graph(io_env_t *env, ir_graph *irg) } numpreds = read_node_header(env, &nodenr, &preds, &nodename); - if (numpreds == -1) break; /* end-of-graph */ - if (!numpreds) { - parse_error(env, "node %s %ld is missing predecessors!", - nodename, nodenr); - ret = 0; - break; - } - - ARR_RESIZE(ir_node *, prednodes, numpreds); - for (i = 0; i < numpreds - 1; i++) - prednodes[i] = get_node_or_dummy(env, preds[i + 1]); node = get_node_or_null(env, nodenr); newnode = NULL; @@ -1511,53 +1668,56 @@ static int parse_graph(io_env_t *env, ir_graph *irg) EXPECT('{'); switch (symbol(nodename, tt_iro)) { - case iro_End: - { - ir_node *newendblock = get_node(env, preds[0]); - newnode = get_irg_end(current_ir_graph); + case iro_End: { + ir_node *newendblock = preds[0]; + newnode = get_irg_end(irg); exchange(get_nodes_block(newnode), newendblock); - for (i = 0; i < numpreds - 1; i++) - add_irn_n(newnode, prednodes[i]); + for (i = 1; i < numpreds; i++) + add_irn_n(newnode, preds[i]); break; } - case iro_Start: - { - ir_node *newstartblock = get_node(env, preds[0]); - newnode = get_irg_start(current_ir_graph); + case iro_Start: { + ir_node *newstartblock = preds[0]; + newnode = get_irg_start(irg); exchange(get_nodes_block(newnode), newstartblock); break; } case iro_Block: - { - if (preds[0] != nodenr) { - parse_error(env, "invalid block: preds[0] != nodenr (%ld != %ld)\n", - preds[0], nodenr); - ret = 0; - goto endloop; - } - - newnode = new_Block(numpreds - 1, prednodes); + newnode = new_r_Block(irg, numpreds, preds); break; - } case iro_Anchor: - newnode = current_ir_graph->anchor; - for (i = 0; i < numpreds - 1; i++) - set_irn_n(newnode, i, prednodes[i]); - set_irn_n(newnode, -1, get_node(env, preds[0])); + newnode = irg->anchor; + for (i = 1; i < numpreds; i++) + set_irn_n(newnode, i-1, preds[i]); + set_nodes_block(newnode, preds[0]); break; - case iro_SymConst: - { + case iro_SymConst: { long entnr = read_long(env); union symconst_symbol sym; sym.entity_p = get_entity(env, entnr); - newnode = new_SymConst(mode_P, sym, symconst_addr_ent); + ir_mode *mode = read_mode(env); + newnode = new_r_SymConst(irg, mode, sym, symconst_addr_ent); + break; + } + + case iro_Proj: { + ir_mode *mode = read_mode(env); + long pn = read_long(env); + newnode = new_r_Proj(preds[1], mode, pn); + /* explicitely set block, since preds[1] might be a dummy node + * which is always in the startblock */ + set_nodes_block(newnode, preds[0]); break; } + case iro_ASM: + newnode = read_ASM(env, numpreds, preds); + break; + #include "gen_irio_import.inl" default: @@ -1578,9 +1738,7 @@ notsupported: set_id(env, nodenr, newnode); } -endloop: DEL_ARR_F(preds); - DEL_ARR_F(prednodes); return ret; } @@ -1601,8 +1759,8 @@ static int parse_modes(io_env_t *env) kwkind = (keyword_t) read_enum(env, tt_keyword); switch (kwkind) { case kw_mode: { - const char *name = read_quoted_string(env); - ir_mode_sort sort = read_enum(env, tt_mode_sort); + const char *name = read_string(env); + ir_mode_sort sort = (ir_mode_sort)read_enum(env, tt_mode_sort); int size = read_long(env); int sign = read_long(env); ir_mode_arithmetic arith = read_mode_arithmetic(env); @@ -1618,6 +1776,11 @@ static int parse_modes(io_env_t *env) if (mode_is_reference(mode)) { set_reference_mode_signed_eq(mode, read_mode(env)); set_reference_mode_unsigned_eq(mode, read_mode(env)); + int is_mode_P = read_int(env); + if (is_mode_P) { + set_modeP_data(mode); + set_modeP_code(mode); + } } break; } @@ -1678,7 +1841,7 @@ void ir_import_file(FILE *input, const char *inputname) firm_verification_t oldver = get_node_verification_mode(); io_env_t ioenv; io_env_t *env = &ioenv; - int i, n; + size_t i, n; symtbl_init(); @@ -1703,7 +1866,7 @@ void ir_import_file(FILE *input, const char *inputname) if (env->c == EOF) break; - kw = read_enum(env, tt_keyword); + kw = (keyword_t)read_enum(env, tt_keyword); switch (kw) { case kw_modes: if (!parse_modes(env)) goto end; @@ -1716,14 +1879,8 @@ void ir_import_file(FILE *input, const char *inputname) case kw_irg: { ir_entity *irgent = get_entity(env, read_long(env)); - long valuetypeid; ir_graph *irg = new_ir_graph(irgent, 0); set_irg_frame_type(irg, get_type(env, read_long(env))); - valuetypeid = read_long(env); - if (valuetypeid != -1) - set_method_value_param_type(get_entity_type(irgent), - get_type(env, valuetypeid)); - if (!parse_graph(env, irg)) goto end; break; }