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