1 #include "l.h"
2
3 void
listinit(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
Pconv(Fmt * fp)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 snprint(str, sizeof(str), "(%ld) %A %D,%d,%D",
28 p->line, p->as, &p->from, p->from.scale, &p->to);
29 break;
30 }
31 default:
32 if(isxyreg(p->to.type) && p->to.index != D_NONE)
33 snprint(str, sizeof(str), "(%ld) V%A %D,%R,%R",
34 p->line, p->as, &p->from, p->to.index, p->to.type);
35 else if(isxyreg(p->from.type) && p->from.index != D_NONE)
36 snprint(str, sizeof(str), "(%ld) V%A %R,%R,%D",
37 p->line, p->as, p->from.type, p->from.index, &p->to);
38 else
39 snprint(str, sizeof(str), "(%ld) %A %D,%D",
40 p->line, p->as, &p->from, &p->to);
41 break;
42 case ADATA:
43 case AINIT:
44 case ADYNT:
45 snprint(str, sizeof(str), "(%ld) %A %D/%d,%D",
46 p->line, p->as, &p->from, p->from.scale, &p->to);
47 break;
48 }
49 bigP = P;
50 return fmtstrcpy(fp, str);
51 }
52
53 int
Aconv(Fmt * fp)54 Aconv(Fmt *fp)
55 {
56 int i;
57
58 i = va_arg(fp->args, int);
59 return fmtstrcpy(fp, anames[i]);
60 }
61
62 int
Dconv(Fmt * fp)63 Dconv(Fmt *fp)
64 {
65 char str[STRINGSZ+40], s[20];
66 Adr *a;
67 int i;
68
69 a = va_arg(fp->args, Adr*);
70 i = a->type;
71 if(i >= D_INDIR && i < D_CONST2) {
72 if(a->offset)
73 snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
74 else
75 snprint(str, sizeof(str), "(%R)", i-D_INDIR);
76 goto brk;
77 }
78 switch(i) {
79
80 default:
81 if(a->offset)
82 snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
83 else
84 snprint(str, sizeof(str), "%R", i);
85 break;
86
87 case D_NONE:
88 str[0] = 0;
89 break;
90
91 case D_BRANCH:
92 if(bigP != P && bigP->pcond != P)
93 if(a->sym != S)
94 snprint(str, sizeof(str), "%llux+%s", bigP->pcond->pc,
95 a->sym->name);
96 else
97 snprint(str, sizeof(str), "%llux", bigP->pcond->pc);
98 else
99 snprint(str, sizeof(str), "%lld(PC)", a->offset);
100 break;
101
102 case D_EXTERN:
103 snprint(str, sizeof(str), "%s+%lld(SB)", a->sym->name, a->offset);
104 break;
105
106 case D_STATIC:
107 snprint(str, sizeof(str), "%s<%d>+%lld(SB)", a->sym->name,
108 a->sym->version, a->offset);
109 break;
110
111 case D_AUTO:
112 snprint(str, sizeof(str), "%s+%lld(SP)", a->sym->name, a->offset);
113 break;
114
115 case D_PARAM:
116 if(a->sym)
117 snprint(str, sizeof(str), "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
118 else
119 snprint(str, sizeof(str), "%lld(%s)", a->offset, paramspace);
120 break;
121
122 case D_CONST:
123 snprint(str, sizeof(str), "$%lld", a->offset);
124 break;
125
126 case D_FCONST:
127 snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
128 break;
129
130 case D_SCONST:
131 snprint(str, sizeof(str), "$\"%S\"", a->scon);
132 break;
133
134 case D_ADDR:
135 a->type = a->index;
136 a->index = D_NONE;
137 snprint(str, sizeof(str), "$%D", a);
138 a->index = a->type;
139 a->type = D_ADDR;
140 goto conv;
141 }
142 brk:
143 if(a->index != D_NONE && !isxyreg(a->type)) {
144 snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
145 strcat(str, s);
146 }
147 conv:
148 return fmtstrcpy(fp, str);
149 }
150
151 char* regstr[] =
152 {
153 "AL", /* [D_AL] */
154 "CL",
155 "DL",
156 "BL",
157 "SPB",
158 "BPB",
159 "SIB",
160 "DIB",
161 "R8B",
162 "R9B",
163 "R10B",
164 "R11B",
165 "R12B",
166 "R13B",
167 "R14B",
168 "R15B",
169
170 "AX", /* [D_AX] */
171 "CX",
172 "DX",
173 "BX",
174 "SP",
175 "BP",
176 "SI",
177 "DI",
178 "R8",
179 "R9",
180 "R10",
181 "R11",
182 "R12",
183 "R13",
184 "R14",
185 "R15",
186
187 "AH",
188 "CH",
189 "DH",
190 "BH",
191
192 "Y0", /* [D_Y0] */
193 "Y1",
194 "Y2",
195 "Y3",
196 "Y4",
197 "Y5",
198 "Y6",
199 "Y7",
200
201 "Y8",
202 "Y9",
203 "Y10",
204 "Y11",
205 "Y12",
206 "Y13",
207 "Y14",
208 "Y15",
209
210 "X0",
211 "X1",
212 "X2",
213 "X3",
214 "X4",
215 "X5",
216 "X6",
217 "X7",
218 "X8",
219 "X9",
220 "X10",
221 "X11",
222 "X12",
223 "X13",
224 "X14",
225 "X15",
226
227 "CS", /* [D_CS] */
228 "SS",
229 "DS",
230 "ES",
231 "FS",
232 "GS",
233
234 "GDTR", /* [D_GDTR] */
235 "IDTR", /* [D_IDTR] */
236 "LDTR", /* [D_LDTR] */
237 "MSW", /* [D_MSW] */
238 "TASK", /* [D_TASK] */
239
240 "CR0", /* [D_CR] */
241 "CR1",
242 "CR2",
243 "CR3",
244 "CR4",
245 "CR5",
246 "CR6",
247 "CR7",
248 "CR8",
249 "CR9",
250 "CR10",
251 "CR11",
252 "CR12",
253 "CR13",
254 "CR14",
255 "CR15",
256
257 "DR0", /* [D_DR] */
258 "DR1",
259 "DR2",
260 "DR3",
261 "DR4",
262 "DR5",
263 "DR6",
264 "DR7",
265
266 "TR0", /* [D_TR] */
267 "TR1",
268 "TR2",
269 "TR3",
270 "TR4",
271 "TR5",
272 "TR6",
273 "TR7",
274
275 "NONE", /* [D_NONE] */
276 };
277
278 int
Rconv(Fmt * fp)279 Rconv(Fmt *fp)
280 {
281 char str[20];
282 int r;
283
284 r = va_arg(fp->args, int);
285 if(r >= D_AL && r <= D_NONE)
286 snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
287 else if(r >= D_Y0 && r <= D_Y15)
288 snprint(str, sizeof(str), "Y%d", r-D_Y0);
289 else if(r >= D_M0 && r <= D_M7)
290 snprint(str, sizeof(str), "Y%d", r-D_M0);
291 else
292 snprint(str, sizeof(str), "gok(%d)", r);
293
294 return fmtstrcpy(fp, str);
295 }
296
297 int
Sconv(Fmt * fp)298 Sconv(Fmt *fp)
299 {
300 int i, c;
301 char str[30], *p, *a;
302
303 a = va_arg(fp->args, char*);
304 p = str;
305 for(i=0; i<sizeof(double); i++) {
306 c = a[i] & 0xff;
307 if(c >= 'a' && c <= 'z' ||
308 c >= 'A' && c <= 'Z' ||
309 c >= '0' && c <= '9') {
310 *p++ = c;
311 continue;
312 }
313 *p++ = '\\';
314 switch(c) {
315 default:
316 if(c < 040 || c >= 0177)
317 break; /* not portable */
318 p[-1] = c;
319 continue;
320 case 0:
321 *p++ = 'z';
322 continue;
323 case '\\':
324 case '"':
325 *p++ = c;
326 continue;
327 case '\n':
328 *p++ = 'n';
329 continue;
330 case '\t':
331 *p++ = 't';
332 continue;
333 }
334 *p++ = (c>>6) + '0';
335 *p++ = ((c>>3) & 7) + '0';
336 *p++ = (c & 7) + '0';
337 }
338 *p = 0;
339 return fmtstrcpy(fp, str);
340 }
341
342 void
diag(char * fmt,...)343 diag(char *fmt, ...)
344 {
345 char buf[STRINGSZ], *tn;
346 va_list arg;
347
348 tn = "??none??";
349 if(curtext != P && curtext->from.sym != S)
350 tn = curtext->from.sym->name;
351 va_start(arg, fmt);
352 vseprint(buf, buf+sizeof(buf), fmt, arg);
353 va_end(arg);
354 print("%s: %s\n", tn, buf);
355
356 nerrors++;
357 if(nerrors > 20 && !debug['A']) {
358 print("too many errors\n");
359 errorexit();
360 }
361 }
362