From 1c04590f91415461c3ded074a02f7ca869876a1b Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Thu, 6 Apr 2006 16:47:27 +0000 Subject: [PATCH] add code for MinGW gas support --- ir/be/ia32/ia32_emitter.c | 72 ++++++++++++++++++++++++++++++++----- ir/be/ia32/ia32_emitter.h | 25 +++++++++++++ ir/be/ia32/ia32_gen_decls.c | 26 +++++++++++--- 3 files changed, 110 insertions(+), 13 deletions(-) diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index d2fab3b55..01531178c 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -38,6 +38,61 @@ /* global arch_env for lc_printf functions */ static const arch_env_t *arch_env = NULL; +/** by default, we generate assembler code for the Linux gas */ +asm_flavour_t asm_flavour = ASM_LINUX_GAS; + +/** + * Switch to a new section + */ +void ia32_switch_section(FILE *F, section_t sec) { + static section_t curr_sec = NO_SECTION; + static const char *text[ASM_MAX][SECTION_MAX] = { + { + ".section\t.text", ".section\t.data", ".section\t.rodata", ".section\t.text" + }, + { + ".section\t.text", ".section\t.data", ".section .rdata,\"dr\"", ".section\t.text" + } + }; + + if (curr_sec == sec) + return; + + curr_sec = sec; + switch (sec) { + + case NO_SECTION: + break; + + case SECTION_TEXT: + case SECTION_DATA: + case SECTION_RODATA: + case SECTION_COMMON: + fprintf(F, "\t%s\n", text[asm_flavour][sec]); + } +} + +static void ia32_dump_function_object(FILE *F, const char *name) +{ + switch (asm_flavour) { + case ASM_LINUX_GAS: + fprintf(F, "\t.type\t%s, @function\n", name); + break; + case ASM_MINGW_GAS: + fprintf(F, "\t.def\t%s;\t.scl\t2;\t.type\t32;\t.endef\n", name); + break; + } +} + +static void ia32_dump_function_size(FILE *F, const char *name) +{ + switch (asm_flavour) { + case ASM_LINUX_GAS: + fprintf(F, "\t.size\t%s, .-%s\n", name, name); + break; + } +} + /************************************************************* * _ _ __ _ _ * (_) | | / _| | | | | @@ -941,7 +996,7 @@ static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) { snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* get jump table entry as target */"); IA32_DO_EMIT(irn); - fprintf(F, "\t.section\t.rodata\n"); + ia32_switch_section(F, SECTION_RODATA); fprintf(F, "\t.align 4\n"); fprintf(F, "%s:\n", tbl.label); @@ -961,8 +1016,7 @@ static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) { snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* case %d */", last_value); IA32_DO_EMIT(irn); } - - fprintf(F, "\n\t.text\n\n"); + ia32_switch_section(F, SECTION_TEXT); } else { /* one jump is enough */ @@ -1441,13 +1495,14 @@ static void ia32_gen_block(ir_node *block, void *env) { */ static void ia32_emit_func_prolog(FILE *F, ir_graph *irg) { entity *irg_ent = get_irg_entity(irg); - const char *irg_name = get_entity_name(irg_ent); + const char *irg_name = get_entity_ld_name(irg_ent); - fprintf(F, "\t.section\t.text\n"); + fprintf(F, "\n"); + ia32_switch_section(F, SECTION_TEXT); if (get_entity_visibility(irg_ent) == visibility_external_visible) { fprintf(F, ".globl %s\n", irg_name); } - fprintf(F, "\t.type\t%s, @function\n", irg_name); + ia32_dump_function_object(F, irg_name); fprintf(F, "%s:\n", irg_name); } @@ -1455,10 +1510,11 @@ static void ia32_emit_func_prolog(FILE *F, ir_graph *irg) { * Emits code for function end */ static void ia32_emit_func_epilog(FILE *F, ir_graph *irg) { - const char *irg_name = get_entity_name(get_irg_entity(irg)); + const char *irg_name = get_entity_ld_name(get_irg_entity(irg)); fprintf(F, "\tret\n"); - fprintf(F, "\t.size\t%s, .-%s\n\n", irg_name, irg_name); + ia32_dump_function_size(F, irg_name); + fprintf(F, "\n"); } /** diff --git a/ir/be/ia32/ia32_emitter.h b/ir/be/ia32/ia32_emitter.h index 41416f439..0a4ae0fb6 100644 --- a/ir/be/ia32/ia32_emitter.h +++ b/ir/be/ia32/ia32_emitter.h @@ -30,4 +30,29 @@ const char *get_ia32_in_reg_name(ir_node *irn, int pos); void ia32_gen_routine(FILE *F, ir_graph *irg, const ia32_code_gen_t *cg); +/** + * Sections. + */ +typedef enum section_t { + NO_SECTION = -1, /**< no section selected yet. */ + SECTION_TEXT = 0, /**< text section */ + SECTION_DATA = 1, /**< data section */ + SECTION_RODATA = 2, /**< rodata section */ + SECTION_COMMON = 3, /**< common section */ + SECTION_MAX = 4 +} section_t; + +/** + * Switch to a new section. + */ +void ia32_switch_section(FILE *f, section_t sec); + +typedef enum asm_flavour_t { + ASM_LINUX_GAS = 0, /**< Linux gas */ + ASM_MINGW_GAS = 1, /**< MinGW gas */ + ASM_MAX = 2 +} asm_flavour_t; + +extern asm_flavour_t asm_flavour; + #endif /* _IA32_EMITTER_H_ */ diff --git a/ir/be/ia32/ia32_gen_decls.c b/ir/be/ia32/ia32_gen_decls.c index 5646266bd..9e6d3da00 100644 --- a/ir/be/ia32/ia32_gen_decls.c +++ b/ir/be/ia32/ia32_gen_decls.c @@ -16,6 +16,7 @@ #include "entity.h" #include "irprog.h" +#include "ia32_emitter.h" #include "ia32_gen_decls.h" /************************************************************************/ @@ -53,6 +54,17 @@ static unsigned highest_bit(unsigned v) return res; } +static void ia32_dump_comm(struct obstack *obst, const char *name, int size, int align) { + switch (asm_flavour) { + case ASM_LINUX_GAS: + obstack_printf(obst, "\t.comm\t%s,%d,%d\n", name, size, align); + break; + case ASM_MINGW_GAS: + obstack_printf(obst, "\t.comm\t%s,%d\n", name, size); + break; + } +} + /* * output the alignment */ @@ -309,8 +321,12 @@ struct arr_info { }; static void dump_object_size(struct obstack *obst, const char *name, int size) { - obstack_printf(obst, "\t.type\t%s,@object\n", name); - obstack_printf(obst, "\t.size\t%s,%d\n", name, size); + switch (asm_flavour) { + case ASM_LINUX_GAS: + obstack_printf(obst, "\t.type\t%s,@object\n", name); + obstack_printf(obst, "\t.size\t%s,%d\n", name, size); + break; + } } /* @@ -499,7 +515,7 @@ static void dump_global(struct obstack *rdata_obstack, struct obstack *data_obst if (align < 1) align = 1; - obstack_printf(comm_obstack, "\t.comm\t%s,%d,%d\n", ld_name, (get_type_size_bits(ty) + 7) >> 3, align); + ia32_dump_comm(comm_obstack, ld_name, (get_type_size_bits(ty) + 7) >> 3, align); } } } @@ -532,7 +548,7 @@ void ia32_gen_decls(FILE *out) { size = obstack_object_size(&data); cp = obstack_finish(&data); if (size > 0) { - fprintf(out, "\t.data\n"); + ia32_switch_section(out, SECTION_DATA); fwrite(cp, 1, size, out); } @@ -546,7 +562,7 @@ void ia32_gen_decls(FILE *out) { size = obstack_object_size(&comm); cp = obstack_finish(&comm); if (size > 0) { - fprintf(out, "\t.text\n"); + ia32_switch_section(out, SECTION_COMMON); fwrite(cp, 1, size, out); } -- 2.20.1