summaryrefslogtreecommitdiff
path: root/limbo/asm.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /limbo/asm.c
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'limbo/asm.c')
-rw-r--r--limbo/asm.c289
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);
+ }
+}