Fixed some problems due to refactoring in previous revisions.
[libfirm] / ir / be / begnuas.c
index bf85fc8..22822e8 100644 (file)
@@ -78,8 +78,8 @@ static const char *get_section_name(be_gas_section_t section) {
                        ".section .rdata,\"dr\"",
                        ".section\t.bss",
                        ".section\t.tbss,\"awT\",@nobits",
-                       ".section\t.ctors,\"aw\",@progbits",
-                       ".section\t.dtors,\"aw\",@progbits",
+                       ".section\t.ctors,\"w\"",
+                       ".section\t.dtors,\"w\"",
                        NULL,
                        NULL,
                        NULL
@@ -293,11 +293,15 @@ const char *be_gas_insn_label_prefix(void) {
        return ".LE";
 }
 
-/**
- * Dump a label.
- */
-static void dump_label(ir_label_t label) {
-       be_emit_irprintf("%s%lu", be_gas_block_label_prefix(), label);
+void be_gas_emit_entity(ir_entity *entity)
+{
+       if (entity->type == firm_code_type) {
+               ir_label_t label = get_entity_label(entity);
+               be_emit_string(be_gas_block_label_prefix());
+               be_emit_irprintf("%lu", label);
+       } else {
+               be_emit_ident(get_entity_ld_ident(entity));
+       }
 }
 
 /**
@@ -339,9 +343,6 @@ 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;
                        }
@@ -363,7 +364,6 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
        ir_mode *mode = get_irn_mode(init);
        int bytes     = get_mode_size_bytes(mode);
        tarval *tv;
-       ir_label_t label;
        ir_entity *ent;
 
        init = skip_Id(init);
@@ -396,17 +396,11 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
                                waitq_put(env->worklist, ent);
                                set_entity_backend_marked(ent, 1);
                        }
-                       be_emit_ident(get_entity_ld_ident(ent));
+                       be_gas_emit_entity(ent);
                        break;
 
                case symconst_ofs_ent:
                        ent = get_SymConst_entity(init);
-#if 0       /* not needed, is it? */
-                       if (!is_entity_backend_marked(ent)) {
-                               waitq_put(env->worklist, ent);
-                               set_entity_backend_marked(ent, 1);
-                       }
-#endif
                        be_emit_irprintf("%d", get_entity_offset(ent));
                        break;
 
@@ -423,11 +417,6 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
                        dump_arith_tarval(tv, bytes);
                        break;
 
-               case symconst_label:
-                       label = get_SymConst_label(init);
-                       dump_label(label);
-                       break;
-
                default:
                        assert(!"dump_atomic_init(): don't know how to init from this SymConst");
                }
@@ -547,8 +536,7 @@ static int initializer_is_string_const(const ir_initializer_t *initializer)
                tv   = sub_initializer->tarval.value;
                mode = get_tarval_mode(tv);
 
-               if (!mode_is_int(mode)
-                               || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
+               if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
                        return 0;
 
                c = get_tarval_long(tv);
@@ -591,8 +579,7 @@ static int ent_is_string_const(ir_entity *ent)
        /* and the mode of the element type is an int of
         * the same size as the byte mode */
        mode = get_type_mode(element_type);
-       if (!mode_is_int(mode)
-               || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
+       if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
                return 0;
 
        if (ent->has_initializer) {
@@ -1116,15 +1103,23 @@ static void dump_compound_init(be_gas_decl_env_t *env, ir_entity *ent)
        xfree(vals);
 }
 
-static void emit_align(unsigned alignment)
+static void emit_align(unsigned p2alignment)
 {
-       if (!is_po2(alignment))
-               panic("alignment not a power of 2");
-
-       be_emit_irprintf("\t.p2align\t%u\n", log2_floor(alignment));
+       be_emit_irprintf("\t.p2align\t%u\n", log2_floor(p2alignment));
        be_emit_write_line();
 }
 
+static unsigned get_effective_entity_alignment(ir_entity *entity)
+{
+       unsigned alignment = get_entity_alignment(entity);
+       if (alignment == 0) {
+               ir_type *type = get_entity_type(entity);
+               alignment     = get_type_alignment_bytes(type);
+       }
+       return alignment;
+}
+
+
 /**
  * Dump a global entity.
  *
@@ -1135,7 +1130,7 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent)
 {
        ir_type          *type           = get_entity_type(ent);
        ident            *ld_ident       = get_entity_ld_ident(ent);
-       unsigned          align          = get_type_alignment_bytes(type);
+       unsigned          alignment      = get_effective_entity_alignment(ent);
        int               emit_as_common = 0;
        be_gas_section_t  section        = env->section;
        ir_variability    variability    = get_entity_variability(ent);
@@ -1144,6 +1139,9 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent)
        if (is_Method_type(type) && section != GAS_SECTION_PIC_TRAMPOLINES) {
                return;
        }
+       if (type == firm_code_type) {
+               return;
+       }
 
        if (section != (be_gas_section_t) -1) {
                emit_as_common = 0;
@@ -1183,10 +1181,12 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent)
                /* we can return now... */
                return;
        }
+       if (!is_po2(alignment))
+               panic("alignment not a power of 2");
        /* alignment */
-       if (align > 1 && !emit_as_common && section != GAS_SECTION_PIC_TRAMPOLINES
+       if (alignment > 1 && !emit_as_common && section != GAS_SECTION_PIC_TRAMPOLINES
                        && section != GAS_SECTION_PIC_SYMBOLS) {
-               emit_align(align);
+               emit_align(alignment);
        }
 
        if (visibility != visibility_external_allocated && !emit_as_common
@@ -1207,16 +1207,20 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent)
        if (variability == variability_uninitialized) {
                if (emit_as_common) {
                        switch (be_gas_flavour) {
-                       case GAS_FLAVOUR_ELF:
                        case GAS_FLAVOUR_MACH_O:
+                               be_emit_irprintf("\t.comm %s,%u,%u\n",
+                                       get_id_str(ld_ident), get_type_size_bytes(type),
+                                       log2_floor(alignment));
+                               break;
+                       case GAS_FLAVOUR_ELF:
                        case GAS_FLAVOUR_YASM:
                                be_emit_irprintf("\t.comm %s,%u,%u\n",
-                                       get_id_str(ld_ident), get_type_size_bytes(type), align);
+                                       get_id_str(ld_ident), get_type_size_bytes(type), alignment);
                                be_emit_write_line();
                                break;
                        case GAS_FLAVOUR_MINGW:
                                be_emit_irprintf("\t.comm %s,%u # %u\n",
-                                       get_id_str(ld_ident), get_type_size_bytes(type), align);
+                                       get_id_str(ld_ident), get_type_size_bytes(type), alignment);
                                be_emit_write_line();
                                break;
                        }