xref: /plan9/sys/src/cmd/8l/list.c (revision 6520663fb7ebac8d17e4a1dbc55d10bf525f7b14)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
listinit(void)43e12c5d1SDavid du Colombier listinit(void)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier 	fmtinstall('R', Rconv);
83e12c5d1SDavid du Colombier 	fmtinstall('A', Aconv);
93e12c5d1SDavid du Colombier 	fmtinstall('D', Dconv);
103e12c5d1SDavid du Colombier 	fmtinstall('S', Sconv);
113e12c5d1SDavid du Colombier 	fmtinstall('P', Pconv);
123e12c5d1SDavid du Colombier }
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier static	Prog	*bigP;
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier int
Pconv(Fmt * fp)179a747e4fSDavid du Colombier Pconv(Fmt *fp)
183e12c5d1SDavid du Colombier {
193e12c5d1SDavid du Colombier 	char str[STRINGSZ];
203e12c5d1SDavid du Colombier 	Prog *p;
213e12c5d1SDavid du Colombier 
229a747e4fSDavid du Colombier 	p = va_arg(fp->args, Prog*);
233e12c5d1SDavid du Colombier 	bigP = p;
243e12c5d1SDavid du Colombier 	switch(p->as) {
253e12c5d1SDavid du Colombier 	case ATEXT:
263e12c5d1SDavid du Colombier 		if(p->from.scale) {
27*6520663fSDavid du Colombier 			snprint(str, sizeof(str), "(%ld)	%A	%D,%d,%D",
283e12c5d1SDavid du Colombier 				p->line, p->as, &p->from, p->from.scale, &p->to);
293e12c5d1SDavid du Colombier 			break;
303e12c5d1SDavid du Colombier 		}
313e12c5d1SDavid du Colombier 	default:
32*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "(%ld)	%A	%D,%D",
333e12c5d1SDavid du Colombier 			p->line, p->as, &p->from, &p->to);
343e12c5d1SDavid du Colombier 		break;
353e12c5d1SDavid du Colombier 	case ADATA:
36219b2ee8SDavid du Colombier 	case AINIT:
37219b2ee8SDavid du Colombier 	case ADYNT:
38*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "(%ld)	%A	%D/%d,%D",
393e12c5d1SDavid du Colombier 			p->line, p->as, &p->from, p->from.scale, &p->to);
403e12c5d1SDavid du Colombier 		break;
413e12c5d1SDavid du Colombier 	}
423e12c5d1SDavid du Colombier 	bigP = P;
439a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
443e12c5d1SDavid du Colombier }
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier int
Aconv(Fmt * fp)479a747e4fSDavid du Colombier Aconv(Fmt *fp)
483e12c5d1SDavid du Colombier {
493e12c5d1SDavid du Colombier 	int i;
503e12c5d1SDavid du Colombier 
519a747e4fSDavid du Colombier 	i = va_arg(fp->args, int);
529a747e4fSDavid du Colombier 	return fmtstrcpy(fp, anames[i]);
533e12c5d1SDavid du Colombier }
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier int
Dconv(Fmt * fp)569a747e4fSDavid du Colombier Dconv(Fmt *fp)
573e12c5d1SDavid du Colombier {
58*6520663fSDavid du Colombier 	char str[STRINGSZ+40], s[20];
593e12c5d1SDavid du Colombier 	Adr *a;
603e12c5d1SDavid du Colombier 	int i;
613e12c5d1SDavid du Colombier 
629a747e4fSDavid du Colombier 	a = va_arg(fp->args, Adr*);
633e12c5d1SDavid du Colombier 	i = a->type;
643e12c5d1SDavid du Colombier 	if(i >= D_INDIR) {
653e12c5d1SDavid du Colombier 		if(a->offset)
66*6520663fSDavid du Colombier 			snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
673e12c5d1SDavid du Colombier 		else
68*6520663fSDavid du Colombier 			snprint(str, sizeof(str), "(%R)", i-D_INDIR);
693e12c5d1SDavid du Colombier 		goto brk;
703e12c5d1SDavid du Colombier 	}
713e12c5d1SDavid du Colombier 	switch(i) {
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier 	default:
74*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "%R", i);
753e12c5d1SDavid du Colombier 		break;
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier 	case D_NONE:
783e12c5d1SDavid du Colombier 		str[0] = 0;
793e12c5d1SDavid du Colombier 		break;
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier 	case D_BRANCH:
827dd7cddfSDavid du Colombier 		if(bigP != P && bigP->pcond != P)
833e12c5d1SDavid du Colombier 			if(a->sym != S)
84*6520663fSDavid du Colombier 				snprint(str, sizeof(str), "%lux+%s", bigP->pcond->pc,
853e12c5d1SDavid du Colombier 					a->sym->name);
863e12c5d1SDavid du Colombier 			else
87*6520663fSDavid du Colombier 				snprint(str, sizeof(str), "%lux", bigP->pcond->pc);
883e12c5d1SDavid du Colombier 		else
89*6520663fSDavid du Colombier 			snprint(str, sizeof(str), "%ld(PC)", a->offset);
903e12c5d1SDavid du Colombier 		break;
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 	case D_EXTERN:
93*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
943e12c5d1SDavid du Colombier 		break;
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 	case D_STATIC:
97*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "%s<%d>+%ld(SB)", a->sym->name,
983e12c5d1SDavid du Colombier 			a->sym->version, a->offset);
993e12c5d1SDavid du Colombier 		break;
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier 	case D_AUTO:
102*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
1033e12c5d1SDavid du Colombier 		break;
1043e12c5d1SDavid du Colombier 
1053e12c5d1SDavid du Colombier 	case D_PARAM:
1063e12c5d1SDavid du Colombier 		if(a->sym)
107*6520663fSDavid du Colombier 			snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
1083e12c5d1SDavid du Colombier 		else
109*6520663fSDavid du Colombier 			snprint(str, sizeof(str), "%ld(FP)", a->offset);
1103e12c5d1SDavid du Colombier 		break;
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier 	case D_CONST:
113*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "$%ld", a->offset);
1143e12c5d1SDavid du Colombier 		break;
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier 	case D_FCONST:
117*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
1183e12c5d1SDavid du Colombier 		break;
1193e12c5d1SDavid du Colombier 
1203e12c5d1SDavid du Colombier 	case D_SCONST:
121*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "$\"%S\"", a->scon);
1223e12c5d1SDavid du Colombier 		break;
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier 	case D_ADDR:
1253e12c5d1SDavid du Colombier 		a->type = a->index;
1263e12c5d1SDavid du Colombier 		a->index = D_NONE;
127*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "$%D", a);
1283e12c5d1SDavid du Colombier 		a->index = a->type;
1293e12c5d1SDavid du Colombier 		a->type = D_ADDR;
1303e12c5d1SDavid du Colombier 		goto conv;
1313e12c5d1SDavid du Colombier 	}
1323e12c5d1SDavid du Colombier brk:
1333e12c5d1SDavid du Colombier 	if(a->index != D_NONE) {
134*6520663fSDavid du Colombier 		snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
1353e12c5d1SDavid du Colombier 		strcat(str, s);
1363e12c5d1SDavid du Colombier 	}
1373e12c5d1SDavid du Colombier conv:
1389a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
1393e12c5d1SDavid du Colombier }
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier char*	regstr[] =
1423e12c5d1SDavid du Colombier {
1437dd7cddfSDavid du Colombier 	"AL",		/* [D_AL] */
1443e12c5d1SDavid du Colombier 	"CL",
1453e12c5d1SDavid du Colombier 	"DL",
1463e12c5d1SDavid du Colombier 	"BL",
1473e12c5d1SDavid du Colombier 	"AH",
1483e12c5d1SDavid du Colombier 	"CH",
1493e12c5d1SDavid du Colombier 	"DH",
1503e12c5d1SDavid du Colombier 	"BH",
1513e12c5d1SDavid du Colombier 
1527dd7cddfSDavid du Colombier 	"AX",		/* [D_AX] */
1533e12c5d1SDavid du Colombier 	"CX",
1543e12c5d1SDavid du Colombier 	"DX",
1553e12c5d1SDavid du Colombier 	"BX",
1563e12c5d1SDavid du Colombier 	"SP",
1573e12c5d1SDavid du Colombier 	"BP",
1583e12c5d1SDavid du Colombier 	"SI",
1593e12c5d1SDavid du Colombier 	"DI",
1603e12c5d1SDavid du Colombier 
1617dd7cddfSDavid du Colombier 	"F0",		/* [D_F0] */
1623e12c5d1SDavid du Colombier 	"F1",
1633e12c5d1SDavid du Colombier 	"F2",
1643e12c5d1SDavid du Colombier 	"F3",
1653e12c5d1SDavid du Colombier 	"F4",
1663e12c5d1SDavid du Colombier 	"F5",
1673e12c5d1SDavid du Colombier 	"F6",
1683e12c5d1SDavid du Colombier 	"F7",
1693e12c5d1SDavid du Colombier 
1707dd7cddfSDavid du Colombier 	"CS",		/* [D_CS] */
1713e12c5d1SDavid du Colombier 	"SS",
1723e12c5d1SDavid du Colombier 	"DS",
1733e12c5d1SDavid du Colombier 	"ES",
1743e12c5d1SDavid du Colombier 	"FS",
1753e12c5d1SDavid du Colombier 	"GS",
1763e12c5d1SDavid du Colombier 
1777dd7cddfSDavid du Colombier 	"GDTR",		/* [D_GDTR] */
1787dd7cddfSDavid du Colombier 	"IDTR",		/* [D_IDTR] */
1797dd7cddfSDavid du Colombier 	"LDTR",		/* [D_LDTR] */
1807dd7cddfSDavid du Colombier 	"MSW",		/* [D_MSW] */
1817dd7cddfSDavid du Colombier 	"TASK",		/* [D_TASK] */
1823e12c5d1SDavid du Colombier 
1837dd7cddfSDavid du Colombier 	"CR0",		/* [D_CR] */
1843e12c5d1SDavid du Colombier 	"CR1",
1853e12c5d1SDavid du Colombier 	"CR2",
1863e12c5d1SDavid du Colombier 	"CR3",
1873e12c5d1SDavid du Colombier 	"CR4",
1883e12c5d1SDavid du Colombier 	"CR5",
1893e12c5d1SDavid du Colombier 	"CR6",
1903e12c5d1SDavid du Colombier 	"CR7",
1913e12c5d1SDavid du Colombier 
1927dd7cddfSDavid du Colombier 	"DR0",		/* [D_DR] */
1933e12c5d1SDavid du Colombier 	"DR1",
1943e12c5d1SDavid du Colombier 	"DR2",
1953e12c5d1SDavid du Colombier 	"DR3",
1963e12c5d1SDavid du Colombier 	"DR4",
1973e12c5d1SDavid du Colombier 	"DR5",
1983e12c5d1SDavid du Colombier 	"DR6",
1993e12c5d1SDavid du Colombier 	"DR7",
2003e12c5d1SDavid du Colombier 
2017dd7cddfSDavid du Colombier 	"TR0",		/* [D_TR] */
2023e12c5d1SDavid du Colombier 	"TR1",
2033e12c5d1SDavid du Colombier 	"TR2",
2043e12c5d1SDavid du Colombier 	"TR3",
2053e12c5d1SDavid du Colombier 	"TR4",
2063e12c5d1SDavid du Colombier 	"TR5",
2073e12c5d1SDavid du Colombier 	"TR6",
2083e12c5d1SDavid du Colombier 	"TR7",
2093e12c5d1SDavid du Colombier 
2107dd7cddfSDavid du Colombier 	"NONE",		/* [D_NONE] */
2113e12c5d1SDavid du Colombier };
2123e12c5d1SDavid du Colombier 
2133e12c5d1SDavid du Colombier int
Rconv(Fmt * fp)2149a747e4fSDavid du Colombier Rconv(Fmt *fp)
2153e12c5d1SDavid du Colombier {
2163e12c5d1SDavid du Colombier 	char str[20];
2173e12c5d1SDavid du Colombier 	int r;
2183e12c5d1SDavid du Colombier 
2199a747e4fSDavid du Colombier 	r = va_arg(fp->args, int);
2203e12c5d1SDavid du Colombier 	if(r >= D_AL && r <= D_NONE)
221*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
2223e12c5d1SDavid du Colombier 	else
223*6520663fSDavid du Colombier 		snprint(str, sizeof(str), "gok(%d)", r);
2243e12c5d1SDavid du Colombier 
2259a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
2263e12c5d1SDavid du Colombier }
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier int
Sconv(Fmt * fp)2299a747e4fSDavid du Colombier Sconv(Fmt *fp)
2303e12c5d1SDavid du Colombier {
2313e12c5d1SDavid du Colombier 	int i, c;
2323e12c5d1SDavid du Colombier 	char str[30], *p, *a;
2333e12c5d1SDavid du Colombier 
2349a747e4fSDavid du Colombier 	a = va_arg(fp->args, char*);
2353e12c5d1SDavid du Colombier 	p = str;
2363e12c5d1SDavid du Colombier 	for(i=0; i<sizeof(double); i++) {
2373e12c5d1SDavid du Colombier 		c = a[i] & 0xff;
2383e12c5d1SDavid du Colombier 		if(c >= 'a' && c <= 'z' ||
2393e12c5d1SDavid du Colombier 		   c >= 'A' && c <= 'Z' ||
2403e12c5d1SDavid du Colombier 		   c >= '0' && c <= '9') {
2413e12c5d1SDavid du Colombier 			*p++ = c;
2423e12c5d1SDavid du Colombier 			continue;
2433e12c5d1SDavid du Colombier 		}
2443e12c5d1SDavid du Colombier 		*p++ = '\\';
2453e12c5d1SDavid du Colombier 		switch(c) {
2463e12c5d1SDavid du Colombier 		default:
2473e12c5d1SDavid du Colombier 			if(c < 040 || c >= 0177)
2483e12c5d1SDavid du Colombier 				break;	/* not portable */
2493e12c5d1SDavid du Colombier 			p[-1] = c;
2503e12c5d1SDavid du Colombier 			continue;
2513e12c5d1SDavid du Colombier 		case 0:
2523e12c5d1SDavid du Colombier 			*p++ = 'z';
2533e12c5d1SDavid du Colombier 			continue;
2543e12c5d1SDavid du Colombier 		case '\\':
2553e12c5d1SDavid du Colombier 		case '"':
2563e12c5d1SDavid du Colombier 			*p++ = c;
2573e12c5d1SDavid du Colombier 			continue;
2583e12c5d1SDavid du Colombier 		case '\n':
2593e12c5d1SDavid du Colombier 			*p++ = 'n';
2603e12c5d1SDavid du Colombier 			continue;
2613e12c5d1SDavid du Colombier 		case '\t':
2623e12c5d1SDavid du Colombier 			*p++ = 't';
2633e12c5d1SDavid du Colombier 			continue;
2643e12c5d1SDavid du Colombier 		}
2653e12c5d1SDavid du Colombier 		*p++ = (c>>6) + '0';
2663e12c5d1SDavid du Colombier 		*p++ = ((c>>3) & 7) + '0';
2673e12c5d1SDavid du Colombier 		*p++ = (c & 7) + '0';
2683e12c5d1SDavid du Colombier 	}
2693e12c5d1SDavid du Colombier 	*p = 0;
2709a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
2713e12c5d1SDavid du Colombier }
2723e12c5d1SDavid du Colombier 
2733e12c5d1SDavid du Colombier void
diag(char * fmt,...)2747dd7cddfSDavid du Colombier diag(char *fmt, ...)
2753e12c5d1SDavid du Colombier {
2763e12c5d1SDavid du Colombier 	char buf[STRINGSZ], *tn;
2777dd7cddfSDavid du Colombier 	va_list arg;
2783e12c5d1SDavid du Colombier 
2793e12c5d1SDavid du Colombier 	tn = "??none??";
2803e12c5d1SDavid du Colombier 	if(curtext != P && curtext->from.sym != S)
2813e12c5d1SDavid du Colombier 		tn = curtext->from.sym->name;
2827dd7cddfSDavid du Colombier 	va_start(arg, fmt);
2839a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
2847dd7cddfSDavid du Colombier 	va_end(arg);
2853e12c5d1SDavid du Colombier 	print("%s: %s\n", tn, buf);
2863e12c5d1SDavid du Colombier 
2873e12c5d1SDavid du Colombier 	nerrors++;
28814cc0f53SDavid du Colombier 	if(nerrors > 20 && !debug['A']) {
2893e12c5d1SDavid du Colombier 		print("too many errors\n");
2903e12c5d1SDavid du Colombier 		errorexit();
2913e12c5d1SDavid du Colombier 	}
2923e12c5d1SDavid du Colombier }
293