scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit cb34e8771eb6d1af7b6cf0fcc181c96f4ab66fb0
parent ede4ae9184f24eaddeed177e0309e6f920c2d53f
Author: Roberto E. Vargas Caballero <roberto.vargas@igrid-td.com>
Date:   Mon,  4 Apr 2016 17:37:06 +0200

[cc2] Add data initilization to QBE

Diffstat:
Mcc2/arch/qbe/code.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/cc2/arch/qbe/code.c b/cc2/arch/qbe/code.c @@ -6,6 +6,77 @@ #include "../../cc2.h" #include "../../../inc/sizes.h" +static char * +symname(Symbol *sym) +{ + static char name[IDENTSIZ+1]; + static unsigned short id; + + if (sym->name) { + switch (sym->kind) { + case EXTRN: + case GLOB: + case PRIVAT: + return sym->name; + } + } + + if (sym->numid == 0 && (sym->numid = ++id) == 0) + error(EIDOVER); + sprintf(name, ".L%d", sym->numid); + + return name; +} + +static void +emitconst(Node *np) +{ + switch (np->type.size) { + case 1: + printf("%d", (int) np->u.i & 0xFF); + break; + case 2: + printf("%d", (int) np->u.i & 0xFFFF); + break; + case 4: + printf("%ld", (long) np->u.i & 0xFFFFFFFF); + break; + case 8: + printf("%lld", (long long) np->u.i & 0xFFFFFFFF); + break; + default: + abort(); + } +} + +static void +emittree(Node *np) +{ + if (!np) + return; + + switch (np->op) { + case OSTRING: + printf("\"%s\"", np->u.s); + free(np->u.s); + np->u.s = NULL; + break; + case OCONST: + emitconst(np); + break; + case OADDR: + emittree(np->left); + break; + case MEM: + fputs(symname(np->u.sym), stdout); + break; + default: + emittree(np->left); + printf(" %c ", np->op); + emittree(np->right); + break; + } +} static void size2asm(Type *tp) @@ -15,7 +86,7 @@ size2asm(Type *tp) /* In qbe we can ignore the aligment because it handles it */ if (tp->flags & STRF) { - abort(); + s = "b\t"; } else { switch (tp->size) { case 1: @@ -44,7 +115,7 @@ defsym(Symbol *sym, int alloc) return; if (sym->kind == GLOB) fputs("export ", stdout); - printf("data $%s = {\n", sym->name); + printf("data $%s = {\n", symname(sym)); if (sym->type.flags & INITF) return; printf("\tz\t%llu\n}\n", (unsigned long long) sym->type.size); @@ -53,6 +124,11 @@ defsym(Symbol *sym, int alloc) void data(Node *np) { + putchar('\t'); + size2asm(&np->type); + emittree(np); + putchar(','); + putchar('\n'); } void @@ -63,4 +139,5 @@ writeout(void) void endinit(void) { + puts("}"); }