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->from.type != D_FREG)
88 snprint(str, sizeof(str), " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
89 else
90 snprint(str, sizeof(str), " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
91 return fmtstrcpy(fp, str);
92 }
93
94 int
Aconv(Fmt * fp)95 Aconv(Fmt *fp)
96 {
97 char *s;
98 int a;
99
100 a = va_arg(fp->args, int);
101 s = "???";
102 if(a >= AXXX && a < ALAST)
103 s = anames[a];
104 return fmtstrcpy(fp, s);
105 }
106
107 int
Dconv(Fmt * fp)108 Dconv(Fmt *fp)
109 {
110 char str[STRINGSZ];
111 Adr *a;
112 char *op;
113 int v;
114
115 a = va_arg(fp->args, Adr*);
116 switch(a->type) {
117
118 default:
119 snprint(str, sizeof(str), "GOK-type(%d)", a->type);
120 break;
121
122 case D_NONE:
123 str[0] = 0;
124 if(a->name != D_NONE || a->reg != NREG || a->sym != S)
125 snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
126 break;
127
128 case D_CONST:
129 if(a->reg != NREG)
130 snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
131 else
132 snprint(str, sizeof(str), "$%N", a);
133 break;
134
135 case D_SHIFT:
136 v = a->offset;
137 op = "<<>>->@>" + (((v>>5) & 3) << 1);
138 if(v & (1<<4))
139 snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
140 else
141 snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
142 if(a->reg != NREG)
143 sprint(str+strlen(str), "(R%d)", a->reg);
144 break;
145
146 case D_OREG:
147 if(a->reg != NREG)
148 snprint(str, sizeof(str), "%N(R%d)", a, a->reg);
149 else
150 snprint(str, sizeof(str), "%N", a);
151 break;
152
153 case D_REG:
154 snprint(str, sizeof(str), "R%d", a->reg);
155 if(a->name != D_NONE || a->sym != S)
156 snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
157 break;
158
159 case D_FREG:
160 snprint(str, sizeof(str), "F%d", a->reg);
161 if(a->name != D_NONE || a->sym != S)
162 snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
163 break;
164
165 case D_PSR:
166 snprint(str, sizeof(str), "PSR");
167 if(a->name != D_NONE || a->sym != S)
168 snprint(str, sizeof(str), "%N(PSR)(REG)", a);
169 break;
170
171 case D_BRANCH:
172 snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
173 break;
174
175 case D_FCONST:
176 snprint(str, sizeof(str), "$%.17e", a->dval);
177 break;
178
179 case D_SCONST:
180 snprint(str, sizeof(str), "$\"%S\"", a->sval);
181 break;
182 }
183 return fmtstrcpy(fp, str);
184 }
185
186 int
Rconv(Fmt * fp)187 Rconv(Fmt *fp)
188 {
189 char str[STRINGSZ], *p, *e;
190 Adr *a;
191 int i, v;
192
193 a = va_arg(fp->args, Adr*);
194 snprint(str, sizeof(str), "GOK-reglist");
195 switch(a->type) {
196 case D_CONST:
197 if(a->reg != NREG)
198 break;
199 if(a->sym != S)
200 break;
201 v = a->offset;
202 p = str;
203 e = str+sizeof(str);
204 for(i=0; i<NREG; i++) {
205 if(v & (1<<i)) {
206 if(p == str)
207 p = seprint(p, e, "[R%d", i);
208 else
209 p = seprint(p, e, ",R%d", i);
210 }
211 }
212 seprint(p, e, "]");
213 }
214 return fmtstrcpy(fp, str);
215 }
216
217 int
Sconv(Fmt * fp)218 Sconv(Fmt *fp)
219 {
220 int i, c;
221 char str[STRINGSZ], *p, *a;
222
223 a = va_arg(fp->args, char*);
224 p = str;
225 for(i=0; i<NSNAME; i++) {
226 c = a[i] & 0xff;
227 if(c >= 'a' && c <= 'z' ||
228 c >= 'A' && c <= 'Z' ||
229 c >= '0' && c <= '9' ||
230 c == ' ' || c == '%') {
231 *p++ = c;
232 continue;
233 }
234 *p++ = '\\';
235 switch(c) {
236 case 0:
237 *p++ = 'z';
238 continue;
239 case '\\':
240 case '"':
241 *p++ = c;
242 continue;
243 case '\n':
244 *p++ = 'n';
245 continue;
246 case '\t':
247 *p++ = 't';
248 continue;
249 case '\r':
250 *p++ = 'r';
251 continue;
252 case '\f':
253 *p++ = 'f';
254 continue;
255 }
256 *p++ = (c>>6) + '0';
257 *p++ = ((c>>3) & 7) + '0';
258 *p++ = (c & 7) + '0';
259 }
260 *p = 0;
261 return fmtstrcpy(fp, str);
262 }
263
264 int
Nconv(Fmt * fp)265 Nconv(Fmt *fp)
266 {
267 char str[STRINGSZ];
268 Adr *a;
269 Sym *s;
270
271 a = va_arg(fp->args, Adr*);
272 s = a->sym;
273 if(s == S) {
274 snprint(str, sizeof(str), "%ld", a->offset);
275 goto out;
276 }
277 switch(a->name) {
278 default:
279 snprint(str, sizeof(str), "GOK-name(%d)", a->name);
280 break;
281
282 case D_NONE:
283 snprint(str, sizeof(str), "%ld", a->offset);
284 break;
285
286 case D_EXTERN:
287 snprint(str, sizeof(str), "%s+%ld(SB)", s->name, a->offset);
288 break;
289
290 case D_STATIC:
291 snprint(str, sizeof(str), "%s<>+%ld(SB)", s->name, a->offset);
292 break;
293
294 case D_AUTO:
295 snprint(str, sizeof(str), "%s-%ld(SP)", s->name, -a->offset);
296 break;
297
298 case D_PARAM:
299 snprint(str, sizeof(str), "%s+%ld(FP)", s->name, a->offset);
300 break;
301 }
302 out:
303 return fmtstrcpy(fp, str);
304 }
305