1 #define EXTERN
2 #include "gc.h"
3
4 void
listinit(void)5 listinit(void)
6 {
7
8 fmtinstall('A', Aconv);
9 fmtinstall('P', Pconv);
10 fmtinstall('S', Sconv);
11 fmtinstall('N', Nconv);
12 fmtinstall('B', Bconv);
13 fmtinstall('D', Dconv);
14 fmtinstall('R', Rconv);
15 }
16
17 int
Bconv(Fmt * fp)18 Bconv(Fmt *fp)
19 {
20 char str[STRINGSZ], ss[STRINGSZ], *s;
21 Bits bits;
22 int i;
23
24 str[0] = 0;
25 bits = va_arg(fp->args, Bits);
26 while(bany(&bits)) {
27 i = bnum(bits);
28 if(str[0])
29 strcat(str, " ");
30 if(var[i].sym == S) {
31 snprint(ss, sizeof(ss), "$%ld", var[i].offset);
32 s = ss;
33 } else
34 s = var[i].sym->name;
35 if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
36 break;
37 strcat(str, s);
38 bits.b[i/32] &= ~(1L << (i%32));
39 }
40 return fmtstrcpy(fp, str);
41 }
42
43 char *extra [] = {
44 ".EQ", ".NE", ".CS", ".CC",
45 ".MI", ".PL", ".VS", ".VC",
46 ".HI", ".LS", ".GE", ".LT",
47 ".GT", ".LE", "", ".NV",
48 };
49
50 int
Pconv(Fmt * fp)51 Pconv(Fmt *fp)
52 {
53 char str[STRINGSZ], sc[20];
54 Prog *p;
55 int a, s;
56
57 p = va_arg(fp->args, Prog*);
58 a = p->as;
59 s = p->scond;
60 strcpy(sc, extra[s & C_SCOND]);
61 if(s & C_SBIT)
62 strcat(sc, ".S");
63 if(s & C_PBIT)
64 strcat(sc, ".P");
65 if(s & C_WBIT)
66 strcat(sc, ".W");
67 if(s & C_UBIT) /* ambiguous with FBIT */
68 strcat(sc, ".U");
69 if(a == AMOVM) {
70 if(p->from.type == D_CONST)
71 snprint(str, sizeof(str), " %A%s %R,%D", a, sc, &p->from, &p->to);
72 else
73 if(p->to.type == D_CONST)
74 snprint(str, sizeof(str), " %A%s %D,%R", a, sc, &p->from, &p->to);
75 else
76 snprint(str, sizeof(str), " %A%s %D,%D", a, sc, &p->from, &p->to);
77 } else
78 if(a == ADATA)
79 snprint(str, sizeof(str), " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
80 else
81 if(p->as == ATEXT)
82 snprint(str, sizeof(str), " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
83 else
84 if(p->reg == NREG)
85 snprint(str, sizeof(str), " %A%s %D,%D", a, sc, &p->from, &p->to);
86 else
87 if(p->reghi != NREG)
88 snprint(str, sizeof(str), " %A%s %D,R%d,%D,R%d", a, sc, &p->from, p->reg, &p->to, p->reghi);
89 else
90 if(p->from.type != D_FREG && p->from.type != D_SFREG && p->from.type != D_FCONST)
91 snprint(str, sizeof(str), " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
92 else
93 snprint(str, sizeof(str), " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
94 return fmtstrcpy(fp, str);
95 }
96
97 int
Aconv(Fmt * fp)98 Aconv(Fmt *fp)
99 {
100 char *s;
101 int a;
102
103 a = va_arg(fp->args, int);
104 s = "???";
105 if(a >= AXXX && a < ALAST)
106 s = anames[a];
107 return fmtstrcpy(fp, s);
108 }
109
110 int
Dconv(Fmt * fp)111 Dconv(Fmt *fp)
112 {
113 char str[STRINGSZ];
114 Adr *a;
115 char *op;
116 int v;
117
118 a = va_arg(fp->args, Adr*);
119 switch(a->type) {
120
121 default:
122 snprint(str, sizeof(str), "GOK-type(%d)", a->type);
123 break;
124
125 case D_NONE:
126 str[0] = 0;
127 if(a->name != D_NONE || a->reg != NREG || a->sym != S)
128 snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
129 break;
130
131 case D_CONST:
132 if(a->reg != NREG)
133 snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
134 else
135 snprint(str, sizeof(str), "$%N", a);
136 break;
137
138 case D_SHIFT:
139 v = a->offset;
140 op = "<<>>->@>" + (((v>>5) & 3) << 1);
141 if(v & (1<<4))
142 snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
143 else
144 snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
145 if(a->reg != NREG)
146 sprint(str+strlen(str), "(R%d)", a->reg);
147 break;
148
149 case D_OREG:
150 if(a->reg != NREG)
151 snprint(str, sizeof(str), "%N(R%d)", a, a->reg);
152 else
153 snprint(str, sizeof(str), "%N", a);
154 break;
155
156 case D_REG:
157 snprint(str, sizeof(str), "R%d", a->reg);
158 if(a->name != D_NONE || a->sym != S)
159 snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
160 break;
161
162 case D_FREG:
163 snprint(str, sizeof(str), "F%d", a->reg);
164 if(a->name != D_NONE || a->sym != S)
165 snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
166 break;
167
168 case D_SFREG:
169 snprint(str, sizeof(str), "S%d", a->reg);
170 if(a->name != D_NONE || a->sym != S)
171 snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
172 break;
173
174 case D_QREG:
175 snprint(str, sizeof(str), "Q%d", a->reg);
176 if(a->name != D_NONE || a->sym != S)
177 snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
178 break;
179
180 case D_PSR:
181 snprint(str, sizeof(str), "PSR");
182 if(a->name != D_NONE || a->sym != S)
183 snprint(str, sizeof(str), "%N(PSR)(REG)", a);
184 break;
185
186 case D_BRANCH:
187 snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
188 break;
189
190 case D_FCONST:
191 snprint(str, sizeof(str), "$%.17e", a->dval);
192 break;
193
194 case D_SCONST:
195 snprint(str, sizeof(str), "$\"%S\"", a->sval);
196 break;
197 }
198 return fmtstrcpy(fp, str);
199 }
200
201 int
Rconv(Fmt * fp)202 Rconv(Fmt *fp)
203 {
204 char str[STRINGSZ], *p, *e;
205 Adr *a;
206 int i, v;
207
208 a = va_arg(fp->args, Adr*);
209 snprint(str, sizeof(str), "GOK-reglist");
210 switch(a->type) {
211 case D_CONST:
212 if(a->reg != NREG)
213 break;
214 if(a->sym != S)
215 break;
216 v = a->offset;
217 p = str;
218 e = str+sizeof(str);
219 for(i=0; i<NREG; i++) {
220 if(v & (1<<i)) {
221 if(p == str)
222 p = seprint(p, e, "[R%d", i);
223 else
224 p = seprint(p, e, ",R%d", i);
225 }
226 }
227 seprint(p, e, "]");
228 }
229 return fmtstrcpy(fp, str);
230 }
231
232 int
Sconv(Fmt * fp)233 Sconv(Fmt *fp)
234 {
235 int i, c;
236 char str[STRINGSZ], *p, *a;
237
238 a = va_arg(fp->args, char*);
239 p = str;
240 for(i=0; i<NSNAME; i++) {
241 c = a[i] & 0xff;
242 if(c >= 'a' && c <= 'z' ||
243 c >= 'A' && c <= 'Z' ||
244 c >= '0' && c <= '9' ||
245 c == ' ' || c == '%') {
246 *p++ = c;
247 continue;
248 }
249 *p++ = '\\';
250 switch(c) {
251 case 0:
252 *p++ = 'z';
253 continue;
254 case '\\':
255 case '"':
256 *p++ = c;
257 continue;
258 case '\n':
259 *p++ = 'n';
260 continue;
261 case '\t':
262 *p++ = 't';
263 continue;
264 case '\r':
265 *p++ = 'r';
266 continue;
267 case '\f':
268 *p++ = 'f';
269 continue;
270 }
271 *p++ = (c>>6) + '0';
272 *p++ = ((c>>3) & 7) + '0';
273 *p++ = (c & 7) + '0';
274 }
275 *p = 0;
276 return fmtstrcpy(fp, str);
277 }
278
279 int
Nconv(Fmt * fp)280 Nconv(Fmt *fp)
281 {
282 char str[STRINGSZ];
283 Adr *a;
284 Sym *s;
285
286 a = va_arg(fp->args, Adr*);
287 s = a->sym;
288 if(s == S) {
289 snprint(str, sizeof(str), "%ld", a->offset);
290 goto out;
291 }
292 switch(a->name) {
293 default:
294 snprint(str, sizeof(str), "GOK-name(%d)", a->name);
295 break;
296
297 case D_NONE:
298 snprint(str, sizeof(str), "%ld", a->offset);
299 break;
300
301 case D_EXTERN:
302 snprint(str, sizeof(str), "%s+%ld(SB)", s->name, a->offset);
303 break;
304
305 case D_STATIC:
306 snprint(str, sizeof(str), "%s<>+%ld(SB)", s->name, a->offset);
307 break;
308
309 case D_AUTO:
310 snprint(str, sizeof(str), "%s-%ld(SP)", s->name, -a->offset);
311 break;
312
313 case D_PARAM:
314 snprint(str, sizeof(str), "%s+%ld(FP)", s->name, a->offset);
315 break;
316 }
317 out:
318 return fmtstrcpy(fp, str);
319 }
320