diff --git a/backend/x86_64.c b/backend/x86_64.c index 43053cd..ce023fa 100644 --- a/backend/x86_64.c +++ b/backend/x86_64.c @@ -1,11 +1,16 @@ #include #include "rifle/mu.h" -#define retreg(msize) \ - (msize >= MSIZE_MAX) \ - ? "bad" \ +#define retreg(msize) \ + ((msize) >= MSIZE_MAX) \ + ? "bad" \ : rettab[(msize)] +#define secname(secid) \ + ((secid) >= SECTION_MAX) \ + ? "bad" \ + : secttab[(secid)] + /* Size to return register table */ static const char *rettab[] = { [MSIZE_BYTE] = "al", @@ -14,8 +19,35 @@ static const char *rettab[] = { [MSIZE_QWORD] = "rax" }; +/* Section ID to name table */ +static const char *secttab[] = { + [SECTION_NONE] = ".none", + [SECTION_TEXT] = ".text", + [SECTION_DATA] = ".data", + [SECTION_RODATA] = ".rodata", + [SECTION_BSS] = ".bss" +}; + +static inline void +force_section(struct rifle_state *state, section_t section) +{ + if (state == NULL) { + return; + } + + if (state->section != section) { + state->section = section; + fprintf( + state->out_fp, + "[section %s]\n", + secname(section) + ); + } +} + int -mu_gen_label(struct rifle_state *state, const char *name, bool global) +mu_gen_label(struct rifle_state *state, section_t section, const char *name, + bool global) { if (state == NULL || name == NULL) { return -1; @@ -29,6 +61,7 @@ mu_gen_label(struct rifle_state *state, const char *name, bool global) ); } + force_section(state, section); fprintf( state->out_fp, "%s:\n", diff --git a/core/codegen.c b/core/codegen.c index b8c29af..72774c9 100644 --- a/core/codegen.c +++ b/core/codegen.c @@ -22,7 +22,7 @@ resolve_func(struct rifle_state *state, struct ast_node *root) return -1; } - return mu_gen_label(state, symbol->name, symbol->pub); + return mu_gen_label(state, SECTION_TEXT, symbol->name, symbol->pub); } static int @@ -81,10 +81,10 @@ resolve_loop(struct rifle_state *state, struct ast_node *root) mu_gen_blab(state, label); snprintf(label, sizeof(label), "L.%zu.1", state->loop_count - 1); - mu_gen_label(state, label, false); + mu_gen_label(state, SECTION_TEXT, label, false); } else { snprintf(label, sizeof(label), "L.%zu", state->loop_count++); - mu_gen_label(state, label, false); + mu_gen_label(state, SECTION_TEXT, label, false); } return 0; diff --git a/inc/rifle/mu.h b/inc/rifle/mu.h index 280ee48..fcfd7d2 100644 --- a/inc/rifle/mu.h +++ b/inc/rifle/mu.h @@ -46,12 +46,16 @@ type_to_msize(data_type_t type) * Generate a named label * * @state: Compiler state + * @section: Section to place label within * @name: Name of label to generate * @global: If true, symbol is to be marked global * * Returns zero on success */ -int mu_gen_label(struct rifle_state *state, const char *name, bool global); +int mu_gen_label( + struct rifle_state *state, section_t section, + const char *name, bool global +); /* * Generate a register fill corresponding to the platform return diff --git a/inc/rifle/state.h b/inc/rifle/state.h index 30bda2c..40dada2 100644 --- a/inc/rifle/state.h +++ b/inc/rifle/state.h @@ -15,6 +15,18 @@ /* Default assembly output path */ #define ASMOUT "rifleout.asm" +/* + * Represents valid section types + */ +typedef enum { + SECTION_NONE, + SECTION_TEXT, + SECTION_DATA, + SECTION_RODATA, + SECTION_BSS, + SECTION_MAX +} section_t; + /* * Represents the compiler state * @@ -31,6 +43,7 @@ * @scope_depth: How deep in scope we are * @have_ret: If set, function has return statement * @scope_stack: Used to track scopes + * @section: Current section * @cur_func: Current function */ struct rifle_state { @@ -47,6 +60,7 @@ struct rifle_state { uint8_t scope_depth; uint8_t have_ret : 1; tt_t scope_stack[SCOPE_STACK_MAX]; + section_t section; struct symbol *cur_func; };