xref: /plan9-contrib/sys/src/cmd/kl/list.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include "l.h"
2 
3 void
4 listinit(void)
5 {
6 
7 	fmtinstall('A', Aconv);
8 	fmtinstall('D', Dconv);
9 	fmtinstall('P', Pconv);
10 	fmtinstall('S', Sconv);
11 	fmtinstall('N', Nconv);
12 }
13 
14 void
15 prasm(Prog *p)
16 {
17 	print("%P\n", p);
18 }
19 
20 int
21 Pconv(void *o, Fconv *fp)
22 {
23 	char str[STRINGSZ], *s;
24 	Prog *p;
25 	int a;
26 
27 	p = *(Prog**)o;
28 	curp = p;
29 	a = p->as;
30 	if(a == ADATA || a == AINIT || a == ADYNT)
31 		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
32 	else{
33 		s = str;
34 		if(p->mark & NOSCHED)
35 			s += sprint(s, "*");
36 		if(p->reg == NREG)
37 			sprint(s, "	%A	%D,%D", a, &p->from, &p->to);
38 		else
39 		if(p->from.type == D_OREG) {
40 			sprint(s, "	%A	%ld(R%d+R%d),%D", a,
41 				p->from.offset, p->from.reg, p->reg, &p->to);
42 		} else
43 		if(p->to.type == D_OREG) {
44 			sprint(s, "	%A	%D,%ld(R%d+R%d)", a,
45 				&p->from, p->to.offset, p->to.reg, p->reg);
46 		} else
47 		if(p->from.type == D_FREG)
48 			sprint(s, "	%A	%D,F%d,%D", a, &p->from, p->reg, &p->to);
49 		else
50 			sprint(s, "	%A	%D,R%d,%D", a, &p->from, p->reg, &p->to);
51 	}
52 	strconv(str, fp);
53 	return sizeof(p);
54 }
55 
56 int
57 Aconv(void *o, Fconv *fp)
58 {
59 	char *s;
60 	int a;
61 
62 	a = *(int*)o;
63 	s = "???";
64 	if(a >= AXXX && a <= ALAST)
65 		s = anames[a];
66 	strconv(s, fp);
67 	return sizeof(a);
68 }
69 
70 int
71 Dconv(void *o, Fconv *fp)
72 {
73 	char str[STRINGSZ];
74 	Adr *a;
75 	long v;
76 
77 	a = *(Adr**)o;
78 	switch(a->type) {
79 
80 	default:
81 		sprint(str, "GOK-type(%d)", a->type);
82 		break;
83 
84 	case D_NONE:
85 		str[0] = 0;
86 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
87 			sprint(str, "%N(R%d)(NONE)", a, a->reg);
88 		break;
89 
90 	case D_CONST:
91 		if(a->reg != NREG)
92 			sprint(str, "$%N(R%d)", a, a->reg);
93 		else
94 			sprint(str, "$%N", a);
95 		break;
96 
97 	case D_ASI:
98 		if(a->reg != NREG)
99 			sprint(str, "(R%d,%ld)", a->reg, a->offset);
100 		else
101 			sprint(str, "(R%d,%ld)", 0, a->offset);
102 		break;
103 
104 	case D_OREG:
105 		if(a->reg != NREG)
106 			sprint(str, "%N(R%d)", a, a->reg);
107 		else
108 			sprint(str, "%N", a);
109 		break;
110 
111 	case D_REG:
112 		sprint(str, "R%d", a->reg);
113 		if(a->name != D_NONE || a->sym != S)
114 			sprint(str, "%N(R%d)(REG)", a, a->reg);
115 		break;
116 
117 	case D_FREG:
118 		sprint(str, "F%d", a->reg);
119 		if(a->name != D_NONE || a->sym != S)
120 			sprint(str, "%N(F%d)(REG)", a, a->reg);
121 		break;
122 
123 	case D_CREG:
124 		sprint(str, "C%d", a->reg);
125 		if(a->name != D_NONE || a->sym != S)
126 			sprint(str, "%N(C%d)(REG)", a, a->reg);
127 		break;
128 
129 	case D_PREG:
130 		sprint(str, "P%d", a->reg);
131 		if(a->name != D_NONE || a->sym != S)
132 			sprint(str, "%N(P%d)(REG)", a, a->reg);
133 		break;
134 
135 	case D_BRANCH:
136 		if(curp->cond != P) {
137 			v = curp->cond->pc;
138 			if(v >= INITTEXT)
139 				v -= INITTEXT-HEADR;
140 			if(a->sym != S)
141 				sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
142 			else
143 				sprint(str, "%.5lux(BRANCH)", v);
144 		} else
145 			if(a->sym != S)
146 				sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
147 			else
148 				sprint(str, "%ld(APC)", a->offset);
149 		break;
150 
151 	case D_FCONST:
152 		sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
153 		break;
154 
155 	case D_SCONST:
156 		sprint(str, "$\"%S\"", a->sval);
157 		break;
158 	}
159 	strconv(str, fp);
160 	return sizeof(a);
161 }
162 
163 int
164 Nconv(void *o, Fconv *fp)
165 {
166 	char str[STRINGSZ];
167 	Adr *a;
168 	Sym *s;
169 
170 	a = *(Adr**)o;
171 	s = a->sym;
172 	if(s == S) {
173 		sprint(str, "%ld", a->offset);
174 		goto out;
175 	}
176 	switch(a->name) {
177 	default:
178 		sprint(str, "GOK-name(%d)", a->name);
179 		break;
180 
181 	case D_EXTERN:
182 		sprint(str, "%s+%ld(SB)", s->name, a->offset);
183 		break;
184 
185 	case D_STATIC:
186 		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
187 		break;
188 
189 	case D_AUTO:
190 		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
191 		break;
192 
193 	case D_PARAM:
194 		sprint(str, "%s+%ld(FP)", s->name, a->offset);
195 		break;
196 	}
197 out:
198 	strconv(str, fp);
199 	return sizeof(a);
200 }
201 
202 int
203 Sconv(void *o, Fconv *fp)
204 {
205 	int i, c;
206 	char str[STRINGSZ], *p, *a;
207 
208 	a = *(char**)o;
209 	p = str;
210 	for(i=0; i<sizeof(long); i++) {
211 		c = a[i] & 0xff;
212 		if(c >= 'a' && c <= 'z' ||
213 		   c >= 'A' && c <= 'Z' ||
214 		   c >= '0' && c <= '9' ||
215 		   c == ' ' || c == '%') {
216 			*p++ = c;
217 			continue;
218 		}
219 		*p++ = '\\';
220 		switch(c) {
221 		case 0:
222 			*p++ = 'z';
223 			continue;
224 		case '\\':
225 		case '"':
226 			*p++ = c;
227 			continue;
228 		case '\n':
229 			*p++ = 'n';
230 			continue;
231 		case '\t':
232 			*p++ = 't';
233 			continue;
234 		}
235 		*p++ = (c>>6) + '0';
236 		*p++ = ((c>>3) & 7) + '0';
237 		*p++ = (c & 7) + '0';
238 	}
239 	*p = 0;
240 	strconv(str, fp);
241 	return sizeof(a);
242 }
243 
244 void
245 diag(char *a, ...)
246 {
247 	char buf[STRINGSZ], *tn;
248 
249 	tn = "??none??";
250 	if(curtext != P && curtext->from.sym != S)
251 		tn = curtext->from.sym->name;
252 	doprint(buf, buf+sizeof(buf), a, &(&a)[1]);	/* ugly */
253 	print("%s: %s\n", tn, buf);
254 
255 	nerrors++;
256 	if(nerrors > 10) {
257 		print("too many errors\n");
258 		errorexit();
259 	}
260 }
261