]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/7c/list.c
disk/format: implement long name support
[plan9front.git] / sys / src / cmd / 7c / list.c
1 #define EXTERN
2 #include "gc.h"
3
4 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
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), "$%lld", 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 static char *conds[] = {
44         ".EQ", ".NE", ".CS", ".CC", 
45         ".MI", ".PL", ".VS", ".VC", 
46         ".HI", ".LS", ".GE", ".LT", 
47         ".GT", ".LE", "", ".NV",
48 };
49
50 int
51 Pconv(Fmt *fp)
52 {
53         char str[STRINGSZ];
54         Prog *p;
55         int a;
56
57         p = va_arg(fp->args, Prog*);
58         a = p->as;
59         if(a == ADATA)
60                 snprint(str, sizeof(str), "     %A      %D/%d,%D", a, &p->from, p->reg, &p->to);
61         else
62         if(p->as == ATEXT)
63                 snprint(str, sizeof(str), "     %A      %D,%d,%D", a, &p->from, p->reg, &p->to);
64         else
65         if(p->reg == NREG)
66                 snprint(str, sizeof(str), "     %A      %D,%D", a, &p->from, &p->to);
67         else
68         if(p->from.type != D_FREG)
69                 snprint(str, sizeof(str), "     %A      %D,R%d,%D", a, &p->from, p->reg, &p->to);
70         else
71                 snprint(str, sizeof(str), "     %A      %D,F%d,%D", a, &p->from, p->reg, &p->to);
72         return fmtstrcpy(fp, str);
73 }
74
75 int
76 Aconv(Fmt *fp)
77 {
78         char *s;
79         int a;
80
81         a = va_arg(fp->args, int);
82         s = "???";
83         if(a >= AXXX && a < ALAST)
84                 s = anames[a];
85         return fmtstrcpy(fp, s);
86 }
87
88 int
89 Dconv(Fmt *fp)
90 {
91         char str[STRINGSZ];
92         Adr *a;
93         char *op;
94         int v;
95         static char *extop[] = {".UB", ".UH", ".UW", ".UX", ".SB", ".SH", ".SW", ".SX"};
96
97         a = va_arg(fp->args, Adr*);
98         switch(a->type) {
99
100         default:
101                 snprint(str, sizeof(str), "GOK-type(%d)", a->type);
102                 break;
103
104         case D_NONE:
105                 str[0] = 0;
106                 if(a->name != D_NONE || a->reg != NREG || a->sym != S)
107                         snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
108                 break;
109
110         case D_CONST:
111                 if(a->reg != NREG)
112                         snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
113                 else
114                         snprint(str, sizeof(str), "$%N", a);
115                 break;
116
117         case D_SHIFT:
118                 v = a->offset;
119                 op = "<<>>->@>" + (((v>>5) & 3) << 1);
120                 if(v & (1<<4))
121                         snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
122                 else
123                         snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
124                 if(a->reg != NREG)
125                         sprint(str+strlen(str), "(R%d)", a->reg);
126                 break;
127
128         case D_OREG:
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_XPRE:
136                 if(a->reg != NREG)
137                         snprint(str, sizeof(str), "%N(R%d)!", a, a->reg);
138                 else
139                         snprint(str, sizeof(str), "%N!", a);
140                 break;
141
142         case D_XPOST:
143                 if(a->reg != NREG)
144                         snprint(str, sizeof(str), "(R%d)%N!", a->reg, a);
145                 else
146                         snprint(str, sizeof(str), "%N!", a);
147                 break;
148
149         case D_EXTREG:
150                 v = a->offset;
151                 if(v & (7<<10))
152                         snprint(str, sizeof(str), "R%d%s<<%d", (v>>16)&31, extop[(v>>13)&7], (v>>10)&7);
153                 else
154                         snprint(str, sizeof(str), "R%d%s", (v>>16)&31, extop[(v>>13)&7]);
155                 break;
156
157         case D_REG:
158                 snprint(str, sizeof(str), "R%d", a->reg);
159                 if(a->name != D_NONE || a->sym != S)
160                         snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
161                 break;
162
163         case D_SP:
164                 if(a->name != D_NONE || a->sym != S)
165                         snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
166                 else
167                         strcpy(str, "SP");
168                 break;
169
170         case D_FREG:
171                 snprint(str, sizeof(str), "F%d", a->reg);
172                 if(a->name != D_NONE || a->sym != S)
173                         snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
174                 break;
175
176
177         case D_SPR:
178                 switch((ulong)a->offset){
179                 case D_FPSR:
180                         sprint(str, "FPSR");
181                         break;
182                 case D_FPCR:
183                         sprint(str, "FPCR");
184                         break;
185                 case D_NZCV:
186                         sprint(str, "NZCV");
187                         break;
188                 default:
189                         sprint(str, "SPR(%#llux)", a->offset);
190                         break;
191                 }
192                 if(a->name != D_NONE || a->sym != S)
193                         snprint(str, sizeof(str), "%N(SPR(%lld))(REG)", a, a->offset);
194                 break;
195
196         case D_BRANCH:
197                 snprint(str, sizeof(str), "%lld(PC)", a->offset-pc);
198                 break;
199
200         case D_FCONST:
201                 snprint(str, sizeof(str), "$%.17e", a->dval);
202                 break;
203
204         case D_SCONST:
205                 snprint(str, sizeof(str), "$\"%S\"", a->sval);
206                 break;
207         }
208         return fmtstrcpy(fp, str);
209 }
210
211 int
212 Rconv(Fmt *fp)
213 {
214         char str[STRINGSZ], *p, *e;
215         Adr *a;
216         int i, v;
217
218         a = va_arg(fp->args, Adr*);
219         snprint(str, sizeof(str), "GOK-reglist");
220         switch(a->type) {
221         case D_CONST:
222                 if(a->reg != NREG)
223                         break;
224                 if(a->sym != S)
225                         break;
226                 v = a->offset;
227                 p = str;
228                 e = str+sizeof(str);
229                 for(i=0; i<NREG; i++) {
230                         if(v & (1<<i)) {
231                                 if(p == str)
232                                         p = seprint(p, e, "[R%d", i);
233                                 else
234                                         p = seprint(p, e, ",R%d", i);
235                         }
236                 }
237                 seprint(p, e, "]");
238         }
239         return fmtstrcpy(fp, str);
240 }
241
242 int
243 Sconv(Fmt *fp)
244 {
245         int i, c;
246         char str[STRINGSZ], *p, *a;
247
248         a = va_arg(fp->args, char*);
249         p = str;
250         for(i=0; i<NSNAME; i++) {
251                 c = a[i] & 0xff;
252                 if(c >= 'a' && c <= 'z' ||
253                    c >= 'A' && c <= 'Z' ||
254                    c >= '0' && c <= '9' ||
255                    c == ' ' || c == '%') {
256                         *p++ = c;
257                         continue;
258                 }
259                 *p++ = '\\';
260                 switch(c) {
261                 case 0:
262                         *p++ = 'z';
263                         continue;
264                 case '\\':
265                 case '"':
266                         *p++ = c;
267                         continue;
268                 case '\n':
269                         *p++ = 'n';
270                         continue;
271                 case '\t':
272                         *p++ = 't';
273                         continue;
274                 case '\r':
275                         *p++ = 'r';
276                         continue;
277                 case '\f':
278                         *p++ = 'f';
279                         continue;
280                 }
281                 *p++ = (c>>6) + '0';
282                 *p++ = ((c>>3) & 7) + '0';
283                 *p++ = (c & 7) + '0';
284         }
285         *p = 0;
286         return fmtstrcpy(fp, str);
287 }
288
289 int
290 Nconv(Fmt *fp)
291 {
292         char str[STRINGSZ];
293         Adr *a;
294         Sym *s;
295
296         a = va_arg(fp->args, Adr*);
297         s = a->sym;
298         if(s == S) {
299                 snprint(str, sizeof(str), "%lld", a->offset);
300                 goto out;
301         }
302         switch(a->name) {
303         default:
304                 snprint(str, sizeof(str), "GOK-name(%d)", a->name);
305                 break;
306
307         case D_NONE:
308                 snprint(str, sizeof(str), "%lld", a->offset);
309                 break;
310
311         case D_EXTERN:
312                 snprint(str, sizeof(str), "%s+%lld(SB)", s->name, a->offset);
313                 break;
314
315         case D_STATIC:
316                 snprint(str, sizeof(str), "%s<>+%lld(SB)", s->name, a->offset);
317                 break;
318
319         case D_AUTO:
320                 snprint(str, sizeof(str), "%s-%lld(SP)", s->name, -a->offset);
321                 break;
322
323         case D_PARAM:
324                 snprint(str, sizeof(str), "%s+%lld(FP)", s->name, a->offset);
325                 break;
326         }
327 out:
328         return fmtstrcpy(fp, str);
329 }