ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/cmd/limbo/asm.b/
asmentry(e: ref Decl)
{
if(e == nil)
return;
bout.puts("\tentry\t"+string e.pc.pc+", "+string e.desc.id+"\n");
}
asmmod(m: ref Decl)
{
bout.puts("\tmodule\t");
bout.puts(m.sym.name);
bout.putc('\n');
for(m = m.ty.tof.ids; m != nil; m = m.next){
case m.store{
Dglobal =>
bout.puts("\tlink\t-1,-1,0x"+hex(sign(m), 0)+",\".mp\"\n");
Dfn =>
bout.puts("\tlink\t"+string m.desc.id+","+string m.pc.pc+",0x"+string hex(sign(m), 0)+",\"");
if(m.dot.ty.kind == Tadt)
bout.puts(m.dot.sym.name+".");
bout.puts(m.sym.name+"\"\n");
}
}
}
asmpath()
{
bout.puts("\tsource\t\"" + srcpath() + "\"\n");
}
asmdesc(d: ref Desc)
{
for(; d != nil; d = d.next){
bout.puts("\tdesc\t$"+string d.id+","+string d.size+",\"");
e := d.nmap;
m := d.map;
for(i := 0; i < e; i++)
bout.puts(hex(int m[i], 2));
bout.puts("\"\n");
}
}
asmvar(size: int, d: ref Decl)
{
bout.puts("\tvar\t@mp," + string size + "\n");
for(; d != nil; d = d.next)
if(d.store == Dglobal && d.init != nil)
asminitializer(d.offset, d.init);
}
asmldt(size: int, d: ref Decl)
{
bout.puts("\tldts\t@ldt," + string size + "\n");
for(; d != nil; d = d.next)
if(d.store == Dglobal && d.init != nil)
asminitializer(d.offset, d.init);
}
asminitializer(offset: int, n: ref Node)
{
wild: ref Node;
c: ref Case;
lab: Label;
id: ref Decl;
i, e: int;
case n.ty.kind{
Tbyte =>
bout.puts("\tbyte\t@mp+"+string offset+","+string(int n.c.val & 16rff)+"\n");
Tint or
Tfix =>
bout.puts("\tword\t@mp+"+string offset+","+string(int n.c.val)+"\n");
Tbig =>
bout.puts("\tlong\t@mp+"+string offset+","+string n.c.val+" # "+string bhex(n.c.val, 16)+"\n");
Tstring =>
asmstring(offset, n.decl.sym);
Treal =>
fs := "";
ba := array[8] of byte;
export_real(ba, array[] of {n.c.rval});
for(i = 0; i < 8; i++)
fs += hex(int ba[i], 2);
bout.puts("\treal\t@mp+"+string offset+","+string n.c.rval+" # "+fs+"\n");
Tadt or
Tadtpick or
Ttuple =>
id = n.ty.ids;
for(n = n.left; n != nil; n = n.right){
asminitializer(offset + id.offset, n.left);
id = id.next;
}
Tcase =>
c = n.ty.cse;
bout.puts("\tword\t@mp+"+string offset+","+string c.nlab);
for(i = 0; i < c.nlab; i++){
lab = c.labs[i];
bout.puts(","+string(int lab.start.c.val)+","+string(int lab.stop.c.val+1)+","+string(lab.inst.pc));
}
if(c.iwild != nil)
bout.puts(","+string c.iwild.pc+"\n");
else
bout.puts(",-1\n");
Tcasel =>
c = n.ty.cse;
bout.puts("\tword\t@mp+"+string offset+","+string c.nlab);
for(i = 0; i < c.nlab; i++){
lab = c.labs[i];
bout.puts(","+string(lab.start.c.val)+","+string(lab.stop.c.val+big 1)+","+string(lab.inst.pc));
}
if(c.iwild != nil)
bout.puts(","+string c.iwild.pc+"\n");
else
bout.puts(",-1\n");
Tcasec =>
c = n.ty.cse;
bout.puts("\tword\t@mp+"+string offset+","+string c.nlab+"\n");
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;
bout.puts("\tword\t@mp+"+string offset+","+string lab.inst.pc+"\n");
offset += IBY2WD;
}
if(c.iwild != nil)
bout.puts("\tword\t@mp+"+string offset+","+string c.iwild.pc+"\n");
else
bout.puts("\tword\t@mp+"+string offset+",-1\n");
Tgoto =>
c = n.ty.cse;
bout.puts("\tword\t@mp+"+string offset);
bout.puts(","+string(n.ty.size/IBY2WD-1));
for(i = 0; i < c.nlab; i++)
bout.puts(","+string c.labs[i].inst.pc);
if(c.iwild != nil)
bout.puts(","+string c.iwild.pc);
bout.puts("\n");
Tany =>
break;
Tarray =>
bout.puts("\tarray\t@mp+"+string offset+",$"+string n.ty.tof.decl.desc.id+","+string int n.left.c.val+"\n");
if(n.right == nil)
break;
bout.puts("\tindir\t@mp+"+string offset+",0\n");
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 = int c.labs[i].start.c.val;
if(wild != nil){
for(; last < e; last++)
asminitializer(esz * last, wild);
}
last = e;
e = int c.labs[i].stop.c.val;
elem := c.labs[i].node.right;
for(; last <= e; last++)
asminitializer(esz * last, elem);
}
if(wild != nil)
for(e = int n.left.c.val; last < e; last++)
asminitializer(esz * last, wild);
bout.puts("\tapop\n");
Tiface =>
if(LDT)
bout.puts("\tword\t@ldt+"+string offset+","+string int n.c.val+"\n");
else
bout.puts("\tword\t@mp+"+string offset+","+string int n.c.val+"\n");
offset += IBY2WD;
for(id = n.decl.ty.ids; id != nil; id = id.next){
offset = align(offset, IBY2WD);
if(LDT)
bout.puts("\text\t@ldt+"+string offset+",0x"+string hex(sign(id), 0)+",\"");
else
bout.puts("\text\t@mp+"+string offset+",0x"+string hex(sign(id), 0)+",\"");
dotlen := 0;
idlen := len array of byte id.sym.name + 1;
if(id.dot.ty.kind == Tadt){
dotlen = len array of byte id.dot.sym.name + 1;
bout.puts(id.dot.sym.name+".");
}
bout.puts(id.sym.name+"\"\n");
offset += idlen + dotlen + IBY2WD;
}
* =>
fatal("can't asm global "+nodeconv(n));
}
}
asmexc(es: ref Except)
{
e: ref Except;
n := 0;
for(e = es; e != nil; e = e.next)
n++;
bout.puts("\texceptions\t" + string n + "\n");
for(e = es; e != nil; e = e.next){
if(!int e.p1.reach && !int e.p2.reach)
continue;
c := e.c;
o := e.d.offset;
if(e.desc != nil)
id := e.desc.id;
else
id = -1;
bout.puts("\texception\t" + string getpc(e.p1) + ", " + string getpc(e.p2) + ", " + string o + ", " + string id + ", " + string c.nlab + ", " + string e.ne + "\n");
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;
bout.puts("\texctab\t\"" + d.sym.name + "\", " + string lab.inst.pc + "\n");
}
if(c.iwild == nil)
bout.puts("\texctab\t" + "*" + ", " + string -1 + "\n");
else
bout.puts("\texctab\t" + "*" + ", " + string c.iwild.pc + "\n");
}
}
asmstring(offset: int, sym: ref Sym)
{
bout.puts("\tstring\t@mp+"+string offset+",\"");
s := sym.name;
for(i := 0; i < len s; i++){
c := s[i];
if(c == '\n')
bout.puts("\\n");
else if(c == '\u0000')
bout.puts("\\z");
else if(c == '"')
bout.puts("\\\"");
else if(c == '\\')
bout.puts("\\\\");
else
bout.putc(c);
}
bout.puts("\"\n");
}
asminst(in: ref Inst)
{
for(; in != nil; in = in.next){
if(in.op == INOOP)
continue;
if(in.pc % 10 == 0){
bout.putc('#');
bout.puts(string in.pc);
bout.putc('\n');
}
bout.puts(instconv(in));
bout.putc('\n');
}
}