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