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