diff options
-rw-r--r-- | qbe.c | 72 |
1 files changed, 42 insertions, 30 deletions
@@ -18,9 +18,10 @@ struct value { VALUE_TEMP, VALUE_TYPE, VALUE_LABEL, + + VALUE_THREAD = 1<<4, } kind; unsigned id; - bool threadlocal; union { char *name; unsigned long long i; @@ -136,6 +137,8 @@ mkglobal(struct decl *d) v = xmalloc(sizeof(*v)); v->kind = VALUE_GLOBAL; + if (d->kind == DECLOBJECT && d->u.obj.storage == SDTHREAD) + v->kind |= VALUE_THREAD; if (d->asmname) { v->u.name = d->asmname; v->id = 0; @@ -143,7 +146,6 @@ mkglobal(struct decl *d) v->u.name = d->name; v->id = d->linkage == LINKNONE ? ++id : 0; } - v->threadlocal = d->kind == DECLOBJECT && d->u.obj.storage == SDTHREAD; return v; } @@ -210,6 +212,7 @@ qbetype(struct type *t) /* functions */ static void emittype(struct type *); +static void emitname(struct value *); static void emitvalue(struct value *); static void @@ -631,7 +634,7 @@ funclval(struct func *f, struct expr *e) error(&tok.loc, "identifier is not an object or function"); /* XXX: fix location, var name */ if (d == f->namedecl) { fputs("data ", stdout); - emitvalue(d->value); + emitname(d->value); printf(" = { b \"%s\", b 0 }\n", f->name); f->namedecl = NULL; } @@ -1017,7 +1020,7 @@ funcswitch(struct func *f, struct value *v, struct switchcases *c, struct block /* emit */ static void -emitvalue(struct value *v) +emitname(struct value *v) { static const char sigil[] = { [VALUE_TEMP] = '%', @@ -1025,8 +1028,24 @@ emitvalue(struct value *v) [VALUE_TYPE] = ':', [VALUE_LABEL] = '@', }; + int kind; + + kind = v->kind & 0xf; + if (kind >= LEN(sigil) || !sigil[kind]) + fatal("invalid value"); + putchar(sigil[kind]); + if (kind == VALUE_GLOBAL && v->id) + fputs(".L", stdout); + if (v->u.name) + fputs(v->u.name, stdout); + if (v->id) + printf(".%u", v->id); +} - switch (v->kind) { +static void +emitvalue(struct value *v) +{ + switch (v->kind & 0xf) { case VALUE_INTCONST: printf("%llu", v->u.i); break; @@ -1036,16 +1055,13 @@ emitvalue(struct value *v) case VALUE_DBLCONST: printf("d_%.17g", v->u.f); break; + case VALUE_GLOBAL: + if (v->kind & VALUE_THREAD) + fputs("thread ", stdout); + /* fallthrough */ default: - if (v->kind >= LEN(sigil) || !sigil[v->kind]) - fatal("invalid value"); - putchar(sigil[v->kind]); - if (v->kind == VALUE_GLOBAL && v->id) - fputs(".L", stdout); - if (v->u.name) - fputs(v->u.name, stdout); - if (v->id) - printf(".%u", v->id); + emitname(v); + break; } } @@ -1053,7 +1069,7 @@ static void emitclass(int class, struct value *v) { if (v && v->kind == VALUE_TYPE) - emitvalue(v); + emitname(v); else if (class) putchar(class); else @@ -1081,7 +1097,7 @@ emittype(struct type *t) emittype(sub); } fputs("type ", stdout); - emitvalue(t->value); + emitname(t->value); if (t == targ->typevalist) { printf(" = align %d { %llu }\n", t->align, t->size); return; @@ -1134,8 +1150,6 @@ emitinst(struct inst **instp, struct inst **instend) } fputs(instname[inst->kind], stdout); putchar(' '); - if (inst->arg[0]->kind == VALUE_GLOBAL && inst->arg[0]->threadlocal) - fputs("thread ", stdout); emitvalue(inst->arg[0]); ++instp; op = inst->kind; @@ -1163,8 +1177,6 @@ emitinst(struct inst **instp, struct inst **instend) default: if (inst->arg[1]) { fputs(", ", stdout); - if (inst->arg[1]->kind == VALUE_GLOBAL && inst->arg[1]->threadlocal) - fputs("thread ", stdout); emitvalue(inst->arg[1]); } } @@ -1186,16 +1198,16 @@ emitjump(struct jump *j) break; case JUMP_JMP: fputs("\tjmp ", stdout); - emitvalue(&j->blk[0]->label); + emitname(&j->blk[0]->label); putchar('\n'); break; case JUMP_JNZ: fputs("\tjnz ", stdout); emitvalue(j->arg); fputs(", ", stdout); - emitvalue(&j->blk[0]->label); + emitname(&j->blk[0]->label); fputs(", ", stdout); - emitvalue(&j->blk[1]->label); + emitname(&j->blk[1]->label); putchar('\n'); break; } @@ -1223,14 +1235,14 @@ emitfunc(struct func *f, bool global) emitclass(qbetype(f->type->base).base, f->type->base->value); putchar(' '); } - emitvalue(f->decl->value); + emitname(f->decl->value); putchar('('); for (p = f->type->u.func.params, v = f->paramtemps; p; p = p->next, ++v) { if (p != f->type->u.func.params) fputs(", ", stdout); emitclass(qbetype(p->type).base, p->type->value); putchar(' '); - emitvalue(v); + emitname(v); } if (f->type->u.func.isvararg) { if (f->type->u.func.params) @@ -1239,17 +1251,17 @@ emitfunc(struct func *f, bool global) } puts(") {"); for (b = f->start; b; b = b->next) { - emitvalue(&b->label); + emitname(&b->label); putchar('\n'); if (b->phi.res.kind) { putchar('\t'); emitvalue(&b->phi.res); printf(" =%c phi ", b->phi.class); - emitvalue(&b->phi.blk[0]->label); + emitname(&b->phi.blk[0]->label); putchar(' '); emitvalue(b->phi.val[0]); fputs(", ", stdout); - emitvalue(&b->phi.blk[1]->label); + emitname(&b->phi.blk[1]->label); putchar(' '); emitvalue(b->phi.val[1]); putchar('\n'); @@ -1279,7 +1291,7 @@ dataitem(struct expr *expr, unsigned long long size) decl = expr->u.ident.decl; if (decl->kind == DECLOBJECT && decl->u.obj.storage != SDSTATIC) error(&tok.loc, "initializer is not a constant expression"); - emitvalue(decl->value); + emitname(decl->value); break; case EXPRBINARY: if (expr->op != TADD || expr->u.binary.l->kind != EXPRUNARY || expr->u.binary.r->kind != EXPRCONST) @@ -1340,7 +1352,7 @@ emitdata(struct decl *d, struct init *init) if (d->linkage == LINKEXTERN) fputs("export ", stdout); fputs("data ", stdout); - emitvalue(d->value); + emitname(d->value); printf(" = align %d { ", align); while (init) { |