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 snprint(ss, sizeof(ss), "$%ld", 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) {
80 if(a->offset)
81 snprint(str, sizeof(str), "%ld(%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), "$%ld,%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), "%ld(PC)", a->offset-pc);
101 break;
102
103 case D_EXTERN:
104 snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
105 break;
106
107 case D_STATIC:
108 snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name,
109 a->offset);
110 break;
111
112 case D_AUTO:
113 snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
114 break;
115
116 case D_PARAM:
117 if(a->sym)
118 snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
119 else
120 snprint(str, sizeof(str), "%ld(FP)", a->offset);
121 break;
122
123 case D_CONST:
124 snprint(str, sizeof(str), "$%ld", 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 "AH",
160 "CH",
161 "DH",
162 "BH",
163
164 "AX", /*[D_AX]*/
165 "CX",
166 "DX",
167 "BX",
168 "SP",
169 "BP",
170 "SI",
171 "DI",
172
173 "F0", /*[D_F0]*/
174 "F1",
175 "F2",
176 "F3",
177 "F4",
178 "F5",
179 "F6",
180 "F7",
181
182 "CS", /*[D_CS]*/
183 "SS",
184 "DS",
185 "ES",
186 "FS",
187 "GS",
188
189 "GDTR", /*[D_GDTR]*/
190 "IDTR", /*[D_IDTR]*/
191 "LDTR", /*[D_LDTR]*/
192 "MSW", /*[D_MSW] */
193 "TASK", /*[D_TASK]*/
194
195 "CR0", /*[D_CR]*/
196 "CR1",
197 "CR2",
198 "CR3",
199 "CR4",
200 "CR5",
201 "CR6",
202 "CR7",
203
204 "DR0", /*[D_DR]*/
205 "DR1",
206 "DR2",
207 "DR3",
208 "DR4",
209 "DR5",
210 "DR6",
211 "DR7",
212
213 "TR0", /*[D_TR]*/
214 "TR1",
215 "TR2",
216 "TR3",
217 "TR4",
218 "TR5",
219 "TR6",
220 "TR7",
221
222 "NONE", /*[D_NONE]*/
223 };
224
225 int
Rconv(Fmt * fp)226 Rconv(Fmt *fp)
227 {
228 char str[20];
229 int r;
230
231 r = va_arg(fp->args, int);
232 if(r >= D_AL && r <= D_NONE)
233 snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
234 else
235 snprint(str, sizeof(str), "gok(%d)", r);
236
237 return fmtstrcpy(fp, str);
238 }
239
240 int
Sconv(Fmt * fp)241 Sconv(Fmt *fp)
242 {
243 int i, c;
244 char str[30], *p, *a;
245
246 a = va_arg(fp->args, char*);
247 p = str;
248 for(i=0; i<sizeof(double); i++) {
249 c = a[i] & 0xff;
250 if(c >= 'a' && c <= 'z' ||
251 c >= 'A' && c <= 'Z' ||
252 c >= '0' && c <= '9') {
253 *p++ = c;
254 continue;
255 }
256 *p++ = '\\';
257 switch(c) {
258 default:
259 if(c < 040 || c >= 0177)
260 break; /* not portable */
261 p[-1] = c;
262 continue;
263 case 0:
264 *p++ = 'z';
265 continue;
266 case '\\':
267 case '"':
268 *p++ = c;
269 continue;
270 case '\n':
271 *p++ = 'n';
272 continue;
273 case '\t':
274 *p++ = 't';
275 continue;
276 }
277 *p++ = (c>>6) + '0';
278 *p++ = ((c>>3) & 7) + '0';
279 *p++ = (c & 7) + '0';
280 }
281 *p = 0;
282 return fmtstrcpy(fp, str);
283 }
284