xref: /plan9-contrib/sys/src/cmd/5c/list.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
17dd7cddfSDavid du Colombier #define	EXTERN
27dd7cddfSDavid du Colombier #include "gc.h"
37dd7cddfSDavid du Colombier 
47dd7cddfSDavid du Colombier void
listinit(void)57dd7cddfSDavid du Colombier listinit(void)
67dd7cddfSDavid du Colombier {
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier 	fmtinstall('A', Aconv);
97dd7cddfSDavid du Colombier 	fmtinstall('P', Pconv);
107dd7cddfSDavid du Colombier 	fmtinstall('S', Sconv);
117dd7cddfSDavid du Colombier 	fmtinstall('N', Nconv);
127dd7cddfSDavid du Colombier 	fmtinstall('B', Bconv);
137dd7cddfSDavid du Colombier 	fmtinstall('D', Dconv);
1459cc4ca5SDavid du Colombier 	fmtinstall('R', Rconv);
157dd7cddfSDavid du Colombier }
167dd7cddfSDavid du Colombier 
177dd7cddfSDavid du Colombier int
Bconv(Fmt * fp)189a747e4fSDavid du Colombier Bconv(Fmt *fp)
197dd7cddfSDavid du Colombier {
207dd7cddfSDavid du Colombier 	char str[STRINGSZ], ss[STRINGSZ], *s;
217dd7cddfSDavid du Colombier 	Bits bits;
227dd7cddfSDavid du Colombier 	int i;
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier 	str[0] = 0;
259a747e4fSDavid du Colombier 	bits = va_arg(fp->args, Bits);
267dd7cddfSDavid du Colombier 	while(bany(&bits)) {
277dd7cddfSDavid du Colombier 		i = bnum(bits);
287dd7cddfSDavid du Colombier 		if(str[0])
297dd7cddfSDavid du Colombier 			strcat(str, " ");
307dd7cddfSDavid du Colombier 		if(var[i].sym == S) {
310591a7c1SDavid du Colombier 			snprint(ss, sizeof(ss), "$%ld", var[i].offset);
327dd7cddfSDavid du Colombier 			s = ss;
337dd7cddfSDavid du Colombier 		} else
347dd7cddfSDavid du Colombier 			s = var[i].sym->name;
357dd7cddfSDavid du Colombier 		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
367dd7cddfSDavid du Colombier 			break;
377dd7cddfSDavid du Colombier 		strcat(str, s);
387dd7cddfSDavid du Colombier 		bits.b[i/32] &= ~(1L << (i%32));
397dd7cddfSDavid du Colombier 	}
409a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
417dd7cddfSDavid du Colombier }
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier char *extra [] = {
447dd7cddfSDavid du Colombier 	".EQ", ".NE", ".CS", ".CC",
457dd7cddfSDavid du Colombier 	".MI", ".PL", ".VS", ".VC",
467dd7cddfSDavid du Colombier 	".HI", ".LS", ".GE", ".LT",
477dd7cddfSDavid du Colombier 	".GT", ".LE", "", ".NV",
487dd7cddfSDavid du Colombier };
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier int
Pconv(Fmt * fp)519a747e4fSDavid du Colombier Pconv(Fmt *fp)
527dd7cddfSDavid du Colombier {
5359cc4ca5SDavid du Colombier 	char str[STRINGSZ], sc[20];
547dd7cddfSDavid du Colombier 	Prog *p;
557dd7cddfSDavid du Colombier 	int a, s;
567dd7cddfSDavid du Colombier 
579a747e4fSDavid du Colombier 	p = va_arg(fp->args, Prog*);
587dd7cddfSDavid du Colombier 	a = p->as;
5959cc4ca5SDavid du Colombier 	s = p->scond;
6059cc4ca5SDavid du Colombier 	strcpy(sc, extra[s & C_SCOND]);
6159cc4ca5SDavid du Colombier 	if(s & C_SBIT)
6259cc4ca5SDavid du Colombier 		strcat(sc, ".S");
6359cc4ca5SDavid du Colombier 	if(s & C_PBIT)
6459cc4ca5SDavid du Colombier 		strcat(sc, ".P");
6559cc4ca5SDavid du Colombier 	if(s & C_WBIT)
6659cc4ca5SDavid du Colombier 		strcat(sc, ".W");
6759cc4ca5SDavid du Colombier 	if(s & C_UBIT)		/* ambiguous with FBIT */
6859cc4ca5SDavid du Colombier 		strcat(sc, ".U");
6959cc4ca5SDavid du Colombier 	if(a == AMOVM) {
7059cc4ca5SDavid du Colombier 		if(p->from.type == D_CONST)
710591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "	%A%s	%R,%D", a, sc, &p->from, &p->to);
7259cc4ca5SDavid du Colombier 		else
7359cc4ca5SDavid du Colombier 		if(p->to.type == D_CONST)
740591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "	%A%s	%D,%R", a, sc, &p->from, &p->to);
7559cc4ca5SDavid du Colombier 		else
760591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "	%A%s	%D,%D", a, sc, &p->from, &p->to);
7759cc4ca5SDavid du Colombier 	} else
787dd7cddfSDavid du Colombier 	if(a == ADATA)
790591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
807dd7cddfSDavid du Colombier 	else
81e288d156SDavid du Colombier 	if(p->as == ATEXT)
820591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
83e288d156SDavid du Colombier 	else
847dd7cddfSDavid du Colombier 	if(p->reg == NREG)
850591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "	%A%s	%D,%D", a, sc, &p->from, &p->to);
867dd7cddfSDavid du Colombier 	else
87*40d01547SDavid du Colombier 	if(p->reghi != NREG)
88*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "	%A%s	%D,R%d,%D,R%d", a, sc, &p->from, p->reg, &p->to, p->reghi);
89*40d01547SDavid du Colombier 	else
90*40d01547SDavid du Colombier 	if(p->from.type != D_FREG && p->from.type != D_SFREG && p->from.type != D_FCONST)
910591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
927dd7cddfSDavid du Colombier 	else
930591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
949a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier 
977dd7cddfSDavid du Colombier int
Aconv(Fmt * fp)989a747e4fSDavid du Colombier Aconv(Fmt *fp)
997dd7cddfSDavid du Colombier {
1007dd7cddfSDavid du Colombier 	char *s;
1017dd7cddfSDavid du Colombier 	int a;
1027dd7cddfSDavid du Colombier 
1039a747e4fSDavid du Colombier 	a = va_arg(fp->args, int);
1047dd7cddfSDavid du Colombier 	s = "???";
1057dd7cddfSDavid du Colombier 	if(a >= AXXX && a < ALAST)
1067dd7cddfSDavid du Colombier 		s = anames[a];
1079a747e4fSDavid du Colombier 	return fmtstrcpy(fp, s);
1087dd7cddfSDavid du Colombier }
1097dd7cddfSDavid du Colombier 
1107dd7cddfSDavid du Colombier int
Dconv(Fmt * fp)1119a747e4fSDavid du Colombier Dconv(Fmt *fp)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier 	char str[STRINGSZ];
1147dd7cddfSDavid du Colombier 	Adr *a;
11559cc4ca5SDavid du Colombier 	char *op;
11659cc4ca5SDavid du Colombier 	int v;
1177dd7cddfSDavid du Colombier 
1189a747e4fSDavid du Colombier 	a = va_arg(fp->args, Adr*);
1197dd7cddfSDavid du Colombier 	switch(a->type) {
1207dd7cddfSDavid du Colombier 
1217dd7cddfSDavid du Colombier 	default:
1220591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "GOK-type(%d)", a->type);
1237dd7cddfSDavid du Colombier 		break;
1247dd7cddfSDavid du Colombier 
1257dd7cddfSDavid du Colombier 	case D_NONE:
1267dd7cddfSDavid du Colombier 		str[0] = 0;
1277dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
1280591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
1297dd7cddfSDavid du Colombier 		break;
1307dd7cddfSDavid du Colombier 
1317dd7cddfSDavid du Colombier 	case D_CONST:
1327dd7cddfSDavid du Colombier 		if(a->reg != NREG)
1330591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
1347dd7cddfSDavid du Colombier 		else
1350591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "$%N", a);
1367dd7cddfSDavid du Colombier 		break;
1377dd7cddfSDavid du Colombier 
13859cc4ca5SDavid du Colombier 	case D_SHIFT:
13959cc4ca5SDavid du Colombier 		v = a->offset;
14059cc4ca5SDavid du Colombier 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
14159cc4ca5SDavid du Colombier 		if(v & (1<<4))
1420591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
14359cc4ca5SDavid du Colombier 		else
1440591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
14559cc4ca5SDavid du Colombier 		if(a->reg != NREG)
14659cc4ca5SDavid du Colombier 			sprint(str+strlen(str), "(R%d)", a->reg);
14759cc4ca5SDavid du Colombier 		break;
14859cc4ca5SDavid du Colombier 
1497dd7cddfSDavid du Colombier 	case D_OREG:
1507dd7cddfSDavid du Colombier 		if(a->reg != NREG)
1510591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "%N(R%d)", a, a->reg);
1527dd7cddfSDavid du Colombier 		else
1530591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "%N", a);
1547dd7cddfSDavid du Colombier 		break;
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier 	case D_REG:
1570591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "R%d", a->reg);
1587dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
1590591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
1607dd7cddfSDavid du Colombier 		break;
1617dd7cddfSDavid du Colombier 
1627dd7cddfSDavid du Colombier 	case D_FREG:
1630591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "F%d", a->reg);
1647dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
1650591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
1667dd7cddfSDavid du Colombier 		break;
1677dd7cddfSDavid du Colombier 
168*40d01547SDavid du Colombier 	case D_SFREG:
169*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "S%d", a->reg);
170*40d01547SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
171*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
172*40d01547SDavid du Colombier 		break;
173*40d01547SDavid du Colombier 
174*40d01547SDavid du Colombier 	case D_QREG:
175*40d01547SDavid du Colombier 		snprint(str, sizeof(str), "Q%d", a->reg);
176*40d01547SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
177*40d01547SDavid du Colombier 			snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
178*40d01547SDavid du Colombier 		break;
179*40d01547SDavid du Colombier 
1807dd7cddfSDavid du Colombier 	case D_PSR:
1810591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "PSR");
1827dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
1830591a7c1SDavid du Colombier 			snprint(str, sizeof(str), "%N(PSR)(REG)", a);
1847dd7cddfSDavid du Colombier 		break;
1857dd7cddfSDavid du Colombier 
1867dd7cddfSDavid du Colombier 	case D_BRANCH:
1870591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
1887dd7cddfSDavid du Colombier 		break;
1897dd7cddfSDavid du Colombier 
1907dd7cddfSDavid du Colombier 	case D_FCONST:
1910591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "$%.17e", a->dval);
1927dd7cddfSDavid du Colombier 		break;
1937dd7cddfSDavid du Colombier 
1947dd7cddfSDavid du Colombier 	case D_SCONST:
1950591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "$\"%S\"", a->sval);
1967dd7cddfSDavid du Colombier 		break;
1977dd7cddfSDavid du Colombier 	}
1989a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
1997dd7cddfSDavid du Colombier }
2007dd7cddfSDavid du Colombier 
2017dd7cddfSDavid du Colombier int
Rconv(Fmt * fp)2029a747e4fSDavid du Colombier Rconv(Fmt *fp)
20359cc4ca5SDavid du Colombier {
2040591a7c1SDavid du Colombier 	char str[STRINGSZ], *p, *e;
20559cc4ca5SDavid du Colombier 	Adr *a;
20659cc4ca5SDavid du Colombier 	int i, v;
20759cc4ca5SDavid du Colombier 
2089a747e4fSDavid du Colombier 	a = va_arg(fp->args, Adr*);
2090591a7c1SDavid du Colombier 	snprint(str, sizeof(str), "GOK-reglist");
21059cc4ca5SDavid du Colombier 	switch(a->type) {
21159cc4ca5SDavid du Colombier 	case D_CONST:
21259cc4ca5SDavid du Colombier 		if(a->reg != NREG)
21359cc4ca5SDavid du Colombier 			break;
21459cc4ca5SDavid du Colombier 		if(a->sym != S)
21559cc4ca5SDavid du Colombier 			break;
21659cc4ca5SDavid du Colombier 		v = a->offset;
2170591a7c1SDavid du Colombier 		p = str;
2180591a7c1SDavid du Colombier 		e = str+sizeof(str);
21959cc4ca5SDavid du Colombier 		for(i=0; i<NREG; i++) {
22059cc4ca5SDavid du Colombier 			if(v & (1<<i)) {
2210591a7c1SDavid du Colombier 				if(p == str)
2220591a7c1SDavid du Colombier 					p = seprint(p, e, "[R%d", i);
22359cc4ca5SDavid du Colombier 				else
2240591a7c1SDavid du Colombier 					p = seprint(p, e, ",R%d", i);
22559cc4ca5SDavid du Colombier 			}
22659cc4ca5SDavid du Colombier 		}
2270591a7c1SDavid du Colombier 		seprint(p, e, "]");
22859cc4ca5SDavid du Colombier 	}
2299a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
23059cc4ca5SDavid du Colombier }
23159cc4ca5SDavid du Colombier 
23259cc4ca5SDavid du Colombier int
Sconv(Fmt * fp)2339a747e4fSDavid du Colombier Sconv(Fmt *fp)
2347dd7cddfSDavid du Colombier {
2357dd7cddfSDavid du Colombier 	int i, c;
2367dd7cddfSDavid du Colombier 	char str[STRINGSZ], *p, *a;
2377dd7cddfSDavid du Colombier 
2389a747e4fSDavid du Colombier 	a = va_arg(fp->args, char*);
2397dd7cddfSDavid du Colombier 	p = str;
2407dd7cddfSDavid du Colombier 	for(i=0; i<NSNAME; i++) {
2417dd7cddfSDavid du Colombier 		c = a[i] & 0xff;
2427dd7cddfSDavid du Colombier 		if(c >= 'a' && c <= 'z' ||
2437dd7cddfSDavid du Colombier 		   c >= 'A' && c <= 'Z' ||
2447dd7cddfSDavid du Colombier 		   c >= '0' && c <= '9' ||
2457dd7cddfSDavid du Colombier 		   c == ' ' || c == '%') {
2467dd7cddfSDavid du Colombier 			*p++ = c;
2477dd7cddfSDavid du Colombier 			continue;
2487dd7cddfSDavid du Colombier 		}
2497dd7cddfSDavid du Colombier 		*p++ = '\\';
2507dd7cddfSDavid du Colombier 		switch(c) {
2517dd7cddfSDavid du Colombier 		case 0:
2527dd7cddfSDavid du Colombier 			*p++ = 'z';
2537dd7cddfSDavid du Colombier 			continue;
2547dd7cddfSDavid du Colombier 		case '\\':
2557dd7cddfSDavid du Colombier 		case '"':
2567dd7cddfSDavid du Colombier 			*p++ = c;
2577dd7cddfSDavid du Colombier 			continue;
2587dd7cddfSDavid du Colombier 		case '\n':
2597dd7cddfSDavid du Colombier 			*p++ = 'n';
2607dd7cddfSDavid du Colombier 			continue;
2617dd7cddfSDavid du Colombier 		case '\t':
2627dd7cddfSDavid du Colombier 			*p++ = 't';
2637dd7cddfSDavid du Colombier 			continue;
2647dd7cddfSDavid du Colombier 		case '\r':
2657dd7cddfSDavid du Colombier 			*p++ = 'r';
2667dd7cddfSDavid du Colombier 			continue;
2677dd7cddfSDavid du Colombier 		case '\f':
2687dd7cddfSDavid du Colombier 			*p++ = 'f';
2697dd7cddfSDavid du Colombier 			continue;
2707dd7cddfSDavid du Colombier 		}
2717dd7cddfSDavid du Colombier 		*p++ = (c>>6) + '0';
2727dd7cddfSDavid du Colombier 		*p++ = ((c>>3) & 7) + '0';
2737dd7cddfSDavid du Colombier 		*p++ = (c & 7) + '0';
2747dd7cddfSDavid du Colombier 	}
2757dd7cddfSDavid du Colombier 	*p = 0;
2769a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
2777dd7cddfSDavid du Colombier }
2787dd7cddfSDavid du Colombier 
2797dd7cddfSDavid du Colombier int
Nconv(Fmt * fp)2809a747e4fSDavid du Colombier Nconv(Fmt *fp)
2817dd7cddfSDavid du Colombier {
2827dd7cddfSDavid du Colombier 	char str[STRINGSZ];
2837dd7cddfSDavid du Colombier 	Adr *a;
2847dd7cddfSDavid du Colombier 	Sym *s;
2857dd7cddfSDavid du Colombier 
2869a747e4fSDavid du Colombier 	a = va_arg(fp->args, Adr*);
2877dd7cddfSDavid du Colombier 	s = a->sym;
2887dd7cddfSDavid du Colombier 	if(s == S) {
2890591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%ld", a->offset);
2907dd7cddfSDavid du Colombier 		goto out;
2917dd7cddfSDavid du Colombier 	}
2927dd7cddfSDavid du Colombier 	switch(a->name) {
2937dd7cddfSDavid du Colombier 	default:
2940591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "GOK-name(%d)", a->name);
2957dd7cddfSDavid du Colombier 		break;
2967dd7cddfSDavid du Colombier 
2977dd7cddfSDavid du Colombier 	case D_NONE:
2980591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%ld", a->offset);
2997dd7cddfSDavid du Colombier 		break;
3007dd7cddfSDavid du Colombier 
3017dd7cddfSDavid du Colombier 	case D_EXTERN:
3020591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%s+%ld(SB)", s->name, a->offset);
3037dd7cddfSDavid du Colombier 		break;
3047dd7cddfSDavid du Colombier 
3057dd7cddfSDavid du Colombier 	case D_STATIC:
3060591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%s<>+%ld(SB)", s->name, a->offset);
3077dd7cddfSDavid du Colombier 		break;
3087dd7cddfSDavid du Colombier 
3097dd7cddfSDavid du Colombier 	case D_AUTO:
3100591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%s-%ld(SP)", s->name, -a->offset);
3117dd7cddfSDavid du Colombier 		break;
3127dd7cddfSDavid du Colombier 
3137dd7cddfSDavid du Colombier 	case D_PARAM:
3140591a7c1SDavid du Colombier 		snprint(str, sizeof(str), "%s+%ld(FP)", s->name, a->offset);
3157dd7cddfSDavid du Colombier 		break;
3167dd7cddfSDavid du Colombier 	}
3177dd7cddfSDavid du Colombier out:
3189a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
3197dd7cddfSDavid du Colombier }
320