make the character used for specifying elf types configurable in begnuas and use...
authorMatthias Braun <matze@braunis.de>
Mon, 1 Feb 2010 18:49:57 +0000 (18:49 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 1 Feb 2010 18:49:57 +0000 (18:49 +0000)
[r27022]

ir/be/arm/arm_emitter.c
ir/be/begnuas.c
ir/be/begnuas.h
ir/be/ia32/ia32_emitter.c
ir/be/sparc/sparc_emitter.c

index 62a8d85..0f22540 100644 (file)
@@ -1085,30 +1085,6 @@ static void arm_gen_block(ir_node *block, ir_node *prev_block) {
        }
 }
 
-/**
- * Emits code for function start.
- */
-void arm_func_prolog(ir_graph *irg) {
-       ir_entity *ent = get_irg_entity(irg);
-       const char *irg_name = get_entity_ld_name(ent);
-
-       be_emit_write_line();
-       be_gas_emit_switch_section(GAS_SECTION_TEXT);
-       be_emit_cstring("\t.align  2\n");
-
-       if (get_entity_visibility(ent) == visibility_external_visible)
-               be_emit_irprintf("\t.global %s\n", irg_name);
-       be_emit_irprintf("%s:\n", irg_name);
-}
-
-/**
- * Emits code for function end
- */
-void arm_emit_end(FILE *F, ir_graph *irg) {
-       (void) irg;
-       fprintf(F, "\t.ident \"firmcc\"\n");
-}
-
 /**
  * Block-walker:
  * Sets labels for control flow nodes (jump target)
@@ -1140,7 +1116,8 @@ static int cmp_sym_or_tv(const void *elt, const void *key, size_t size) {
 /**
  * Main driver. Emits the code for one routine.
  */
-void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) {
+void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg)
+{
        ir_node   **blk_sched;
        int       i, n;
        ir_node   *last_block = NULL;
@@ -1149,6 +1126,8 @@ void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) {
        cg        = arm_cg;
        sym_or_tv = new_set(cmp_sym_or_tv, 8);
 
+       be_gas_elf_type_char = '%';
+
        arm_register_emitters();
 
        be_dbg_method_begin(entity, be_abi_get_stack_layout(cg->birg->abi));
@@ -1156,7 +1135,8 @@ void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) {
        /* create the block schedule. For now, we don't need it earlier. */
        blk_sched = be_create_block_schedule(cg->irg, cg->birg->exec_freq);
 
-       arm_func_prolog(irg);
+       be_gas_emit_function_prolog(entity, 4);
+
        irg_block_walk_graph(irg, arm_gen_labels, NULL, NULL);
 
        n = ARR_LEN(blk_sched);
@@ -1173,6 +1153,7 @@ void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) {
                last_block = block;
        }
 
+       be_gas_emit_function_epilog(entity);
        be_dbg_method_end();
 
        /* emit SymConst values */
index 16b9fd9..be0d0ea 100644 (file)
@@ -46,8 +46,9 @@
 #include "be_dbgout.h"
 
 /** by default, we generate assembler code for the Linux gas */
-be_gas_flavour_t be_gas_flavour    = GAS_FLAVOUR_ELF;
-bool             be_gas_emit_types = true;
+be_gas_flavour_t be_gas_flavour       = GAS_FLAVOUR_ELF;
+char             be_gas_elf_type_char = '@';
+bool             be_gas_emit_types    = true;
 
 static be_gas_section_t current_section = (be_gas_section_t) -1;
 
@@ -127,11 +128,11 @@ void be_gas_emit_switch_section(be_gas_section_t section) {
        current_section = section;
 }
 
-void be_gas_emit_function_prolog(ir_entity *entity, unsigned alignment)
+void be_gas_emit_function_prolog(ir_entity *entity, unsigned po2alignment)
 {
        const char *name = get_entity_ld_name(entity);
        const char *fill_byte = "";
-       unsigned maximum_skip;
+       unsigned    maximum_skip;
 
        be_gas_emit_switch_section(GAS_SECTION_TEXT);
 
@@ -147,10 +148,10 @@ void be_gas_emit_function_prolog(ir_entity *entity, unsigned alignment)
                fill_byte = "0x90";
        }
 
-       if (alignment > 0) {
-               maximum_skip = (1 << alignment) - 1;
+       if (po2alignment > 0) {
+               maximum_skip = (1 << po2alignment) - 1;
                be_emit_cstring("\t.p2align ");
-               be_emit_irprintf("%u,%s,%u\n", alignment, fill_byte, maximum_skip);
+               be_emit_irprintf("%u,%s,%u\n", po2alignment, fill_byte, maximum_skip);
                be_emit_write_line();
        }
        if (get_entity_visibility(entity) == visibility_external_visible) {
@@ -164,7 +165,9 @@ void be_gas_emit_function_prolog(ir_entity *entity, unsigned alignment)
        case GAS_FLAVOUR_ELF:
                be_emit_cstring("\t.type\t");
                be_emit_string(name);
-               be_emit_cstring(", @function\n");
+               be_emit_cstring(", ");
+               be_emit_char(be_gas_elf_type_char);
+               be_emit_cstring("function\n");
                be_emit_write_line();
                break;
        case GAS_FLAVOUR_MINGW:
@@ -1197,7 +1200,9 @@ static void dump_global(be_gas_decl_env_t *env, ir_entity *ent)
                        && be_gas_emit_types) {
                be_emit_cstring("\t.type\t");
                be_emit_ident(ld_ident);
-               be_emit_cstring(", @object\n\t.size\t");
+               be_emit_cstring(", ");
+               be_emit_char(be_gas_elf_type_char);
+               be_emit_cstring("object\n\t.size\t");
                be_emit_ident(ld_ident);
                be_emit_irprintf(", %u\n", get_type_size_bytes(type));
        }
index 0ec885c..708d8ec 100644 (file)
@@ -62,6 +62,11 @@ typedef enum asm_flavour_t {
 /** The variable where the GAS dialect is stored. */
 extern be_gas_flavour_t be_gas_flavour;
 extern bool             be_gas_emit_types;
+/**
+ * the .type directive needs to specify @function, #function or %function
+ * depending on the target architecture (yay)
+ */
+extern char             be_gas_elf_type_char;
 
 /**
  * Generate all entities.
@@ -88,7 +93,7 @@ void be_gas_emit_switch_section(be_gas_section_t section);
 /**
  * emit assembler instructions necessary before starting function code
  */
-void be_gas_emit_function_prolog(ir_entity *entity, unsigned alignment);
+void be_gas_emit_function_prolog(ir_entity *entity, unsigned po2alignment);
 
 void be_gas_emit_function_epilog(ir_entity *entity);
 
index a0f2732..244d6ef 100644 (file)
@@ -2244,6 +2244,8 @@ void ia32_gen_routine(ia32_code_gen_t *ia32_cg, ir_graph *irg)
        isa      = cg->isa;
        do_pic   = cg->birg->main_env->options->pic;
 
+       be_gas_elf_type_char = '@';
+
        ia32_register_emitters();
 
        get_unique_label(pic_base_label, sizeof(pic_base_label), ".PIC_BASE");
index 3c21aa4..04ed07a 100644 (file)
@@ -638,6 +638,8 @@ void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
        ir_entity *entity     = get_irg_entity(irg);
        int i, n;
 
+       be_gas_elf_type_char = '#';
+
        /* register all emitter functions */
        sparc_register_emitters();
        be_dbg_method_begin(entity, be_abi_get_stack_layout(cg->birg->abi));