Commit 3a4bad53 authored by Matthias Braun's avatar Matthias Braun
Browse files

make the character used for specifying elf types configurable in begnuas and...

make the character used for specifying elf types configurable in begnuas and use generic function prolog in arm backend

[r27022]
parent 11a2eb0c
......@@ -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 */
......
......@@ -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));
}
......
......@@ -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);
......
......@@ -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");
......
......@@ -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));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment