changelog shortlog tags branches changeset file revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/7l/list.c

revision 7144: d0b9ab522e8b
     1.1new file mode 100644
     1.2--- /dev/null
     1.3+++ b/sys/src/cmd/7l/list.c
     1.4@@ -0,0 +1,362 @@
     1.5+#include "l.h"
     1.6+
     1.7+void
     1.8+listinit(void)
     1.9+{
    1.10+
    1.11+	fmtinstall('A', Aconv);
    1.12+	fmtinstall('D', Dconv);
    1.13+	fmtinstall('P', Pconv);
    1.14+	fmtinstall('S', Sconv);
    1.15+	fmtinstall('N', Nconv);
    1.16+	fmtinstall('R', Rconv);
    1.17+}
    1.18+
    1.19+int
    1.20+Pconv(Fmt *fp)
    1.21+{
    1.22+	char str[STRINGSZ], *s;
    1.23+	Prog *p;
    1.24+	int a;
    1.25+
    1.26+	p = va_arg(fp->args, Prog*);
    1.27+	curp = p;
    1.28+	a = p->as;
    1.29+	switch(a) {
    1.30+	default:
    1.31+		s = str;
    1.32+		s += sprint(s, "(%ld)", p->line);
    1.33+		if(p->reg == NREG && p->from3.type == D_NONE)
    1.34+			sprint(s, "	%A	%D,%D",
    1.35+				a, &p->from, &p->to);
    1.36+		else if(p->from.type != D_FREG){
    1.37+			s += sprint(s, "	%A	%D", a, &p->from);
    1.38+			if(p->from3.type != D_NONE)
    1.39+				s += sprint(s, ",%D", &p->from3);
    1.40+			if(p->reg != NREG)
    1.41+				s += sprint(s, ",R%d", p->reg);
    1.42+			sprint(s, ",%D", &p->to);
    1.43+		}else
    1.44+			sprint(s, "	%A	%D,F%d,%D",
    1.45+				a, &p->from, p->reg, &p->to);
    1.46+		break;
    1.47+
    1.48+	case ADATA:
    1.49+	case AINIT:
    1.50+	case ADYNT:
    1.51+		sprint(str, "(%ld)	%A	%D/%d,%D",
    1.52+			p->line, a, &p->from, p->reg, &p->to);
    1.53+		break;
    1.54+	}
    1.55+	return fmtstrcpy(fp, str);
    1.56+}
    1.57+
    1.58+int
    1.59+Aconv(Fmt *fp)
    1.60+{
    1.61+	char *s;
    1.62+	int a;
    1.63+
    1.64+	a = va_arg(fp->args, int);
    1.65+	s = "???";
    1.66+	if(a >= AXXX && a < ALAST && anames[a])
    1.67+		s = anames[a];
    1.68+	return fmtstrcpy(fp, s);
    1.69+}
    1.70+
    1.71+char*	strcond[16] =
    1.72+{
    1.73+	"EQ",
    1.74+	"NE",
    1.75+	"HS",
    1.76+	"LO",
    1.77+	"MI",
    1.78+	"PL",
    1.79+	"VS",
    1.80+	"VC",
    1.81+	"HI",
    1.82+	"LS",
    1.83+	"GE",
    1.84+	"LT",
    1.85+	"GT",
    1.86+	"LE",
    1.87+	"AL",
    1.88+	"NV"
    1.89+};
    1.90+
    1.91+int
    1.92+Dconv(Fmt *fp)
    1.93+{
    1.94+	char str[STRINGSZ];
    1.95+	char *op;
    1.96+	Adr *a;
    1.97+	long v;
    1.98+	static char *extop[] = {".UB", ".UH", ".UW", ".UX", ".SB", ".SH", ".SW", ".SX"};
    1.99+
   1.100+	a = va_arg(fp->args, Adr*);
   1.101+	switch(a->type) {
   1.102+
   1.103+	default:
   1.104+		sprint(str, "GOK-type(%d)", a->type);
   1.105+		break;
   1.106+
   1.107+	case D_NONE:
   1.108+		str[0] = 0;
   1.109+		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
   1.110+			sprint(str, "%N(R%d)(NONE)", a, a->reg);
   1.111+		break;
   1.112+
   1.113+	case D_CONST:
   1.114+		if(a->reg == NREG || a->reg == REGZERO)
   1.115+			sprint(str, "$%N", a);
   1.116+		else
   1.117+			sprint(str, "$%N(R%d)", a, a->reg);
   1.118+		break;
   1.119+
   1.120+	case D_SHIFT:
   1.121+		v = a->offset;
   1.122+		op = "<<>>->@>" + (((v>>22) & 3) << 1);
   1.123+		sprint(str, "R%ld%c%c%ld", (v>>16)&0x1F, op[0], op[1], (v>>10)&0x3F);
   1.124+		if(a->reg != NREG)
   1.125+			sprint(str+strlen(str), "(R%d)", a->reg);
   1.126+		break;
   1.127+
   1.128+	case D_OCONST:
   1.129+		sprint(str, "$*$%N", a);
   1.130+		if(a->reg != NREG)
   1.131+			sprint(str, "%N(R%d)(CONST)", a, a->reg);
   1.132+		break;
   1.133+
   1.134+	case D_OREG:
   1.135+		if(a->reg != NREG)
   1.136+			sprint(str, "%N(R%d)", a, a->reg);
   1.137+		else
   1.138+			sprint(str, "%N", a);
   1.139+		break;
   1.140+
   1.141+	case D_XPRE:
   1.142+		if(a->reg != NREG)
   1.143+			sprint(str, "%N(R%d)!", a, a->reg);
   1.144+		else
   1.145+			sprint(str, "%N!", a);
   1.146+		break;
   1.147+
   1.148+	case D_XPOST:
   1.149+		if(a->reg != NREG)
   1.150+			sprint(str, "(R%d)%N!", a->reg, a);
   1.151+		else
   1.152+			sprint(str, "%N!", a);
   1.153+		break;
   1.154+
   1.155+	case D_EXTREG:
   1.156+		v = a->offset;
   1.157+		if(v & (7<<10))
   1.158+			snprint(str, sizeof(str), "R%ld%s<<%ld", (v>>16)&31, extop[(v>>13)&7], (v>>10)&7);
   1.159+		else
   1.160+			snprint(str, sizeof(str), "R%ld%s", (v>>16)&31, extop[(v>>13)&7]);
   1.161+		break;
   1.162+
   1.163+	case D_ROFF:
   1.164+		v = a->offset;
   1.165+		if(v & (1<<16))
   1.166+			snprint(str, sizeof(str), "(R%d)[R%ld%s]", a->reg, v&31, extop[(v>>8)&7]);
   1.167+		else
   1.168+			snprint(str, sizeof(str), "(R%d)(R%ld%s)", a->reg, v&31, extop[(v>>8)&7]);
   1.169+		break;
   1.170+
   1.171+	case D_REG:
   1.172+		sprint(str, "R%d", a->reg);
   1.173+		if(a->name != D_NONE || a->sym != S)
   1.174+			sprint(str, "%N(R%d)(REG)", a, a->reg);
   1.175+		break;
   1.176+
   1.177+	case D_SP:
   1.178+		if(a->name != D_NONE || a->sym != S)
   1.179+			sprint(str, "%N(R%d)(REG)", a, a->reg);
   1.180+		else
   1.181+			strcpy(str, "SP");
   1.182+		break;
   1.183+
   1.184+	case D_COND:
   1.185+		strcpy(str, strcond[a->reg & 0xF]);
   1.186+		break;
   1.187+
   1.188+	case D_FREG:
   1.189+		sprint(str, "F%d", a->reg);
   1.190+		if(a->name != D_NONE || a->sym != S)
   1.191+			sprint(str, "%N(R%d)(REG)", a, a->reg);
   1.192+		break;
   1.193+
   1.194+	case D_SPR:
   1.195+		switch((ulong)a->offset){
   1.196+		case D_FPSR:
   1.197+			sprint(str, "FPSR");
   1.198+			break;
   1.199+		case D_FPCR:
   1.200+			sprint(str, "FPCR");
   1.201+			break;
   1.202+		case D_NZCV:
   1.203+			sprint(str, "NZCV");
   1.204+			break;
   1.205+		default:
   1.206+			sprint(str, "SPR(%#llux)", a->offset);
   1.207+			break;
   1.208+		}
   1.209+		if(a->name != D_NONE || a->sym != S)
   1.210+			sprint(str, "%N(SPR%lld)(REG)", a, a->offset);
   1.211+		break;
   1.212+
   1.213+	case D_BRANCH:	/* botch */
   1.214+		if(curp->cond != P) {
   1.215+			v = curp->cond->pc;
   1.216+			if(a->sym != S)
   1.217+				sprint(str, "%s+%#.5lux(BRANCH)", a->sym->name, v);
   1.218+			else
   1.219+				sprint(str, "%.5lux(BRANCH)", v);
   1.220+		} else
   1.221+			if(a->sym != S)
   1.222+				sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
   1.223+			else
   1.224+				sprint(str, "%lld(APC)", a->offset);
   1.225+		break;
   1.226+
   1.227+	case D_FCONST:
   1.228+		sprint(str, "$%e", ieeedtod(a->ieee));
   1.229+		break;
   1.230+
   1.231+	case D_SCONST:
   1.232+		sprint(str, "$\"%S\"", a->sval);
   1.233+		break;
   1.234+	}
   1.235+	return fmtstrcpy(fp, str);
   1.236+}
   1.237+
   1.238+int
   1.239+Nconv(Fmt *fp)
   1.240+{
   1.241+	char str[STRINGSZ];
   1.242+	Adr *a;
   1.243+	Sym *s;
   1.244+
   1.245+	a = va_arg(fp->args, Adr*);
   1.246+	s = a->sym;
   1.247+	switch(a->name) {
   1.248+	default:
   1.249+		sprint(str, "GOK-name(%d)", a->name);
   1.250+		break;
   1.251+
   1.252+	case D_NONE:
   1.253+		sprint(str, "%lld", a->offset);
   1.254+		break;
   1.255+
   1.256+	case D_EXTERN:
   1.257+		if(s == S)
   1.258+			sprint(str, "%lld(SB)", a->offset);
   1.259+		else
   1.260+			sprint(str, "%s+%lld(SB)", s->name, a->offset);
   1.261+		break;
   1.262+
   1.263+	case D_STATIC:
   1.264+		if(s == S)
   1.265+			sprint(str, "<>+%lld(SB)", a->offset);
   1.266+		else
   1.267+			sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
   1.268+		break;
   1.269+
   1.270+	case D_AUTO:
   1.271+		if(s == S)
   1.272+			sprint(str, "%lld(SP)", a->offset);
   1.273+		else
   1.274+			sprint(str, "%s-%lld(SP)", s->name, -a->offset);
   1.275+		break;
   1.276+
   1.277+	case D_PARAM:
   1.278+		if(s == S)
   1.279+			sprint(str, "%lld(FP)", a->offset);
   1.280+		else
   1.281+			sprint(str, "%s+%lld(FP)", s->name, a->offset);
   1.282+		break;
   1.283+	}
   1.284+	return fmtstrcpy(fp, str);
   1.285+}
   1.286+
   1.287+int
   1.288+Rconv(Fmt *fp)
   1.289+{
   1.290+	char *s;
   1.291+	int a;
   1.292+
   1.293+	a = va_arg(fp->args, int);
   1.294+	s = "C_??";
   1.295+	if(a >= C_NONE && a <= C_NCLASS)
   1.296+		s = cnames[a];
   1.297+	return fmtstrcpy(fp, s);
   1.298+}
   1.299+
   1.300+void
   1.301+prasm(Prog *p)
   1.302+{
   1.303+	print("%P\n", p);
   1.304+}
   1.305+
   1.306+int
   1.307+Sconv(Fmt *fp)
   1.308+{
   1.309+	int i, c;
   1.310+	char str[STRINGSZ], *p, *a;
   1.311+
   1.312+	a = va_arg(fp->args, char*);
   1.313+	p = str;
   1.314+	for(i=0; i<sizeof(long); i++) {
   1.315+		c = a[i] & 0xff;
   1.316+		if(c >= 'a' && c <= 'z' ||
   1.317+		   c >= 'A' && c <= 'Z' ||
   1.318+		   c >= '0' && c <= '9' ||
   1.319+		   c == ' ' || c == '%') {
   1.320+			*p++ = c;
   1.321+			continue;
   1.322+		}
   1.323+		*p++ = '\\';
   1.324+		switch(c) {
   1.325+		case 0:
   1.326+			*p++ = 'z';
   1.327+			continue;
   1.328+		case '\\':
   1.329+		case '"':
   1.330+			*p++ = c;
   1.331+			continue;
   1.332+		case '\n':
   1.333+			*p++ = 'n';
   1.334+			continue;
   1.335+		case '\t':
   1.336+			*p++ = 't';
   1.337+			continue;
   1.338+		}
   1.339+		*p++ = (c>>6) + '0';
   1.340+		*p++ = ((c>>3) & 7) + '0';
   1.341+		*p++ = (c & 7) + '0';
   1.342+	}
   1.343+	*p = 0;
   1.344+	return fmtstrcpy(fp, str);
   1.345+}
   1.346+
   1.347+void
   1.348+diag(char *fmt, ...)
   1.349+{
   1.350+	char buf[STRINGSZ], *tn;
   1.351+	va_list arg;
   1.352+
   1.353+	tn = "??none??";
   1.354+	if(curtext != P && curtext->from.sym != S)
   1.355+		tn = curtext->from.sym->name;
   1.356+	va_start(arg, fmt);
   1.357+	vseprint(buf, buf+sizeof(buf), fmt, arg);
   1.358+	va_end(arg);
   1.359+	print("%s: %s\n", tn, buf);
   1.360+
   1.361+	nerrors++;
   1.362+	if(nerrors > 10) {
   1.363+		print("too many errors\n");
   1.364+		errorexit();
   1.365+	}
   1.366+}