trverify: cleanup, check irg.entity == entity.irg
[libfirm] / ir / be / begnuas.c
index 16f62a5..1839def 100644 (file)
@@ -22,7 +22,6 @@
  * @brief       Dumps global variables and constants as gas assembler.
  * @author      Christian Wuerdig, Matthias Braun
  * @date        04.11.2005
- * @version     $Id$
  */
 #include "config.h"
 
@@ -43,7 +42,7 @@
 
 #include "be_t.h"
 #include "beemitter.h"
-#include "be_dbgout.h"
+#include "bedwarf.h"
 
 /** by default, we generate assembler code for the Linux gas */
 object_file_format_t  be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF;
@@ -90,6 +89,7 @@ static void emit_section_macho(be_gas_section_t section)
                case GAS_SECTION_DEBUG_ABBREV:    name = "section __DWARF,__debug_abbrev,regular,debug"; break;
                case GAS_SECTION_DEBUG_LINE:      name = "section __DWARF,__debug_line,regular,debug"; break;
                case GAS_SECTION_DEBUG_PUBNAMES:  name = "section __DWARF,__debug_pubnames,regular,debug"; break;
+               case GAS_SECTION_DEBUG_FRAME:     name = "section __DWARF,__debug_frame,regular,debug"; break;
                default: panic("unsupported scetion type 0x%X", section);
                }
                be_emit_irprintf("\t.%s\n", name);
@@ -103,8 +103,10 @@ static void emit_section_macho(be_gas_section_t section)
                case GAS_SECTION_CSTRING:         name = "section __TEXT,__const_coal,coalesced"; break;
                default: panic("unsupported scetion type 0x%X", section);
                }
+       } else if (flags & GAS_SECTION_FLAG_TLS) {
+               panic("thread local storage not supported on macho (section 0x%X)", section);
        } else {
-               panic("unsupported section type 0x%X\n", section);
+               panic("unsupported section type 0x%X", section);
        }
 }
 
@@ -126,6 +128,7 @@ static void emit_section_sparc(be_gas_section_t section, const ir_entity *entity
                "debug_abbrev",
                "debug_line",
                "debug_pubnames"
+               "debug_frame",
        };
 
        if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
@@ -192,6 +195,7 @@ static void emit_section(be_gas_section_t section, const ir_entity *entity)
                { "debug_abbrev",   "progbits", ""   },
                { "debug_line",     "progbits", ""   },
                { "debug_pubnames", "progbits", ""   },
+               { "debug_frame",    "progbits", ""   },
        };
 
        if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
@@ -527,18 +531,17 @@ static void emit_visibility(const ir_entity *entity)
        }
 }
 
-void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment)
+void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment,                                 const parameter_dbg_info_t *parameter_infos)
 {
        be_gas_section_t section;
 
-       be_dbg_method_begin(entity);
+       be_dwarf_method_before(entity, parameter_infos);
 
        section = determine_section(NULL, entity);
        emit_section(section, entity);
 
        /* write the begin line (makes the life easier for scripts parsing the
         * assembler) */
-       be_emit_write_line();
        be_emit_cstring("# -- Begin  ");
        be_gas_emit_entity(entity);
        be_emit_char('\n');
@@ -584,10 +587,14 @@ void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment)
        be_gas_emit_entity(entity);
        be_emit_cstring(":\n");
        be_emit_write_line();
+
+       be_dwarf_method_begin();
 }
 
 void be_gas_emit_function_epilog(const ir_entity *entity)
 {
+       be_dwarf_method_end();
+
        if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF) {
                be_emit_cstring("\t.size\t");
                be_gas_emit_entity(entity);
@@ -602,8 +609,6 @@ void be_gas_emit_function_epilog(const ir_entity *entity)
        be_emit_char('\n');
        be_emit_write_line();
 
-       be_dbg_method_end();
-
        be_emit_char('\n');
        be_emit_write_line();
 }
@@ -929,13 +934,6 @@ typedef struct {
        } v;
 } normal_or_bitfield;
 
-static int is_type_variable_size(ir_type *type)
-{
-       (void) type;
-       /* TODO */
-       return 0;
-}
-
 static size_t get_initializer_size(const ir_initializer_t *initializer,
                                    ir_type *type)
 {
@@ -947,28 +945,34 @@ static size_t get_initializer_size(const ir_initializer_t *initializer,
        case IR_INITIALIZER_NULL:
                return get_type_size_bytes(type);
        case IR_INITIALIZER_COMPOUND:
-               if (!is_type_variable_size(type)) {
-                       return get_type_size_bytes(type);
+               if (is_Array_type(type)) {
+                       if (is_array_variable_size(type)) {
+                               ir_type   *element_type = get_array_element_type(type);
+                               unsigned   element_size = get_type_size_bytes(element_type);
+                               unsigned   element_align
+                                       = get_type_alignment_bytes(element_type);
+                               unsigned   misalign     = element_size % element_align;
+                               size_t     n_inits
+                                       = get_initializer_compound_n_entries(initializer);
+                               element_size += element_align - misalign;
+                               return n_inits * element_size;
+                       } else {
+                               return get_type_size_bytes(type);
+                       }
                } else {
-                       size_t n_entries
-                               = get_initializer_compound_n_entries(initializer);
-                       size_t i;
-                       unsigned initializer_size = get_type_size_bytes(type);
-                       for (i = 0; i < n_entries; ++i) {
-                               ir_entity *entity = get_compound_member(type, i);
-                               ir_type   *type   = get_entity_type(entity);
-
-                               const ir_initializer_t *sub_initializer
-                                       = get_initializer_compound_value(initializer, i);
-
-                               unsigned offset = get_entity_offset(entity);
-                               unsigned size   = get_initializer_size(sub_initializer, type);
-
-                               if (offset + size > initializer_size) {
-                                       initializer_size = offset + size;
-                               }
+                       assert(is_compound_type(type));
+                       size_t size = get_type_size_bytes(type);
+                       if (is_compound_variable_size(type)) {
+                               /* last initializer has to be an array of variable size */
+                               size_t l = get_initializer_compound_n_entries(initializer)-1;
+                               const ir_initializer_t *last
+                                       = get_initializer_compound_value(initializer, l);
+                               const ir_entity *last_ent  = get_compound_member(type, l);
+                               ir_type         *last_type = get_entity_type(last_ent);
+                               assert(is_array_variable_size(last_type));
+                               size += get_initializer_size(last, last_type);
                        }
-                       return initializer_size;
+                       return size;
                }
        }
 
@@ -1548,7 +1552,7 @@ char const *be_gas_get_private_prefix(void)
 
 void be_gas_emit_entity(const ir_entity *entity)
 {
-       if (entity->type == firm_code_type) {
+       if (entity->type == get_code_type()) {
                ir_label_t label = get_entity_label(entity);
                be_emit_irprintf("%s_%lu", be_gas_get_private_prefix(), label);
                return;
@@ -1562,8 +1566,8 @@ void be_gas_emit_entity(const ir_entity *entity)
 
 void be_gas_emit_block_name(const ir_node *block)
 {
-       if (has_Block_entity(block)) {
-               ir_entity *entity = get_Block_entity(block);
+       ir_entity *entity = get_Block_entity(block);
+       if (entity != NULL) {
                be_gas_emit_entity(entity);
        } else {
                be_emit_irprintf("%s%ld", be_gas_get_private_prefix(), get_irn_node_nr(block));
@@ -1586,7 +1590,7 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity)
        ir_linkage        linkage    = get_entity_linkage(entity);
 
        /* block labels are already emittet in the code */
-       if (type == firm_code_type)
+       if (type == get_code_type())
                return;
 
        /* we already emitted all methods. Except for the trampolines which
@@ -1600,7 +1604,7 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity)
                return;
        }
 
-       be_dbg_variable(entity);
+       be_dwarf_variable(entity);
 
        if (section == GAS_SECTION_BSS) {
                switch (visibility) {
@@ -1838,9 +1842,8 @@ static void emit_global_asms(void)
 
 void be_gas_begin_compilation_unit(const be_main_env_t *env)
 {
-       be_dbg_open();
-       be_dbg_unit_begin(env->cup_name);
-       be_dbg_types();
+       be_dwarf_open();
+       be_dwarf_unit_begin(env->cup_name);
 
        emit_global_asms();
 }
@@ -1849,6 +1852,6 @@ void be_gas_end_compilation_unit(const be_main_env_t *env)
 {
        emit_global_decls(env);
 
-       be_dbg_unit_end();
-       be_dbg_close();
+       be_dwarf_unit_end();
+       be_dwarf_close();
 }