diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/limbo/asm.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/limbo/asm.b')
| -rw-r--r-- | appl/cmd/limbo/asm.b | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/appl/cmd/limbo/asm.b b/appl/cmd/limbo/asm.b new file mode 100644 index 00000000..3788d016 --- /dev/null +++ b/appl/cmd/limbo/asm.b @@ -0,0 +1,263 @@ +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'); + } +} |
