X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbegnuas.c;h=c2b87bf197f4f531369b888790d00f2ac95be19a;hb=bd31a5350ce9e110c058b4ad2223d460c9eb5c4e;hp=7269b3fe8f53ea01182960e9d692a3a57e047d40;hpb=19de422b80ac543c0160fd1130266e52f1047550;p=libfirm diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c index 7269b3fe8..c2b87bf19 100644 --- a/ir/be/begnuas.c +++ b/ir/be/begnuas.c @@ -90,11 +90,11 @@ static const char *get_section_name(be_gas_section_t section) { * @param env the emitter environment * @param section the section to switch to */ -void be_gas_emit_switch_section(be_emit_env_t *env, be_gas_section_t section) { - be_emit_char(env, '\t'); - be_emit_string(env, get_section_name(section)); - be_emit_char(env, '\n'); - be_emit_write_line(env); +void be_gas_emit_switch_section(be_gas_section_t section) { + be_emit_char('\t'); + be_emit_string(get_section_name(section)); + be_emit_char('\n'); + be_emit_write_line(); } /** @@ -168,10 +168,24 @@ static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes) } } +/** + * Return the label prefix for labeled blocks. + */ +const char *be_gas_label_prefix(void) { + return ".LG"; +} + +/** + * Dump a label. + */ +static void dump_label(obstack_t *obst, ir_label_t label) { + obstack_printf(obst, "%s%ld", be_gas_label_prefix(), label); +} + /** * Return the tarval of an atomic initializer. * - * @param init a node representing the initializer (on teh const code irg) + * @param init a node representing the initializer (on the const code irg) * * @return the tarval */ @@ -207,6 +221,9 @@ static tarval *get_atomic_init_tv(ir_node *init) case symconst_enum_const: return get_enumeration_value(get_SymConst_enum(init)); + case symconst_label: + return NULL; + default: return NULL; } @@ -230,6 +247,7 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, obstack_t *obst, ir_mode *mode = get_irn_mode(init); int bytes = get_mode_size_bytes(mode); tarval *tv; + ir_label_t label; ir_entity *ent; switch (get_irn_opcode(init)) { @@ -288,6 +306,11 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, obstack_t *obst, dump_arith_tarval(obst, tv, bytes); break; + case symconst_label: + label = get_SymConst_label(init); + dump_label(obst, label); + break; + default: assert(!"dump_atomic_init(): don't know how to init from this SymConst"); } @@ -537,32 +560,33 @@ static void dump_compound_init(be_gas_decl_env_t *env, obstack_t *obst, if (offset_bits != 0 || (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) { - tarval *shift, *shifted; tarval *tv = get_atomic_init_tv(value); + unsigned char curr_bits, last_bits = 0; if (tv == NULL) { panic("Couldn't get numeric value for bitfield initializer '%s'\n", get_entity_ld_name(ent)); } - tv = tarval_convert_to(tv, mode_Lu); - shift = new_tarval_from_long(offset_bits, mode_Is); - shifted = tarval_shl(tv, shift); - if (shifted == tarval_bad || shifted == tarval_undefined) { - panic("Couldn't shift numeric value for bitfield initializer '%s'\n", - get_entity_ld_name(ent)); - } + /* normalize offset */ + offset += offset_bits >> 3; + offset_bits &= 7; - for (j = 0; value_len > 0; ++j) { + for (j = 0; value_len + offset_bits > 0; ++j) { assert(offset + j < last_ofs); assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL); vals[offset + j].kind = BITFIELD; - vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j); - value_len -= 8 - offset_bits; - offset_bits = 0; + curr_bits = get_tarval_sub_bits(tv, j); + vals[offset + j].v.bf_val |= (last_bits >> (8 - offset_bits)) | (curr_bits << offset_bits); + value_len -= 8; + last_bits = curr_bits; } } else { + int i; + assert(offset < last_ofs); assert(vals[offset].kind == NORMAL); - assert(vals[offset].v.value == NULL); + for (i = 1; i < value_len / 8; ++i) { + assert(vals[offset + i].v.value == NULL); + } vals[offset].v.value = value; } } @@ -583,7 +607,6 @@ static void dump_compound_init(be_gas_decl_env_t *env, obstack_t *obst, } ++i; - space = 0; while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) { ++space; ++i; @@ -683,6 +706,7 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent, int emit_commons break; case tpo_struct: case tpo_class: + case tpo_union: dump_compound_init(env, obst, ent); break; default: @@ -739,13 +763,16 @@ static void be_gas_dump_globals(ir_type *gt, be_gas_decl_env_t *env, /************************************************************************/ /* Generate all entities. */ -void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env, +void be_gas_emit_decls(const be_main_env_t *main_env, int only_emit_marked_entities) { be_gas_decl_env_t env; - obstack_t rodata, data, bss, ctor; - int size; - char *cp; + obstack_t rodata; + obstack_t data; + obstack_t bss; + obstack_t ctor; + int size; + char *cp; /* dump the global type */ obstack_init(&rodata); @@ -764,33 +791,33 @@ void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env, size = obstack_object_size(&data); cp = obstack_finish(&data); if (size > 0) { - be_gas_emit_switch_section(emit, GAS_SECTION_DATA); - be_emit_string_len(emit, cp, size); - be_emit_write_line(emit); + be_gas_emit_switch_section(GAS_SECTION_DATA); + be_emit_string_len(cp, size); + be_emit_write_line(); } size = obstack_object_size(&rodata); cp = obstack_finish(&rodata); if (size > 0) { - be_gas_emit_switch_section(emit, GAS_SECTION_RODATA); - be_emit_string_len(emit, cp, size); - be_emit_write_line(emit); + be_gas_emit_switch_section(GAS_SECTION_RODATA); + be_emit_string_len(cp, size); + be_emit_write_line(); } size = obstack_object_size(&bss); cp = obstack_finish(&bss); if (size > 0) { - be_gas_emit_switch_section(emit, GAS_SECTION_COMMON); - be_emit_string_len(emit, cp, size); - be_emit_write_line(emit); + be_gas_emit_switch_section(GAS_SECTION_COMMON); + be_emit_string_len(cp, size); + be_emit_write_line(); } size = obstack_object_size(&ctor); cp = obstack_finish(&ctor); if (size > 0) { - be_gas_emit_switch_section(emit, GAS_SECTION_CTOR); - be_emit_string_len(emit, cp, size); - be_emit_write_line(emit); + be_gas_emit_switch_section(GAS_SECTION_CTOR); + be_emit_string_len(cp, size); + be_emit_write_line(); } obstack_free(&rodata, NULL); @@ -811,11 +838,11 @@ void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env, size = obstack_object_size(&data); cp = obstack_finish(&data); if (size > 0) { - be_gas_emit_switch_section(emit, GAS_SECTION_TLS); - be_emit_cstring(emit, ".balign\t32\n"); - be_emit_write_line(emit); - be_emit_string_len(emit, cp, size); - be_emit_write_line(emit); + be_gas_emit_switch_section(GAS_SECTION_TLS); + be_emit_cstring(".balign\t32\n"); + be_emit_write_line(); + be_emit_string_len(cp, size); + be_emit_write_line(); } obstack_free(&data, NULL);