Commit f19e702d authored by Matthias Braun's avatar Matthias Braun
Browse files

let backends decide wether to use begnuas

This also means that dependent modules like bedbgout should be
initialized by begnuas.
parent 87b21b8d
......@@ -159,16 +159,17 @@ static TEMPLATE_isa_t TEMPLATE_isa_template = {
/**
* Initializes the backend ISA
*/
static arch_env_t *TEMPLATE_init(FILE *outfile)
static arch_env_t *TEMPLATE_init(const be_main_env_t *env)
{
TEMPLATE_isa_t *isa = XMALLOC(TEMPLATE_isa_t);
*isa = TEMPLATE_isa_template;
be_emit_init(outfile);
TEMPLATE_register_init();
TEMPLATE_create_opcodes(&TEMPLATE_irn_ops);
be_emit_init(env->file_handle);
be_gas_begin_compilation_unit(env);
return &isa->base;
}
......@@ -180,7 +181,7 @@ static void TEMPLATE_done(void *self)
TEMPLATE_isa_t *isa = (TEMPLATE_isa_t*)self;
/* emit now all global declarations */
be_gas_emit_decls(isa->base.main_env);
be_gas_end_compilation_unit(isa->base.main_env);
be_emit_exit();
free(self);
......
......@@ -306,16 +306,17 @@ static amd64_isa_t amd64_isa_template = {
/**
* Initializes the backend ISA
*/
static arch_env_t *amd64_init(FILE *outfile)
static arch_env_t *amd64_init(const be_main_env_t *env)
{
amd64_isa_t *isa = XMALLOC(amd64_isa_t);
*isa = amd64_isa_template;
be_emit_init(outfile);
amd64_register_init();
amd64_create_opcodes(&amd64_irn_ops);
be_emit_init(env->file_handle);
be_gas_begin_compilation_unit(env);
return &isa->base;
}
......@@ -329,7 +330,7 @@ static void amd64_done(void *self)
amd64_isa_t *isa = (amd64_isa_t*)self;
/* emit now all global declarations */
be_gas_emit_decls(isa->base.main_env);
be_gas_end_compilation_unit(isa->base.main_env);
be_emit_exit();
free(self);
......
......@@ -439,20 +439,21 @@ static arm_isa_t arm_isa_template = {
/**
* Initializes the backend ISA and opens the output file.
*/
static arch_env_t *arm_init(FILE *file_handle)
static arch_env_t *arm_init(const be_main_env_t *env)
{
arm_isa_t *isa = XMALLOC(arm_isa_t);
*isa = arm_isa_template;
arm_register_init();
be_emit_init(file_handle);
arm_create_opcodes(&arm_irn_ops);
arm_handle_intrinsics();
be_gas_emit_types = false;
be_emit_init(env->file_handle);
be_gas_begin_compilation_unit(env);
return &isa->base;
}
......@@ -465,7 +466,7 @@ static void arm_done(void *self)
{
arm_isa_t *isa = (arm_isa_t*)self;
be_gas_emit_decls(isa->base.main_env);
be_gas_end_compilation_unit(isa->base.main_env);
be_emit_exit();
free(self);
......
......@@ -75,6 +75,7 @@ struct be_options_t {
struct be_main_env_t {
arch_env_t *arch_env;
FILE *file_handle;
be_options_t *options; /**< backend options */
const char *cup_name; /**< name of the compilation unit */
pmap *ent_trampoline_map; /**< A map containing PIC trampolines for methods. */
......
......@@ -56,9 +56,9 @@ static reg_out_info_t dummy_info = {
};
/* Initialize the architecture environment struct. */
arch_env_t *arch_env_init(const arch_isa_if_t *isa_if, FILE *file_handle, be_main_env_t *main_env)
arch_env_t *arch_env_init(const arch_isa_if_t *isa_if, be_main_env_t *main_env)
{
arch_env_t *arch_env = isa_if->init(file_handle);
arch_env_t *arch_env = isa_if->init(main_env);
arch_env->main_env = main_env;
return arch_env;
}
......
......@@ -239,7 +239,7 @@ arch_irn_class_t arch_irn_classify(const ir_node *irn);
* @return The environment.
*/
extern arch_env_t *arch_env_init(const arch_isa_if_t *isa,
FILE *file_handle, be_main_env_t *main_env);
be_main_env_t *main_env);
/**
* Register an instruction set architecture
......@@ -467,7 +467,7 @@ struct arch_isa_if_t {
* @param file_handle the file handle to write the output to
* @return a new isa instance
*/
arch_env_t *(*init)(FILE *file_handle);
arch_env_t *(*init)(const be_main_env_t *env);
/**
* lowers current program for target. See the documentation for
......
......@@ -157,11 +157,24 @@ static void emit_section(be_gas_section_t section, const ir_entity *entity)
{
be_gas_section_t base = section & GAS_SECTION_TYPE_MASK;
be_gas_section_t flags = section & ~GAS_SECTION_TYPE_MASK;
static const char *const basename[] = {
"text", "data", "rodata", "bss", "ctors", "dtors"
};
static const char *const type[] = {
"progbits", "progbits", "progbits", "nobits", "progbits", "progbits"
const char *f;
static const struct {
const char *name;
const char *type;
const char *flags;
} sectioninfos[] = {
{ "text", "progbits", "ax" },
{ "data", "progbits", "aw" },
{ "rodata", "progbits", "a" },
{ "bss", "nobits", "aw" },
{ "ctors", "progbits", "aw" },
{ "dtors", "progbits", "aw" },
{ NULL, NULL, NULL }, /* cstring */
{ NULL, NULL, NULL }, /* pic trampolines */
{ NULL, NULL, NULL }, /* pic symbols */
{ "debug_info", "progbits", "" },
{ "debug_abbrev", "progbits", "" },
{ "debug_line", "progbits", "" },
};
if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
......@@ -200,12 +213,12 @@ static void emit_section(be_gas_section_t section, const ir_entity *entity)
}
}
assert(base < (be_gas_section_t) ARRAY_SIZE(basename));
assert(base < (be_gas_section_t) ARRAY_SIZE(sectioninfos));
be_emit_cstring("\t.section\t.");
/* section name */
if (flags & GAS_SECTION_FLAG_TLS)
be_emit_char('t');
be_emit_string(basename[base]);
be_emit_string(sectioninfos[base].name);
if (flags & GAS_SECTION_FLAG_COMDAT) {
be_emit_char('.');
be_gas_emit_entity(entity);
......@@ -213,21 +226,19 @@ static void emit_section(be_gas_section_t section, const ir_entity *entity)
/* section flags */
be_emit_cstring(",\"");
if (be_gas_object_file_format != OBJECT_FILE_FORMAT_COFF)
be_emit_char('a');
if (base == GAS_SECTION_TEXT)
be_emit_char('x');
if (base != GAS_SECTION_RODATA && base != GAS_SECTION_TEXT)
be_emit_char('w');
for (f = sectioninfos[base].flags; *f != '\0'; ++f) {
be_emit_char(*f);
}
if (flags & GAS_SECTION_FLAG_TLS)
be_emit_char('T');
if (flags & GAS_SECTION_FLAG_COMDAT)
be_emit_char('G');
/* section type */
if (be_gas_object_file_format != OBJECT_FILE_FORMAT_COFF) {
be_emit_cstring("\",");
be_emit_char(be_gas_elf_type_char);
be_emit_string(type[base]);
be_emit_string(sectioninfos[base].type);
}
if (flags & GAS_SECTION_FLAG_COMDAT) {
......@@ -1654,7 +1665,7 @@ static void be_gas_emit_globals(ir_type *gt, be_gas_decl_env_t *env)
}
/* Generate all entities. */
void be_gas_emit_decls(const be_main_env_t *main_env)
static void emit_global_decls(const be_main_env_t *main_env)
{
be_gas_decl_env_t env;
memset(&env, 0, sizeof(env));
......@@ -1744,3 +1755,39 @@ void emit_jump_table(const ir_node *node, long default_pn, ir_entity *entity,
xfree(table);
}
static void emit_global_asms(void)
{
size_t n = get_irp_n_asms();
size_t i;
be_gas_emit_switch_section(GAS_SECTION_TEXT);
for (i = 0; i < n; ++i) {
ident *asmtext = get_irp_asm(i);
be_emit_cstring("#APP\n");
be_emit_write_line();
be_emit_ident(asmtext);
be_emit_char('\n');
be_emit_write_line();
be_emit_cstring("#NO_APP\n");
be_emit_write_line();
}
}
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();
emit_global_asms();
}
void be_gas_end_compilation_unit(const be_main_env_t *env)
{
emit_global_decls(env);
be_dbg_unit_end();
be_dbg_close();
}
......@@ -72,12 +72,6 @@ extern elf_variant_t be_gas_elf_variant;
*/
extern char be_gas_elf_type_char;
/**
* Generate all entities.
* @param main_env the main backend environment
*/
void be_gas_emit_decls(const be_main_env_t *main_env);
/**
* Switch the current output section to the given out.
*
......@@ -107,6 +101,20 @@ void be_gas_emit_entity(const ir_entity *entity);
*/
void be_gas_emit_block_name(const ir_node *block);
/**
* Starts emitting a compilation unit. This emits:
* - global assembler snippets
* - debug info
*/
void be_gas_begin_compilation_unit(const be_main_env_t *env);
/**
* ends a compilation unit. This emits:
* - global declarations/variables
* - debug info
*/
void be_gas_end_compilation_unit(const be_main_env_t *env);
/**
* Return the label prefix for labeled instructions.
*/
......
......@@ -345,21 +345,24 @@ const backend_params *be_get_backend_param(void)
* @param env an empty environment
* @param file_handle the file handle where the output will be written to
*/
static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle)
static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle,
const char *compilation_unit_name)
{
memset(env, 0, sizeof(*env));
env->options = &be_options;
env->file_handle = file_handle;
env->ent_trampoline_map = pmap_create();
env->pic_trampolines_type = new_type_class(NEW_ID("$PIC_TRAMPOLINE_TYPE"));
env->ent_pic_symbol_map = pmap_create();
env->pic_symbols_type = new_type_struct(NEW_ID("$PIC_SYMBOLS_TYPE"));
env->cup_name = compilation_unit_name;
remove_irp_type(env->pic_trampolines_type);
remove_irp_type(env->pic_symbols_type);
set_class_final(env->pic_trampolines_type, 1);
memset(asm_constraint_flags, 0, sizeof(asm_constraint_flags));
env->arch_env = arch_env_init(isa_if, file_handle, env);
env->arch_env = arch_env_init(isa_if, env);
return env;
}
......@@ -479,17 +482,6 @@ void be_lower_for_target(void)
set_irp_phase_state(phase_low);
}
static void emit_global_asms(void)
{
size_t n = get_irp_n_asms();
size_t i;
for (i = 0; i < n; ++i) {
be_emit_cstring("#APP\n");
be_emit_ident(get_irp_asm(i));
be_emit_cstring("\n#NO_APP\n");
}
}
/**
* The Firm backend main loop.
* Do architecture specific lowering for all graphs
......@@ -517,14 +509,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
}
}
be_init_env(&env, file_handle);
env.cup_name = cup_name;
be_dbg_open();
be_dbg_unit_begin(cup_name);
be_dbg_types();
emit_global_asms();
be_init_env(&env, file_handle, cup_name);
arch_env = env.arch_env;
......@@ -796,9 +781,6 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
stat_ev_ctx_pop("bemain_irg");
}
be_dbg_unit_end();
be_dbg_close();
arch_env_done(arch_env);
ir_profile_free();
......
......@@ -1523,7 +1523,7 @@ static void init_asm_constraints(void)
/**
* Initializes the backend ISA.
*/
static arch_env_t *ia32_init(FILE *file_handle)
static arch_env_t *ia32_init(const be_main_env_t *env)
{
ia32_isa_t *isa = XMALLOC(ia32_isa_t);
......@@ -1538,18 +1538,18 @@ static arch_env_t *ia32_init(FILE *file_handle)
ia32_register_init();
ia32_create_opcodes(&ia32_irn_ops);
be_emit_init(file_handle);
isa->tv_ent = pmap_create();
isa->cpu = ia32_init_machine_description();
/* enter the ISA object into the intrinsic environment */
intrinsic_env.isa = isa;
be_emit_init(env->file_handle);
be_gas_begin_compilation_unit(env);
return &isa->base;
}
/**
* Closes the output file and frees the ISA structure.
*/
......@@ -1558,12 +1558,11 @@ static void ia32_done(void *self)
ia32_isa_t *isa = (ia32_isa_t*)self;
/* emit now all global declarations */
be_gas_emit_decls(isa->base.main_env);
pmap_destroy(isa->tv_ent);
be_gas_end_compilation_unit(isa->base.main_env);
be_emit_exit();
pmap_destroy(isa->tv_ent);
free(self);
}
......
......@@ -352,7 +352,7 @@ static void sparc_handle_intrinsics(void)
/**
* Initializes the backend ISA
*/
static arch_env_t *sparc_init(FILE *outfile)
static arch_env_t *sparc_init(const be_main_env_t *env)
{
sparc_isa_t *isa = XMALLOC(sparc_isa_t);
*isa = sparc_isa_template;
......@@ -362,13 +362,14 @@ static arch_env_t *sparc_init(FILE *outfile)
be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF;
be_gas_elf_variant = ELF_VARIANT_SPARC;
be_emit_init(outfile);
sparc_register_init();
sparc_create_opcodes(&sparc_irn_ops);
sparc_handle_intrinsics();
sparc_cconv_init();
be_emit_init(env->file_handle);
be_gas_begin_compilation_unit(env);
return &isa->base;
}
......@@ -380,7 +381,7 @@ static void sparc_done(void *self)
sparc_isa_t *isa = (sparc_isa_t*)self;
/* emit now all global declarations */
be_gas_emit_decls(isa->base.main_env);
be_gas_end_compilation_unit(isa->base.main_env);
pmap_destroy(isa->constants);
be_emit_exit();
......
Markdown is supported
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