1 #include "l.h"
2
3 void
listinit(void)4 listinit(void)
5 {
6
7 fmtinstall('R', Rconv);
8 fmtinstall('A', Aconv);
9 fmtinstall('D', Dconv);
10 fmtinstall('S', Sconv);
11 fmtinstall('P', Pconv);
12 }
13
14 static Prog *bigP;
15
16 int
Pconv(Fmt * fp)17 Pconv(Fmt *fp)
18 {
19 char str[STRINGSZ];
20 Prog *p;
21
22 p = va_arg(fp->args, Prog*);
23 bigP = p;
24 switch(p->as) {
25 case ATEXT:
26 if(p->from.scale) {
27 snprint(str, sizeof(str), "(%ld) %A %D,%d,%D",
28 p->line, p->as, &p->from, p->from.scale, &p->to);
29 break;
30 }
31 default:
32 snprint(str, sizeof(str), "(%ld) %A %D,%D",
33 p->line, p->as, &p->from, &p->to);
34 break;
35 case ADATA:
36 case AINIT:
37 case ADYNT:
38 snprint(str, sizeof(str), "(%ld) %A %D/%d,%D",
39 p->line, p->as, &p->from, p->from.scale, &p->to);
40 break;
41 }
42 bigP = P;
43 return fmtstrcpy(fp, str);
44 }
45
46 int
Aconv(Fmt * fp)47 Aconv(Fmt *fp)
48 {
49 int i;
50
51 i = va_arg(fp->args, int);
52 return fmtstrcpy(fp, anames[i]);
53 }
54
55 int
Dconv(Fmt * fp)56 Dconv(Fmt *fp)
57 {
58 char str[STRINGSZ+40], s[20];
59 Adr *a;
60 int i;
61
62 a = va_arg(fp->args, Adr*);
63 i = a->type;
64 if(i >= D_INDIR) {
65 if(a->offset)
66 snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
67 else
68 snprint(str, sizeof(str), "(%R)", i-D_INDIR);
69 goto brk;
70 }
71 switch(i) {
72
73 default:
74 snprint(str, sizeof(str), "%R", i);
75 break;
76
77 case D_NONE:
78 str[0] = 0;
79 break;
80
81 case D_BRANCH:
82 if(bigP != P && bigP->pcond != P)
83 if(a->sym != S)
84 snprint(str, sizeof(str), "%lux+%s", bigP->pcond->pc,
85 a->sym->name);
86 else
87 snprint(str, sizeof(str), "%lux", bigP->pcond->pc);
88 else
89 snprint(str, sizeof(str), "%ld(PC)", a->offset);
90 break;
91
92 case D_EXTERN:
93 snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
94 break;
95
96 case D_STATIC:
97 snprint(str, sizeof(str), "%s<%d>+%ld(SB)", a->sym->name,
98 a->sym->version, a->offset);
99 break;
100
101 case D_AUTO:
102 snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
103 break;
104
105 case D_PARAM:
106 if(a->sym)
107 snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
108 else
109 snprint(str, sizeof(str), "%ld(FP)", a->offset);
110 break;
111
112 case D_CONST:
113 snprint(str, sizeof(str), "$%ld", a->offset);
114 break;
115
116 case D_FCONST:
117 snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
118 break;
119
120 case D_SCONST:
121 snprint(str, sizeof(str), "$\"%S\"", a->scon);
122 break;
123
124 case D_ADDR:
125 a->type = a->index;
126 a->index = D_NONE;
127 snprint(str, sizeof(str), "$%D", a);
128 a->index = a->type;
129 a->type = D_ADDR;
130 goto conv;
131 }
132 brk:
133 if(a->index != D_NONE) {
134 snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
135 strcat(str, s);
136 }
137 conv:
138 return fmtstrcpy(fp, str);
139 }
140
141 char* regstr[] =
142 {
143 "AL", /* [D_AL] */
144 "CL",
145 "DL",
146 "BL",
147 "AH",
148 "CH",
149 "DH",
150 "BH",
151
152 "AX", /* [D_AX] */
153 "CX",
154 "DX",
155 "BX",
156 "SP",
157 "BP",
158 "SI",
159 "DI",
160
161 "F0", /* [D_F0] */
162 "F1",
163 "F2",
164 "F3",
165 "F4",
166 "F5",
167 "F6",
168 "F7",
169
170 "CS", /* [D_CS] */
171 "SS",
172 "DS",
173 "ES",
174 "FS",
175 "GS",
176
177 "GDTR", /* [D_GDTR] */
178 "IDTR", /* [D_IDTR] */
179 "LDTR", /* [D_LDTR] */
180 "MSW", /* [D_MSW] */
181 "TASK", /* [D_TASK] */
182
183 "CR0", /* [D_CR] */
184 "CR1",
185 "CR2",
186 "CR3",
187 "CR4",
188 "CR5",
189 "CR6",
190 "CR7",
191
192 "DR0", /* [D_DR] */
193 "DR1",
194 "DR2",
195 "DR3",
196 "DR4",
197 "DR5",
198 "DR6",
199 "DR7",
200
201 "TR0", /* [D_TR] */
202 "TR1",
203 "TR2",
204 "TR3",
205 "TR4",
206 "TR5",
207 "TR6",
208 "TR7",
209
210 "NONE", /* [D_NONE] */
211 };
212
213 int
Rconv(Fmt * fp)214 Rconv(Fmt *fp)
215 {
216 char str[20];
217 int r;
218
219 r = va_arg(fp->args, int);
220 if(r >= D_AL && r <= D_NONE)
221 snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
222 else
223 snprint(str, sizeof(str), "gok(%d)", r);
224
225 return fmtstrcpy(fp, str);
226 }
227
228 int
Sconv(Fmt * fp)229 Sconv(Fmt *fp)
230 {
231 int i, c;
232 char str[30], *p, *a;
233
234 a = va_arg(fp->args, char*);
235 p = str;
236 for(i=0; i<sizeof(double); i++) {
237 c = a[i] & 0xff;
238 if(c >= 'a' && c <= 'z' ||
239 c >= 'A' && c <= 'Z' ||
240 c >= '0' && c <= '9') {
241 *p++ = c;
242 continue;
243 }
244 *p++ = '\\';
245 switch(c) {
246 default:
247 if(c < 040 || c >= 0177)
248 break; /* not portable */
249 p[-1] = c;
250 continue;
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 }
265 *p++ = (c>>6) + '0';
266 *p++ = ((c>>3) & 7) + '0';
267 *p++ = (c & 7) + '0';
268 }
269 *p = 0;
270 return fmtstrcpy(fp, str);
271 }
272
273 void
diag(char * fmt,...)274 diag(char *fmt, ...)
275 {
276 char buf[STRINGSZ], *tn;
277 va_list arg;
278
279 tn = "??none??";
280 if(curtext != P && curtext->from.sym != S)
281 tn = curtext->from.sym->name;
282 va_start(arg, fmt);
283 vseprint(buf, buf+sizeof(buf), fmt, arg);
284 va_end(arg);
285 print("%s: %s\n", tn, buf);
286
287 nerrors++;
288 if(nerrors > 20 && !debug['A']) {
289 print("too many errors\n");
290 errorexit();
291 }
292 }
293