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('C', Cconv);
97dd7cddfSDavid du Colombier fmtinstall('D', Dconv);
107dd7cddfSDavid du Colombier fmtinstall('P', Pconv);
117dd7cddfSDavid du Colombier fmtinstall('S', Sconv);
127dd7cddfSDavid du Colombier fmtinstall('N', Nconv);
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)22*9a747e4fSDavid 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
28*9a747e4fSDavid du Colombier p = va_arg(fp->args, Prog*);
297dd7cddfSDavid du Colombier curp = p;
307dd7cddfSDavid du Colombier a = p->as;
317dd7cddfSDavid du Colombier switch(a) {
327dd7cddfSDavid du Colombier default:
337dd7cddfSDavid du Colombier s = str;
347dd7cddfSDavid du Colombier s += sprint(s, "(%ld)", p->line);
357dd7cddfSDavid du Colombier if(p->reg == NREG)
367dd7cddfSDavid du Colombier sprint(s, " %A%C %D,%D",
377dd7cddfSDavid du Colombier a, p->scond, &p->from, &p->to);
387dd7cddfSDavid du Colombier else
397dd7cddfSDavid du Colombier if(p->from.type != D_FREG)
407dd7cddfSDavid du Colombier sprint(s, " %A%C %D,R%d,%D",
417dd7cddfSDavid du Colombier a, p->scond, &p->from, p->reg, &p->to);
427dd7cddfSDavid du Colombier else
437dd7cddfSDavid du Colombier sprint(s, " %A%C %D,F%d,%D",
447dd7cddfSDavid du Colombier a, p->scond, &p->from, p->reg, &p->to);
457dd7cddfSDavid du Colombier break;
467dd7cddfSDavid du Colombier
477dd7cddfSDavid du Colombier case ASWPW:
487dd7cddfSDavid du Colombier case ASWPBU:
497dd7cddfSDavid du Colombier sprint(str, "(%ld) %A%C R%d,%D,%D",
507dd7cddfSDavid du Colombier p->line, a, p->scond, p->reg, &p->from, &p->to);
517dd7cddfSDavid du Colombier break;
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier case ADATA:
547dd7cddfSDavid du Colombier case AINIT:
557dd7cddfSDavid du Colombier case ADYNT:
567dd7cddfSDavid du Colombier sprint(str, "(%ld) %A%C %D/%d,%D",
577dd7cddfSDavid du Colombier p->line, a, p->scond, &p->from, p->reg, &p->to);
587dd7cddfSDavid du Colombier break;
597dd7cddfSDavid du Colombier }
60*9a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
617dd7cddfSDavid du Colombier }
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier int
Aconv(Fmt * fp)64*9a747e4fSDavid du Colombier Aconv(Fmt *fp)
657dd7cddfSDavid du Colombier {
667dd7cddfSDavid du Colombier char *s;
677dd7cddfSDavid du Colombier int a;
687dd7cddfSDavid du Colombier
69*9a747e4fSDavid du Colombier a = va_arg(fp->args, int);
707dd7cddfSDavid du Colombier s = "???";
717dd7cddfSDavid du Colombier if(a >= AXXX && a < ALAST)
727dd7cddfSDavid du Colombier s = anames[a];
73*9a747e4fSDavid du Colombier return fmtstrcpy(fp, s);
747dd7cddfSDavid du Colombier }
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier char* strcond[16] =
777dd7cddfSDavid du Colombier {
787dd7cddfSDavid du Colombier ".EQ",
797dd7cddfSDavid du Colombier ".NE",
807dd7cddfSDavid du Colombier ".HS",
817dd7cddfSDavid du Colombier ".LO",
827dd7cddfSDavid du Colombier ".MI",
837dd7cddfSDavid du Colombier ".PL",
847dd7cddfSDavid du Colombier ".VS",
857dd7cddfSDavid du Colombier ".VC",
867dd7cddfSDavid du Colombier ".HI",
877dd7cddfSDavid du Colombier ".LS",
887dd7cddfSDavid du Colombier ".GE",
897dd7cddfSDavid du Colombier ".LT",
907dd7cddfSDavid du Colombier ".GT",
917dd7cddfSDavid du Colombier ".LE",
927dd7cddfSDavid du Colombier "",
937dd7cddfSDavid du Colombier ".NV"
947dd7cddfSDavid du Colombier };
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier int
Cconv(Fmt * fp)97*9a747e4fSDavid du Colombier Cconv(Fmt *fp)
987dd7cddfSDavid du Colombier {
997dd7cddfSDavid du Colombier char s[20];
1007dd7cddfSDavid du Colombier int c;
1017dd7cddfSDavid du Colombier
102*9a747e4fSDavid du Colombier c = va_arg(fp->args, int);
1037dd7cddfSDavid du Colombier strcpy(s, strcond[c & C_SCOND]);
1047dd7cddfSDavid du Colombier if(c & C_SBIT)
1057dd7cddfSDavid du Colombier strcat(s, ".S");
1067dd7cddfSDavid du Colombier if(c & C_PBIT)
1077dd7cddfSDavid du Colombier strcat(s, ".P");
1087dd7cddfSDavid du Colombier if(c & C_WBIT)
1097dd7cddfSDavid du Colombier strcat(s, ".W");
1107dd7cddfSDavid du Colombier if(c & C_UBIT) /* ambiguous with FBIT */
1117dd7cddfSDavid du Colombier strcat(s, ".U");
112*9a747e4fSDavid du Colombier return fmtstrcpy(fp, s);
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier int
Dconv(Fmt * fp)116*9a747e4fSDavid du Colombier Dconv(Fmt *fp)
1177dd7cddfSDavid du Colombier {
1187dd7cddfSDavid du Colombier char str[STRINGSZ];
1197dd7cddfSDavid du Colombier char *op;
1207dd7cddfSDavid du Colombier Adr *a;
1217dd7cddfSDavid du Colombier long v;
1227dd7cddfSDavid du Colombier
123*9a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
1247dd7cddfSDavid du Colombier switch(a->type) {
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier default:
1277dd7cddfSDavid du Colombier sprint(str, "GOK-type(%d)", a->type);
1287dd7cddfSDavid du Colombier break;
1297dd7cddfSDavid du Colombier
1307dd7cddfSDavid du Colombier case D_NONE:
1317dd7cddfSDavid du Colombier str[0] = 0;
1327dd7cddfSDavid du Colombier if(a->name != D_NONE || a->reg != NREG || a->sym != S)
1337dd7cddfSDavid du Colombier sprint(str, "%N(R%d)(NONE)", a, a->reg);
1347dd7cddfSDavid du Colombier break;
1357dd7cddfSDavid du Colombier
1367dd7cddfSDavid du Colombier case D_CONST:
1377dd7cddfSDavid du Colombier if(a->reg == NREG)
1387dd7cddfSDavid du Colombier sprint(str, "$%N", a);
1397dd7cddfSDavid du Colombier else
1407dd7cddfSDavid du Colombier sprint(str, "$%N(R%d)", a, a->reg);
1417dd7cddfSDavid du Colombier break;
1427dd7cddfSDavid du Colombier
1437dd7cddfSDavid du Colombier case D_SHIFT:
1447dd7cddfSDavid du Colombier v = a->offset;
1457dd7cddfSDavid du Colombier op = "<<>>->@>" + (((v>>5) & 3) << 1);
1467dd7cddfSDavid du Colombier if(v & (1<<4))
1477dd7cddfSDavid du Colombier sprint(str, "R%ld%c%cR%ld", v&15, op[0], op[1], (v>>8)&15);
1487dd7cddfSDavid du Colombier else
1497dd7cddfSDavid du Colombier sprint(str, "R%ld%c%c%ld", v&15, op[0], op[1], (v>>7)&31);
15059cc4ca5SDavid du Colombier if(a->reg != NREG)
15159cc4ca5SDavid du Colombier sprint(str+strlen(str), "(R%d)", a->reg);
1527dd7cddfSDavid du Colombier break;
1537dd7cddfSDavid du Colombier
1547dd7cddfSDavid du Colombier case D_OCONST:
1557dd7cddfSDavid du Colombier sprint(str, "$*$%N", a);
1567dd7cddfSDavid du Colombier if(a->reg != NREG)
1577dd7cddfSDavid du Colombier sprint(str, "%N(R%d)(CONST)", a, a->reg);
1587dd7cddfSDavid du Colombier break;
1597dd7cddfSDavid du Colombier
1607dd7cddfSDavid du Colombier case D_OREG:
1617dd7cddfSDavid du Colombier if(a->reg != NREG)
1627dd7cddfSDavid du Colombier sprint(str, "%N(R%d)", a, a->reg);
1637dd7cddfSDavid du Colombier else
1647dd7cddfSDavid du Colombier sprint(str, "%N", a);
1657dd7cddfSDavid du Colombier break;
1667dd7cddfSDavid du Colombier
1677dd7cddfSDavid du Colombier case D_REG:
1687dd7cddfSDavid du Colombier sprint(str, "R%d", a->reg);
1697dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1707dd7cddfSDavid du Colombier sprint(str, "%N(R%d)(REG)", a, a->reg);
1717dd7cddfSDavid du Colombier break;
1727dd7cddfSDavid du Colombier
17359cc4ca5SDavid du Colombier case D_REGREG:
17459cc4ca5SDavid du Colombier sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
17559cc4ca5SDavid du Colombier if(a->name != D_NONE || a->sym != S)
17659cc4ca5SDavid du Colombier sprint(str, "%N(R%d)(REG)", a, a->reg);
17759cc4ca5SDavid du Colombier break;
17859cc4ca5SDavid du Colombier
1797dd7cddfSDavid du Colombier case D_FREG:
1807dd7cddfSDavid du Colombier sprint(str, "F%d", a->reg);
1817dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1827dd7cddfSDavid du Colombier sprint(str, "%N(R%d)(REG)", a, a->reg);
1837dd7cddfSDavid du Colombier break;
1847dd7cddfSDavid du Colombier
1857dd7cddfSDavid du Colombier case D_PSR:
1867dd7cddfSDavid du Colombier switch(a->reg) {
1877dd7cddfSDavid du Colombier case 0:
1887dd7cddfSDavid du Colombier sprint(str, "CPSR");
1897dd7cddfSDavid du Colombier break;
1907dd7cddfSDavid du Colombier case 1:
1917dd7cddfSDavid du Colombier sprint(str, "SPSR");
1927dd7cddfSDavid du Colombier break;
1937dd7cddfSDavid du Colombier default:
1947dd7cddfSDavid du Colombier sprint(str, "PSR%d", a->reg);
1957dd7cddfSDavid du Colombier break;
1967dd7cddfSDavid du Colombier }
1977dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1987dd7cddfSDavid du Colombier sprint(str, "%N(PSR%d)(REG)", a, a->reg);
1997dd7cddfSDavid du Colombier break;
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier case D_FPCR:
2027dd7cddfSDavid du Colombier switch(a->reg){
2037dd7cddfSDavid du Colombier case 0:
2047dd7cddfSDavid du Colombier sprint(str, "FPSR");
2057dd7cddfSDavid du Colombier break;
2067dd7cddfSDavid du Colombier case 1:
2077dd7cddfSDavid du Colombier sprint(str, "FPCR");
2087dd7cddfSDavid du Colombier break;
2097dd7cddfSDavid du Colombier default:
2107dd7cddfSDavid du Colombier sprint(str, "FCR%d", a->reg);
2117dd7cddfSDavid du Colombier break;
2127dd7cddfSDavid du Colombier }
2137dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
2147dd7cddfSDavid du Colombier sprint(str, "%N(FCR%d)(REG)", a, a->reg);
2157dd7cddfSDavid du Colombier
2167dd7cddfSDavid du Colombier break;
2177dd7cddfSDavid du Colombier
2187dd7cddfSDavid du Colombier case D_BRANCH: /* botch */
2197dd7cddfSDavid du Colombier if(curp->cond != P) {
2207dd7cddfSDavid du Colombier v = curp->cond->pc;
2217dd7cddfSDavid du Colombier if(a->sym != S)
2227dd7cddfSDavid du Colombier sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v);
2237dd7cddfSDavid du Colombier else
2247dd7cddfSDavid du Colombier sprint(str, "%.5lux(BRANCH)", v);
2257dd7cddfSDavid du Colombier } else
2267dd7cddfSDavid du Colombier if(a->sym != S)
2277dd7cddfSDavid du Colombier sprint(str, "%s+%ld(APC)", a->sym->name, a->offset);
2287dd7cddfSDavid du Colombier else
2297dd7cddfSDavid du Colombier sprint(str, "%ld(APC)", a->offset);
2307dd7cddfSDavid du Colombier break;
2317dd7cddfSDavid du Colombier
2327dd7cddfSDavid du Colombier case D_FCONST:
2337dd7cddfSDavid du Colombier sprint(str, "$%e", ieeedtod(a->ieee));
2347dd7cddfSDavid du Colombier break;
2357dd7cddfSDavid du Colombier
2367dd7cddfSDavid du Colombier case D_SCONST:
2377dd7cddfSDavid du Colombier sprint(str, "$\"%S\"", a->sval);
2387dd7cddfSDavid du Colombier break;
2397dd7cddfSDavid du Colombier }
240*9a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier
2437dd7cddfSDavid du Colombier int
Nconv(Fmt * fp)244*9a747e4fSDavid du Colombier Nconv(Fmt *fp)
2457dd7cddfSDavid du Colombier {
2467dd7cddfSDavid du Colombier char str[STRINGSZ];
2477dd7cddfSDavid du Colombier Adr *a;
2487dd7cddfSDavid du Colombier Sym *s;
2497dd7cddfSDavid du Colombier
250*9a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
2517dd7cddfSDavid du Colombier s = a->sym;
2527dd7cddfSDavid du Colombier switch(a->name) {
2537dd7cddfSDavid du Colombier default:
2547dd7cddfSDavid du Colombier sprint(str, "GOK-name(%d)", a->name);
2557dd7cddfSDavid du Colombier break;
2567dd7cddfSDavid du Colombier
2577dd7cddfSDavid du Colombier case D_NONE:
2587dd7cddfSDavid du Colombier sprint(str, "%ld", a->offset);
2597dd7cddfSDavid du Colombier break;
2607dd7cddfSDavid du Colombier
2617dd7cddfSDavid du Colombier case D_EXTERN:
2627dd7cddfSDavid du Colombier if(s == S)
2637dd7cddfSDavid du Colombier sprint(str, "%ld(SB)", a->offset);
2647dd7cddfSDavid du Colombier else
2657dd7cddfSDavid du Colombier sprint(str, "%s+%ld(SB)", s->name, a->offset);
2667dd7cddfSDavid du Colombier break;
2677dd7cddfSDavid du Colombier
2687dd7cddfSDavid du Colombier case D_STATIC:
2697dd7cddfSDavid du Colombier if(s == S)
2707dd7cddfSDavid du Colombier sprint(str, "<>+%ld(SB)", a->offset);
2717dd7cddfSDavid du Colombier else
2727dd7cddfSDavid du Colombier sprint(str, "%s<>+%ld(SB)", s->name, a->offset);
2737dd7cddfSDavid du Colombier break;
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier case D_AUTO:
2767dd7cddfSDavid du Colombier if(s == S)
2777dd7cddfSDavid du Colombier sprint(str, "%ld(SP)", a->offset);
2787dd7cddfSDavid du Colombier else
2797dd7cddfSDavid du Colombier sprint(str, "%s-%ld(SP)", s->name, -a->offset);
2807dd7cddfSDavid du Colombier break;
2817dd7cddfSDavid du Colombier
2827dd7cddfSDavid du Colombier case D_PARAM:
2837dd7cddfSDavid du Colombier if(s == S)
2847dd7cddfSDavid du Colombier sprint(str, "%ld(FP)", a->offset);
2857dd7cddfSDavid du Colombier else
2867dd7cddfSDavid du Colombier sprint(str, "%s+%ld(FP)", s->name, a->offset);
2877dd7cddfSDavid du Colombier break;
2887dd7cddfSDavid du Colombier }
289*9a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
2907dd7cddfSDavid du Colombier }
2917dd7cddfSDavid du Colombier
2927dd7cddfSDavid du Colombier int
Sconv(Fmt * fp)293*9a747e4fSDavid du Colombier Sconv(Fmt *fp)
2947dd7cddfSDavid du Colombier {
2957dd7cddfSDavid du Colombier int i, c;
2967dd7cddfSDavid du Colombier char str[STRINGSZ], *p, *a;
2977dd7cddfSDavid du Colombier
298*9a747e4fSDavid du Colombier a = va_arg(fp->args, char*);
2997dd7cddfSDavid du Colombier p = str;
3007dd7cddfSDavid du Colombier for(i=0; i<sizeof(long); i++) {
3017dd7cddfSDavid du Colombier c = a[i] & 0xff;
3027dd7cddfSDavid du Colombier if(c >= 'a' && c <= 'z' ||
3037dd7cddfSDavid du Colombier c >= 'A' && c <= 'Z' ||
3047dd7cddfSDavid du Colombier c >= '0' && c <= '9' ||
3057dd7cddfSDavid du Colombier c == ' ' || c == '%') {
3067dd7cddfSDavid du Colombier *p++ = c;
3077dd7cddfSDavid du Colombier continue;
3087dd7cddfSDavid du Colombier }
3097dd7cddfSDavid du Colombier *p++ = '\\';
3107dd7cddfSDavid du Colombier switch(c) {
3117dd7cddfSDavid du Colombier case 0:
3127dd7cddfSDavid du Colombier *p++ = 'z';
3137dd7cddfSDavid du Colombier continue;
3147dd7cddfSDavid du Colombier case '\\':
3157dd7cddfSDavid du Colombier case '"':
3167dd7cddfSDavid du Colombier *p++ = c;
3177dd7cddfSDavid du Colombier continue;
3187dd7cddfSDavid du Colombier case '\n':
3197dd7cddfSDavid du Colombier *p++ = 'n';
3207dd7cddfSDavid du Colombier continue;
3217dd7cddfSDavid du Colombier case '\t':
3227dd7cddfSDavid du Colombier *p++ = 't';
3237dd7cddfSDavid du Colombier continue;
3247dd7cddfSDavid du Colombier }
3257dd7cddfSDavid du Colombier *p++ = (c>>6) + '0';
3267dd7cddfSDavid du Colombier *p++ = ((c>>3) & 7) + '0';
3277dd7cddfSDavid du Colombier *p++ = (c & 7) + '0';
3287dd7cddfSDavid du Colombier }
3297dd7cddfSDavid du Colombier *p = 0;
330*9a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
3317dd7cddfSDavid du Colombier }
3327dd7cddfSDavid du Colombier
3337dd7cddfSDavid du Colombier void
diag(char * fmt,...)3347dd7cddfSDavid du Colombier diag(char *fmt, ...)
3357dd7cddfSDavid du Colombier {
3367dd7cddfSDavid du Colombier char buf[STRINGSZ], *tn;
3377dd7cddfSDavid du Colombier va_list arg;
3387dd7cddfSDavid du Colombier
3397dd7cddfSDavid du Colombier tn = "??none??";
3407dd7cddfSDavid du Colombier if(curtext != P && curtext->from.sym != S)
3417dd7cddfSDavid du Colombier tn = curtext->from.sym->name;
3427dd7cddfSDavid du Colombier va_start(arg, fmt);
343*9a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg);
3447dd7cddfSDavid du Colombier va_end(arg);
3457dd7cddfSDavid du Colombier print("%s: %s\n", tn, buf);
3467dd7cddfSDavid du Colombier
3477dd7cddfSDavid du Colombier nerrors++;
3487dd7cddfSDavid du Colombier if(nerrors > 10) {
3497dd7cddfSDavid du Colombier print("too many errors\n");
3507dd7cddfSDavid du Colombier errorexit();
3517dd7cddfSDavid du Colombier }
3527dd7cddfSDavid du Colombier }
353