xref: /inferno-os/utils/qc/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('D', Dconv);
13 	fmtinstall('B', Bconv);
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], *s;
46 	Prog *p;
47 	int a;
48 
49 	p = va_arg(fp->args, Prog*);
50 	a = p->as;
51 	if(a == ADATA)
52 		sprint(str, "	%A	%D/%d,%D", a, &p->from, p->reg, &p->to);
53 	else if(p->as == ATEXT)
54 		sprint(str, "	%A	%D,%d,%D", a, &p->from, p->reg, &p->to);
55 	else {
56 		s = seprint(str, str+sizeof(str), "	%A	%D", a, &p->from);
57 		if(p->reg != NREG)
58 			s = seprint(s, str+sizeof(str), ",%c%d", p->from.type==D_FREG? 'F': 'R', p->reg);
59 		if(p->from3.type != D_NONE)
60 			s = seprint(s, str+sizeof(str), ",%D", &p->from3);
61 		seprint(s, s+sizeof(str), ",%D", &p->to);
62 	}
63 	return fmtstrcpy(fp, str);
64 }
65 
66 int
67 Aconv(Fmt *fp)
68 {
69 	char *s;
70 	int a;
71 
72 	a = va_arg(fp->args, int);
73 	s = "?";
74 	if(a >= AXXX && a <= ALAST)
75 		s = anames[a];
76 	return fmtstrcpy(fp, s);
77 }
78 
79 int
80 Dconv(Fmt *fp)
81 {
82 	char str[STRINGSZ];
83 	Adr *a;
84 
85 	a = va_arg(fp->args, Adr*);
86 	switch(a->type) {
87 
88 	default:
89 		sprint(str, "GOK-type(%d)", a->type);
90 		break;
91 
92 	case D_NONE:
93 		str[0] = 0;
94 		if(a->name != D_NONE || a->reg != NREG || a->sym != S)
95 			sprint(str, "%N(R%d)(NONE)", a, a->reg);
96 		break;
97 
98 	case D_CONST:
99 		if(a->reg != NREG)
100 			sprint(str, "$%N(R%d)", a, a->reg);
101 		else
102 			sprint(str, "$%N", a);
103 		break;
104 
105 	case D_OREG:
106 		if(a->reg != NREG)
107 			sprint(str, "%N(R%d)", a, a->reg);
108 		else
109 			sprint(str, "%N", a);
110 		break;
111 
112 	case D_REG:
113 		sprint(str, "R%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(F%d)(REG)", a, a->reg);
122 		break;
123 
124 	case D_CREG:
125 		sprint(str, "C%d", a->reg);
126 		if(a->name != D_NONE || a->sym != S)
127 			sprint(str, "%N(C%d)(REG)", a, a->reg);
128 		break;
129 
130 	case D_BRANCH:
131 		sprint(str, "%ld(PC)", a->offset-pc);
132 		break;
133 
134 	case D_FCONST:
135 		sprint(str, "$%.17e", a->dval);
136 		break;
137 
138 	case D_SCONST:
139 		sprint(str, "$\"%S\"", a->sval);
140 		break;
141 	}
142 	return fmtstrcpy(fp, str);
143 }
144 
145 int
146 Sconv(Fmt *fp)
147 {
148 	int i, c;
149 	char str[STRINGSZ], *p, *a;
150 
151 	a = va_arg(fp->args, char*);
152 	p = str;
153 	for(i=0; i<NSNAME; i++) {
154 		c = a[i] & 0xff;
155 		if(c >= 'a' && c <= 'z' ||
156 		   c >= 'A' && c <= 'Z' ||
157 		   c >= '0' && c <= '9' ||
158 		   c == ' ' || c == '%') {
159 			*p++ = c;
160 			continue;
161 		}
162 		*p++ = '\\';
163 		switch(c) {
164 		case 0:
165 			*p++ = 'z';
166 			continue;
167 		case '\\':
168 		case '"':
169 			*p++ = c;
170 			continue;
171 		case '\n':
172 			*p++ = 'n';
173 			continue;
174 		case '\t':
175 			*p++ = 't';
176 			continue;
177 		case '\r':
178 			*p++ = 'r';
179 			continue;
180 		case '\f':
181 			*p++ = 'f';
182 			continue;
183 		}
184 		*p++ = (c>>6) + '0';
185 		*p++ = ((c>>3) & 7) + '0';
186 		*p++ = (c & 7) + '0';
187 	}
188 	*p = 0;
189 	return fmtstrcpy(fp, str);
190 }
191 
192 int
193 Nconv(Fmt *fp)
194 {
195 	char str[STRINGSZ];
196 	Adr *a;
197 	Sym *s;
198 	int i, l, b, n;
199 
200 	a = va_arg(fp->args, Adr*);
201 	s = a->sym;
202 	if(s == S) {
203 		if(a->offset > 64 || -a->offset > 64) {
204 			n = 0;
205 			l = a->offset & 1;
206 			for(i=0; i<32; i++){
207 				b = (a->offset >> i) & 1;
208 				if(b != l)
209 					n++;
210 				l = b;
211 			}
212 			if(n < 2) {
213 				sprint(str, "%#lux", a->offset);
214 				goto out;
215 			}
216 		}
217 		sprint(str, "%ld", a->offset);
218 		goto out;
219 	}
220 	switch(a->name) {
221 	default:
222 		sprint(str, "GOK-name(%d)", a->name);
223 		break;
224 
225 	case D_EXTERN:
226 		sprint(str, "%s+%ld(SB)", s->name, a->offset);
227 		break;
228 
229 	case D_STATIC:
230 		sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
231 		break;
232 
233 	case D_AUTO:
234 		sprint(str, "%s-%ld(SP)", s->name, -a->offset);
235 		break;
236 
237 	case D_PARAM:
238 		sprint(str, "%s+%ld(FP)", s->name, a->offset);
239 		break;
240 	}
241 out:
242 	return fmtstrcpy(fp, str);
243 }
244