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