1 #include "l.h"
2
3 void
listinit(void)4 listinit(void)
5 {
6
7 fmtinstall('A', Aconv);
8 fmtinstall('D', Dconv);
9 fmtinstall('P', Pconv);
10 fmtinstall('S', Sconv);
11 fmtinstall('N', Nconv);
12 }
13
14 void
prasm(Prog * p)15 prasm(Prog *p)
16 {
17 print("%P\n", p);
18 }
19
20 int
Pconv(Fmt * fp)21 Pconv(Fmt *fp)
22 {
23 char str[STRINGSZ], *s;
24 Prog *p;
25 int a;
26
27 p = va_arg(fp->args, Prog*);
28 curp = p;
29 a = p->as;
30 if(a == ADATA || a == ADYNT || a == AINIT)
31 sprint(str, "(%ld) %A %D/%d,%D",
32 p->line, a, &p->from, p->reg, &p->to);
33 else{
34 s = str;
35 s += sprint(s, "(%ld)", p->line);
36 if(p->mark & NOSCHED)
37 s += sprint(s, "*");
38 if(p->reg == NREG)
39 sprint(s, " %A %D,%D",
40 a, &p->from, &p->to);
41 else
42 if(p->from.type != D_FREG)
43 sprint(s, " %A %D,R%d,%D",
44 a, &p->from, p->reg, &p->to);
45 else
46 sprint(s, " %A %D,F%d,%D",
47 a, &p->from, p->reg, &p->to);
48 }
49 return fmtstrcpy(fp, str);
50 }
51
52 int
Aconv(Fmt * fp)53 Aconv(Fmt *fp)
54 {
55 char *s;
56 int a;
57
58 a = va_arg(fp->args, int);
59 s = "???";
60 if(a >= AXXX && a < ALAST)
61 s = anames[a];
62 return fmtstrcpy(fp, s);
63 }
64
65 int
Dconv(Fmt * fp)66 Dconv(Fmt *fp)
67 {
68 char str[STRINGSZ];
69 Adr *a;
70 long v;
71
72 a = va_arg(fp->args, Adr*);
73 switch(a->type) {
74
75 default:
76 sprint(str, "GOK-type(%d)", a->type);
77 break;
78
79 case D_NONE:
80 str[0] = 0;
81 if(a->name != D_NONE || a->reg != NREG || a->sym != S)
82 sprint(str, "%N(R%d)(NONE)", a, a->reg);
83 break;
84
85 case D_CONST:
86 sprint(str, "$%N", a);
87 if(a->reg != NREG)
88 sprint(str, "%N(R%d)(CONST)", a, a->reg);
89 break;
90
91 case D_OCONST:
92 sprint(str, "$*$%N", a);
93 if(a->reg != NREG)
94 sprint(str, "%N(R%d)(CONST)", a, a->reg);
95 break;
96
97 case D_OREG:
98 if(a->reg != NREG)
99 sprint(str, "%N(R%d)", a, a->reg);
100 else
101 sprint(str, "%N", a);
102 break;
103
104 case D_REG:
105 sprint(str, "R%d", a->reg);
106 if(a->name != D_NONE || a->sym != S)
107 sprint(str, "%N(R%d)(REG)", a, a->reg);
108 break;
109
110 case D_MREG:
111 sprint(str, "M%d", a->reg);
112 if(a->name != D_NONE || a->sym != S)
113 sprint(str, "%N(R%d)(REG)", a, a->reg);
114 break;
115
116 case D_FREG:
117 sprint(str, "F%d", a->reg);
118 if(a->name != D_NONE || a->sym != S)
119 sprint(str, "%N(R%d)(REG)", a, a->reg);
120 break;
121
122 case D_FCREG:
123 sprint(str, "FC%d", a->reg);
124 if(a->name != D_NONE || a->sym != S)
125 sprint(str, "%N(R%d)(REG)", a, a->reg);
126 break;
127
128 case D_LO:
129 sprint(str, "LO");
130 if(a->name != D_NONE || a->sym != S)
131 sprint(str, "%N(LO)(REG)", a);
132 break;
133
134 case D_HI:
135 sprint(str, "HI");
136 if(a->name != D_NONE || a->sym != S)
137 sprint(str, "%N(HI)(REG)", a);
138 break;
139
140 case D_BRANCH: /* botch */
141 if(curp->cond != P) {
142 v = curp->cond->pc;
143 if(v >= INITTEXT)
144 v -= INITTEXT-HEADR;
145 if(a->sym != S)
146 sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
147 else
148 sprint(str, "%.5lux(BRANCH)", v);
149 } else
150 if(a->sym != S)
151 sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
152 else
153 sprint(str, "%ld(APC)", a->offset);
154 break;
155
156 case D_FCONST:
157 sprint(str, "$%e", ieeedtod(a->ieee));
158 break;
159
160 case D_SCONST:
161 sprint(str, "$\"%S\"", a->sval);
162 break;
163 }
164 return fmtstrcpy(fp, str);
165 }
166
167 int
Nconv(Fmt * fp)168 Nconv(Fmt *fp)
169 {
170 char str[STRINGSZ];
171 Adr *a;
172 Sym *s;
173
174 a = va_arg(fp->args, Adr*);
175 s = a->sym;
176 switch(a->name) {
177 default:
178 sprint(str, "GOK-name(%d)", a->name);
179 break;
180
181 case D_NONE:
182 sprint(str, "%ld", a->offset);
183 break;
184
185 case D_EXTERN:
186 if(s == S)
187 sprint(str, "%ld(SB)", a->offset);
188 else
189 sprint(str, "%s+%ld(SB)", s->name, a->offset);
190 break;
191
192 case D_STATIC:
193 if(s == S)
194 sprint(str, "<>+%ld(SB)", a->offset);
195 else
196 sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
197 break;
198
199 case D_AUTO:
200 if(s == S)
201 sprint(str, "%ld(SP)", a->offset);
202 else
203 sprint(str, "%s-%ld(SP)", s->name, -a->offset);
204 break;
205
206 case D_PARAM:
207 if(s == S)
208 sprint(str, "%ld(FP)", a->offset);
209 else
210 sprint(str, "%s+%ld(FP)", s->name, a->offset);
211 break;
212 }
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<sizeof(long); 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 }
250 *p++ = (c>>6) + '0';
251 *p++ = ((c>>3) & 7) + '0';
252 *p++ = (c & 7) + '0';
253 }
254 *p = 0;
255 return fmtstrcpy(fp, str);
256 }
257
258 void
diag(char * fmt,...)259 diag(char *fmt, ...)
260 {
261 char buf[STRINGSZ], *tn;
262 va_list arg;
263
264 tn = "??none??";
265 if(curtext != P && curtext->from.sym != S)
266 tn = curtext->from.sym->name;
267 va_start(arg, fmt);
268 vseprint(buf, buf+sizeof(buf), fmt, arg);
269 va_end(arg);
270 print("%s: %s\n", tn, buf);
271
272 nerrors++;
273 if(nerrors > 10) {
274 print("too many errors\n");
275 errorexit();
276 }
277 }
278