xref: /plan9-contrib/sys/src/cmd/6l/list.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include	"l.h"
2 
3 void
4 listinit(void)
5 {
6 
7 	fmtinstall('R', Rconv);
8 	fmtinstall('A', Aconv);
9 	fmtinstall('D', Dconv);
10 	fmtinstall('X', Xconv);
11 	fmtinstall('S', Sconv);
12 	fmtinstall('P', Pconv);
13 }
14 
15 static	Prog	*bigP;
16 
17 int
18 Pconv(void *o, Fconv *fp)
19 {
20 	char str[STRINGSZ];
21 	Prog *p;
22 
23 	p = *(Prog**)o;
24 	bigP = p;
25 	if(p->as == ADATA)
26 		sprint(str, "(%ld)	%A	%D/%d,%D",
27 			p->line, p->as, &p->from, p->from.scale, &p->to);
28 	else
29 	if(p->type != D_NONE) {
30 		if(p->type >= D_R0 && p->type < D_R0+32)
31 			sprint(str, "(%ld)	%A	%D,%R,%D",
32 				p->line, p->as, &p->from, p->type, &p->to);
33 		else
34 		if(p->type == D_CONST)
35 			sprint(str, "(%ld)	%A	%D,$%d,%D",
36 				p->line, p->as, &p->from, p->offset, &p->to);
37 		else
38 			sprint(str, "(%ld)	%A	%D,gok(%d),%D",
39 				p->line, p->as, &p->from, p->type, &p->to);
40 	} else
41 		sprint(str, "(%ld)	%A	%D,%D",
42 			p->line, p->as, &p->from, &p->to);
43 	strconv(str, fp);
44 	bigP = P;
45 	return sizeof(Prog*);
46 }
47 
48 int
49 Aconv(void *o, Fconv *fp)
50 {
51 
52 	strconv(anames[*(int*)o], fp);
53 	return sizeof(int);
54 }
55 
56 int
57 Xconv(void *o, Fconv *fp)
58 {
59 	char str[20];
60 	int i;
61 
62 	str[0] = 0;
63 	i = ((int*)o)[0];
64 	if(i != D_NONE)
65 		sprint(str, "(%R*%d)", i, ((int*)o)[1]);
66 	strconv(str, fp);
67 	return sizeof(int[2]);
68 }
69 
70 int
71 Dconv(void *o, Fconv *fp)
72 {
73 	char str[40], s[20];
74 	Adr *a;
75 	int i;
76 
77 	a = *(Adr**)o;
78 	i = a->type;
79 	if(i >= D_INDIR) {
80 		if(a->offset)
81 			sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
82 		else
83 			sprint(str, "(%R)", i-D_INDIR);
84 		goto brk;
85 	}
86 	switch(i) {
87 
88 	default:
89 		sprint(str, "%R", i);
90 		break;
91 
92 	case D_NONE:
93 		str[0] = 0;
94 		break;
95 
96 	case D_BRANCH:
97 		if(bigP != P && bigP->cond != P)
98 			if(a->sym != S)
99 				sprint(str, "%lux+%s", bigP->cond->pc,
100 					a->sym->name);
101 			else
102 				sprint(str, "%lux", bigP->cond->pc);
103 		else
104 			sprint(str, "%ld(PC)", a->offset);
105 		break;
106 
107 	case D_EXTERN:
108 		sprint(str, "%s+%ld(SB)", a->sym->name, a->offset);
109 		break;
110 
111 	case D_STATIC:
112 		sprint(str, "%s<%d>+%ld(SB)", a->sym->name,
113 			a->sym->version, a->offset);
114 		break;
115 
116 	case D_AUTO:
117 		sprint(str, "%s+%ld(SP)", a->sym->name, a->offset);
118 		break;
119 
120 	case D_PARAM:
121 		if(a->sym)
122 			sprint(str, "%s+%ld(FP)", a->sym->name, a->offset);
123 		else
124 			sprint(str, "%ld(FP)", a->offset);
125 		break;
126 
127 	case D_CONST:
128 		sprint(str, "$%ld", a->offset);
129 		break;
130 
131 	case D_FCONST:
132 		sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
133 		break;
134 
135 	case D_SCONST:
136 		sprint(str, "$\"%S\"", a->scon);
137 		break;
138 
139 	case D_ADDR:
140 		a->type = a->index;
141 		a->index = D_NONE;
142 		sprint(str, "$%D", a);
143 		a->index = a->type;
144 		a->type = D_ADDR;
145 		goto conv;
146 	}
147 brk:
148 	if(a->index != D_NONE) {
149 		sprint(s, "%X", a->index, a->scale);
150 		strcat(str, s);
151 	}
152 conv:
153 	strconv(str, fp);
154 	return sizeof(Adr*);
155 }
156 
157 int
158 Rconv(void *o, Fconv *fp)
159 {
160 	char str[20];
161 	int r;
162 
163 	r = *(int*)o;
164 	if(r >= D_R0 && r < D_R0+32)
165 		sprint(str, "R%d", r);
166 	else
167 	if(r == D_NONE)
168 		sprint(str, "");
169 	else
170 		sprint(str, "gok(%d)", r);
171 
172 	strconv(str, fp);
173 	return sizeof(int);
174 }
175 
176 int
177 Sconv(void *o, Fconv *fp)
178 {
179 	int i, c;
180 	char str[30], *p, *a;
181 
182 	a = *(char**)o;
183 	p = str;
184 	for(i=0; i<sizeof(double); i++) {
185 		c = a[i] & 0xff;
186 		if(c >= 'a' && c <= 'z' ||
187 		   c >= 'A' && c <= 'Z' ||
188 		   c >= '0' && c <= '9') {
189 			*p++ = c;
190 			continue;
191 		}
192 		*p++ = '\\';
193 		switch(c) {
194 		default:
195 			if(c < 040 || c >= 0177)
196 				break;	/* not portable */
197 			p[-1] = c;
198 			continue;
199 		case 0:
200 			*p++ = 'z';
201 			continue;
202 		case '\\':
203 		case '"':
204 			*p++ = c;
205 			continue;
206 		case '\n':
207 			*p++ = 'n';
208 			continue;
209 		case '\t':
210 			*p++ = 't';
211 			continue;
212 		}
213 		*p++ = (c>>6) + '0';
214 		*p++ = ((c>>3) & 7) + '0';
215 		*p++ = (c & 7) + '0';
216 	}
217 	*p = 0;
218 	strconv(str, fp);
219 	return sizeof(char*);
220 }
221 
222 void
223 diag(char *a, ...)
224 {
225 	char buf[STRINGSZ], *tn;
226 
227 	tn = "??none??";
228 	if(curtext != P && curtext->from.sym != S)
229 		tn = curtext->from.sym->name;
230 	doprint(buf, buf+sizeof(buf), a, &(&a)[1]);	/* ugly */
231 	print("%s: %s\n", tn, buf);
232 
233 	nerrors++;
234 	if(nerrors > 10) {
235 		print("too many errors\n");
236 		errorexit();
237 	}
238 }
239