1 #define EXTERN
2 #include "gc.h"
3
4 void
listinit(void)5 listinit(void)
6 {
7
8 fmtinstall('A', Aconv);
9 fmtinstall('P', Pconv);
10 fmtinstall('S', Sconv);
11 fmtinstall('N', Nconv);
12 fmtinstall('D', Dconv);
13 fmtinstall('B', Bconv);
14 }
15
16 int
Bconv(Fmt * fp)17 Bconv(Fmt *fp)
18 {
19 char str[STRINGSZ], ss[STRINGSZ], *s;
20 Bits bits;
21 int i;
22
23 str[0] = 0;
24 bits = va_arg(fp->args, Bits);
25 while(bany(&bits)) {
26 i = bnum(bits);
27 if(str[0])
28 strcat(str, " ");
29 if(var[i].sym == S) {
30 sprint(ss, "$%ld", var[i].offset);
31 s = ss;
32 } else
33 s = var[i].sym->name;
34 if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
35 break;
36 strcat(str, s);
37 bits.b[i/32] &= ~(1L << (i%32));
38 }
39 return fmtstrcpy(fp, str);
40 }
41
42 int
Pconv(Fmt * fp)43 Pconv(Fmt *fp)
44 {
45 char str[STRINGSZ], *s;
46 Prog *p;
47 int a;
48
49 p = va_arg(fp->args, Prog*);
50 a = p->as;
51 if(a == ADATA)
52 sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
53 else if(p->as == ATEXT)
54 sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
55 else {
56 s = seprint(str, str+sizeof(str), " %A %D", a, &p->from);
57 if(p->reg != NREG)
58 s = seprint(s, str+sizeof(str), ",%c%d", p->from.type==D_FREG? 'F': 'R', p->reg);
59 if(p->from3.type != D_NONE)
60 s = seprint(s, str+sizeof(str), ",%D", &p->from3);
61 seprint(s, s+sizeof(str), ",%D", &p->to);
62 }
63 return fmtstrcpy(fp, str);
64 }
65
66 int
Aconv(Fmt * fp)67 Aconv(Fmt *fp)
68 {
69 char *s;
70 int a;
71
72 a = va_arg(fp->args, int);
73 s = "???";
74 if(a >= AXXX && a <= ALAST)
75 s = anames[a];
76 return fmtstrcpy(fp, s);
77 }
78
79 int
Dconv(Fmt * fp)80 Dconv(Fmt *fp)
81 {
82 char str[STRINGSZ];
83 Adr *a;
84
85 a = va_arg(fp->args, Adr*);
86 switch(a->type) {
87
88 default:
89 sprint(str, "GOK-type(%d)", a->type);
90 break;
91
92 case D_NONE:
93 str[0] = 0;
94 if(a->name != D_NONE || a->reg != NREG || a->sym != S)
95 sprint(str, "%N(R%d)(NONE)", a, a->reg);
96 break;
97
98 case D_CONST:
99 if(a->reg != NREG)
100 sprint(str, "$%N(R%d)", a, a->reg);
101 else
102 sprint(str, "$%N", a);
103 break;
104
105 case D_OREG:
106 if(a->reg != NREG)
107 sprint(str, "%N(R%d)", a, a->reg);
108 else
109 sprint(str, "%N", a);
110 break;
111
112 case D_REG:
113 sprint(str, "R%d", a->reg);
114 if(a->name != D_NONE || a->sym != S)
115 sprint(str, "%N(R%d)(REG)", a, a->reg);
116 break;
117
118 case D_FREG:
119 sprint(str, "F%d", a->reg);
120 if(a->name != D_NONE || a->sym != S)
121 sprint(str, "%N(F%d)(REG)", a, a->reg);
122 break;
123
124 case D_CREG:
125 sprint(str, "C%d", a->reg);
126 if(a->name != D_NONE || a->sym != S)
127 sprint(str, "%N(C%d)(REG)", a, a->reg);
128 break;
129
130 case D_BRANCH:
131 sprint(str, "%ld(PC)", a->offset-pc);
132 break;
133
134 case D_FCONST:
135 sprint(str, "$%.17e", a->dval);
136 break;
137
138 case D_SCONST:
139 sprint(str, "$\"%S\"", a->sval);
140 break;
141 }
142 return fmtstrcpy(fp, str);
143 }
144
145 int
Sconv(Fmt * fp)146 Sconv(Fmt *fp)
147 {
148 int i, c;
149 char str[STRINGSZ], *p, *a;
150
151 a = va_arg(fp->args, char*);
152 p = str;
153 for(i=0; i<NSNAME; i++) {
154 c = a[i] & 0xff;
155 if(c >= 'a' && c <= 'z' ||
156 c >= 'A' && c <= 'Z' ||
157 c >= '0' && c <= '9' ||
158 c == ' ' || c == '%') {
159 *p++ = c;
160 continue;
161 }
162 *p++ = '\\';
163 switch(c) {
164 case 0:
165 *p++ = 'z';
166 continue;
167 case '\\':
168 case '"':
169 *p++ = c;
170 continue;
171 case '\n':
172 *p++ = 'n';
173 continue;
174 case '\t':
175 *p++ = 't';
176 continue;
177 case '\r':
178 *p++ = 'r';
179 continue;
180 case '\f':
181 *p++ = 'f';
182 continue;
183 }
184 *p++ = (c>>6) + '0';
185 *p++ = ((c>>3) & 7) + '0';
186 *p++ = (c & 7) + '0';
187 }
188 *p = 0;
189 return fmtstrcpy(fp, str);
190 }
191
192 int
Nconv(Fmt * fp)193 Nconv(Fmt *fp)
194 {
195 char str[STRINGSZ];
196 Adr *a;
197 Sym *s;
198 int i, l, b, n;
199
200 a = va_arg(fp->args, Adr*);
201 s = a->sym;
202 if(s == S) {
203 if(a->offset > 64 || -a->offset > 64) {
204 n = 0;
205 l = a->offset & 1;
206 for(i=0; i<32; i++){
207 b = (a->offset >> i) & 1;
208 if(b != l)
209 n++;
210 l = b;
211 }
212 if(n < 2) {
213 sprint(str, "%#lux", a->offset);
214 goto out;
215 }
216 }
217 sprint(str, "%ld", a->offset);
218 goto out;
219 }
220 switch(a->name) {
221 default:
222 sprint(str, "GOK-name(%d)", a->name);
223 break;
224
225 case D_EXTERN:
226 sprint(str, "%s+%ld(SB)", s->name, a->offset);
227 break;
228
229 case D_STATIC:
230 sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
231 break;
232
233 case D_AUTO:
234 sprint(str, "%s-%ld(SP)", s->name, -a->offset);
235 break;
236
237 case D_PARAM:
238 sprint(str, "%s+%ld(FP)", s->name, a->offset);
239 break;
240 }
241 out:
242 return fmtstrcpy(fp, str);
243 }
244