xref: /plan9/sys/src/cmd/5l/list.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
17dd7cddfSDavid du Colombier #include "l.h"
27dd7cddfSDavid du Colombier 
37dd7cddfSDavid du Colombier void
listinit(void)47dd7cddfSDavid du Colombier listinit(void)
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier 	fmtinstall('A', Aconv);
87dd7cddfSDavid du Colombier 	fmtinstall('C', Cconv);
97dd7cddfSDavid du Colombier 	fmtinstall('D', Dconv);
107dd7cddfSDavid du Colombier 	fmtinstall('P', Pconv);
117dd7cddfSDavid du Colombier 	fmtinstall('S', Sconv);
127dd7cddfSDavid du Colombier 	fmtinstall('N', Nconv);
137dd7cddfSDavid du Colombier }
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier void
prasm(Prog * p)167dd7cddfSDavid du Colombier prasm(Prog *p)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier 	print("%P\n", p);
197dd7cddfSDavid du Colombier }
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier int
Pconv(Fmt * fp)22*9a747e4fSDavid du Colombier Pconv(Fmt *fp)
237dd7cddfSDavid du Colombier {
247dd7cddfSDavid du Colombier 	char str[STRINGSZ], *s;
257dd7cddfSDavid du Colombier 	Prog *p;
267dd7cddfSDavid du Colombier 	int a;
277dd7cddfSDavid du Colombier 
28*9a747e4fSDavid du Colombier 	p = va_arg(fp->args, Prog*);
297dd7cddfSDavid du Colombier 	curp = p;
307dd7cddfSDavid du Colombier 	a = p->as;
317dd7cddfSDavid du Colombier 	switch(a) {
327dd7cddfSDavid du Colombier 	default:
337dd7cddfSDavid du Colombier 		s = str;
347dd7cddfSDavid du Colombier 		s += sprint(s, "(%ld)", p->line);
357dd7cddfSDavid du Colombier 		if(p->reg == NREG)
367dd7cddfSDavid du Colombier 			sprint(s, "	%A%C	%D,%D",
377dd7cddfSDavid du Colombier 				a, p->scond, &p->from, &p->to);
387dd7cddfSDavid du Colombier 		else
397dd7cddfSDavid du Colombier 		if(p->from.type != D_FREG)
407dd7cddfSDavid du Colombier 			sprint(s, "	%A%C	%D,R%d,%D",
417dd7cddfSDavid du Colombier 				a, p->scond, &p->from, p->reg, &p->to);
427dd7cddfSDavid du Colombier 		else
437dd7cddfSDavid du Colombier 			sprint(s, "	%A%C	%D,F%d,%D",
447dd7cddfSDavid du Colombier 				a, p->scond, &p->from, p->reg, &p->to);
457dd7cddfSDavid du Colombier 		break;
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier 	case ASWPW:
487dd7cddfSDavid du Colombier 	case ASWPBU:
497dd7cddfSDavid du Colombier 		sprint(str, "(%ld)	%A%C	R%d,%D,%D",
507dd7cddfSDavid du Colombier 			p->line, a, p->scond, p->reg, &p->from, &p->to);
517dd7cddfSDavid du Colombier 		break;
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier 	case ADATA:
547dd7cddfSDavid du Colombier 	case AINIT:
557dd7cddfSDavid du Colombier 	case ADYNT:
567dd7cddfSDavid du Colombier 		sprint(str, "(%ld)	%A%C	%D/%d,%D",
577dd7cddfSDavid du Colombier 			p->line, a, p->scond, &p->from, p->reg, &p->to);
587dd7cddfSDavid du Colombier 		break;
597dd7cddfSDavid du Colombier 	}
60*9a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
617dd7cddfSDavid du Colombier }
627dd7cddfSDavid du Colombier 
637dd7cddfSDavid du Colombier int
Aconv(Fmt * fp)64*9a747e4fSDavid du Colombier Aconv(Fmt *fp)
657dd7cddfSDavid du Colombier {
667dd7cddfSDavid du Colombier 	char *s;
677dd7cddfSDavid du Colombier 	int a;
687dd7cddfSDavid du Colombier 
69*9a747e4fSDavid du Colombier 	a = va_arg(fp->args, int);
707dd7cddfSDavid du Colombier 	s = "???";
717dd7cddfSDavid du Colombier 	if(a >= AXXX && a < ALAST)
727dd7cddfSDavid du Colombier 		s = anames[a];
73*9a747e4fSDavid du Colombier 	return fmtstrcpy(fp, s);
747dd7cddfSDavid du Colombier }
757dd7cddfSDavid du Colombier 
767dd7cddfSDavid du Colombier char*	strcond[16] =
777dd7cddfSDavid du Colombier {
787dd7cddfSDavid du Colombier 	".EQ",
797dd7cddfSDavid du Colombier 	".NE",
807dd7cddfSDavid du Colombier 	".HS",
817dd7cddfSDavid du Colombier 	".LO",
827dd7cddfSDavid du Colombier 	".MI",
837dd7cddfSDavid du Colombier 	".PL",
847dd7cddfSDavid du Colombier 	".VS",
857dd7cddfSDavid du Colombier 	".VC",
867dd7cddfSDavid du Colombier 	".HI",
877dd7cddfSDavid du Colombier 	".LS",
887dd7cddfSDavid du Colombier 	".GE",
897dd7cddfSDavid du Colombier 	".LT",
907dd7cddfSDavid du Colombier 	".GT",
917dd7cddfSDavid du Colombier 	".LE",
927dd7cddfSDavid du Colombier 	"",
937dd7cddfSDavid du Colombier 	".NV"
947dd7cddfSDavid du Colombier };
957dd7cddfSDavid du Colombier 
967dd7cddfSDavid du Colombier int
Cconv(Fmt * fp)97*9a747e4fSDavid du Colombier Cconv(Fmt *fp)
987dd7cddfSDavid du Colombier {
997dd7cddfSDavid du Colombier 	char s[20];
1007dd7cddfSDavid du Colombier 	int c;
1017dd7cddfSDavid du Colombier 
102*9a747e4fSDavid du Colombier 	c = va_arg(fp->args, int);
1037dd7cddfSDavid du Colombier 	strcpy(s, strcond[c & C_SCOND]);
1047dd7cddfSDavid du Colombier 	if(c & C_SBIT)
1057dd7cddfSDavid du Colombier 		strcat(s, ".S");
1067dd7cddfSDavid du Colombier 	if(c & C_PBIT)
1077dd7cddfSDavid du Colombier 		strcat(s, ".P");
1087dd7cddfSDavid du Colombier 	if(c & C_WBIT)
1097dd7cddfSDavid du Colombier 		strcat(s, ".W");
1107dd7cddfSDavid du Colombier 	if(c & C_UBIT)		/* ambiguous with FBIT */
1117dd7cddfSDavid du Colombier 		strcat(s, ".U");
112*9a747e4fSDavid du Colombier 	return fmtstrcpy(fp, s);
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier 
1157dd7cddfSDavid du Colombier int
Dconv(Fmt * fp)116*9a747e4fSDavid du Colombier Dconv(Fmt *fp)
1177dd7cddfSDavid du Colombier {
1187dd7cddfSDavid du Colombier 	char str[STRINGSZ];
1197dd7cddfSDavid du Colombier 	char *op;
1207dd7cddfSDavid du Colombier 	Adr *a;
1217dd7cddfSDavid du Colombier 	long v;
1227dd7cddfSDavid du Colombier 
123*9a747e4fSDavid du Colombier 	a = va_arg(fp->args, Adr*);
1247dd7cddfSDavid du Colombier 	switch(a->type) {
1257dd7cddfSDavid du Colombier 
1267dd7cddfSDavid du Colombier 	default:
1277dd7cddfSDavid du Colombier 		sprint(str, "GOK-type(%d)", a->type);
1287dd7cddfSDavid du Colombier 		break;
1297dd7cddfSDavid du Colombier 
1307dd7cddfSDavid du Colombier 	case D_NONE:
1317dd7cddfSDavid du Colombier 		str[0] = 0;
1327dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
1337dd7cddfSDavid du Colombier 			sprint(str, "%N(R%d)(NONE)", a, a->reg);
1347dd7cddfSDavid du Colombier 		break;
1357dd7cddfSDavid du Colombier 
1367dd7cddfSDavid du Colombier 	case D_CONST:
1377dd7cddfSDavid du Colombier 		if(a->reg == NREG)
1387dd7cddfSDavid du Colombier 			sprint(str, "$%N", a);
1397dd7cddfSDavid du Colombier 		else
1407dd7cddfSDavid du Colombier 			sprint(str, "$%N(R%d)", a, a->reg);
1417dd7cddfSDavid du Colombier 		break;
1427dd7cddfSDavid du Colombier 
1437dd7cddfSDavid du Colombier 	case D_SHIFT:
1447dd7cddfSDavid du Colombier 		v = a->offset;
1457dd7cddfSDavid du Colombier 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
1467dd7cddfSDavid du Colombier 		if(v & (1<<4))
1477dd7cddfSDavid du Colombier 			sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15);
1487dd7cddfSDavid du Colombier 		else
1497dd7cddfSDavid du Colombier 			sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31);
15059cc4ca5SDavid du Colombier 		if(a->reg != NREG)
15159cc4ca5SDavid du Colombier 			sprint(str+strlen(str), "(R%d)", a->reg);
1527dd7cddfSDavid du Colombier 		break;
1537dd7cddfSDavid du Colombier 
1547dd7cddfSDavid du Colombier 	case D_OCONST:
1557dd7cddfSDavid du Colombier 		sprint(str, "$*$%N", a);
1567dd7cddfSDavid du Colombier 		if(a->reg != NREG)
1577dd7cddfSDavid du Colombier 			sprint(str, "%N(R%d)(CONST)", a, a->reg);
1587dd7cddfSDavid du Colombier 		break;
1597dd7cddfSDavid du Colombier 
1607dd7cddfSDavid du Colombier 	case D_OREG:
1617dd7cddfSDavid du Colombier 		if(a->reg != NREG)
1627dd7cddfSDavid du Colombier 			sprint(str, "%N(R%d)", a, a->reg);
1637dd7cddfSDavid du Colombier 		else
1647dd7cddfSDavid du Colombier 			sprint(str, "%N", a);
1657dd7cddfSDavid du Colombier 		break;
1667dd7cddfSDavid du Colombier 
1677dd7cddfSDavid du Colombier 	case D_REG:
1687dd7cddfSDavid du Colombier 		sprint(str, "R%d", a->reg);
1697dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
1707dd7cddfSDavid du Colombier 			sprint(str, "%N(R%d)(REG)", a, a->reg);
1717dd7cddfSDavid du Colombier 		break;
1727dd7cddfSDavid du Colombier 
17359cc4ca5SDavid du Colombier 	case D_REGREG:
17459cc4ca5SDavid du Colombier 		sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
17559cc4ca5SDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
17659cc4ca5SDavid du Colombier 			sprint(str, "%N(R%d)(REG)", a, a->reg);
17759cc4ca5SDavid du Colombier 		break;
17859cc4ca5SDavid du Colombier 
1797dd7cddfSDavid du Colombier 	case D_FREG:
1807dd7cddfSDavid du Colombier 		sprint(str, "F%d", a->reg);
1817dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
1827dd7cddfSDavid du Colombier 			sprint(str, "%N(R%d)(REG)", a, a->reg);
1837dd7cddfSDavid du Colombier 		break;
1847dd7cddfSDavid du Colombier 
1857dd7cddfSDavid du Colombier 	case D_PSR:
1867dd7cddfSDavid du Colombier 		switch(a->reg) {
1877dd7cddfSDavid du Colombier 		case 0:
1887dd7cddfSDavid du Colombier 			sprint(str, "CPSR");
1897dd7cddfSDavid du Colombier 			break;
1907dd7cddfSDavid du Colombier 		case 1:
1917dd7cddfSDavid du Colombier 			sprint(str, "SPSR");
1927dd7cddfSDavid du Colombier 			break;
1937dd7cddfSDavid du Colombier 		default:
1947dd7cddfSDavid du Colombier 			sprint(str, "PSR%d", a->reg);
1957dd7cddfSDavid du Colombier 			break;
1967dd7cddfSDavid du Colombier 		}
1977dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
1987dd7cddfSDavid du Colombier 			sprint(str, "%N(PSR%d)(REG)", a, a->reg);
1997dd7cddfSDavid du Colombier 		break;
2007dd7cddfSDavid du Colombier 
2017dd7cddfSDavid du Colombier 	case D_FPCR:
2027dd7cddfSDavid du Colombier 		switch(a->reg){
2037dd7cddfSDavid du Colombier 		case 0:
2047dd7cddfSDavid du Colombier 			sprint(str, "FPSR");
2057dd7cddfSDavid du Colombier 			break;
2067dd7cddfSDavid du Colombier 		case 1:
2077dd7cddfSDavid du Colombier 			sprint(str, "FPCR");
2087dd7cddfSDavid du Colombier 			break;
2097dd7cddfSDavid du Colombier 		default:
2107dd7cddfSDavid du Colombier 			sprint(str, "FCR%d", a->reg);
2117dd7cddfSDavid du Colombier 			break;
2127dd7cddfSDavid du Colombier 		}
2137dd7cddfSDavid du Colombier 		if(a->name != D_NONE || a->sym != S)
2147dd7cddfSDavid du Colombier 			sprint(str, "%N(FCR%d)(REG)", a, a->reg);
2157dd7cddfSDavid du Colombier 
2167dd7cddfSDavid du Colombier 		break;
2177dd7cddfSDavid du Colombier 
2187dd7cddfSDavid du Colombier 	case D_BRANCH:	/* botch */
2197dd7cddfSDavid du Colombier 		if(curp->cond != P) {
2207dd7cddfSDavid du Colombier 			v = curp->cond->pc;
2217dd7cddfSDavid du Colombier 			if(a->sym != S)
2227dd7cddfSDavid du Colombier 				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
2237dd7cddfSDavid du Colombier 			else
2247dd7cddfSDavid du Colombier 				sprint(str, "%.5lux(BRANCH)", v);
2257dd7cddfSDavid du Colombier 		} else
2267dd7cddfSDavid du Colombier 			if(a->sym != S)
2277dd7cddfSDavid du Colombier 				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
2287dd7cddfSDavid du Colombier 			else
2297dd7cddfSDavid du Colombier 				sprint(str, "%ld(APC)", a->offset);
2307dd7cddfSDavid du Colombier 		break;
2317dd7cddfSDavid du Colombier 
2327dd7cddfSDavid du Colombier 	case D_FCONST:
2337dd7cddfSDavid du Colombier 		sprint(str, "$%e", ieeedtod(a->ieee));
2347dd7cddfSDavid du Colombier 		break;
2357dd7cddfSDavid du Colombier 
2367dd7cddfSDavid du Colombier 	case D_SCONST:
2377dd7cddfSDavid du Colombier 		sprint(str, "$\"%S\"", a->sval);
2387dd7cddfSDavid du Colombier 		break;
2397dd7cddfSDavid du Colombier 	}
240*9a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier 
2437dd7cddfSDavid du Colombier int
Nconv(Fmt * fp)244*9a747e4fSDavid du Colombier Nconv(Fmt *fp)
2457dd7cddfSDavid du Colombier {
2467dd7cddfSDavid du Colombier 	char str[STRINGSZ];
2477dd7cddfSDavid du Colombier 	Adr *a;
2487dd7cddfSDavid du Colombier 	Sym *s;
2497dd7cddfSDavid du Colombier 
250*9a747e4fSDavid du Colombier 	a = va_arg(fp->args, Adr*);
2517dd7cddfSDavid du Colombier 	s = a->sym;
2527dd7cddfSDavid du Colombier 	switch(a->name) {
2537dd7cddfSDavid du Colombier 	default:
2547dd7cddfSDavid du Colombier 		sprint(str, "GOK-name(%d)", a->name);
2557dd7cddfSDavid du Colombier 		break;
2567dd7cddfSDavid du Colombier 
2577dd7cddfSDavid du Colombier 	case D_NONE:
2587dd7cddfSDavid du Colombier 		sprint(str, "%ld", a->offset);
2597dd7cddfSDavid du Colombier 		break;
2607dd7cddfSDavid du Colombier 
2617dd7cddfSDavid du Colombier 	case D_EXTERN:
2627dd7cddfSDavid du Colombier 		if(s == S)
2637dd7cddfSDavid du Colombier 			sprint(str, "%ld(SB)", a->offset);
2647dd7cddfSDavid du Colombier 		else
2657dd7cddfSDavid du Colombier 			sprint(str, "%s+%ld(SB)", s->name, a->offset);
2667dd7cddfSDavid du Colombier 		break;
2677dd7cddfSDavid du Colombier 
2687dd7cddfSDavid du Colombier 	case D_STATIC:
2697dd7cddfSDavid du Colombier 		if(s == S)
2707dd7cddfSDavid du Colombier 			sprint(str, "<>+%ld(SB)", a->offset);
2717dd7cddfSDavid du Colombier 		else
2727dd7cddfSDavid du Colombier 			sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
2737dd7cddfSDavid du Colombier 		break;
2747dd7cddfSDavid du Colombier 
2757dd7cddfSDavid du Colombier 	case D_AUTO:
2767dd7cddfSDavid du Colombier 		if(s == S)
2777dd7cddfSDavid du Colombier 			sprint(str, "%ld(SP)", a->offset);
2787dd7cddfSDavid du Colombier 		else
2797dd7cddfSDavid du Colombier 			sprint(str, "%s-%ld(SP)", s->name, -a->offset);
2807dd7cddfSDavid du Colombier 		break;
2817dd7cddfSDavid du Colombier 
2827dd7cddfSDavid du Colombier 	case D_PARAM:
2837dd7cddfSDavid du Colombier 		if(s == S)
2847dd7cddfSDavid du Colombier 			sprint(str, "%ld(FP)", a->offset);
2857dd7cddfSDavid du Colombier 		else
2867dd7cddfSDavid du Colombier 			sprint(str, "%s+%ld(FP)", s->name, a->offset);
2877dd7cddfSDavid du Colombier 		break;
2887dd7cddfSDavid du Colombier 	}
289*9a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
2907dd7cddfSDavid du Colombier }
2917dd7cddfSDavid du Colombier 
2927dd7cddfSDavid du Colombier int
Sconv(Fmt * fp)293*9a747e4fSDavid du Colombier Sconv(Fmt *fp)
2947dd7cddfSDavid du Colombier {
2957dd7cddfSDavid du Colombier 	int i, c;
2967dd7cddfSDavid du Colombier 	char str[STRINGSZ], *p, *a;
2977dd7cddfSDavid du Colombier 
298*9a747e4fSDavid du Colombier 	a = va_arg(fp->args, char*);
2997dd7cddfSDavid du Colombier 	p = str;
3007dd7cddfSDavid du Colombier 	for(i=0; i<sizeof(long); i++) {
3017dd7cddfSDavid du Colombier 		c = a[i] & 0xff;
3027dd7cddfSDavid du Colombier 		if(c >= 'a' && c <= 'z' ||
3037dd7cddfSDavid du Colombier 		   c >= 'A' && c <= 'Z' ||
3047dd7cddfSDavid du Colombier 		   c >= '0' && c <= '9' ||
3057dd7cddfSDavid du Colombier 		   c == ' ' || c == '%') {
3067dd7cddfSDavid du Colombier 			*p++ = c;
3077dd7cddfSDavid du Colombier 			continue;
3087dd7cddfSDavid du Colombier 		}
3097dd7cddfSDavid du Colombier 		*p++ = '\\';
3107dd7cddfSDavid du Colombier 		switch(c) {
3117dd7cddfSDavid du Colombier 		case 0:
3127dd7cddfSDavid du Colombier 			*p++ = 'z';
3137dd7cddfSDavid du Colombier 			continue;
3147dd7cddfSDavid du Colombier 		case '\\':
3157dd7cddfSDavid du Colombier 		case '"':
3167dd7cddfSDavid du Colombier 			*p++ = c;
3177dd7cddfSDavid du Colombier 			continue;
3187dd7cddfSDavid du Colombier 		case '\n':
3197dd7cddfSDavid du Colombier 			*p++ = 'n';
3207dd7cddfSDavid du Colombier 			continue;
3217dd7cddfSDavid du Colombier 		case '\t':
3227dd7cddfSDavid du Colombier 			*p++ = 't';
3237dd7cddfSDavid du Colombier 			continue;
3247dd7cddfSDavid du Colombier 		}
3257dd7cddfSDavid du Colombier 		*p++ = (c>>6) + '0';
3267dd7cddfSDavid du Colombier 		*p++ = ((c>>3) & 7) + '0';
3277dd7cddfSDavid du Colombier 		*p++ = (c & 7) + '0';
3287dd7cddfSDavid du Colombier 	}
3297dd7cddfSDavid du Colombier 	*p = 0;
330*9a747e4fSDavid du Colombier 	return fmtstrcpy(fp, str);
3317dd7cddfSDavid du Colombier }
3327dd7cddfSDavid du Colombier 
3337dd7cddfSDavid du Colombier void
diag(char * fmt,...)3347dd7cddfSDavid du Colombier diag(char *fmt, ...)
3357dd7cddfSDavid du Colombier {
3367dd7cddfSDavid du Colombier 	char buf[STRINGSZ], *tn;
3377dd7cddfSDavid du Colombier 	va_list arg;
3387dd7cddfSDavid du Colombier 
3397dd7cddfSDavid du Colombier 	tn = "??none??";
3407dd7cddfSDavid du Colombier 	if(curtext != P && curtext->from.sym != S)
3417dd7cddfSDavid du Colombier 		tn = curtext->from.sym->name;
3427dd7cddfSDavid du Colombier 	va_start(arg, fmt);
343*9a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
3447dd7cddfSDavid du Colombier 	va_end(arg);
3457dd7cddfSDavid du Colombier 	print("%s: %s\n", tn, buf);
3467dd7cddfSDavid du Colombier 
3477dd7cddfSDavid du Colombier 	nerrors++;
3487dd7cddfSDavid du Colombier 	if(nerrors > 10) {
3497dd7cddfSDavid du Colombier 		print("too many errors\n");
3507dd7cddfSDavid du Colombier 		errorexit();
3517dd7cddfSDavid du Colombier 	}
3527dd7cddfSDavid du Colombier }
353