263 lines · 6.5 KB · Brainfuck
RawDownload
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');	}}