xref: /inferno-os/utils/8c/list.c (revision 2b69dba5038ffd0b59cf30a4c44bce549e5097f8)
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 			sprint(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 		sprint(str, "	%A	%D/%d,%D",
51 			p->as, &p->from, p->from.scale, &p->to);
52 	else if(p->as == ATEXT)
53 		sprint(str, "	%A	%D,%d,%D",
54 			p->as, &p->from, p->from.scale, &p->to);
55 	else
56 		sprint(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[STRINGSZ], s[STRINGSZ];
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 			sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
82 		else
83 			sprint(str, "(%R)", i-D_INDIR);
84 		goto brk;
85 	}
86 	switch(i) {
87 
88 	default:
89 		if(a->offset)
90 			sprint(str, "$%ld,%R", a->offset, i);
91 		else
92 			sprint(str, "%R", i);
93 		break;
94 
95 	case D_NONE:
96 		str[0] = 0;
97 		break;
98 
99 	case D_BRANCH:
100 		sprint(str, "%ld(PC)", a->offset-pc);
101 		break;
102 
103 	case D_EXTERN:
104 		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
105 		break;
106 
107 	case D_STATIC:
108 		sprint(str, "%s<>+%ld(SB)", a->sym->name,
109 			a->offset);
110 		break;
111 
112 	case D_AUTO:
113 		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
114 		break;
115 
116 	case D_PARAM:
117 		if(a->sym)
118 			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
119 		else
120 			sprint(str, "%ld(FP)", a->offset);
121 		break;
122 
123 	case D_CONST:
124 		sprint(str, "$%ld", a->offset);
125 		break;
126 
127 	case D_FCONST:
128 		sprint(str, "$(%.17e)", a->dval);
129 		break;
130 
131 	case D_SCONST:
132 		sprint(str, "$\"%S\"", a->sval);
133 		break;
134 
135 	case D_ADDR:
136 		a->type = a->index;
137 		a->index = D_NONE;
138 		sprint(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 		sprint(s, "(%R*%d)", (int)a->index, (int)a->scale);
146 		strcat(str, s);
147 	}
148 conv:
149 	return fmtstrcpy(fp, str);
150 }
151 
152 char*	regstr[] =
153 {
154 	"AL",	/*[D_AL]*/
155 	"CL",
156 	"DL",
157 	"BL",
158 	"AH",
159 	"CH",
160 	"DH",
161 	"BH",
162 
163 	"AX",	/*[D_AX]*/
164 	"CX",
165 	"DX",
166 	"BX",
167 	"SP",
168 	"BP",
169 	"SI",
170 	"DI",
171 
172 	"F0",	/*[D_F0]*/
173 	"F1",
174 	"F2",
175 	"F3",
176 	"F4",
177 	"F5",
178 	"F6",
179 	"F7",
180 
181 	"CS",	/*[D_CS]*/
182 	"SS",
183 	"DS",
184 	"ES",
185 	"FS",
186 	"GS",
187 
188 	"GDTR",	/*[D_GDTR]*/
189 	"IDTR",	/*[D_IDTR]*/
190 	"LDTR",	/*[D_LDTR]*/
191 	"MSW",	/*[D_MSW] */
192 	"TASK",	/*[D_TASK]*/
193 
194 	"CR0",	/*[D_CR]*/
195 	"CR1",
196 	"CR2",
197 	"CR3",
198 	"CR4",
199 	"CR5",
200 	"CR6",
201 	"CR7",
202 
203 	"DR0",	/*[D_DR]*/
204 	"DR1",
205 	"DR2",
206 	"DR3",
207 	"DR4",
208 	"DR5",
209 	"DR6",
210 	"DR7",
211 
212 	"TR0",	/*[D_TR]*/
213 	"TR1",
214 	"TR2",
215 	"TR3",
216 	"TR4",
217 	"TR5",
218 	"TR6",
219 	"TR7",
220 
221 	"NONE",	/*[D_NONE]*/
222 };
223 
224 int
225 Rconv(Fmt *fp)
226 {
227 	char str[STRINGSZ];
228 	int r;
229 
230 	r = va_arg(fp->args, int);
231 	if(r >= D_AL && r <= D_NONE)
232 		sprint(str, "%s", regstr[r-D_AL]);
233 	else
234 		sprint(str, "gok(%d)", r);
235 
236 	return fmtstrcpy(fp, str);
237 }
238 
239 int
240 Sconv(Fmt *fp)
241 {
242 	int i, c;
243 	char str[STRINGSZ], *p, *a;
244 
245 	a = va_arg(fp->args, char*);
246 	p = str;
247 	for(i=0; i<sizeof(double); i++) {
248 		c = a[i] & 0xff;
249 		if(c >= 'a' && c <= 'z' ||
250 		   c >= 'A' && c <= 'Z' ||
251 		   c >= '0' && c <= '9') {
252 			*p++ = c;
253 			continue;
254 		}
255 		*p++ = '\\';
256 		switch(c) {
257 		default:
258 			if(c < 040 || c >= 0177)
259 				break;	/* not portable */
260 			p[-1] = c;
261 			continue;
262 		case 0:
263 			*p++ = 'z';
264 			continue;
265 		case '\\':
266 		case '"':
267 			*p++ = c;
268 			continue;
269 		case '\n':
270 			*p++ = 'n';
271 			continue;
272 		case '\t':
273 			*p++ = 't';
274 			continue;
275 		}
276 		*p++ = (c>>6) + '0';
277 		*p++ = ((c>>3) & 7) + '0';
278 		*p++ = (c & 7) + '0';
279 	}
280 	*p = 0;
281 	return fmtstrcpy(fp, str);
282 }
283