xref: /inferno-os/utils/8c/list.c (revision 06155dbb53eb0585800b239acd6e45b946c6e0cf)
1 #define EXTERN
2 #include "gc.h"
3 
4 void
5 listinit(void)
6 {
7 
8 	fmtinstall('A', Aconv);
9 	fmtinstall('B', Bconv);
10 	fmtinstall('P', Pconv);
11 	fmtinstall('S', Sconv);
12 	fmtinstall('D', Dconv);
13 	fmtinstall('R', Rconv);
14 }
15 
16 int
17 Bconv(Fmt *fp)
18 {
19 	char str[STRINGSZ], ss[STRINGSZ], *s;
20 	Bits bits;
21 	int i;
22 
23 	str[0] = 0;
24 	bits = va_arg(fp->args, Bits);
25 	while(bany(&bits)) {
26 		i = bnum(bits);
27 		if(str[0])
28 			strcat(str, " ");
29 		if(var[i].sym == S) {
30 			snprint(ss, sizeof(ss), "$%ld", var[i].offset);
31 			s = ss;
32 		} else
33 			s = var[i].sym->name;
34 		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
35 			break;
36 		strcat(str, s);
37 		bits.b[i/32] &= ~(1L << (i%32));
38 	}
39 	return fmtstrcpy(fp, str);
40 }
41 
42 int
43 Pconv(Fmt *fp)
44 {
45 	char str[STRINGSZ];
46 	Prog *p;
47 
48 	p = va_arg(fp->args, Prog*);
49 	if(p->as == ADATA)
50 		snprint(str, sizeof(str), "	%A	%D/%d,%D",
51 			p->as, &p->from, p->from.scale, &p->to);
52 	else if(p->as == ATEXT)
53 		snprint(str, sizeof(str), "	%A	%D,%d,%D",
54 			p->as, &p->from, p->from.scale, &p->to);
55 	else
56 		snprint(str, sizeof(str), "	%A	%D,%D",
57 			p->as, &p->from, &p->to);
58 	return fmtstrcpy(fp, str);
59 }
60 
61 int
62 Aconv(Fmt *fp)
63 {
64 	int i;
65 
66 	i = va_arg(fp->args, int);
67 	return fmtstrcpy(fp, anames[i]);
68 }
69 
70 int
71 Dconv(Fmt *fp)
72 {
73 	char str[40], s[20];
74 	Adr *a;
75 	int i;
76 
77 	a = va_arg(fp->args, Adr*);
78 	i = a->type;
79 	if(i >= D_INDIR) {
80 		if(a->offset)
81 			snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR);
82 		else
83 			snprint(str, sizeof(str), "(%R)", i-D_INDIR);
84 		goto brk;
85 	}
86 	switch(i) {
87 
88 	default:
89 		if(a->offset)
90 			snprint(str, sizeof(str), "$%ld,%R", a->offset, i);
91 		else
92 			snprint(str, sizeof(str), "%R", i);
93 		break;
94 
95 	case D_NONE:
96 		str[0] = 0;
97 		break;
98 
99 	case D_BRANCH:
100 		snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
101 		break;
102 
103 	case D_EXTERN:
104 		snprint(str, sizeof(str), "%s+%ld(SB)", a->sym->name, a->offset);
105 		break;
106 
107 	case D_STATIC:
108 		snprint(str, sizeof(str), "%s<>+%ld(SB)", a->sym->name,
109 			a->offset);
110 		break;
111 
112 	case D_AUTO:
113 		snprint(str, sizeof(str), "%s+%ld(SP)", a->sym->name, a->offset);
114 		break;
115 
116 	case D_PARAM:
117 		if(a->sym)
118 			snprint(str, sizeof(str), "%s+%ld(FP)", a->sym->name, a->offset);
119 		else
120 			snprint(str, sizeof(str), "%ld(FP)", a->offset);
121 		break;
122 
123 	case D_CONST:
124 		snprint(str, sizeof(str), "$%ld", a->offset);
125 		break;
126 
127 	case D_FCONST:
128 		snprint(str, sizeof(str), "$(%.17e)", a->dval);
129 		break;
130 
131 	case D_SCONST:
132 		snprint(str, sizeof(str), "$\"%S\"", a->sval);
133 		break;
134 
135 	case D_ADDR:
136 		a->type = a->index;
137 		a->index = D_NONE;
138 		snprint(str, sizeof(str), "$%D", a);
139 		a->index = a->type;
140 		a->type = D_ADDR;
141 		goto conv;
142 	}
143 brk:
144 	if(a->index != D_NONE) {
145 		fmtstrcpy(fp, str);
146 		snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
147 		return fmtstrcpy(fp, s);
148 	}
149 conv:
150 	return fmtstrcpy(fp, str);
151 }
152 
153 char*	regstr[] =
154 {
155 	"AL",	/*[D_AL]*/
156 	"CL",
157 	"DL",
158 	"BL",
159 	"AH",
160 	"CH",
161 	"DH",
162 	"BH",
163 
164 	"AX",	/*[D_AX]*/
165 	"CX",
166 	"DX",
167 	"BX",
168 	"SP",
169 	"BP",
170 	"SI",
171 	"DI",
172 
173 	"F0",	/*[D_F0]*/
174 	"F1",
175 	"F2",
176 	"F3",
177 	"F4",
178 	"F5",
179 	"F6",
180 	"F7",
181 
182 	"CS",	/*[D_CS]*/
183 	"SS",
184 	"DS",
185 	"ES",
186 	"FS",
187 	"GS",
188 
189 	"GDTR",	/*[D_GDTR]*/
190 	"IDTR",	/*[D_IDTR]*/
191 	"LDTR",	/*[D_LDTR]*/
192 	"MSW",	/*[D_MSW] */
193 	"TASK",	/*[D_TASK]*/
194 
195 	"CR0",	/*[D_CR]*/
196 	"CR1",
197 	"CR2",
198 	"CR3",
199 	"CR4",
200 	"CR5",
201 	"CR6",
202 	"CR7",
203 
204 	"DR0",	/*[D_DR]*/
205 	"DR1",
206 	"DR2",
207 	"DR3",
208 	"DR4",
209 	"DR5",
210 	"DR6",
211 	"DR7",
212 
213 	"TR0",	/*[D_TR]*/
214 	"TR1",
215 	"TR2",
216 	"TR3",
217 	"TR4",
218 	"TR5",
219 	"TR6",
220 	"TR7",
221 
222 	"NONE",	/*[D_NONE]*/
223 };
224 
225 int
226 Rconv(Fmt *fp)
227 {
228 	char str[20];
229 	int r;
230 
231 	r = va_arg(fp->args, int);
232 	if(r >= D_AL && r <= D_NONE)
233 		snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
234 	else
235 		snprint(str, sizeof(str), "gok(%d)", r);
236 
237 	return fmtstrcpy(fp, str);
238 }
239 
240 int
241 Sconv(Fmt *fp)
242 {
243 	int i, c;
244 	char str[30], *p, *a;
245 
246 	a = va_arg(fp->args, char*);
247 	p = str;
248 	for(i=0; i<sizeof(double); i++) {
249 		c = a[i] & 0xff;
250 		if(c >= 'a' && c <= 'z' ||
251 		   c >= 'A' && c <= 'Z' ||
252 		   c >= '0' && c <= '9') {
253 			*p++ = c;
254 			continue;
255 		}
256 		*p++ = '\\';
257 		switch(c) {
258 		default:
259 			if(c < 040 || c >= 0177)
260 				break;	/* not portable */
261 			p[-1] = c;
262 			continue;
263 		case 0:
264 			*p++ = 'z';
265 			continue;
266 		case '\\':
267 		case '"':
268 			*p++ = c;
269 			continue;
270 		case '\n':
271 			*p++ = 'n';
272 			continue;
273 		case '\t':
274 			*p++ = 't';
275 			continue;
276 		}
277 		*p++ = (c>>6) + '0';
278 		*p++ = ((c>>3) & 7) + '0';
279 		*p++ = (c & 7) + '0';
280 	}
281 	*p = 0;
282 	return fmtstrcpy(fp, str);
283 }
284