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