1*fbadb1c4SDavid du Colombier #include "l.h"
2*fbadb1c4SDavid du Colombier
3*fbadb1c4SDavid du Colombier void
listinit(void)4*fbadb1c4SDavid du Colombier listinit(void)
5*fbadb1c4SDavid du Colombier {
6*fbadb1c4SDavid du Colombier
7*fbadb1c4SDavid du Colombier fmtinstall('A', Aconv);
8*fbadb1c4SDavid du Colombier fmtinstall('D', Dconv);
9*fbadb1c4SDavid du Colombier fmtinstall('P', Pconv);
10*fbadb1c4SDavid du Colombier fmtinstall('S', Sconv);
11*fbadb1c4SDavid du Colombier fmtinstall('N', Nconv);
12*fbadb1c4SDavid du Colombier fmtinstall('R', Rconv);
13*fbadb1c4SDavid du Colombier }
14*fbadb1c4SDavid du Colombier
15*fbadb1c4SDavid du Colombier void
prasm(Prog * p)16*fbadb1c4SDavid du Colombier prasm(Prog *p)
17*fbadb1c4SDavid du Colombier {
18*fbadb1c4SDavid du Colombier print("%P\n", p);
19*fbadb1c4SDavid du Colombier }
20*fbadb1c4SDavid du Colombier
21*fbadb1c4SDavid du Colombier int
Pconv(Fmt * fp)22*fbadb1c4SDavid du Colombier Pconv(Fmt *fp)
23*fbadb1c4SDavid du Colombier {
24*fbadb1c4SDavid du Colombier char str[STRINGSZ], *s;
25*fbadb1c4SDavid du Colombier Prog *p;
26*fbadb1c4SDavid du Colombier int a;
27*fbadb1c4SDavid du Colombier
28*fbadb1c4SDavid du Colombier p = va_arg(fp->args, Prog*);
29*fbadb1c4SDavid du Colombier curp = p;
30*fbadb1c4SDavid du Colombier a = p->as;
31*fbadb1c4SDavid du Colombier if(a == ADATA || a == AINIT || a == ADYNT)
32*fbadb1c4SDavid du Colombier sprint(str, "(%d) %A %D/%d,%D", p->line, a, &p->from, p->reg, &p->to);
33*fbadb1c4SDavid du Colombier else {
34*fbadb1c4SDavid du Colombier s = str;
35*fbadb1c4SDavid du Colombier if(p->mark & NOSCHED)
36*fbadb1c4SDavid du Colombier s += sprint(s, "*");
37*fbadb1c4SDavid du Colombier if(p->reg == NREG && p->from3.type == D_NONE)
38*fbadb1c4SDavid du Colombier sprint(s, "(%d) %A %D,%D", p->line, a, &p->from, &p->to);
39*fbadb1c4SDavid du Colombier else
40*fbadb1c4SDavid du Colombier if(a != ATEXT && p->from.type == D_OREG) {
41*fbadb1c4SDavid du Colombier sprint(s, "(%d) %A %lld(R%d+R%d),%D", p->line, a,
42*fbadb1c4SDavid du Colombier p->from.offset, p->from.reg, p->reg, &p->to);
43*fbadb1c4SDavid du Colombier } else
44*fbadb1c4SDavid du Colombier if(p->to.type == D_OREG) {
45*fbadb1c4SDavid du Colombier sprint(s, "(%d) %A %D,%lld(R%d+R%d)", p->line, a,
46*fbadb1c4SDavid du Colombier &p->from, p->to.offset, p->to.reg, p->reg);
47*fbadb1c4SDavid du Colombier } else {
48*fbadb1c4SDavid du Colombier s += sprint(s, "(%d) %A %D", p->line, a, &p->from);
49*fbadb1c4SDavid du Colombier if(p->reg != NREG)
50*fbadb1c4SDavid du Colombier s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
51*fbadb1c4SDavid du Colombier if(p->from3.type != D_NONE)
52*fbadb1c4SDavid du Colombier s += sprint(s, ",%D", &p->from3);
53*fbadb1c4SDavid du Colombier sprint(s, ",%D", &p->to);
54*fbadb1c4SDavid du Colombier }
55*fbadb1c4SDavid du Colombier }
56*fbadb1c4SDavid du Colombier return fmtstrcpy(fp, str);
57*fbadb1c4SDavid du Colombier }
58*fbadb1c4SDavid du Colombier
59*fbadb1c4SDavid du Colombier int
Aconv(Fmt * fp)60*fbadb1c4SDavid du Colombier Aconv(Fmt *fp)
61*fbadb1c4SDavid du Colombier {
62*fbadb1c4SDavid du Colombier char *s;
63*fbadb1c4SDavid du Colombier int a;
64*fbadb1c4SDavid du Colombier
65*fbadb1c4SDavid du Colombier a = va_arg(fp->args, int);
66*fbadb1c4SDavid du Colombier s = "???";
67*fbadb1c4SDavid du Colombier if(a >= AXXX && a < ALAST)
68*fbadb1c4SDavid du Colombier s = anames[a];
69*fbadb1c4SDavid du Colombier return fmtstrcpy(fp, s);
70*fbadb1c4SDavid du Colombier }
71*fbadb1c4SDavid du Colombier
72*fbadb1c4SDavid du Colombier int
Dconv(Fmt * fp)73*fbadb1c4SDavid du Colombier Dconv(Fmt *fp)
74*fbadb1c4SDavid du Colombier {
75*fbadb1c4SDavid du Colombier char str[STRINGSZ];
76*fbadb1c4SDavid du Colombier Adr *a;
77*fbadb1c4SDavid du Colombier long v;
78*fbadb1c4SDavid du Colombier
79*fbadb1c4SDavid du Colombier a = va_arg(fp->args, Adr*);
80*fbadb1c4SDavid du Colombier switch(a->type) {
81*fbadb1c4SDavid du Colombier
82*fbadb1c4SDavid du Colombier default:
83*fbadb1c4SDavid du Colombier sprint(str, "GOK-type(%d)", a->type);
84*fbadb1c4SDavid du Colombier break;
85*fbadb1c4SDavid du Colombier
86*fbadb1c4SDavid du Colombier case D_NONE:
87*fbadb1c4SDavid du Colombier str[0] = 0;
88*fbadb1c4SDavid du Colombier if(a->name != D_NONE || a->reg != NREG || a->sym != S)
89*fbadb1c4SDavid du Colombier sprint(str, "%N(R%d)(NONE)", a, a->reg);
90*fbadb1c4SDavid du Colombier break;
91*fbadb1c4SDavid du Colombier
92*fbadb1c4SDavid du Colombier case D_CONST:
93*fbadb1c4SDavid du Colombier case D_DCONST:
94*fbadb1c4SDavid du Colombier if(a->reg != NREG)
95*fbadb1c4SDavid du Colombier sprint(str, "$%N(R%d)", a, a->reg);
96*fbadb1c4SDavid du Colombier else
97*fbadb1c4SDavid du Colombier sprint(str, "$%N", a);
98*fbadb1c4SDavid du Colombier break;
99*fbadb1c4SDavid du Colombier
100*fbadb1c4SDavid du Colombier case D_OREG:
101*fbadb1c4SDavid du Colombier if(a->reg != NREG)
102*fbadb1c4SDavid du Colombier sprint(str, "%N(R%d)", a, a->reg);
103*fbadb1c4SDavid du Colombier else
104*fbadb1c4SDavid du Colombier sprint(str, "%N", a);
105*fbadb1c4SDavid du Colombier break;
106*fbadb1c4SDavid du Colombier
107*fbadb1c4SDavid du Colombier case D_REG:
108*fbadb1c4SDavid du Colombier sprint(str, "R%d", a->reg);
109*fbadb1c4SDavid du Colombier if(a->name != D_NONE || a->sym != S)
110*fbadb1c4SDavid du Colombier sprint(str, "%N(R%d)(REG)", a, a->reg);
111*fbadb1c4SDavid du Colombier break;
112*fbadb1c4SDavid du Colombier
113*fbadb1c4SDavid du Colombier case D_FREG:
114*fbadb1c4SDavid du Colombier sprint(str, "F%d", a->reg);
115*fbadb1c4SDavid du Colombier if(a->name != D_NONE || a->sym != S)
116*fbadb1c4SDavid du Colombier sprint(str, "%N(F%d)(REG)", a, a->reg);
117*fbadb1c4SDavid du Colombier break;
118*fbadb1c4SDavid du Colombier
119*fbadb1c4SDavid du Colombier case D_CREG:
120*fbadb1c4SDavid du Colombier if(a->reg == NREG)
121*fbadb1c4SDavid du Colombier strcpy(str, "CR");
122*fbadb1c4SDavid du Colombier else
123*fbadb1c4SDavid du Colombier sprint(str, "CR%d", a->reg);
124*fbadb1c4SDavid du Colombier if(a->name != D_NONE || a->sym != S)
125*fbadb1c4SDavid du Colombier sprint(str, "%N(C%d)(REG)", a, a->reg);
126*fbadb1c4SDavid du Colombier break;
127*fbadb1c4SDavid du Colombier
128*fbadb1c4SDavid du Colombier case D_SPR:
129*fbadb1c4SDavid du Colombier if(a->name == D_NONE && a->sym == S) {
130*fbadb1c4SDavid du Colombier switch((ulong)a->offset) {
131*fbadb1c4SDavid du Colombier case D_XER: sprint(str, "XER"); break;
132*fbadb1c4SDavid du Colombier case D_LR: sprint(str, "LR"); break;
133*fbadb1c4SDavid du Colombier case D_CTR: sprint(str, "CTR"); break;
134*fbadb1c4SDavid du Colombier default: sprint(str, "SPR(%lld)", a->offset); break;
135*fbadb1c4SDavid du Colombier }
136*fbadb1c4SDavid du Colombier break;
137*fbadb1c4SDavid du Colombier }
138*fbadb1c4SDavid du Colombier sprint(str, "SPR-GOK(%d)", a->reg);
139*fbadb1c4SDavid du Colombier if(a->name != D_NONE || a->sym != S)
140*fbadb1c4SDavid du Colombier sprint(str, "%N(SPR-GOK%d)(REG)", a, a->reg);
141*fbadb1c4SDavid du Colombier break;
142*fbadb1c4SDavid du Colombier
143*fbadb1c4SDavid du Colombier case D_DCR:
144*fbadb1c4SDavid du Colombier if(a->name == D_NONE && a->sym == S) {
145*fbadb1c4SDavid du Colombier sprint(str, "DCR(%lld)", a->offset);
146*fbadb1c4SDavid du Colombier break;
147*fbadb1c4SDavid du Colombier }
148*fbadb1c4SDavid du Colombier sprint(str, "DCR-GOK(%d)", a->reg);
149*fbadb1c4SDavid du Colombier if(a->name != D_NONE || a->sym != S)
150*fbadb1c4SDavid du Colombier sprint(str, "%N(DCR-GOK%d)(REG)", a, a->reg);
151*fbadb1c4SDavid du Colombier break;
152*fbadb1c4SDavid du Colombier
153*fbadb1c4SDavid du Colombier case D_OPT:
154*fbadb1c4SDavid du Colombier sprint(str, "OPT(%d)", a->reg);
155*fbadb1c4SDavid du Colombier break;
156*fbadb1c4SDavid du Colombier
157*fbadb1c4SDavid du Colombier case D_FPSCR:
158*fbadb1c4SDavid du Colombier if(a->reg == NREG)
159*fbadb1c4SDavid du Colombier strcpy(str, "FPSCR");
160*fbadb1c4SDavid du Colombier else
161*fbadb1c4SDavid du Colombier sprint(str, "FPSCR(%d)", a->reg);
162*fbadb1c4SDavid du Colombier break;
163*fbadb1c4SDavid du Colombier
164*fbadb1c4SDavid du Colombier case D_MSR:
165*fbadb1c4SDavid du Colombier sprint(str, "MSR");
166*fbadb1c4SDavid du Colombier break;
167*fbadb1c4SDavid du Colombier
168*fbadb1c4SDavid du Colombier case D_BRANCH:
169*fbadb1c4SDavid du Colombier if(curp->cond != P) {
170*fbadb1c4SDavid du Colombier v = curp->cond->pc;
171*fbadb1c4SDavid du Colombier if(v >= INITTEXT)
172*fbadb1c4SDavid du Colombier v -= INITTEXT-HEADR;
173*fbadb1c4SDavid du Colombier if(a->sym != S)
174*fbadb1c4SDavid du Colombier sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
175*fbadb1c4SDavid du Colombier else
176*fbadb1c4SDavid du Colombier sprint(str, "%.5lux(BRANCH)", v);
177*fbadb1c4SDavid du Colombier } else
178*fbadb1c4SDavid du Colombier if(a->sym != S)
179*fbadb1c4SDavid du Colombier sprint(str, "%s+%lld(APC)", a->sym->name, a->offset);
180*fbadb1c4SDavid du Colombier else
181*fbadb1c4SDavid du Colombier sprint(str, "%lld(APC)", a->offset);
182*fbadb1c4SDavid du Colombier break;
183*fbadb1c4SDavid du Colombier
184*fbadb1c4SDavid du Colombier case D_FCONST:
185*fbadb1c4SDavid du Colombier sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
186*fbadb1c4SDavid du Colombier break;
187*fbadb1c4SDavid du Colombier
188*fbadb1c4SDavid du Colombier case D_SCONST:
189*fbadb1c4SDavid du Colombier sprint(str, "$\"%S\"", a->sval);
190*fbadb1c4SDavid du Colombier break;
191*fbadb1c4SDavid du Colombier }
192*fbadb1c4SDavid du Colombier return fmtstrcpy(fp, str);
193*fbadb1c4SDavid du Colombier }
194*fbadb1c4SDavid du Colombier
195*fbadb1c4SDavid du Colombier int
Nconv(Fmt * fp)196*fbadb1c4SDavid du Colombier Nconv(Fmt *fp)
197*fbadb1c4SDavid du Colombier {
198*fbadb1c4SDavid du Colombier char str[STRINGSZ];
199*fbadb1c4SDavid du Colombier Adr *a;
200*fbadb1c4SDavid du Colombier Sym *s;
201*fbadb1c4SDavid du Colombier long l;
202*fbadb1c4SDavid du Colombier
203*fbadb1c4SDavid du Colombier a = va_arg(fp->args, Adr*);
204*fbadb1c4SDavid du Colombier s = a->sym;
205*fbadb1c4SDavid du Colombier if(s == S) {
206*fbadb1c4SDavid du Colombier l = a->offset;
207*fbadb1c4SDavid du Colombier if((vlong)l != a->offset)
208*fbadb1c4SDavid du Colombier sprint(str, "0x%llux", a->offset);
209*fbadb1c4SDavid du Colombier else
210*fbadb1c4SDavid du Colombier sprint(str, "%lld", a->offset);
211*fbadb1c4SDavid du Colombier goto out;
212*fbadb1c4SDavid du Colombier }
213*fbadb1c4SDavid du Colombier switch(a->name) {
214*fbadb1c4SDavid du Colombier default:
215*fbadb1c4SDavid du Colombier sprint(str, "GOK-name(%d)", a->name);
216*fbadb1c4SDavid du Colombier break;
217*fbadb1c4SDavid du Colombier
218*fbadb1c4SDavid du Colombier case D_EXTERN:
219*fbadb1c4SDavid du Colombier sprint(str, "%s+%lld(SB)", s->name, a->offset);
220*fbadb1c4SDavid du Colombier break;
221*fbadb1c4SDavid du Colombier
222*fbadb1c4SDavid du Colombier case D_STATIC:
223*fbadb1c4SDavid du Colombier sprint(str, "%s<>+%lld(SB)", s->name, a->offset);
224*fbadb1c4SDavid du Colombier break;
225*fbadb1c4SDavid du Colombier
226*fbadb1c4SDavid du Colombier case D_AUTO:
227*fbadb1c4SDavid du Colombier sprint(str, "%s-%lld(SP)", s->name, -a->offset);
228*fbadb1c4SDavid du Colombier break;
229*fbadb1c4SDavid du Colombier
230*fbadb1c4SDavid du Colombier case D_PARAM:
231*fbadb1c4SDavid du Colombier sprint(str, "%s+%lld(FP)", s->name, a->offset);
232*fbadb1c4SDavid du Colombier break;
233*fbadb1c4SDavid du Colombier }
234*fbadb1c4SDavid du Colombier out:
235*fbadb1c4SDavid du Colombier return fmtstrcpy(fp, str);
236*fbadb1c4SDavid du Colombier }
237*fbadb1c4SDavid du Colombier
238*fbadb1c4SDavid du Colombier int
Rconv(Fmt * fp)239*fbadb1c4SDavid du Colombier Rconv(Fmt *fp)
240*fbadb1c4SDavid du Colombier {
241*fbadb1c4SDavid du Colombier char *s;
242*fbadb1c4SDavid du Colombier int a;
243*fbadb1c4SDavid du Colombier
244*fbadb1c4SDavid du Colombier a = va_arg(fp->args, int);
245*fbadb1c4SDavid du Colombier s = "C_??";
246*fbadb1c4SDavid du Colombier if(a >= C_NONE && a <= C_NCLASS)
247*fbadb1c4SDavid du Colombier s = cnames[a];
248*fbadb1c4SDavid du Colombier return fmtstrcpy(fp, s);
249*fbadb1c4SDavid du Colombier }
250*fbadb1c4SDavid du Colombier
251*fbadb1c4SDavid du Colombier int
Sconv(Fmt * fp)252*fbadb1c4SDavid du Colombier Sconv(Fmt *fp)
253*fbadb1c4SDavid du Colombier {
254*fbadb1c4SDavid du Colombier int i, c;
255*fbadb1c4SDavid du Colombier char str[STRINGSZ], *p, *a;
256*fbadb1c4SDavid du Colombier
257*fbadb1c4SDavid du Colombier a = va_arg(fp->args, char*);
258*fbadb1c4SDavid du Colombier p = str;
259*fbadb1c4SDavid du Colombier for(i=0; i<sizeof(long); i++) {
260*fbadb1c4SDavid du Colombier c = a[i] & 0xff;
261*fbadb1c4SDavid du Colombier if(c >= 'a' && c <= 'z' ||
262*fbadb1c4SDavid du Colombier c >= 'A' && c <= 'Z' ||
263*fbadb1c4SDavid du Colombier c >= '0' && c <= '9' ||
264*fbadb1c4SDavid du Colombier c == ' ' || c == '%') {
265*fbadb1c4SDavid du Colombier *p++ = c;
266*fbadb1c4SDavid du Colombier continue;
267*fbadb1c4SDavid du Colombier }
268*fbadb1c4SDavid du Colombier *p++ = '\\';
269*fbadb1c4SDavid du Colombier switch(c) {
270*fbadb1c4SDavid du Colombier case 0:
271*fbadb1c4SDavid du Colombier *p++ = 'z';
272*fbadb1c4SDavid du Colombier continue;
273*fbadb1c4SDavid du Colombier case '\\':
274*fbadb1c4SDavid du Colombier case '"':
275*fbadb1c4SDavid du Colombier *p++ = c;
276*fbadb1c4SDavid du Colombier continue;
277*fbadb1c4SDavid du Colombier case '\n':
278*fbadb1c4SDavid du Colombier *p++ = 'n';
279*fbadb1c4SDavid du Colombier continue;
280*fbadb1c4SDavid du Colombier case '\t':
281*fbadb1c4SDavid du Colombier *p++ = 't';
282*fbadb1c4SDavid du Colombier continue;
283*fbadb1c4SDavid du Colombier }
284*fbadb1c4SDavid du Colombier *p++ = (c>>6) + '0';
285*fbadb1c4SDavid du Colombier *p++ = ((c>>3) & 7) + '0';
286*fbadb1c4SDavid du Colombier *p++ = (c & 7) + '0';
287*fbadb1c4SDavid du Colombier }
288*fbadb1c4SDavid du Colombier *p = 0;
289*fbadb1c4SDavid du Colombier return fmtstrcpy(fp, str);
290*fbadb1c4SDavid du Colombier }
291*fbadb1c4SDavid du Colombier
292*fbadb1c4SDavid du Colombier void
diag(char * fmt,...)293*fbadb1c4SDavid du Colombier diag(char *fmt, ...)
294*fbadb1c4SDavid du Colombier {
295*fbadb1c4SDavid du Colombier char buf[STRINGSZ], *tn;
296*fbadb1c4SDavid du Colombier va_list arg;
297*fbadb1c4SDavid du Colombier
298*fbadb1c4SDavid du Colombier tn = "??none??";
299*fbadb1c4SDavid du Colombier if(curtext != P && curtext->from.sym != S)
300*fbadb1c4SDavid du Colombier tn = curtext->from.sym->name;
301*fbadb1c4SDavid du Colombier va_start(arg, fmt);
302*fbadb1c4SDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg);
303*fbadb1c4SDavid du Colombier va_end(arg);
304*fbadb1c4SDavid du Colombier print("%s: %s\n", tn, buf);
305*fbadb1c4SDavid du Colombier
306*fbadb1c4SDavid du Colombier nerrors++;
307*fbadb1c4SDavid du Colombier if(nerrors > 10) {
308*fbadb1c4SDavid du Colombier print("too many errors\n");
309*fbadb1c4SDavid du Colombier errorexit();
310*fbadb1c4SDavid du Colombier }
311*fbadb1c4SDavid du Colombier }
312