xref: /plan9-contrib/sys/src/cmd/6c/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('Z', Zconv);
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, "(%ld)	%A	%D/%d,%D",
25 			p->lineno, p->as, &p->from, p->from.scale, &p->to);
26 	else
27 	if(p->type != D_NONE) {
28 		if(p->type >= D_R0 && p->type < D_R0+32)
29 			sprint(str, "(%ld)	%A	%D,%R,%D",
30 				p->lineno, p->as, &p->from, p->type, &p->to);
31 		else
32 		if(p->type == D_CONST)
33 			sprint(str, "(%ld)	%A	%D,$%d,%D",
34 				p->lineno, p->as, &p->from, p->offset, &p->to);
35 		else
36 			sprint(str, "(%ld)	%A	%D,gok(%d),%D",
37 				p->lineno, p->as, &p->from, p->type, &p->to);
38 	} else
39 		sprint(str, "(%ld)	%A	%D,%D",
40 			p->lineno, p->as, &p->from, &p->to);
41 	strconv(str, fp);
42 	return sizeof(Prog*);
43 }
44 
45 int
46 Aconv(void *o, Fconv *fp)
47 {
48 
49 	strconv(anames[*(int*)o], fp);
50 	return sizeof(int);
51 }
52 
53 int
54 Xconv(void *o, Fconv *fp)
55 {
56 	char str[20];
57 	int i;
58 
59 	str[0] = 0;
60 	i = ((int*)o)[0];
61 	if(i != D_NONE)
62 		sprint(str, "(%R*%d)", i, ((int*)o)[1]);
63 	strconv(str, fp);
64 	return sizeof(int[2]);
65 }
66 
67 int
68 Dconv(void *o, Fconv *fp)
69 {
70 	char str[40], s[20];
71 	Adr *a;
72 	int i;
73 
74 	a = *(Adr**)o;
75 	i = a->type;
76 	if(i >= D_INDIR) {
77 		if(a->offset)
78 			sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
79 		else
80 			sprint(str, "(%R)", i-D_INDIR);
81 		goto brk;
82 	}
83 	switch(i) {
84 
85 	default:
86 		if(a->offset)
87 			sprint(str, "$%ld,%R", a->offset, i);
88 		else
89 			sprint(str, "%R", i);
90 		break;
91 
92 	case D_NONE:
93 		str[0] = 0;
94 		break;
95 
96 	case D_BRANCH:
97 		sprint(str, "%ld(PC)", a->offset-pc);
98 		break;
99 
100 	case D_EXTERN:
101 		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
102 		break;
103 
104 	case D_STATIC:
105 		sprint(str, "%s<>+%ld(SB)", a->sym->name,
106 			a->offset);
107 		break;
108 
109 	case D_AUTO:
110 		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
111 		break;
112 
113 	case D_PARAM:
114 		if(a->sym)
115 			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
116 		else
117 			sprint(str, "%ld(FP)", a->offset);
118 		break;
119 
120 	case D_CONST:
121 		sprint(str, "$%ld", a->offset);
122 		break;
123 
124 	case D_FCONST:
125 		sprint(str, "$(%.17e)", a->dval);
126 		break;
127 
128 	case D_SCONST:
129 		sprint(str, "$\"%Z\"", a->sval);
130 		break;
131 
132 	case D_ADDR:
133 		a->type = a->index;
134 		a->index = D_NONE;
135 		sprint(str, "$%D", a);
136 		a->index = a->type;
137 		a->type = D_ADDR;
138 		goto conv;
139 	}
140 brk:
141 	if(a->index != D_NONE) {
142 		sprint(s, "%X", a->index, a->scale);
143 		strcat(str, s);
144 	}
145 conv:
146 	strconv(str, fp);
147 	return sizeof(Adr*);
148 }
149 
150 int
151 Rconv(void *o, Fconv *fp)
152 {
153 	char str[20];
154 	int r;
155 
156 	r = *(int*)o;
157 	if(r >= D_R0 && r <= D_R0+31)
158 		sprint(str, "R%d", r-D_R0);
159 	else
160 	if(r == D_NONE)
161 		sprint(str, "");
162 	else
163 		sprint(str, "gok(%d)", r);
164 
165 	strconv(str, fp);
166 	return sizeof(int);
167 }
168 
169 int
170 Zconv(void *o, Fconv *fp)
171 {
172 	int i, c;
173 	char str[30], *p, *a;
174 
175 	a = *(char**)o;
176 	p = str;
177 	for(i=0; i<sizeof(double); i++) {
178 		c = a[i] & 0xff;
179 		if(c >= 'a' && c <= 'z' ||
180 		   c >= 'A' && c <= 'Z' ||
181 		   c >= '0' && c <= '9') {
182 			*p++ = c;
183 			continue;
184 		}
185 		*p++ = '\\';
186 		switch(c) {
187 		default:
188 			if(c < 040 || c >= 0177)
189 				break;	/* not portable */
190 			p[-1] = c;
191 			continue;
192 		case 0:
193 			*p++ = 'z';
194 			continue;
195 		case '\\':
196 		case '"':
197 			*p++ = c;
198 			continue;
199 		case '\n':
200 			*p++ = 'n';
201 			continue;
202 		case '\t':
203 			*p++ = 't';
204 			continue;
205 		}
206 		*p++ = (c>>6) + '0';
207 		*p++ = ((c>>3) & 7) + '0';
208 		*p++ = (c & 7) + '0';
209 	}
210 	*p = 0;
211 	strconv(str, fp);
212 	return sizeof(char*);
213 }
214