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