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