#include "limbo.h" voidasmentry(Decl *e){ if(e == nil) return; Bprint(bout, "\tentry\t%ld, %d\n", e->pc->pc, e->desc->id);} voidasmmod(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 voidasmpath(void){ char name[8*NAMELEN], *sp; sp = srcpath(name, 8*NAMELEN); Bprint(bout, "\tsource\t\"%s\"\n", sp);} voidasmdesc(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"); }} voidasmvar(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);} voidasmldt(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);} voidasminitializer(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; }} voidasmexc(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); }} voidasmstring(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");} voidasminst(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); }}
#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);
}
}