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