xref: /inferno-os/appl/cmd/limbo/asm.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1asmentry(e: ref Decl)
2{
3	if(e == nil)
4		return;
5	bout.puts("\tentry\t"+string e.pc.pc+", "+string e.desc.id+"\n");
6}
7
8asmmod(m: ref Decl)
9{
10	bout.puts("\tmodule\t");
11	bout.puts(m.sym.name);
12	bout.putc('\n');
13	for(m = m.ty.tof.ids; m != nil; m = m.next){
14		case m.store{
15		Dglobal =>
16			bout.puts("\tlink\t-1,-1,0x"+hex(sign(m), 0)+",\".mp\"\n");
17		Dfn =>
18			bout.puts("\tlink\t"+string m.desc.id+","+string m.pc.pc+",0x"+string hex(sign(m), 0)+",\"");
19			if(m.dot.ty.kind == Tadt)
20				bout.puts(m.dot.sym.name+".");
21			bout.puts(m.sym.name+"\"\n");
22		}
23	}
24}
25
26asmpath()
27{
28	bout.puts("\tsource\t\"" + srcpath() + "\"\n");
29}
30
31asmdesc(d: ref Desc)
32{
33	for(; d != nil; d = d.next){
34		bout.puts("\tdesc\t$"+string d.id+","+string d.size+",\"");
35		e := d.nmap;
36		m := d.map;
37		for(i := 0; i < e; i++)
38			bout.puts(hex(int m[i], 2));
39		bout.puts("\"\n");
40	}
41}
42
43asmvar(size: int, d: ref Decl)
44{
45	bout.puts("\tvar\t@mp," + string size + "\n");
46
47	for(; d != nil; d = d.next)
48		if(d.store == Dglobal && d.init != nil)
49			asminitializer(d.offset, d.init);
50}
51
52asmldt(size: int, d: ref Decl)
53{
54	bout.puts("\tldts\t@ldt," + string size + "\n");
55
56	for(; d != nil; d = d.next)
57		if(d.store == Dglobal && d.init != nil)
58			asminitializer(d.offset, d.init);
59}
60
61asminitializer(offset: int, n: ref Node)
62{
63	wild: ref Node;
64	c: ref Case;
65	lab: Label;
66	id: ref Decl;
67	i, e: int;
68
69	case n.ty.kind{
70	Tbyte =>
71		bout.puts("\tbyte\t@mp+"+string offset+","+string(int n.c.val & 16rff)+"\n");
72	Tint or
73	Tfix =>
74		bout.puts("\tword\t@mp+"+string offset+","+string(int n.c.val)+"\n");
75	Tbig =>
76		bout.puts("\tlong\t@mp+"+string offset+","+string n.c.val+" # "+string bhex(n.c.val, 16)+"\n");
77	Tstring =>
78		asmstring(offset, n.decl.sym);
79	Treal =>
80		fs := "";
81		ba := array[8] of byte;
82		export_real(ba, array[] of {n.c.rval});
83		for(i = 0; i < 8; i++)
84			fs += hex(int ba[i], 2);
85		bout.puts("\treal\t@mp+"+string offset+","+string n.c.rval+" # "+fs+"\n");
86	Tadt or
87	Tadtpick or
88	Ttuple =>
89		id = n.ty.ids;
90		for(n = n.left; n != nil; n = n.right){
91			asminitializer(offset + id.offset, n.left);
92			id = id.next;
93		}
94	Tcase =>
95		c = n.ty.cse;
96		bout.puts("\tword\t@mp+"+string offset+","+string c.nlab);
97		for(i = 0; i < c.nlab; i++){
98			lab = c.labs[i];
99			bout.puts(","+string(int lab.start.c.val)+","+string(int lab.stop.c.val+1)+","+string(lab.inst.pc));
100		}
101		if(c.iwild != nil)
102			bout.puts(","+string c.iwild.pc+"\n");
103		else
104			bout.puts(",-1\n");
105	Tcasel =>
106		c = n.ty.cse;
107		bout.puts("\tword\t@mp+"+string offset+","+string c.nlab);
108		for(i = 0; i < c.nlab; i++){
109			lab = c.labs[i];
110			bout.puts(","+string(lab.start.c.val)+","+string(lab.stop.c.val+big 1)+","+string(lab.inst.pc));
111		}
112		if(c.iwild != nil)
113			bout.puts(","+string c.iwild.pc+"\n");
114		else
115			bout.puts(",-1\n");
116	Tcasec =>
117		c = n.ty.cse;
118		bout.puts("\tword\t@mp+"+string offset+","+string c.nlab+"\n");
119		offset += IBY2WD;
120		for(i = 0; i < c.nlab; i++){
121			lab = c.labs[i];
122			asmstring(offset, lab.start.decl.sym);
123			offset += IBY2WD;
124			if(lab.stop != lab.start)
125				asmstring(offset, lab.stop.decl.sym);
126			offset += IBY2WD;
127			bout.puts("\tword\t@mp+"+string offset+","+string lab.inst.pc+"\n");
128			offset += IBY2WD;
129		}
130		if(c.iwild != nil)
131			bout.puts("\tword\t@mp+"+string offset+","+string c.iwild.pc+"\n");
132		else
133			bout.puts("\tword\t@mp+"+string offset+",-1\n");
134	Tgoto =>
135		c = n.ty.cse;
136		bout.puts("\tword\t@mp+"+string offset);
137		bout.puts(","+string(n.ty.size/IBY2WD-1));
138		for(i = 0; i < c.nlab; i++)
139			bout.puts(","+string c.labs[i].inst.pc);
140		if(c.iwild != nil)
141			bout.puts(","+string c.iwild.pc);
142		bout.puts("\n");
143	Tany =>
144		break;
145	Tarray =>
146		bout.puts("\tarray\t@mp+"+string offset+",$"+string n.ty.tof.decl.desc.id+","+string int n.left.c.val+"\n");
147		if(n.right == nil)
148			break;
149		bout.puts("\tindir\t@mp+"+string offset+",0\n");
150		c = n.right.ty.cse;
151		wild = nil;
152		if(c.wild != nil)
153			wild = c.wild.right;
154		last := 0;
155		esz := n.ty.tof.size;
156		for(i = 0; i < c.nlab; i++){
157			e = int c.labs[i].start.c.val;
158			if(wild != nil){
159				for(; last < e; last++)
160					asminitializer(esz * last, wild);
161			}
162			last = e;
163			e = int c.labs[i].stop.c.val;
164			elem := c.labs[i].node.right;
165			for(; last <= e; last++)
166				asminitializer(esz * last, elem);
167		}
168		if(wild != nil)
169			for(e = int n.left.c.val; last < e; last++)
170				asminitializer(esz * last, wild);
171		bout.puts("\tapop\n");
172	Tiface =>
173		if(LDT)
174			bout.puts("\tword\t@ldt+"+string offset+","+string int n.c.val+"\n");
175		else
176			bout.puts("\tword\t@mp+"+string offset+","+string int n.c.val+"\n");
177		offset += IBY2WD;
178		for(id = n.decl.ty.ids; id != nil; id = id.next){
179			offset = align(offset, IBY2WD);
180			if(LDT)
181				bout.puts("\text\t@ldt+"+string offset+",0x"+string hex(sign(id), 0)+",\"");
182			else
183				bout.puts("\text\t@mp+"+string offset+",0x"+string hex(sign(id), 0)+",\"");
184			dotlen := 0;
185			idlen := len array of byte id.sym.name + 1;
186			if(id.dot.ty.kind == Tadt){
187				dotlen = len array of byte id.dot.sym.name + 1;
188				bout.puts(id.dot.sym.name+".");
189			}
190			bout.puts(id.sym.name+"\"\n");
191			offset += idlen + dotlen + IBY2WD;
192		}
193	* =>
194		fatal("can't asm global "+nodeconv(n));
195	}
196}
197
198asmexc(es: ref Except)
199{
200	e: ref Except;
201
202	n := 0;
203	for(e = es; e != nil; e = e.next)
204		n++;
205	bout.puts("\texceptions\t" + string n + "\n");
206	for(e = es; e != nil; e = e.next){
207		if(!int e.p1.reach && !int e.p2.reach)
208			continue;
209		c := e.c;
210		o := e.d.offset;
211		if(e.desc != nil)
212			id := e.desc.id;
213		else
214			id = -1;
215		bout.puts("\texception\t" + string getpc(e.p1) + ", " + string getpc(e.p2) + ", " + string o + ", " + string id + ", " + string c.nlab + ", " + string e.ne + "\n");
216		for(i := 0; i < c.nlab; i++){
217			lab := c.labs[i];
218			d := lab.start.decl;
219			if(lab.start.ty.kind == Texception)
220				d = d.init.decl;
221			bout.puts("\texctab\t\"" + d.sym.name + "\", " + string lab.inst.pc + "\n");
222		}
223		if(c.iwild == nil)
224			bout.puts("\texctab\t" + "*" + ", " + string -1 + "\n");
225		else
226			bout.puts("\texctab\t" + "*" + ", " + string c.iwild.pc + "\n");
227	}
228}
229
230asmstring(offset: int, sym: ref Sym)
231{
232	bout.puts("\tstring\t@mp+"+string offset+",\"");
233	s := sym.name;
234	for(i := 0; i < len s; i++){
235		c := s[i];
236		if(c == '\n')
237			bout.puts("\\n");
238		else if(c == '\u0000')
239			bout.puts("\\z");
240		else if(c == '"')
241			bout.puts("\\\"");
242		else if(c == '\\')
243			bout.puts("\\\\");
244		else
245			bout.putc(c);
246	}
247	bout.puts("\"\n");
248}
249
250asminst(in: ref Inst)
251{
252	for(; in != nil; in = in.next){
253		if(in.op == INOOP)
254			continue;
255		if(in.pc % 10 == 0){
256			bout.putc('#');
257			bout.puts(string in.pc);
258			bout.putc('\n');
259		}
260		bout.puts(instconv(in));
261		bout.putc('\n');
262	}
263}
264