diff options
Diffstat (limited to 'limbo/asm.c')
| -rw-r--r-- | limbo/asm.c | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/limbo/asm.c b/limbo/asm.c new file mode 100644 index 00000000..cf9b2d5f --- /dev/null +++ b/limbo/asm.c @@ -0,0 +1,289 @@ +#include "limbo.h" + +void +asmentry(Decl *e) +{ + if(e == nil) + return; + Bprint(bout, "\tentry\t%ld, %d\n", e->pc->pc, e->desc->id); +} + +void +asmmod(Decl *m) +{ + Bprint(bout, "\tmodule\t"); + Bprint(bout, "%s\n", m->sym->name); + for(m = m->ty->tof->ids; m != nil; m = m->next){ + switch(m->store){ + case Dglobal: + Bprint(bout, "\tlink\t-1,-1,0x%lux,\".mp\"\n", sign(m)); + break; + case Dfn: + Bprint(bout, "\tlink\t%d,%ld,0x%lux,\"", + m->desc->id, m->pc->pc, sign(m)); + if(m->dot->ty->kind == Tadt) + Bprint(bout, "%s.", m->dot->sym->name); + Bprint(bout, "%s\"\n", m->sym->name); + break; + } + } +} + +#define NAMELEN 64 + +void +asmpath(void) +{ + char name[8*NAMELEN], *sp; + + sp = srcpath(name, 8*NAMELEN); + Bprint(bout, "\tsource\t\"%s\"\n", sp); +} + +void +asmdesc(Desc *d) +{ + uchar *m, *e; + + for(; d != nil; d = d->next){ + Bprint(bout, "\tdesc\t$%d,%lud,\"", d->id, d->size); + e = d->map + d->nmap; + for(m = d->map; m < e; m++) + Bprint(bout, "%.2x", *m); + Bprint(bout, "\"\n"); + } +} + +void +asmvar(long size, Decl *d) +{ + Bprint(bout, "\tvar\t@mp,%ld\n", size); + + for(; d != nil; d = d->next) + if(d->store == Dglobal && d->init != nil) + asminitializer(d->offset, d->init); +} + +void +asmldt(long size, Decl *d) +{ + Bprint(bout, "\tldts\t@ldt,%ld\n", size); + + for(; d != nil; d = d->next) + if(d->store == Dglobal && d->init != nil) + asminitializer(d->offset, d->init); +} + +void +asminitializer(long offset, Node *n) +{ + Node *elem, *wild; + Case *c; + Label *lab; + Decl *id; + ulong dv[2]; + long e, last, esz, dotlen, idlen; + int i; + + switch(n->ty->kind){ + case Tbyte: + Bprint(bout, "\tbyte\t@mp+%ld,%ld\n", offset, (long)n->val & 0xff); + break; + case Tint: + case Tfix: + Bprint(bout, "\tword\t@mp+%ld,%ld\n", offset, (long)n->val); + break; + case Tbig: + Bprint(bout, "\tlong\t@mp+%ld,%lld # %.16llux\n", offset, n->val, n->val); + break; + case Tstring: + asmstring(offset, n->decl->sym); + break; + case Treal: + dtocanon(n->rval, dv); + Bprint(bout, "\treal\t@mp+%ld,%g # %.8lux%.8lux\n", offset, n->rval, dv[0], dv[1]); + break; + case Tadt: + case Tadtpick: + case Ttuple: + id = n->ty->ids; + for(n = n->left; n != nil; n = n->right){ + asminitializer(offset + id->offset, n->left); + id = id->next; + } + break; + case Tcase: + c = n->ty->cse; + Bprint(bout, "\tword\t@mp+%ld,%d", offset, c->nlab); + for(i = 0; i < c->nlab; i++){ + lab = &c->labs[i]; + Bprint(bout, ",%ld,%ld,%ld", (long)lab->start->val, (long)lab->stop->val+1, lab->inst->pc); + } + Bprint(bout, ",%ld\n", c->iwild ? c->iwild->pc : -1); + break; + case Tcasel: + c = n->ty->cse; + Bprint(bout, "\tword\t@mp+%ld,%d", offset, c->nlab); + for(i = 0; i < c->nlab; i++){ + lab = &c->labs[i]; + Bprint(bout, ",%lld,%lld,%ld", lab->start->val, lab->stop->val+1, lab->inst->pc); + } + Bprint(bout, ",%ld\n", c->iwild ? c->iwild->pc : -1); + break; + case Tcasec: + c = n->ty->cse; + Bprint(bout, "\tword\t@mp+%ld,%d\n", offset, c->nlab); + offset += IBY2WD; + for(i = 0; i < c->nlab; i++){ + lab = &c->labs[i]; + asmstring(offset, lab->start->decl->sym); + offset += IBY2WD; + if(lab->stop != lab->start) + asmstring(offset, lab->stop->decl->sym); + offset += IBY2WD; + Bprint(bout, "\tword\t@mp+%ld,%ld\n", offset, lab->inst->pc); + offset += IBY2WD; + } + Bprint(bout, "\tword\t@mp+%ld,%d\n", offset, c->iwild ? c->iwild->pc : -1); + break; + case Tgoto: + c = n->ty->cse; + Bprint(bout, "\tword\t@mp+%ld", offset); + Bprint(bout, ",%ld", n->ty->size/IBY2WD-1); + for(i = 0; i < c->nlab; i++) + Bprint(bout, ",%ld", c->labs[i].inst->pc); + if(c->iwild != nil) + Bprint(bout, ",%ld", c->iwild->pc); + Bprint(bout, "\n"); + break; + case Tany: + break; + case Tarray: + Bprint(bout, "\tarray\t@mp+%ld,$%d,%ld\n", offset, n->ty->tof->decl->desc->id, (long)n->left->val); + if(n->right == nil) + break; + Bprint(bout, "\tindir\t@mp+%ld,0\n", offset); + c = n->right->ty->cse; + wild = nil; + if(c->wild != nil) + wild = c->wild->right; + last = 0; + esz = n->ty->tof->size; + for(i = 0; i < c->nlab; i++){ + e = c->labs[i].start->val; + if(wild != nil){ + for(; last < e; last++) + asminitializer(esz * last, wild); + } + last = e; + e = c->labs[i].stop->val; + elem = c->labs[i].node->right; + for(; last <= e; last++) + asminitializer(esz * last, elem); + } + if(wild != nil) + for(e = n->left->val; last < e; last++) + asminitializer(esz * last, wild); + Bprint(bout, "\tapop\n"); + break; + case Tiface: + if(LDT) + Bprint(bout, "\tword\t@ldt+%d,%d\n", offset, (long)n->val); + else + Bprint(bout, "\tword\t@mp+%d,%d\n", offset, (long)n->val); + offset += IBY2WD; + for(id = n->decl->ty->ids; id != nil; id = id->next){ + offset = align(offset, IBY2WD); + if(LDT) + Bprint(bout, "\text\t@ldt+%d,0x%lux,\"", offset, sign(id)); + else + Bprint(bout, "\text\t@mp+%d,0x%lux,\"", offset, sign(id)); + dotlen = 0; + idlen = id->sym->len + 1; + if(id->dot->ty->kind == Tadt){ + dotlen = id->dot->sym->len + 1; + Bprint(bout, "%s.", id->dot->sym->name); + } + Bprint(bout, "%s\"\n", id->sym->name); + offset += idlen + dotlen + IBY2WD; + } + break; + default: + nerror(n, "can't asm global %n", n); + break; + } +} + +void +asmexc(Except *es) +{ + int i, o, n, id; + Decl *d; + Except *e; + Case *c; + Label *lab; + + n = 0; + for(e = es; e != nil; e = e->next) + n++; + Bprint(bout, "\texceptions\t%d\n", n); + for(e = es; e != nil; e = e->next){ + if(!e->p1->reach && !e->p2->reach) + continue; + c = e->c; + o = e->d->offset; + if(e->desc != nil) + id = e->desc->id; + else + id = -1; + Bprint(bout, "\texception\t%d, %d, %d, %d, %d, %d\n", getpc(e->p1), getpc(e->p2), o, id, c->nlab, e->ne); + for(i = 0; i < c->nlab; i++){ + lab = &c->labs[i]; + d = lab->start->decl; + if(lab->start->ty->kind == Texception) + d = d->init->decl; + Bprint(bout, "\texctab\t\"%s\", %d\n", d->sym->name, lab->inst->pc); + } + if(c->iwild == nil) + Bprint(bout, "\texctab\t*, %d\n", -1); + else + Bprint(bout, "\texctab\t*, %d\n", c->iwild->pc); + } +} + +void +asmstring(long offset, Sym *sym) +{ + char *s, *se; + int c; + + Bprint(bout, "\tstring\t@mp+%ld,\"", offset); + s = sym->name; + se = s + sym->len; + for(; s < se; s++){ + c = *s; + if(c == '\n') + Bwrite(bout, "\\n", 2); + else if(c == '\0') + Bwrite(bout, "\\z", 2); + else if(c == '"') + Bwrite(bout, "\\\"", 2); + else if(c == '\\') + Bwrite(bout, "\\\\", 2); + else + Bputc(bout, c); + } + Bprint(bout, "\"\n"); +} + +void +asminst(Inst *in) +{ + for(; in != nil; in = in->next){ + if(in->op == INOOP) + continue; + if(in->pc % 10 == 0) + Bprint(bout, "#%d\n", in->pc); + Bprint(bout, "%I\n", in); + } +} |
