## Dis opcode mnemonics. Keep in sync with interp/tab.h!# #MAXDIS: con INEWAZ+1; instname := array [MAXDIS] of { "nop", "alt", "nbalt", "goto", "call", "frame", "spawn", "runt", "load", "mcall", "mspawn", "mframe", "ret", "jmp", "case", "exit", "new", "newa", "newcb", "newcw", "newcf", "newcp", "newcm", "newcmp", "send", "recv", "consb", "consw", "consp", "consf", "consm", "consmp", "headb", "headw", "headp", "headf", "headm", "headmp", "tail", "lea", "indx", "movp", "movm", "movmp", "movb", "movw", "movf", "cvtbw", "cvtwb", "cvtfw", "cvtwf", "cvtca", "cvtac", "cvtwc", "cvtcw", "cvtfc", "cvtcf", "addb", "addw", "addf", "subb", "subw", "subf", "mulb", "mulw", "mulf", "divb", "divw", "divf", "modw", "modb", "andb", "andw", "orb", "orw", "xorb", "xorw", "shlb", "shlw", "shrb", "shrw", "insc", "indc", "addc", "lenc", "lena", "lenl", "beqb", "bneb", "bltb", "bleb", "bgtb", "bgeb", "beqw", "bnew", "bltw", "blew", "bgtw", "bgew", "beqf", "bnef", "bltf", "blef", "bgtf", "bgef", "beqc", "bnec", "bltc", "blec", "bgtc", "bgec", "slicea", "slicela", "slicec", "indw", "indf", "indb", "negf", "movl", "addl", "subl", "divl", "modl", "mull", "andl", "orl", "xorl", "shll", "shrl", "bnel", "bltl", "blel", "bgtl", "bgel", "beql", "cvtlf", "cvtfl", "cvtlw", "cvtwl", "cvtlc", "cvtcl", "headl", "consl", "newcl", "casec", "indl", "movpc", "tcmp", "mnewz", "cvtrf", "cvtfr", "cvtws", "cvtsw", "lsrw", "lsrl", "eclr", "newz", "newaz", "raise",}; ## %A format conversion.# addrconv(a: ref Addr): string{ s := ""; case int a.mode { int Aimm => s = "$" + string a.ival; int Afp => s = string a.offset + "(fp)"; int Amp => s = string a.offset + "(mp)"; int Afpind => s = string a.offset + "(" + string a.ival + "(fp))"; int Ampind => s = string a.offset + "(" + string a.ival + "(mp))"; } return s;} ## %I format conversion.# instconv(in: ref Inst): string{ op := ""; if(in.op < byte MAXDIS) op = instname[int in.op]; else op = "??"; s := "\t" + op + "\t"; comma := ""; if(in.s.mode != Anone) { s += addrconv(in.s); comma = ","; } if(in.m.mode != Anone) { s += comma; s += addrconv(in.m); comma = ","; } if(in.d.mode != Anone) s += comma; s += addrconv(in.d); return s;} asmhandlers(){ nex := len class.handlers; bout.puts("\texceptions " + string nex + "\n"); for (it := class.handlers; it != nil; it = tl it) { h := hd it; bout.puts(sprint("\texception\t%d, %d, 0, -1, 0, 0\n", h.start_pc, h.end_pc)); bout.puts(sprint("\texctab\t*, %d\n", h.handler_pc)); }} ehtable(c: ref Code){ i: int; s: string; h: ref Handler; if(c.nex == 0) return; bout.puts("#\tException Table\n"); for(i = 0; i < c.nex; i++) { h = c.ex[i]; if(h.catch_type == 0) s = "*"; else s = CLASSNAME(h.catch_type); bout.puts("#\t" + string h.start_pc + " " + string h.end_pc + " " + string h.handler_pc + " " + s + "\n"); }} putinst(i: ref Inst){ while(i != nil) { if(i.pc % 10 == 0) bout.puts("#" + string i.pc + "\n"); bout.puts(instconv(i) + "\n"); i = i.next; }} clinitclone: ref Inst; # generated <clinit>, <clone> methods ## Emit assembly instructions for a method.# asminst(){ i: ref Inst; j: ref Jinst; n, jix: int; c: ref Code; if(verbose == 0) { putinst(ihead); return; } # -v option for(n = 0; n < class.methods_count; n++) { bout.puts("#Method: " + pcode[n].name + pcode[n].sig + "\n"); if(pcode[n].code == nil) continue; ehtable(pcode[n].code); c = pcode[n].code; jix = 0; while(jix < c.code_length) { j = c.j[jix]; bout.puts("#J" + string j.pc + "\t" + jinstconv(j) + "\n"); for(i = j.dis; i != nil && i.j == j; i = i.next) { if(i.pc % 10 == 0) bout.puts("#" + string i.pc + "\n"); bout.puts(instconv(i) + "\n"); } jix += j.size; } } if(clinitclone != nil) { bout.puts("#Method: <clinit|clone>()V\n"); putinst(clinitclone); }} sblinst(bsym: ref Bufio->Iobuf){ i: ref Inst; n, curline, lastline, lastchar, blockid: int; if(itail != nil) n = itail.pc + 1; else n = 0; bsym.puts(string n + "\n"); curline = 1; lastline = -1; # A small hack: we cannot know the exact number of chars in the line, # so we supply some dummy large value. lastchar = 42000; blockid = -1; for(i = ihead; i != nil; i = i.next) { if(i.j != nil) curline = i.j.line; if(curline != lastline) { lastline = curline; lastchar = 42000; blockid++; bsym.puts(string curline + "."); } bsym.puts("0," + string lastchar++ + " " + string blockid + "\n"); }}
#
# Dis opcode mnemonics. Keep in sync with interp/tab.h!
#
#MAXDIS: con INEWAZ+1;
instname := array [MAXDIS] of {
"nop",
"alt",
"nbalt",
"goto",
"call",
"frame",
"spawn",
"runt",
"load",
"mcall",
"mspawn",
"mframe",
"ret",
"jmp",
"case",
"exit",
"new",
"newa",
"newcb",
"newcw",
"newcf",
"newcp",
"newcm",
"newcmp",
"send",
"recv",
"consb",
"consw",
"consp",
"consf",
"consm",
"consmp",
"headb",
"headw",
"headp",
"headf",
"headm",
"headmp",
"tail",
"lea",
"indx",
"movp",
"movm",
"movmp",
"movb",
"movw",
"movf",
"cvtbw",
"cvtwb",
"cvtfw",
"cvtwf",
"cvtca",
"cvtac",
"cvtwc",
"cvtcw",
"cvtfc",
"cvtcf",
"addb",
"addw",
"addf",
"subb",
"subw",
"subf",
"mulb",
"mulw",
"mulf",
"divb",
"divw",
"divf",
"modw",
"modb",
"andb",
"andw",
"orb",
"orw",
"xorb",
"xorw",
"shlb",
"shlw",
"shrb",
"shrw",
"insc",
"indc",
"addc",
"lenc",
"lena",
"lenl",
"beqb",
"bneb",
"bltb",
"bleb",
"bgtb",
"bgeb",
"beqw",
"bnew",
"bltw",
"blew",
"bgtw",
"bgew",
"beqf",
"bnef",
"bltf",
"blef",
"bgtf",
"bgef",
"beqc",
"bnec",
"bltc",
"blec",
"bgtc",
"bgec",
"slicea",
"slicela",
"slicec",
"indw",
"indf",
"indb",
"negf",
"movl",
"addl",
"subl",
"divl",
"modl",
"mull",
"andl",
"orl",
"xorl",
"shll",
"shrl",
"bnel",
"bltl",
"blel",
"bgtl",
"bgel",
"beql",
"cvtlf",
"cvtfl",
"cvtlw",
"cvtwl",
"cvtlc",
"cvtcl",
"headl",
"consl",
"newcl",
"casec",
"indl",
"movpc",
"tcmp",
"mnewz",
"cvtrf",
"cvtfr",
"cvtws",
"cvtsw",
"lsrw",
"lsrl",
"eclr",
"newz",
"newaz",
"raise",
};
#
# %A format conversion.
#
addrconv(a: ref Addr): string
{
s := "";
case int a.mode {
int Aimm =>
s = "$" + string a.ival;
int Afp =>
s = string a.offset + "(fp)";
int Amp =>
s = string a.offset + "(mp)";
int Afpind =>
s = string a.offset + "(" + string a.ival + "(fp))";
int Ampind =>
s = string a.offset + "(" + string a.ival + "(mp))";
}
return s;
}
#
# %I format conversion.
#
instconv(in: ref Inst): string
{
op := "";
if(in.op < byte MAXDIS)
op = instname[int in.op];
else
op = "??";
s := "\t" + op + "\t";
comma := "";
if(in.s.mode != Anone) {
s += addrconv(in.s);
comma = ",";
}
if(in.m.mode != Anone) {
s += comma;
s += addrconv(in.m);
comma = ",";
}
if(in.d.mode != Anone)
s += comma;
s += addrconv(in.d);
return s;
}
asmhandlers()
{
nex := len class.handlers;
bout.puts("\texceptions " + string nex + "\n");
for (it := class.handlers; it != nil; it = tl it) {
h := hd it;
bout.puts(sprint("\texception\t%d, %d, 0, -1, 0, 0\n", h.start_pc, h.end_pc));
bout.puts(sprint("\texctab\t*, %d\n", h.handler_pc));
}
}
ehtable(c: ref Code)
{
i: int;
s: string;
h: ref Handler;
if(c.nex == 0)
return;
bout.puts("#\tException Table\n");
for(i = 0; i < c.nex; i++) {
h = c.ex[i];
if(h.catch_type == 0)
s = "*";
else
s = CLASSNAME(h.catch_type);
bout.puts("#\t" + string h.start_pc + " " + string h.end_pc
+ " " + string h.handler_pc + " " + s + "\n");
}
}
putinst(i: ref Inst)
{
while(i != nil) {
if(i.pc % 10 == 0)
bout.puts("#" + string i.pc + "\n");
bout.puts(instconv(i) + "\n");
i = i.next;
}
}
clinitclone: ref Inst; # generated <clinit>, <clone> methods
#
# Emit assembly instructions for a method.
#
asminst()
{
i: ref Inst;
j: ref Jinst;
n, jix: int;
c: ref Code;
if(verbose == 0) {
putinst(ihead);
return;
}
# -v option
for(n = 0; n < class.methods_count; n++) {
bout.puts("#Method: " + pcode[n].name + pcode[n].sig + "\n");
if(pcode[n].code == nil)
continue;
ehtable(pcode[n].code);
c = pcode[n].code;
jix = 0;
while(jix < c.code_length) {
j = c.j[jix];
bout.puts("#J" + string j.pc + "\t" + jinstconv(j) + "\n");
for(i = j.dis; i != nil && i.j == j; i = i.next) {
if(i.pc % 10 == 0)
bout.puts("#" + string i.pc + "\n");
bout.puts(instconv(i) + "\n");
}
jix += j.size;
}
}
if(clinitclone != nil) {
bout.puts("#Method: <clinit|clone>()V\n");
putinst(clinitclone);
}
}
sblinst(bsym: ref Bufio->Iobuf)
{
i: ref Inst;
n, curline, lastline, lastchar, blockid: int;
if(itail != nil)
n = itail.pc + 1;
else
n = 0;
bsym.puts(string n + "\n");
curline = 1;
lastline = -1;
# A small hack: we cannot know the exact number of chars in the line,
# so we supply some dummy large value.
lastchar = 42000;
blockid = -1;
for(i = ihead; i != nil; i = i.next) {
if(i.j != nil)
curline = i.j.line;
if(curline != lastline) {
lastline = curline;
lastchar = 42000;
blockid++;
bsym.puts(string curline + ".");
}
bsym.puts("0," + string lastchar++ + " " + string blockid + "\n");
}
}