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