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