xref: /plan9-contrib/sys/src/cmd/9l/list.c (revision fbadb1c4d4463e58337ffb1ed396c9caee5d1889)
1*fbadb1c4SDavid du Colombier #include "l.h"
2*fbadb1c4SDavid du Colombier 
3*fbadb1c4SDavid du Colombier void
listinit(void)4*fbadb1c4SDavid du Colombier listinit(void)
5*fbadb1c4SDavid du Colombier {
6*fbadb1c4SDavid du Colombier 
7*fbadb1c4SDavid du Colombier 	fmtinstall('A', Aconv);
8*fbadb1c4SDavid du Colombier 	fmtinstall('D', Dconv);
9*fbadb1c4SDavid du Colombier 	fmtinstall('P', Pconv);
10*fbadb1c4SDavid du Colombier 	fmtinstall('S', Sconv);
11*fbadb1c4SDavid du Colombier 	fmtinstall('N', Nconv);
12*fbadb1c4SDavid du Colombier 	fmtinstall('R', Rconv);
13*fbadb1c4SDavid du Colombier }
14*fbadb1c4SDavid du Colombier 
15*fbadb1c4SDavid du Colombier void
prasm(Prog * p)16*fbadb1c4SDavid du Colombier prasm(Prog *p)
17*fbadb1c4SDavid du Colombier {
18*fbadb1c4SDavid du Colombier 	print("%P\n", p);
19*fbadb1c4SDavid du Colombier }
20*fbadb1c4SDavid du Colombier 
21*fbadb1c4SDavid du Colombier int
Pconv(Fmt * fp)22*fbadb1c4SDavid du Colombier Pconv(Fmt *fp)
23*fbadb1c4SDavid du Colombier {
24*fbadb1c4SDavid du Colombier 	char str[STRINGSZ], *s;
25*fbadb1c4SDavid du Colombier 	Prog *p;
26*fbadb1c4SDavid du Colombier 	int a;
27*fbadb1c4SDavid du Colombier 
28*fbadb1c4SDavid du Colombier 	p = va_arg(fp->args, Prog*);
29*fbadb1c4SDavid du Colombier 	curp = p;
30*fbadb1c4SDavid du Colombier 	a = p->as;
31*fbadb1c4SDavid du Colombier 	if(a == ADATA || a == AINIT || a == ADYNT)
32*fbadb1c4SDavid du Colombier 		sprint(str, "(%d)	%A	%D/%d,%D", p->line, a, &p->from, p->reg, &p->to);
33*fbadb1c4SDavid du Colombier 	else {
34*fbadb1c4SDavid du Colombier 		s = str;
35*fbadb1c4SDavid du Colombier 		if(p->mark & NOSCHED)
36*fbadb1c4SDavid du Colombier 			s += sprint(s, "*");
37*fbadb1c4SDavid du Colombier 		if(p->reg == NREG && p->from3.type == D_NONE)
38*fbadb1c4SDavid du Colombier 			sprint(s, "(%d)	%A	%D,%D", p->line, a, &p->from, &p->to);
39*fbadb1c4SDavid du Colombier 		else
40*fbadb1c4SDavid du Colombier 		if(a != ATEXT && p->from.type == D_OREG) {
41*fbadb1c4SDavid du Colombier 			sprint(s, "(%d)	%A	%lld(R%d+R%d),%D", p->line, a,
42*fbadb1c4SDavid du Colombier 				p->from.offset, p->from.reg, p->reg, &p->to);
43*fbadb1c4SDavid du Colombier 		} else
44*fbadb1c4SDavid du Colombier 		if(p->to.type == D_OREG) {
45*fbadb1c4SDavid du Colombier 			sprint(s, "(%d)	%A	%D,%lld(R%d+R%d)", p->line, a,
46*fbadb1c4SDavid du Colombier 					&p->from, p->to.offset, p->to.reg, p->reg);
47*fbadb1c4SDavid du Colombier 		} else {
48*fbadb1c4SDavid du Colombier 			s += sprint(s, "(%d)	%A	%D", p->line, a, &p->from);
49*fbadb1c4SDavid du Colombier 			if(p->reg != NREG)
50*fbadb1c4SDavid du Colombier 				s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
51*fbadb1c4SDavid du Colombier 			if(p->from3.type != D_NONE)
52*fbadb1c4SDavid du Colombier 				s += sprint(s, ",%D", &p->from3);
53*fbadb1c4SDavid du Colombier 			sprint(s, ",%D", &p->to);
54*fbadb1c4SDavid du Colombier 		}
55*fbadb1c4SDavid du Colombier 	}
56*fbadb1c4SDavid du Colombier 	return fmtstrcpy(fp, str);
57*fbadb1c4SDavid du Colombier }
58*fbadb1c4SDavid du Colombier 
59*fbadb1c4SDavid du Colombier int
Aconv(Fmt * fp)60*fbadb1c4SDavid du Colombier Aconv(Fmt *fp)
61*fbadb1c4SDavid du Colombier {
62*fbadb1c4SDavid du Colombier 	char *s;
63*fbadb1c4SDavid du Colombier 	int a;
64*fbadb1c4SDavid du Colombier 
65*fbadb1c4SDavid du Colombier 	a = va_arg(fp->args, int);
66*fbadb1c4SDavid du Colombier 	s = "???";
67*fbadb1c4SDavid du Colombier 	if(a >= AXXX && a < ALAST)
68*fbadb1c4SDavid du Colombier 		s = anames[a];
69*fbadb1c4SDavid du Colombier 	return fmtstrcpy(fp, s);
70*fbadb1c4SDavid du Colombier }
71*fbadb1c4SDavid du Colombier 
72*fbadb1c4SDavid du Colombier int
Dconv(Fmt * fp)73*fbadb1c4SDavid du Colombier Dconv(Fmt *fp)
74*fbadb1c4SDavid du Colombier {
75*fbadb1c4SDavid du Colombier 	char str[STRINGSZ];
76*fbadb1c4SDavid du Colombier 	Adr *a;
77*fbadb1c4SDavid du Colombier 	long v;
78*fbadb1c4SDavid du Colombier 
79*fbadb1c4SDavid du Colombier 	a = va_arg(fp->args, Adr*);
80*fbadb1c4SDavid du Colombier 	switch(a->type) {
81*fbadb1c4SDavid du Colombier 
82*fbadb1c4SDavid du Colombier 	default:
83*fbadb1c4SDavid du Colombier 		sprint(str, "GOK-type(%d)", a->type);
84*fbadb1c4SDavid du Colombier 		break;
85*fbadb1c4SDavid du Colombier 
86*fbadb1c4SDavid du Colombier 	case D_NONE:
87*fbadb1c4SDavid du Colombier 		str[0] = 0;
88*fbadb1c4SDavid du Colombier 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
89*fbadb1c4SDavid du Colombier 			sprint(str, "%N(R%d)(NONE)", a, a->reg);
90*fbadb1c4SDavid du Colombier 		break;
91*fbadb1c4SDavid du Colombier 
92*fbadb1c4SDavid du Colombier 	case D_CONST:
93*fbadb1c4SDavid du Colombier 	case D_DCONST:
94*fbadb1c4SDavid du Colombier 		if(a->reg != NREG)
95*fbadb1c4SDavid du Colombier 			sprint(str, "$%N(R%d)", a, a->reg);
96*fbadb1c4SDavid du Colombier 		else
97*fbadb1c4SDavid du Colombier 			sprint(str, "$%N", a);
98*fbadb1c4SDavid du Colombier 		break;
99*fbadb1c4SDavid du Colombier 
100*fbadb1c4SDavid du Colombier 	case D_OREG:
101*fbadb1c4SDavid du Colombier 		if(a->reg != NREG)
102*fbadb1c4SDavid du Colombier 			sprint(str, "%N(R%d)", a, a->reg);
103*fbadb1c4SDavid du Colombier 		else
104*fbadb1c4SDavid du Colombier 			sprint(str, "%N", a);
105*fbadb1c4SDavid du Colombier 		break;
106*fbadb1c4SDavid du Colombier 
107*fbadb1c4SDavid du Colombier 	case D_REG:
108*fbadb1c4SDavid du Colombier 		sprint(str, "R%d", a->reg);
109*fbadb1c4SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
110*fbadb1c4SDavid du Colombier 			sprint(str, "%N(R%d)(REG)", a, a->reg);
111*fbadb1c4SDavid du Colombier 		break;
112*fbadb1c4SDavid du Colombier 
113*fbadb1c4SDavid du Colombier 	case D_FREG:
114*fbadb1c4SDavid du Colombier 		sprint(str, "F%d", a->reg);
115*fbadb1c4SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
116*fbadb1c4SDavid du Colombier 			sprint(str, "%N(F%d)(REG)", a, a->reg);
117*fbadb1c4SDavid du Colombier 		break;
118*fbadb1c4SDavid du Colombier 
119*fbadb1c4SDavid du Colombier 	case D_CREG:
120*fbadb1c4SDavid du Colombier 		if(a->reg == NREG)
121*fbadb1c4SDavid du Colombier 			strcpy(str, "CR");
122*fbadb1c4SDavid du Colombier 		else
123*fbadb1c4SDavid du Colombier 			sprint(str, "CR%d", a->reg);
124*fbadb1c4SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
125*fbadb1c4SDavid du Colombier 			sprint(str, "%N(C%d)(REG)", a, a->reg);
126*fbadb1c4SDavid du Colombier 		break;
127*fbadb1c4SDavid du Colombier 
128*fbadb1c4SDavid du Colombier 	case D_SPR:
129*fbadb1c4SDavid du Colombier 		if(a->name == D_NONE && a->sym == S) {
130*fbadb1c4SDavid du Colombier 			switch((ulong)a->offset) {
131*fbadb1c4SDavid du Colombier 			case D_XER: sprint(str, "XER"); break;
132*fbadb1c4SDavid du Colombier 			case D_LR: sprint(str, "LR"); break;
133*fbadb1c4SDavid du Colombier 			case D_CTR: sprint(str, "CTR"); break;
134*fbadb1c4SDavid du Colombier 			default: sprint(str, "SPR(%lld)", a->offset); break;
135*fbadb1c4SDavid du Colombier 			}
136*fbadb1c4SDavid du Colombier 			break;
137*fbadb1c4SDavid du Colombier 		}
138*fbadb1c4SDavid du Colombier 		sprint(str, "SPR-GOK(%d)", a->reg);
139*fbadb1c4SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
140*fbadb1c4SDavid du Colombier 			sprint(str, "%N(SPR-GOK%d)(REG)", a, a->reg);
141*fbadb1c4SDavid du Colombier 		break;
142*fbadb1c4SDavid du Colombier 
143*fbadb1c4SDavid du Colombier 	case D_DCR:
144*fbadb1c4SDavid du Colombier 		if(a->name == D_NONE && a->sym == S) {
145*fbadb1c4SDavid du Colombier 			sprint(str, "DCR(%lld)", a->offset);
146*fbadb1c4SDavid du Colombier 			break;
147*fbadb1c4SDavid du Colombier 		}
148*fbadb1c4SDavid du Colombier 		sprint(str, "DCR-GOK(%d)", a->reg);
149*fbadb1c4SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
150*fbadb1c4SDavid du Colombier 			sprint(str, "%N(DCR-GOK%d)(REG)", a, a->reg);
151*fbadb1c4SDavid du Colombier 		break;
152*fbadb1c4SDavid du Colombier 
153*fbadb1c4SDavid du Colombier 	case D_OPT:
154*fbadb1c4SDavid du Colombier 		sprint(str, "OPT(%d)", a->reg);
155*fbadb1c4SDavid du Colombier 		break;
156*fbadb1c4SDavid du Colombier 
157*fbadb1c4SDavid du Colombier 	case D_FPSCR:
158*fbadb1c4SDavid du Colombier 		if(a->reg == NREG)
159*fbadb1c4SDavid du Colombier 			strcpy(str, "FPSCR");
160*fbadb1c4SDavid du Colombier 		else
161*fbadb1c4SDavid du Colombier 			sprint(str, "FPSCR(%d)", a->reg);
162*fbadb1c4SDavid du Colombier 		break;
163*fbadb1c4SDavid du Colombier 
164*fbadb1c4SDavid du Colombier 	case D_MSR:
165*fbadb1c4SDavid du Colombier 		sprint(str, "MSR");
166*fbadb1c4SDavid du Colombier 		break;
167*fbadb1c4SDavid du Colombier 
168*fbadb1c4SDavid du Colombier 	case D_BRANCH:
169*fbadb1c4SDavid du Colombier 		if(curp->cond != P) {
170*fbadb1c4SDavid du Colombier 			v = curp->cond->pc;
171*fbadb1c4SDavid du Colombier 			if(v >= INITTEXT)
172*fbadb1c4SDavid du Colombier 				v -= INITTEXT-HEADR;
173*fbadb1c4SDavid du Colombier 			if(a->sym != S)
174*fbadb1c4SDavid du Colombier 				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
175*fbadb1c4SDavid du Colombier 			else
176*fbadb1c4SDavid du Colombier 				sprint(str, "%.5lux(BRANCH)", v);
177*fbadb1c4SDavid du Colombier 		} else
178*fbadb1c4SDavid du Colombier 			if(a->sym != S)
179*fbadb1c4SDavid du Colombier 				sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
180*fbadb1c4SDavid du Colombier 			else
181*fbadb1c4SDavid du Colombier 				sprint(str, "%lld(APC)", a->offset);
182*fbadb1c4SDavid du Colombier 		break;
183*fbadb1c4SDavid du Colombier 
184*fbadb1c4SDavid du Colombier 	case D_FCONST:
185*fbadb1c4SDavid du Colombier 		sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
186*fbadb1c4SDavid du Colombier 		break;
187*fbadb1c4SDavid du Colombier 
188*fbadb1c4SDavid du Colombier 	case D_SCONST:
189*fbadb1c4SDavid du Colombier 		sprint(str, "$\"%S\"", a->sval);
190*fbadb1c4SDavid du Colombier 		break;
191*fbadb1c4SDavid du Colombier 	}
192*fbadb1c4SDavid du Colombier 	return fmtstrcpy(fp, str);
193*fbadb1c4SDavid du Colombier }
194*fbadb1c4SDavid du Colombier 
195*fbadb1c4SDavid du Colombier int
Nconv(Fmt * fp)196*fbadb1c4SDavid du Colombier Nconv(Fmt *fp)
197*fbadb1c4SDavid du Colombier {
198*fbadb1c4SDavid du Colombier 	char str[STRINGSZ];
199*fbadb1c4SDavid du Colombier 	Adr *a;
200*fbadb1c4SDavid du Colombier 	Sym *s;
201*fbadb1c4SDavid du Colombier 	long l;
202*fbadb1c4SDavid du Colombier 
203*fbadb1c4SDavid du Colombier 	a = va_arg(fp->args, Adr*);
204*fbadb1c4SDavid du Colombier 	s = a->sym;
205*fbadb1c4SDavid du Colombier 	if(s == S) {
206*fbadb1c4SDavid du Colombier 		l = a->offset;
207*fbadb1c4SDavid du Colombier 		if((vlong)l != a->offset)
208*fbadb1c4SDavid du Colombier 			sprint(str, "0x%llux", a->offset);
209*fbadb1c4SDavid du Colombier 		else
210*fbadb1c4SDavid du Colombier 			sprint(str, "%lld", a->offset);
211*fbadb1c4SDavid du Colombier 		goto out;
212*fbadb1c4SDavid du Colombier 	}
213*fbadb1c4SDavid du Colombier 	switch(a->name) {
214*fbadb1c4SDavid du Colombier 	default:
215*fbadb1c4SDavid du Colombier 		sprint(str, "GOK-name(%d)", a->name);
216*fbadb1c4SDavid du Colombier 		break;
217*fbadb1c4SDavid du Colombier 
218*fbadb1c4SDavid du Colombier 	case D_EXTERN:
219*fbadb1c4SDavid du Colombier 		sprint(str, "%s+%lld(SB)", s->name, a->offset);
220*fbadb1c4SDavid du Colombier 		break;
221*fbadb1c4SDavid du Colombier 
222*fbadb1c4SDavid du Colombier 	case D_STATIC:
223*fbadb1c4SDavid du Colombier 		sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
224*fbadb1c4SDavid du Colombier 		break;
225*fbadb1c4SDavid du Colombier 
226*fbadb1c4SDavid du Colombier 	case D_AUTO:
227*fbadb1c4SDavid du Colombier 		sprint(str, "%s-%lld(SP)", s->name, -a->offset);
228*fbadb1c4SDavid du Colombier 		break;
229*fbadb1c4SDavid du Colombier 
230*fbadb1c4SDavid du Colombier 	case D_PARAM:
231*fbadb1c4SDavid du Colombier 		sprint(str, "%s+%lld(FP)", s->name, a->offset);
232*fbadb1c4SDavid du Colombier 		break;
233*fbadb1c4SDavid du Colombier 	}
234*fbadb1c4SDavid du Colombier out:
235*fbadb1c4SDavid du Colombier 	return fmtstrcpy(fp, str);
236*fbadb1c4SDavid du Colombier }
237*fbadb1c4SDavid du Colombier 
238*fbadb1c4SDavid du Colombier int
Rconv(Fmt * fp)239*fbadb1c4SDavid du Colombier Rconv(Fmt *fp)
240*fbadb1c4SDavid du Colombier {
241*fbadb1c4SDavid du Colombier 	char *s;
242*fbadb1c4SDavid du Colombier 	int a;
243*fbadb1c4SDavid du Colombier 
244*fbadb1c4SDavid du Colombier 	a = va_arg(fp->args, int);
245*fbadb1c4SDavid du Colombier 	s = "C_??";
246*fbadb1c4SDavid du Colombier 	if(a >= C_NONE && a <= C_NCLASS)
247*fbadb1c4SDavid du Colombier 		s = cnames[a];
248*fbadb1c4SDavid du Colombier 	return fmtstrcpy(fp, s);
249*fbadb1c4SDavid du Colombier }
250*fbadb1c4SDavid du Colombier 
251*fbadb1c4SDavid du Colombier int
Sconv(Fmt * fp)252*fbadb1c4SDavid du Colombier Sconv(Fmt *fp)
253*fbadb1c4SDavid du Colombier {
254*fbadb1c4SDavid du Colombier 	int i, c;
255*fbadb1c4SDavid du Colombier 	char str[STRINGSZ], *p, *a;
256*fbadb1c4SDavid du Colombier 
257*fbadb1c4SDavid du Colombier 	a = va_arg(fp->args, char*);
258*fbadb1c4SDavid du Colombier 	p = str;
259*fbadb1c4SDavid du Colombier 	for(i=0; i<sizeof(long); i++) {
260*fbadb1c4SDavid du Colombier 		c = a[i] & 0xff;
261*fbadb1c4SDavid du Colombier 		if(c >= 'a' && c <= 'z' ||
262*fbadb1c4SDavid du Colombier 		   c >= 'A' && c <= 'Z' ||
263*fbadb1c4SDavid du Colombier 		   c >= '0' && c <= '9' ||
264*fbadb1c4SDavid du Colombier 		   c == ' ' || c == '%') {
265*fbadb1c4SDavid du Colombier 			*p++ = c;
266*fbadb1c4SDavid du Colombier 			continue;
267*fbadb1c4SDavid du Colombier 		}
268*fbadb1c4SDavid du Colombier 		*p++ = '\\';
269*fbadb1c4SDavid du Colombier 		switch(c) {
270*fbadb1c4SDavid du Colombier 		case 0:
271*fbadb1c4SDavid du Colombier 			*p++ = 'z';
272*fbadb1c4SDavid du Colombier 			continue;
273*fbadb1c4SDavid du Colombier 		case '\\':
274*fbadb1c4SDavid du Colombier 		case '"':
275*fbadb1c4SDavid du Colombier 			*p++ = c;
276*fbadb1c4SDavid du Colombier 			continue;
277*fbadb1c4SDavid du Colombier 		case '\n':
278*fbadb1c4SDavid du Colombier 			*p++ = 'n';
279*fbadb1c4SDavid du Colombier 			continue;
280*fbadb1c4SDavid du Colombier 		case '\t':
281*fbadb1c4SDavid du Colombier 			*p++ = 't';
282*fbadb1c4SDavid du Colombier 			continue;
283*fbadb1c4SDavid du Colombier 		}
284*fbadb1c4SDavid du Colombier 		*p++ = (c>>6) + '0';
285*fbadb1c4SDavid du Colombier 		*p++ = ((c>>3) & 7) + '0';
286*fbadb1c4SDavid du Colombier 		*p++ = (c & 7) + '0';
287*fbadb1c4SDavid du Colombier 	}
288*fbadb1c4SDavid du Colombier 	*p = 0;
289*fbadb1c4SDavid du Colombier 	return fmtstrcpy(fp, str);
290*fbadb1c4SDavid du Colombier }
291*fbadb1c4SDavid du Colombier 
292*fbadb1c4SDavid du Colombier void
diag(char * fmt,...)293*fbadb1c4SDavid du Colombier diag(char *fmt, ...)
294*fbadb1c4SDavid du Colombier {
295*fbadb1c4SDavid du Colombier 	char buf[STRINGSZ], *tn;
296*fbadb1c4SDavid du Colombier 	va_list arg;
297*fbadb1c4SDavid du Colombier 
298*fbadb1c4SDavid du Colombier 	tn = "??none??";
299*fbadb1c4SDavid du Colombier 	if(curtext != P && curtext->from.sym != S)
300*fbadb1c4SDavid du Colombier 		tn = curtext->from.sym->name;
301*fbadb1c4SDavid du Colombier 	va_start(arg, fmt);
302*fbadb1c4SDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
303*fbadb1c4SDavid du Colombier 	va_end(arg);
304*fbadb1c4SDavid du Colombier 	print("%s: %s\n", tn, buf);
305*fbadb1c4SDavid du Colombier 
306*fbadb1c4SDavid du Colombier 	nerrors++;
307*fbadb1c4SDavid du Colombier 	if(nerrors > 10) {
308*fbadb1c4SDavid du Colombier 		print("too many errors\n");
309*fbadb1c4SDavid du Colombier 		errorexit();
310*fbadb1c4SDavid du Colombier 	}
311*fbadb1c4SDavid du Colombier }
312