From 3a4bad532d2f47a8f3920fbfd12159f7d4a45eaf Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 1 Feb 2010 18:49:57 +0000 Subject: [PATCH] make the character used for specifying elf types configurable in begnuas and use generic function prolog in arm backend [r27022] --- ir/be/arm/arm_emitter.c | 33 +++++++-------------------------- ir/be/begnuas.c | 23 ++++++++++++++--------- ir/be/begnuas.h | 7 ++++++- ir/be/ia32/ia32_emitter.c | 2 ++ ir/be/sparc/sparc_emitter.c | 2 ++ 5 files changed, 31 insertions(+), 36 deletions(-) diff --git a/ir/be/arm/arm_emitter.c b/ir/be/arm/arm_emitter.c index 62a8d8555..0f22540c9 100644 --- a/ir/be/arm/arm_emitter.c +++ b/ir/be/arm/arm_emitter.c @@ -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 */ diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c index 16b9fd946..be0d0ead8 100644 --- a/ir/be/begnuas.c +++ b/ir/be/begnuas.c @@ -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)); } diff --git a/ir/be/begnuas.h b/ir/be/begnuas.h index 0ec885c0d..708d8ec78 100644 --- a/ir/be/begnuas.h +++ b/ir/be/begnuas.h @@ -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); diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index a0f2732dc..244d6efc2 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -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"); diff --git a/ir/be/sparc/sparc_emitter.c b/ir/be/sparc/sparc_emitter.c index 3c21aa47b..04ed07a4f 100644 --- a/ir/be/sparc/sparc_emitter.c +++ b/ir/be/sparc/sparc_emitter.c @@ -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)); -- 2.20.1