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:
M | cc2/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("}");
}