diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-19 01:39:13 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-19 01:39:13 +0200 |
| commit | 35f6532764c90dabeb131b165101a5f931fd68bb (patch) | |
| tree | 7c1d05f0f74f16c1c6a7e01b5b5af40a1bed462b /src | |
| parent | 268a53de823a6750d6256ee1fb1e7707b4b45740 (diff) | |
SDCCgas: work on emitting .rodata section
Diffstat (limited to 'src')
| -rw-r--r-- | src/SDCCgas.c | 97 |
1 files changed, 92 insertions, 5 deletions
diff --git a/src/SDCCgas.c b/src/SDCCgas.c index f2877fd..b626ee3 100644 --- a/src/SDCCgas.c +++ b/src/SDCCgas.c @@ -20,15 +20,25 @@ #include "SDCCgas.h" #include "SDCCglobl.h" +#include "SDCCmem.h" +#include "SDCCsymt.h" +#include "SDCCicode.h" +#include "port.h" #include "newalloc.h" +#include "dbuf_string.h" #include <stdio.h> #include <stdlib.h> #include <stddef.h> static char *set_dst(void); -static FILE *create_file(const char *const path); -static void emit_file_name(FILE *const f, const char *const dst); -static const char *get_filename(const char *const dst); +static FILE *create_file(const char *path); +static void emit_file_name(FILE *f, const char *dst); +static void emit_rodata(FILE *f); +static void print_section(FILE *f, const char *section); +static const char *get_filename(const char *dst); + +extern const char *iComments1; +extern const char *iComments2; void gas_glue(void) { @@ -52,8 +62,14 @@ void gas_glue(void) FILE *const f = create_file(dst); + fprintf(f, "%s%s", iComments1, iComments2); + + /* Print input file name without extension. */ emit_file_name(f, fullSrcFileName); + /* Print read only local variables. */ + emit_rodata(f); + if (clean_dst) /* dst must not be modified by gas_glue(), but memory * cleanup is needed if no output filepath was given. */ @@ -80,8 +96,10 @@ static char *set_dst(void) ; { - /* No output file name has been designated. Use default extension. */ - const char extension[] = ".s"; + /* No output file name has been designated. + * Use port default extension, if available. */ + const char *const extension = port->assembler.file_ext ? + port->assembler.file_ext : ".asm"; const size_t total_len = len + strlen(extension) + 1; dst = Safe_calloc(total_len, sizeof *fullDstFileName); @@ -116,6 +134,75 @@ static void emit_file_name(FILE *const f, const char *const dst) fprintf(f, "\t.file\t\"%s\"\n", filename); } +static void emit_rodata(FILE *const f) +{ + if (!statsg) + return; + + if (!statsg->syms) + return; + + print_section(f, "rodata"); + + { + struct set *p; + + for (p = statsg->syms; p; p = p->next) + { + symbol *const sym = p->item; + struct sym_link *const etype = sym->etype; + + if (IS_EXTERN(etype) || !sym->ival) + continue; + + if (SPEC_CONST(etype)) + { + const char *const name = sym->name; + + /* Declare object. */ + if (SPEC_STAT(etype)) + fprintf(f, "\t.local %s\n", name); + else + fprintf(f, "\t.global %s\n", name); + + fprintf(f, "\t.type %s, @object\n", name); + + if (SPEC_STRUCT(etype)) + { + /* Point to first struct element. */ + struct symbol *field; + + /* Print sizeof struct. */ + fprintf(f, "\t.size %s, %d\n", name, etype->select.s.v_struct->size); + /* Print instance name as a label. */ + fprintf(f, "%s:\n", name); + + for (field = etype->select.s.v_struct->fields; field; field = field->next) + { + struct sym_link *ft = field->etype; + + printf("%s.%s\n", name, field->name); + + if (SPEC_LONG(ft)) + { + fprintf(f, "\t.long %d\n", ft->select.s.const_val.v_long); + } + else if (SPEC_SHORT(ft)) + { + fprintf(f, "\t.hword %d\n", ft->select.s.const_val.v_int); + } + } + } + } + } + } +} + +static void print_section(FILE *const f, const char *const section) +{ + fprintf(f, "\t.section .%s\n", section); +} + static const char *get_filename(const char *const dst) { const char *p; |
