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 == AINIT || a == ADYNT)
31 sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
32 else{
33 s = str;
34 if(p->mark & NOSCHED)
35 s += sprint(s, "*");
36 if(p->reg == NREG)
37 sprint(s, " %A %D,%D", a, &p->from, &p->to);
38 else
39 if(p->from.type == D_OREG) {
40 sprint(s, " %A %ld(R%d+R%d),%D", a,
41 p->from.offset, p->from.reg, p->reg, &p->to);
42 } else
43 if(p->to.type == D_OREG) {
44 sprint(s, " %A %D,%ld(R%d+R%d)", a,
45 &p->from, p->to.offset, p->to.reg, p->reg);
46 } else
47 if(p->from.type == D_FREG)
48 sprint(s, " %A %D,F%d,%D", a, &p->from, p->reg, &p->to);
49 else
50 sprint(s, " %A %D,R%d,%D", a, &p->from, p->reg, &p->to);
51 }
52 return fmtstrcpy(fp, str);
53 }
54
55 int
Aconv(Fmt * fp)56 Aconv(Fmt *fp)
57 {
58 char *s;
59 int a;
60
61 a = va_arg(fp->args, int);
62 s = "???";
63 if(a >= AXXX && a <= ALAST)
64 s = anames[a];
65 return fmtstrcpy(fp, s);
66 }
67
68 int
Dconv(Fmt * fp)69 Dconv(Fmt *fp)
70 {
71 char str[STRINGSZ];
72 Adr *a;
73 long v;
74
75 a = va_arg(fp->args, Adr*);
76 switch(a->type) {
77
78 default:
79 sprint(str, "GOK-type(%d)", a->type);
80 break;
81
82 case D_NONE:
83 str[0] = 0;
84 if(a->name != D_NONE || a->reg != NREG || a->sym != S)
85 sprint(str, "%N(R%d)(NONE)", a, a->reg);
86 break;
87
88 case D_CONST:
89 if(a->reg != NREG)
90 sprint(str, "$%N(R%d)", a, a->reg);
91 else
92 sprint(str, "$%N", a);
93 break;
94
95 case D_ASI:
96 if(a->reg != NREG)
97 sprint(str, "(R%d,%ld)", a->reg, a->offset);
98 else
99 sprint(str, "(R%d,%ld)", 0, a->offset);
100 break;
101
102 case D_OREG:
103 if(a->reg != NREG)
104 sprint(str, "%N(R%d)", a, a->reg);
105 else
106 sprint(str, "%N", a);
107 break;
108
109 case D_REG:
110 sprint(str, "R%d", a->reg);
111 if(a->name != D_NONE || a->sym != S)
112 sprint(str, "%N(R%d)(REG)", a, a->reg);
113 break;
114
115 case D_FREG:
116 sprint(str, "F%d", a->reg);
117 if(a->name != D_NONE || a->sym != S)
118 sprint(str, "%N(F%d)(REG)", a, a->reg);
119 break;
120
121 case D_CREG:
122 sprint(str, "C%d", a->reg);
123 if(a->name != D_NONE || a->sym != S)
124 sprint(str, "%N(C%d)(REG)", a, a->reg);
125 break;
126
127 case D_PREG:
128 sprint(str, "P%d", a->reg);
129 if(a->name != D_NONE || a->sym != S)
130 sprint(str, "%N(P%d)(REG)", a, a->reg);
131 break;
132
133 case D_BRANCH:
134 if(curp->cond != P) {
135 v = curp->cond->pc;
136 if(v >= INITTEXT)
137 v -= INITTEXT-HEADR;
138 if(a->sym != S)
139 sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
140 else
141 sprint(str, "%.5lux(BRANCH)", v);
142 } else
143 if(a->sym != S)
144 sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
145 else
146 sprint(str, "%ld(APC)", a->offset);
147 break;
148
149 case D_FCONST:
150 sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
151 break;
152
153 case D_SCONST:
154 sprint(str, "$\"%S\"", a->sval);
155 break;
156 }
157 return fmtstrcpy(fp, str);
158 }
159
160 int
Nconv(Fmt * fp)161 Nconv(Fmt *fp)
162 {
163 char str[STRINGSZ];
164 Adr *a;
165 Sym *s;
166
167 a = va_arg(fp->args, Adr*);
168 s = a->sym;
169 if(s == S) {
170 sprint(str, "%ld", a->offset);
171 goto out;
172 }
173 switch(a->name) {
174 default:
175 sprint(str, "GOK-name(%d)", a->name);
176 break;
177
178 case D_EXTERN:
179 sprint(str, "%s+%ld(SB)", s->name, a->offset);
180 break;
181
182 case D_STATIC:
183 sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
184 break;
185
186 case D_AUTO:
187 sprint(str, "%s-%ld(SP)", s->name, -a->offset);
188 break;
189
190 case D_PARAM:
191 sprint(str, "%s+%ld(FP)", s->name, a->offset);
192 break;
193 }
194 out:
195 return fmtstrcpy(fp, str);
196 }
197
198 int
Sconv(Fmt * fp)199 Sconv(Fmt *fp)
200 {
201 int i, c;
202 char str[STRINGSZ], *p, *a;
203
204 a = va_arg(fp->args, char*);
205 p = str;
206 for(i=0; i<sizeof(long); i++) {
207 c = a[i] & 0xff;
208 if(c >= 'a' && c <= 'z' ||
209 c >= 'A' && c <= 'Z' ||
210 c >= '0' && c <= '9' ||
211 c == ' ' || c == '%') {
212 *p++ = c;
213 continue;
214 }
215 *p++ = '\\';
216 switch(c) {
217 case 0:
218 *p++ = 'z';
219 continue;
220 case '\\':
221 case '"':
222 *p++ = c;
223 continue;
224 case '\n':
225 *p++ = 'n';
226 continue;
227 case '\t':
228 *p++ = 't';
229 continue;
230 }
231 *p++ = (c>>6) + '0';
232 *p++ = ((c>>3) & 7) + '0';
233 *p++ = (c & 7) + '0';
234 }
235 *p = 0;
236 return fmtstrcpy(fp, str);
237 }
238
239 void
diag(char * fmt,...)240 diag(char *fmt, ...)
241 {
242 char buf[STRINGSZ], *tn;
243 va_list arg;
244
245 tn = "??none??";
246 if(curtext != P && curtext->from.sym != S)
247 tn = curtext->from.sym->name;
248 va_start(arg, fmt);
249 vseprint(buf, buf+sizeof(buf), fmt, arg);
250 va_end(arg);
251 print("%s: %s\n", tn, buf);
252
253 nerrors++;
254 if(nerrors > 10) {
255 print("too many errors\n");
256 errorexit();
257 }
258 }
259