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