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