xref: /plan9-contrib/sys/src/cmd/8l/list.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"l.h"
2 
3 void
4 listinit(void)
5 {
6 
7 	fmtinstall('R', Rconv);
8 	fmtinstall('A', Aconv);
9 	fmtinstall('D', Dconv);
10 	fmtinstall('X', Xconv);
11 	fmtinstall('S', Sconv);
12 	fmtinstall('P', Pconv);
13 }
14 
15 static	Prog	*bigP;
16 
17 int
18 Pconv(void *o, Fconv *fp)
19 {
20 	char str[STRINGSZ];
21 	Prog *p;
22 
23 	p = *(Prog**)o;
24 	bigP = p;
25 	switch(p->as) {
26 	case ATEXT:
27 		if(p->from.scale) {
28 			sprint(str, "(%ld)	%A	%D,%d,%D",
29 				p->line, p->as, &p->from, p->from.scale, &p->to);
30 			break;
31 		}
32 	default:
33 		sprint(str, "(%ld)	%A	%D,%D",
34 			p->line, p->as, &p->from, &p->to);
35 		break;
36 	case ADATA:
37 	case AINIT:
38 	case ADYNT:
39 		sprint(str, "(%ld)	%A	%D/%d,%D",
40 			p->line, p->as, &p->from, p->from.scale, &p->to);
41 		break;
42 	}
43 	strconv(str, fp);
44 	bigP = P;
45 	return sizeof(Prog*);
46 }
47 
48 int
49 Aconv(void *o, Fconv *fp)
50 {
51 
52 	strconv(anames[*(int*)o], fp);
53 	return sizeof(int);
54 }
55 
56 int
57 Xconv(void *o, Fconv *fp)
58 {
59 	char str[20];
60 	int i;
61 
62 	str[0] = 0;
63 	i = ((int*)o)[0];
64 	if(i != D_NONE)
65 		sprint(str, "(%R*%d)", i, ((int*)o)[1]);
66 	strconv(str, fp);
67 	return sizeof(int[2]);
68 }
69 
70 int
71 Dconv(void *o, Fconv *fp)
72 {
73 	char str[40], s[20];
74 	Adr *a;
75 	int i;
76 
77 	a = *(Adr**)o;
78 	i = a->type;
79 	if(i >= D_INDIR) {
80 		if(a->offset)
81 			sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
82 		else
83 			sprint(str, "(%R)", i-D_INDIR);
84 		goto brk;
85 	}
86 	switch(i) {
87 
88 	default:
89 		sprint(str, "%R", i);
90 		break;
91 
92 	case D_NONE:
93 		str[0] = 0;
94 		break;
95 
96 	case D_BRANCH:
97 		if(bigP != P && bigP->cond != P)
98 			if(a->sym != S)
99 				sprint(str, "%lux+%s", bigP->cond->pc,
100 					a->sym->name);
101 			else
102 				sprint(str, "%lux", bigP->cond->pc);
103 		else
104 			sprint(str, "%ld(PC)", a->offset);
105 		break;
106 
107 	case D_EXTERN:
108 		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
109 		break;
110 
111 	case D_STATIC:
112 		sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
113 			a->sym->version, a->offset);
114 		break;
115 
116 	case D_AUTO:
117 		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
118 		break;
119 
120 	case D_PARAM:
121 		if(a->sym)
122 			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
123 		else
124 			sprint(str, "%ld(FP)", a->offset);
125 		break;
126 
127 	case D_CONST:
128 		sprint(str, "$%ld", a->offset);
129 		break;
130 
131 	case D_FCONST:
132 		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
133 		break;
134 
135 	case D_SCONST:
136 		sprint(str, "$\"%S\"", a->scon);
137 		break;
138 
139 	case D_ADDR:
140 		a->type = a->index;
141 		a->index = D_NONE;
142 		sprint(str, "$%D", a);
143 		a->index = a->type;
144 		a->type = D_ADDR;
145 		goto conv;
146 	}
147 brk:
148 	if(a->index != D_NONE) {
149 		sprint(s, "%X", a->index, a->scale);
150 		strcat(str, s);
151 	}
152 conv:
153 	strconv(str, fp);
154 	return sizeof(Adr*);
155 }
156 
157 char*	regstr[] =
158 {
159 [D_AL]	"AL",
160 	"CL",
161 	"DL",
162 	"BL",
163 	"AH",
164 	"CH",
165 	"DH",
166 	"BH",
167 
168 [D_AX]	"AX",
169 	"CX",
170 	"DX",
171 	"BX",
172 	"SP",
173 	"BP",
174 	"SI",
175 	"DI",
176 
177 [D_F0]	"F0",
178 	"F1",
179 	"F2",
180 	"F3",
181 	"F4",
182 	"F5",
183 	"F6",
184 	"F7",
185 
186 [D_CS]	"CS",
187 	"SS",
188 	"DS",
189 	"ES",
190 	"FS",
191 	"GS",
192 
193 [D_GDTR]"GDTR",
194 [D_IDTR]"IDTR",
195 [D_LDTR]"LDTR",
196 [D_MSW]	"MSW",
197 [D_TASK]"TASK",
198 
199 [D_CR]	"CR0",
200 	"CR1",
201 	"CR2",
202 	"CR3",
203 	"CR4",
204 	"CR5",
205 	"CR6",
206 	"CR7",
207 
208 [D_DR]	"DR0",
209 	"DR1",
210 	"DR2",
211 	"DR3",
212 	"DR4",
213 	"DR5",
214 	"DR6",
215 	"DR7",
216 
217 [D_TR]	"TR0",
218 	"TR1",
219 	"TR2",
220 	"TR3",
221 	"TR4",
222 	"TR5",
223 	"TR6",
224 	"TR7",
225 
226 [D_NONE]"NONE",
227 };
228 
229 int
230 Rconv(void *o, Fconv *fp)
231 {
232 	char str[20];
233 	int r;
234 
235 	r = *(int*)o;
236 	if(r >= D_AL && r <= D_NONE)
237 		sprint(str, "%s", regstr[r-D_AL]);
238 	else
239 		sprint(str, "gok(%d)", r);
240 
241 	strconv(str, fp);
242 	return sizeof(int);
243 }
244 
245 int
246 Sconv(void *o, Fconv *fp)
247 {
248 	int i, c;
249 	char str[30], *p, *a;
250 
251 	a = *(char**)o;
252 	p = str;
253 	for(i=0; i<sizeof(double); i++) {
254 		c = a[i] & 0xff;
255 		if(c >= 'a' && c <= 'z' ||
256 		   c >= 'A' && c <= 'Z' ||
257 		   c >= '0' && c <= '9') {
258 			*p++ = c;
259 			continue;
260 		}
261 		*p++ = '\\';
262 		switch(c) {
263 		default:
264 			if(c < 040 || c >= 0177)
265 				break;	/* not portable */
266 			p[-1] = c;
267 			continue;
268 		case 0:
269 			*p++ = 'z';
270 			continue;
271 		case '\\':
272 		case '"':
273 			*p++ = c;
274 			continue;
275 		case '\n':
276 			*p++ = 'n';
277 			continue;
278 		case '\t':
279 			*p++ = 't';
280 			continue;
281 		}
282 		*p++ = (c>>6) + '0';
283 		*p++ = ((c>>3) & 7) + '0';
284 		*p++ = (c & 7) + '0';
285 	}
286 	*p = 0;
287 	strconv(str, fp);
288 	return sizeof(char*);
289 }
290 
291 void
292 diag(char *a, ...)
293 {
294 	char buf[STRINGSZ], *tn;
295 
296 	tn = "??none??";
297 	if(curtext != P && curtext->from.sym != S)
298 		tn = curtext->from.sym->name;
299 	doprint(buf, buf+sizeof(buf), a, &(&a)[1]);	/* ugly */
300 	print("%s: %s\n", tn, buf);
301 
302 	nerrors++;
303 	if(nerrors > 10) {
304 		print("too many errors\n");
305 		errorexit();
306 	}
307 }
308