xref: /inferno-os/utils/5c/list.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 #define	EXTERN
2 #include "gc.h"
3 
4 void
5 listinit(void)
6 {
7 
8 	fmtinstall('A', Aconv);
9 	fmtinstall('P', Pconv);
10 	fmtinstall('S', Sconv);
11 	fmtinstall('N', Nconv);
12 	fmtinstall('B', Bconv);
13 	fmtinstall('D', Dconv);
14 	fmtinstall('R', Rconv);
15 }
16 
17 int
18 Bconv(Fmt *fp)
19 {
20 	char str[STRINGSZ], ss[STRINGSZ], *s;
21 	Bits bits;
22 	int i;
23 
24 	str[0] = 0;
25 	bits = va_arg(fp->args, Bits);
26 	while(bany(&bits)) {
27 		i = bnum(bits);
28 		if(str[0])
29 			strcat(str, " ");
30 		if(var[i].sym == S) {
31 			sprint(ss, "$%ld", var[i].offset);
32 			s = ss;
33 		} else
34 			s = var[i].sym->name;
35 		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
36 			break;
37 		strcat(str, s);
38 		bits.b[i/32] &= ~(1L << (i%32));
39 	}
40 	return fmtstrcpy(fp, str);
41 }
42 
43 char *extra [] = {
44 	".EQ", ".NE", ".CS", ".CC",
45 	".MI", ".PL", ".VS", ".VC",
46 	".HI", ".LS", ".GE", ".LT",
47 	".GT", ".LE", "", ".NV",
48 };
49 
50 int
51 Pconv(Fmt *fp)
52 {
53 	char str[STRINGSZ], sc[20];
54 	Prog *p;
55 	int a, s;
56 
57 	p = va_arg(fp->args, Prog*);
58 	a = p->as;
59 	s = p->scond;
60 	strcpy(sc, extra[s & C_SCOND]);
61 	if(s & C_SBIT)
62 		strcat(sc, ".S");
63 	if(s & C_PBIT)
64 		strcat(sc, ".P");
65 	if(s & C_WBIT)
66 		strcat(sc, ".W");
67 	if(s & C_UBIT)		/* ambiguous with FBIT */
68 		strcat(sc, ".U");
69 	if(a == AMOVM) {
70 		if(p->from.type == D_CONST)
71 			sprint(str, "	%A%s	%R,%D", a, sc, &p->from, &p->to);
72 		else
73 		if(p->to.type == D_CONST)
74 			sprint(str, "	%A%s	%D,%R", a, sc, &p->from, &p->to);
75 		else
76 			sprint(str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
77 	} else
78 	if(a == ADATA)
79 		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
80 	else
81 	if(p->as == ATEXT)
82 		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
83 	else
84 	if(p->reg == NREG)
85 		sprint(str, "	%A%s	%D,%D", a, sc, &p->from, &p->to);
86 	else
87 	if(p->from.type != D_FREG)
88 		sprint(str, "	%A%s	%D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
89 	else
90 		sprint(str, "	%A%s	%D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
91 	return fmtstrcpy(fp, str);
92 }
93 
94 int
95 Aconv(Fmt *fp)
96 {
97 	char *s;
98 	int a;
99 
100 	a = va_arg(fp->args, int);
101 	s = "?";
102 	if(a >= AXXX && a < ALAST)
103 		s = anames[a];
104 	return fmtstrcpy(fp, s);
105 }
106 
107 int
108 Dconv(Fmt *fp)
109 {
110 	char str[STRINGSZ];
111 	Adr *a;
112 	char *op;
113 	int v;
114 
115 	a = va_arg(fp->args, Adr*);
116 	switch(a->type) {
117 
118 	default:
119 		sprint(str, "GOK-type(%d)", a->type);
120 		break;
121 
122 	case D_NONE:
123 		str[0] = 0;
124 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
125 			sprint(str, "%N(R%d)(NONE)", a, a->reg);
126 		break;
127 
128 	case D_CONST:
129 		if(a->reg != NREG)
130 			sprint(str, "$%N(R%d)", a, a->reg);
131 		else
132 			sprint(str, "$%N", a);
133 		break;
134 
135 	case D_SHIFT:
136 		v = a->offset;
137 		op = "<<>>->@>" + (((v>>5) & 3) << 1);
138 		if(v & (1<<4))
139 			sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
140 		else
141 			sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
142 		if(a->reg != NREG)
143 			sprint(str+strlen(str), "(R%d)", a->reg);
144 		break;
145 
146 	case D_OREG:
147 		if(a->reg != NREG)
148 			sprint(str, "%N(R%d)", a, a->reg);
149 		else
150 			sprint(str, "%N", a);
151 		break;
152 
153 	case D_REG:
154 		sprint(str, "R%d", a->reg);
155 		if(a->name != D_NONE || a->sym != S)
156 			sprint(str, "%N(R%d)(REG)", a, a->reg);
157 		break;
158 
159 	case D_FREG:
160 		sprint(str, "F%d", a->reg);
161 		if(a->name != D_NONE || a->sym != S)
162 			sprint(str, "%N(R%d)(REG)", a, a->reg);
163 		break;
164 
165 	case D_PSR:
166 		sprint(str, "PSR");
167 		if(a->name != D_NONE || a->sym != S)
168 			sprint(str, "%N(PSR)(REG)", a);
169 		break;
170 
171 	case D_BRANCH:
172 		sprint(str, "%ld(PC)", a->offset-pc);
173 		break;
174 
175 	case D_FCONST:
176 		sprint(str, "$%.17e", a->dval);
177 		break;
178 
179 	case D_SCONST:
180 		sprint(str, "$\"%S\"", a->sval);
181 		break;
182 	}
183 	return fmtstrcpy(fp, str);
184 }
185 
186 int
187 Rconv(Fmt *fp)
188 {
189 	char str[STRINGSZ];
190 	Adr *a;
191 	int i, v;
192 
193 	a = va_arg(fp->args, Adr*);
194 	sprint(str, "GOK-reglist");
195 	switch(a->type) {
196 	case D_CONST:
197 		if(a->reg != NREG)
198 			break;
199 		if(a->sym != S)
200 			break;
201 		v = a->offset;
202 		strcpy(str, "");
203 		for(i=0; i<NREG; i++) {
204 			if(v & (1<<i)) {
205 				if(str[0] == 0)
206 					strcat(str, "[R");
207 				else
208 					strcat(str, ",R");
209 				sprint(strchr(str, 0), "%d", i);
210 			}
211 		}
212 		strcat(str, "]");
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<NSNAME; 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 		case '\r':
250 			*p++ = 'r';
251 			continue;
252 		case '\f':
253 			*p++ = 'f';
254 			continue;
255 		}
256 		*p++ = (c>>6) + '0';
257 		*p++ = ((c>>3) & 7) + '0';
258 		*p++ = (c & 7) + '0';
259 	}
260 	*p = 0;
261 	return fmtstrcpy(fp, str);
262 }
263 
264 int
265 Nconv(Fmt *fp)
266 {
267 	char str[STRINGSZ];
268 	Adr *a;
269 	Sym *s;
270 
271 	a = va_arg(fp->args, Adr*);
272 	s = a->sym;
273 	if(s == S) {
274 		sprint(str, "%ld", a->offset);
275 		goto out;
276 	}
277 	switch(a->name) {
278 	default:
279 		sprint(str, "GOK-name(%d)", a->name);
280 		break;
281 
282 	case D_NONE:
283 		sprint(str, "%ld", a->offset);
284 		break;
285 
286 	case D_EXTERN:
287 		sprint(str, "%s+%ld(SB)", s->name, a->offset);
288 		break;
289 
290 	case D_STATIC:
291 		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
292 		break;
293 
294 	case D_AUTO:
295 		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
296 		break;
297 
298 	case D_PARAM:
299 		sprint(str, "%s+%ld(FP)", s->name, a->offset);
300 		break;
301 	}
302 out:
303 	return fmtstrcpy(fp, str);
304 }
305