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