17dd7cddfSDavid du Colombier #include "l.h"
27dd7cddfSDavid du Colombier
37dd7cddfSDavid du Colombier void
listinit(void)47dd7cddfSDavid du Colombier listinit(void)
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier fmtinstall('A', Aconv);
87dd7cddfSDavid du Colombier fmtinstall('D', Dconv);
97dd7cddfSDavid du Colombier fmtinstall('P', Pconv);
107dd7cddfSDavid du Colombier fmtinstall('S', Sconv);
117dd7cddfSDavid du Colombier fmtinstall('N', Nconv);
127dd7cddfSDavid du Colombier fmtinstall('R', Rconv);
137dd7cddfSDavid du Colombier }
147dd7cddfSDavid du Colombier
157dd7cddfSDavid du Colombier void
prasm(Prog * p)167dd7cddfSDavid du Colombier prasm(Prog *p)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier print("%P\n", p);
197dd7cddfSDavid du Colombier }
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier int
Pconv(Fmt * fp)229a747e4fSDavid du Colombier Pconv(Fmt *fp)
237dd7cddfSDavid du Colombier {
247dd7cddfSDavid du Colombier char str[STRINGSZ], *s;
257dd7cddfSDavid du Colombier Prog *p;
267dd7cddfSDavid du Colombier int a;
277dd7cddfSDavid du Colombier
289a747e4fSDavid du Colombier p = va_arg(fp->args, Prog*);
297dd7cddfSDavid du Colombier curp = p;
307dd7cddfSDavid du Colombier a = p->as;
317dd7cddfSDavid du Colombier if(a == ADATA || a == AINIT || a == ADYNT)
327dd7cddfSDavid du Colombier sprint(str, "(%d) %A %D/%d,%D", p->line, a, &p->from, p->reg, &p->to);
337dd7cddfSDavid du Colombier else {
347dd7cddfSDavid du Colombier s = str;
357dd7cddfSDavid du Colombier if(p->mark & NOSCHED)
367dd7cddfSDavid du Colombier s += sprint(s, "*");
377dd7cddfSDavid du Colombier if(p->reg == NREG && p->from3.type == D_NONE)
387dd7cddfSDavid du Colombier sprint(s, "(%d) %A %D,%D", p->line, a, &p->from, &p->to);
397dd7cddfSDavid du Colombier else
407dd7cddfSDavid du Colombier if(a != ATEXT && p->from.type == D_OREG) {
417dd7cddfSDavid du Colombier sprint(s, "(%d) %A %ld(R%d+R%d),%D", p->line, a,
427dd7cddfSDavid du Colombier p->from.offset, p->from.reg, p->reg, &p->to);
437dd7cddfSDavid du Colombier } else
447dd7cddfSDavid du Colombier if(p->to.type == D_OREG) {
457dd7cddfSDavid du Colombier sprint(s, "(%d) %A %D,%ld(R%d+R%d)", p->line, a,
467dd7cddfSDavid du Colombier &p->from, p->to.offset, p->to.reg, p->reg);
477dd7cddfSDavid du Colombier } else {
487dd7cddfSDavid du Colombier s += sprint(s, "(%d) %A %D", p->line, a, &p->from);
497dd7cddfSDavid du Colombier if(p->reg != NREG)
507dd7cddfSDavid du Colombier s += sprint(s, ",%c%d", p->from.type==D_FREG?'F':'R', p->reg);
517dd7cddfSDavid du Colombier if(p->from3.type != D_NONE)
527dd7cddfSDavid du Colombier s += sprint(s, ",%D", &p->from3);
537dd7cddfSDavid du Colombier sprint(s, ",%D", &p->to);
547dd7cddfSDavid du Colombier }
557dd7cddfSDavid du Colombier }
569a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
577dd7cddfSDavid du Colombier }
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier int
Aconv(Fmt * fp)609a747e4fSDavid du Colombier Aconv(Fmt *fp)
617dd7cddfSDavid du Colombier {
627dd7cddfSDavid du Colombier char *s;
637dd7cddfSDavid du Colombier int a;
647dd7cddfSDavid du Colombier
659a747e4fSDavid du Colombier a = va_arg(fp->args, int);
667dd7cddfSDavid du Colombier s = "???";
673f193c01SDavid du Colombier if(a >= AXXX && a < ALAST)
687dd7cddfSDavid du Colombier s = anames[a];
699a747e4fSDavid du Colombier return fmtstrcpy(fp, s);
707dd7cddfSDavid du Colombier }
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier int
Dconv(Fmt * fp)739a747e4fSDavid du Colombier Dconv(Fmt *fp)
747dd7cddfSDavid du Colombier {
757dd7cddfSDavid du Colombier char str[STRINGSZ];
767dd7cddfSDavid du Colombier Adr *a;
777dd7cddfSDavid du Colombier long v;
787dd7cddfSDavid du Colombier
799a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
807dd7cddfSDavid du Colombier switch(a->type) {
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier default:
837dd7cddfSDavid du Colombier sprint(str, "GOK-type(%d)", a->type);
847dd7cddfSDavid du Colombier break;
857dd7cddfSDavid du Colombier
867dd7cddfSDavid du Colombier case D_NONE:
877dd7cddfSDavid du Colombier str[0] = 0;
887dd7cddfSDavid du Colombier if(a->name != D_NONE || a->reg != NREG || a->sym != S)
897dd7cddfSDavid du Colombier sprint(str, "%N(R%d)(NONE)", a, a->reg);
907dd7cddfSDavid du Colombier break;
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier case D_CONST:
937dd7cddfSDavid du Colombier if(a->reg != NREG)
947dd7cddfSDavid du Colombier sprint(str, "$%N(R%d)", a, a->reg);
957dd7cddfSDavid du Colombier else
967dd7cddfSDavid du Colombier sprint(str, "$%N", a);
977dd7cddfSDavid du Colombier break;
987dd7cddfSDavid du Colombier
997dd7cddfSDavid du Colombier case D_OREG:
1007dd7cddfSDavid du Colombier if(a->reg != NREG)
1017dd7cddfSDavid du Colombier sprint(str, "%N(R%d)", a, a->reg);
1027dd7cddfSDavid du Colombier else
1037dd7cddfSDavid du Colombier sprint(str, "%N", a);
1047dd7cddfSDavid du Colombier break;
1057dd7cddfSDavid du Colombier
1067dd7cddfSDavid du Colombier case D_REG:
1077dd7cddfSDavid du Colombier sprint(str, "R%d", a->reg);
1087dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1097dd7cddfSDavid du Colombier sprint(str, "%N(R%d)(REG)", a, a->reg);
1107dd7cddfSDavid du Colombier break;
1117dd7cddfSDavid du Colombier
1127dd7cddfSDavid du Colombier case D_FREG:
1137dd7cddfSDavid du Colombier sprint(str, "F%d", a->reg);
1147dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1157dd7cddfSDavid du Colombier sprint(str, "%N(F%d)(REG)", a, a->reg);
1167dd7cddfSDavid du Colombier break;
1177dd7cddfSDavid du Colombier
1187dd7cddfSDavid du Colombier case D_CREG:
1197dd7cddfSDavid du Colombier if(a->reg == NREG)
1207dd7cddfSDavid du Colombier strcpy(str, "CR");
1217dd7cddfSDavid du Colombier else
1227dd7cddfSDavid du Colombier sprint(str, "CR%d", a->reg);
1237dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1247dd7cddfSDavid du Colombier sprint(str, "%N(C%d)(REG)", a, a->reg);
1257dd7cddfSDavid du Colombier break;
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier case D_SPR:
1287dd7cddfSDavid du Colombier if(a->name == D_NONE && a->sym == S) {
1297dd7cddfSDavid du Colombier switch(a->offset) {
1307dd7cddfSDavid du Colombier case D_XER: sprint(str, "XER"); break;
1317dd7cddfSDavid du Colombier case D_LR: sprint(str, "LR"); break;
1327dd7cddfSDavid du Colombier case D_CTR: sprint(str, "CTR"); break;
1337dd7cddfSDavid du Colombier default: sprint(str, "SPR(%ld)", a->offset); break;
1347dd7cddfSDavid du Colombier }
1357dd7cddfSDavid du Colombier break;
1367dd7cddfSDavid du Colombier }
1377dd7cddfSDavid du Colombier sprint(str, "SPR-GOK(%d)", a->reg);
1387dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1397dd7cddfSDavid du Colombier sprint(str, "%N(SPR-GOK%d)(REG)", a, a->reg);
1407dd7cddfSDavid du Colombier break;
1417dd7cddfSDavid du Colombier
142375daca8SDavid du Colombier case D_DCR:
143375daca8SDavid du Colombier if(a->name == D_NONE && a->sym == S) {
144*6891d857SDavid du Colombier if(a->reg == NREG)
145375daca8SDavid du Colombier sprint(str, "DCR(%ld)", a->offset);
146*6891d857SDavid du Colombier else
147*6891d857SDavid du Colombier sprint(str, "DCR(R%d)", a->reg);
148375daca8SDavid du Colombier break;
149375daca8SDavid du Colombier }
150375daca8SDavid du Colombier sprint(str, "DCR-GOK(%d)", a->reg);
151375daca8SDavid du Colombier if(a->name != D_NONE || a->sym != S)
152375daca8SDavid du Colombier sprint(str, "%N(DCR-GOK%d)(REG)", a, a->reg);
153375daca8SDavid du Colombier break;
154375daca8SDavid du Colombier
1557dd7cddfSDavid du Colombier case D_OPT:
1567dd7cddfSDavid du Colombier sprint(str, "OPT(%d)", a->reg);
1577dd7cddfSDavid du Colombier break;
1587dd7cddfSDavid du Colombier
1597dd7cddfSDavid du Colombier case D_FPSCR:
1607dd7cddfSDavid du Colombier if(a->reg == NREG)
1617dd7cddfSDavid du Colombier strcpy(str, "FPSCR");
1627dd7cddfSDavid du Colombier else
1637dd7cddfSDavid du Colombier sprint(str, "FPSCR(%d)", a->reg);
1647dd7cddfSDavid du Colombier break;
1657dd7cddfSDavid du Colombier
1667dd7cddfSDavid du Colombier case D_MSR:
1677dd7cddfSDavid du Colombier sprint(str, "MSR");
1687dd7cddfSDavid du Colombier break;
1697dd7cddfSDavid du Colombier
1707dd7cddfSDavid du Colombier case D_SREG:
1717dd7cddfSDavid du Colombier sprint(str, "SREG(%d)", a->reg);
1727dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1737dd7cddfSDavid du Colombier sprint(str, "%N(SREG%d)(REG)", a, a->reg);
1747dd7cddfSDavid du Colombier break;
1757dd7cddfSDavid du Colombier
1767dd7cddfSDavid du Colombier case D_BRANCH:
1777dd7cddfSDavid du Colombier if(curp->cond != P) {
1787dd7cddfSDavid du Colombier v = curp->cond->pc;
1797dd7cddfSDavid du Colombier if(v >= INITTEXT)
1807dd7cddfSDavid du Colombier v -= INITTEXT-HEADR;
1817dd7cddfSDavid du Colombier if(a->sym != S)
1827dd7cddfSDavid du Colombier sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
1837dd7cddfSDavid du Colombier else
1847dd7cddfSDavid du Colombier sprint(str, "%.5lux(BRANCH)", v);
1857dd7cddfSDavid du Colombier } else
1867dd7cddfSDavid du Colombier if(a->sym != S)
1877dd7cddfSDavid du Colombier sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
1887dd7cddfSDavid du Colombier else
1897dd7cddfSDavid du Colombier sprint(str, "%ld(APC)", a->offset);
1907dd7cddfSDavid du Colombier break;
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier case D_FCONST:
1937dd7cddfSDavid du Colombier sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l);
1947dd7cddfSDavid du Colombier break;
1957dd7cddfSDavid du Colombier
1967dd7cddfSDavid du Colombier case D_SCONST:
1977dd7cddfSDavid du Colombier sprint(str, "$\"%S\"", a->sval);
1987dd7cddfSDavid du Colombier break;
1997dd7cddfSDavid du Colombier }
2009a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
2017dd7cddfSDavid du Colombier }
2027dd7cddfSDavid du Colombier
2037dd7cddfSDavid du Colombier int
Nconv(Fmt * fp)2049a747e4fSDavid du Colombier Nconv(Fmt *fp)
2057dd7cddfSDavid du Colombier {
2067dd7cddfSDavid du Colombier char str[STRINGSZ];
2077dd7cddfSDavid du Colombier Adr *a;
2087dd7cddfSDavid du Colombier Sym *s;
2097dd7cddfSDavid du Colombier
2109a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
2117dd7cddfSDavid du Colombier s = a->sym;
2127dd7cddfSDavid du Colombier if(s == S) {
2137dd7cddfSDavid du Colombier sprint(str, "%ld", a->offset);
2147dd7cddfSDavid du Colombier goto out;
2157dd7cddfSDavid du Colombier }
2167dd7cddfSDavid du Colombier switch(a->name) {
2177dd7cddfSDavid du Colombier default:
2187dd7cddfSDavid du Colombier sprint(str, "GOK-name(%d)", a->name);
2197dd7cddfSDavid du Colombier break;
2207dd7cddfSDavid du Colombier
2217dd7cddfSDavid du Colombier case D_EXTERN:
2227dd7cddfSDavid du Colombier sprint(str, "%s+%ld(SB)", s->name, a->offset);
2237dd7cddfSDavid du Colombier break;
2247dd7cddfSDavid du Colombier
2257dd7cddfSDavid du Colombier case D_STATIC:
2267dd7cddfSDavid du Colombier sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
2277dd7cddfSDavid du Colombier break;
2287dd7cddfSDavid du Colombier
2297dd7cddfSDavid du Colombier case D_AUTO:
2307dd7cddfSDavid du Colombier sprint(str, "%s-%ld(SP)", s->name, -a->offset);
2317dd7cddfSDavid du Colombier break;
2327dd7cddfSDavid du Colombier
2337dd7cddfSDavid du Colombier case D_PARAM:
2347dd7cddfSDavid du Colombier sprint(str, "%s+%ld(FP)", s->name, a->offset);
2357dd7cddfSDavid du Colombier break;
2367dd7cddfSDavid du Colombier }
2377dd7cddfSDavid du Colombier out:
2389a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
2397dd7cddfSDavid du Colombier }
2407dd7cddfSDavid du Colombier
2417dd7cddfSDavid du Colombier int
Rconv(Fmt * fp)2429a747e4fSDavid du Colombier Rconv(Fmt *fp)
2437dd7cddfSDavid du Colombier {
2447dd7cddfSDavid du Colombier char *s;
2457dd7cddfSDavid du Colombier int a;
2467dd7cddfSDavid du Colombier
2479a747e4fSDavid du Colombier a = va_arg(fp->args, int);
2487dd7cddfSDavid du Colombier s = "C_??";
2497dd7cddfSDavid du Colombier if(a >= C_NONE && a <= C_NCLASS)
2507dd7cddfSDavid du Colombier s = cnames[a];
2519a747e4fSDavid du Colombier return fmtstrcpy(fp, s);
2527dd7cddfSDavid du Colombier }
2537dd7cddfSDavid du Colombier
2547dd7cddfSDavid du Colombier int
Sconv(Fmt * fp)2559a747e4fSDavid du Colombier Sconv(Fmt *fp)
2567dd7cddfSDavid du Colombier {
2577dd7cddfSDavid du Colombier int i, c;
2587dd7cddfSDavid du Colombier char str[STRINGSZ], *p, *a;
2597dd7cddfSDavid du Colombier
2609a747e4fSDavid du Colombier a = va_arg(fp->args, char*);
2617dd7cddfSDavid du Colombier p = str;
2627dd7cddfSDavid du Colombier for(i=0; i<sizeof(long); i++) {
2637dd7cddfSDavid du Colombier c = a[i] & 0xff;
2647dd7cddfSDavid du Colombier if(c >= 'a' && c <= 'z' ||
2657dd7cddfSDavid du Colombier c >= 'A' && c <= 'Z' ||
2667dd7cddfSDavid du Colombier c >= '0' && c <= '9' ||
2677dd7cddfSDavid du Colombier c == ' ' || c == '%') {
2687dd7cddfSDavid du Colombier *p++ = c;
2697dd7cddfSDavid du Colombier continue;
2707dd7cddfSDavid du Colombier }
2717dd7cddfSDavid du Colombier *p++ = '\\';
2727dd7cddfSDavid du Colombier switch(c) {
2737dd7cddfSDavid du Colombier case 0:
2747dd7cddfSDavid du Colombier *p++ = 'z';
2757dd7cddfSDavid du Colombier continue;
2767dd7cddfSDavid du Colombier case '\\':
2777dd7cddfSDavid du Colombier case '"':
2787dd7cddfSDavid du Colombier *p++ = c;
2797dd7cddfSDavid du Colombier continue;
2807dd7cddfSDavid du Colombier case '\n':
2817dd7cddfSDavid du Colombier *p++ = 'n';
2827dd7cddfSDavid du Colombier continue;
2837dd7cddfSDavid du Colombier case '\t':
2847dd7cddfSDavid du Colombier *p++ = 't';
2857dd7cddfSDavid du Colombier continue;
2867dd7cddfSDavid du Colombier }
2877dd7cddfSDavid du Colombier *p++ = (c>>6) + '0';
2887dd7cddfSDavid du Colombier *p++ = ((c>>3) & 7) + '0';
2897dd7cddfSDavid du Colombier *p++ = (c & 7) + '0';
2907dd7cddfSDavid du Colombier }
2917dd7cddfSDavid du Colombier *p = 0;
2929a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
2937dd7cddfSDavid du Colombier }
2947dd7cddfSDavid du Colombier
2957dd7cddfSDavid du Colombier void
diag(char * fmt,...)2967dd7cddfSDavid du Colombier diag(char *fmt, ...)
2977dd7cddfSDavid du Colombier {
2987dd7cddfSDavid du Colombier char buf[STRINGSZ], *tn;
2997dd7cddfSDavid du Colombier va_list arg;
3007dd7cddfSDavid du Colombier
3017dd7cddfSDavid du Colombier tn = "??none??";
3027dd7cddfSDavid du Colombier if(curtext != P && curtext->from.sym != S)
3037dd7cddfSDavid du Colombier tn = curtext->from.sym->name;
3047dd7cddfSDavid du Colombier va_start(arg, fmt);
3059a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg);
3067dd7cddfSDavid du Colombier va_end(arg);
3077dd7cddfSDavid du Colombier print("%s: %s\n", tn, buf);
3087dd7cddfSDavid du Colombier
3097dd7cddfSDavid du Colombier nerrors++;
3107dd7cddfSDavid du Colombier if(nerrors > 10) {
3117dd7cddfSDavid du Colombier print("too many errors\n");
3127dd7cddfSDavid du Colombier errorexit();
3137dd7cddfSDavid du Colombier }
3147dd7cddfSDavid du Colombier }
315