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