17dd7cddfSDavid du Colombier #define EXTERN
27dd7cddfSDavid du Colombier #include "gc.h"
37dd7cddfSDavid du Colombier
47dd7cddfSDavid du Colombier void
listinit(void)57dd7cddfSDavid du Colombier listinit(void)
67dd7cddfSDavid du Colombier {
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier fmtinstall('A', Aconv);
97dd7cddfSDavid du Colombier fmtinstall('P', Pconv);
107dd7cddfSDavid du Colombier fmtinstall('S', Sconv);
117dd7cddfSDavid du Colombier fmtinstall('N', Nconv);
127dd7cddfSDavid du Colombier fmtinstall('B', Bconv);
137dd7cddfSDavid du Colombier fmtinstall('D', Dconv);
1459cc4ca5SDavid du Colombier fmtinstall('R', Rconv);
157dd7cddfSDavid du Colombier }
167dd7cddfSDavid du Colombier
177dd7cddfSDavid du Colombier int
Bconv(Fmt * fp)189a747e4fSDavid du Colombier Bconv(Fmt *fp)
197dd7cddfSDavid du Colombier {
207dd7cddfSDavid du Colombier char str[STRINGSZ], ss[STRINGSZ], *s;
217dd7cddfSDavid du Colombier Bits bits;
227dd7cddfSDavid du Colombier int i;
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier str[0] = 0;
259a747e4fSDavid du Colombier bits = va_arg(fp->args, Bits);
267dd7cddfSDavid du Colombier while(bany(&bits)) {
277dd7cddfSDavid du Colombier i = bnum(bits);
287dd7cddfSDavid du Colombier if(str[0])
297dd7cddfSDavid du Colombier strcat(str, " ");
307dd7cddfSDavid du Colombier if(var[i].sym == S) {
310591a7c1SDavid du Colombier snprint(ss, sizeof(ss), "$%ld", var[i].offset);
327dd7cddfSDavid du Colombier s = ss;
337dd7cddfSDavid du Colombier } else
347dd7cddfSDavid du Colombier s = var[i].sym->name;
357dd7cddfSDavid du Colombier if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
367dd7cddfSDavid du Colombier break;
377dd7cddfSDavid du Colombier strcat(str, s);
387dd7cddfSDavid du Colombier bits.b[i/32] &= ~(1L << (i%32));
397dd7cddfSDavid du Colombier }
409a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
417dd7cddfSDavid du Colombier }
427dd7cddfSDavid du Colombier
437dd7cddfSDavid du Colombier char *extra [] = {
447dd7cddfSDavid du Colombier ".EQ", ".NE", ".CS", ".CC",
457dd7cddfSDavid du Colombier ".MI", ".PL", ".VS", ".VC",
467dd7cddfSDavid du Colombier ".HI", ".LS", ".GE", ".LT",
477dd7cddfSDavid du Colombier ".GT", ".LE", "", ".NV",
487dd7cddfSDavid du Colombier };
497dd7cddfSDavid du Colombier
507dd7cddfSDavid du Colombier int
Pconv(Fmt * fp)519a747e4fSDavid du Colombier Pconv(Fmt *fp)
527dd7cddfSDavid du Colombier {
5359cc4ca5SDavid du Colombier char str[STRINGSZ], sc[20];
547dd7cddfSDavid du Colombier Prog *p;
557dd7cddfSDavid du Colombier int a, s;
567dd7cddfSDavid du Colombier
579a747e4fSDavid du Colombier p = va_arg(fp->args, Prog*);
587dd7cddfSDavid du Colombier a = p->as;
5959cc4ca5SDavid du Colombier s = p->scond;
6059cc4ca5SDavid du Colombier strcpy(sc, extra[s & C_SCOND]);
6159cc4ca5SDavid du Colombier if(s & C_SBIT)
6259cc4ca5SDavid du Colombier strcat(sc, ".S");
6359cc4ca5SDavid du Colombier if(s & C_PBIT)
6459cc4ca5SDavid du Colombier strcat(sc, ".P");
6559cc4ca5SDavid du Colombier if(s & C_WBIT)
6659cc4ca5SDavid du Colombier strcat(sc, ".W");
6759cc4ca5SDavid du Colombier if(s & C_UBIT) /* ambiguous with FBIT */
6859cc4ca5SDavid du Colombier strcat(sc, ".U");
6959cc4ca5SDavid du Colombier if(a == AMOVM) {
7059cc4ca5SDavid du Colombier if(p->from.type == D_CONST)
710591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A%s %R,%D", a, sc, &p->from, &p->to);
7259cc4ca5SDavid du Colombier else
7359cc4ca5SDavid du Colombier if(p->to.type == D_CONST)
740591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A%s %D,%R", a, sc, &p->from, &p->to);
7559cc4ca5SDavid du Colombier else
760591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A%s %D,%D", a, sc, &p->from, &p->to);
7759cc4ca5SDavid du Colombier } else
787dd7cddfSDavid du Colombier if(a == ADATA)
790591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
807dd7cddfSDavid du Colombier else
81e288d156SDavid du Colombier if(p->as == ATEXT)
820591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
83e288d156SDavid du Colombier else
847dd7cddfSDavid du Colombier if(p->reg == NREG)
850591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A%s %D,%D", a, sc, &p->from, &p->to);
867dd7cddfSDavid du Colombier else
87*40d01547SDavid du Colombier if(p->reghi != NREG)
88*40d01547SDavid du Colombier snprint(str, sizeof(str), " %A%s %D,R%d,%D,R%d", a, sc, &p->from, p->reg, &p->to, p->reghi);
89*40d01547SDavid du Colombier else
90*40d01547SDavid du Colombier if(p->from.type != D_FREG && p->from.type != D_SFREG && p->from.type != D_FCONST)
910591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
927dd7cddfSDavid du Colombier else
930591a7c1SDavid du Colombier snprint(str, sizeof(str), " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
949a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier int
Aconv(Fmt * fp)989a747e4fSDavid du Colombier Aconv(Fmt *fp)
997dd7cddfSDavid du Colombier {
1007dd7cddfSDavid du Colombier char *s;
1017dd7cddfSDavid du Colombier int a;
1027dd7cddfSDavid du Colombier
1039a747e4fSDavid du Colombier a = va_arg(fp->args, int);
1047dd7cddfSDavid du Colombier s = "???";
1057dd7cddfSDavid du Colombier if(a >= AXXX && a < ALAST)
1067dd7cddfSDavid du Colombier s = anames[a];
1079a747e4fSDavid du Colombier return fmtstrcpy(fp, s);
1087dd7cddfSDavid du Colombier }
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier int
Dconv(Fmt * fp)1119a747e4fSDavid du Colombier Dconv(Fmt *fp)
1127dd7cddfSDavid du Colombier {
1137dd7cddfSDavid du Colombier char str[STRINGSZ];
1147dd7cddfSDavid du Colombier Adr *a;
11559cc4ca5SDavid du Colombier char *op;
11659cc4ca5SDavid du Colombier int v;
1177dd7cddfSDavid du Colombier
1189a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
1197dd7cddfSDavid du Colombier switch(a->type) {
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier default:
1220591a7c1SDavid du Colombier snprint(str, sizeof(str), "GOK-type(%d)", a->type);
1237dd7cddfSDavid du Colombier break;
1247dd7cddfSDavid du Colombier
1257dd7cddfSDavid du Colombier case D_NONE:
1267dd7cddfSDavid du Colombier str[0] = 0;
1277dd7cddfSDavid du Colombier if(a->name != D_NONE || a->reg != NREG || a->sym != S)
1280591a7c1SDavid du Colombier snprint(str, sizeof(str), "%N(R%d)(NONE)", a, a->reg);
1297dd7cddfSDavid du Colombier break;
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier case D_CONST:
1327dd7cddfSDavid du Colombier if(a->reg != NREG)
1330591a7c1SDavid du Colombier snprint(str, sizeof(str), "$%N(R%d)", a, a->reg);
1347dd7cddfSDavid du Colombier else
1350591a7c1SDavid du Colombier snprint(str, sizeof(str), "$%N", a);
1367dd7cddfSDavid du Colombier break;
1377dd7cddfSDavid du Colombier
13859cc4ca5SDavid du Colombier case D_SHIFT:
13959cc4ca5SDavid du Colombier v = a->offset;
14059cc4ca5SDavid du Colombier op = "<<>>->@>" + (((v>>5) & 3) << 1);
14159cc4ca5SDavid du Colombier if(v & (1<<4))
1420591a7c1SDavid du Colombier snprint(str, sizeof(str), "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
14359cc4ca5SDavid du Colombier else
1440591a7c1SDavid du Colombier snprint(str, sizeof(str), "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
14559cc4ca5SDavid du Colombier if(a->reg != NREG)
14659cc4ca5SDavid du Colombier sprint(str+strlen(str), "(R%d)", a->reg);
14759cc4ca5SDavid du Colombier break;
14859cc4ca5SDavid du Colombier
1497dd7cddfSDavid du Colombier case D_OREG:
1507dd7cddfSDavid du Colombier if(a->reg != NREG)
1510591a7c1SDavid du Colombier snprint(str, sizeof(str), "%N(R%d)", a, a->reg);
1527dd7cddfSDavid du Colombier else
1530591a7c1SDavid du Colombier snprint(str, sizeof(str), "%N", a);
1547dd7cddfSDavid du Colombier break;
1557dd7cddfSDavid du Colombier
1567dd7cddfSDavid du Colombier case D_REG:
1570591a7c1SDavid du Colombier snprint(str, sizeof(str), "R%d", a->reg);
1587dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1590591a7c1SDavid du Colombier snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
1607dd7cddfSDavid du Colombier break;
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier case D_FREG:
1630591a7c1SDavid du Colombier snprint(str, sizeof(str), "F%d", a->reg);
1647dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1650591a7c1SDavid du Colombier snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
1667dd7cddfSDavid du Colombier break;
1677dd7cddfSDavid du Colombier
168*40d01547SDavid du Colombier case D_SFREG:
169*40d01547SDavid du Colombier snprint(str, sizeof(str), "S%d", a->reg);
170*40d01547SDavid du Colombier if(a->name != D_NONE || a->sym != S)
171*40d01547SDavid du Colombier snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
172*40d01547SDavid du Colombier break;
173*40d01547SDavid du Colombier
174*40d01547SDavid du Colombier case D_QREG:
175*40d01547SDavid du Colombier snprint(str, sizeof(str), "Q%d", a->reg);
176*40d01547SDavid du Colombier if(a->name != D_NONE || a->sym != S)
177*40d01547SDavid du Colombier snprint(str, sizeof(str), "%N(R%d)(REG)", a, a->reg);
178*40d01547SDavid du Colombier break;
179*40d01547SDavid du Colombier
1807dd7cddfSDavid du Colombier case D_PSR:
1810591a7c1SDavid du Colombier snprint(str, sizeof(str), "PSR");
1827dd7cddfSDavid du Colombier if(a->name != D_NONE || a->sym != S)
1830591a7c1SDavid du Colombier snprint(str, sizeof(str), "%N(PSR)(REG)", a);
1847dd7cddfSDavid du Colombier break;
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier case D_BRANCH:
1870591a7c1SDavid du Colombier snprint(str, sizeof(str), "%ld(PC)", a->offset-pc);
1887dd7cddfSDavid du Colombier break;
1897dd7cddfSDavid du Colombier
1907dd7cddfSDavid du Colombier case D_FCONST:
1910591a7c1SDavid du Colombier snprint(str, sizeof(str), "$%.17e", a->dval);
1927dd7cddfSDavid du Colombier break;
1937dd7cddfSDavid du Colombier
1947dd7cddfSDavid du Colombier case D_SCONST:
1950591a7c1SDavid du Colombier snprint(str, sizeof(str), "$\"%S\"", a->sval);
1967dd7cddfSDavid du Colombier break;
1977dd7cddfSDavid du Colombier }
1989a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
1997dd7cddfSDavid du Colombier }
2007dd7cddfSDavid du Colombier
2017dd7cddfSDavid du Colombier int
Rconv(Fmt * fp)2029a747e4fSDavid du Colombier Rconv(Fmt *fp)
20359cc4ca5SDavid du Colombier {
2040591a7c1SDavid du Colombier char str[STRINGSZ], *p, *e;
20559cc4ca5SDavid du Colombier Adr *a;
20659cc4ca5SDavid du Colombier int i, v;
20759cc4ca5SDavid du Colombier
2089a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
2090591a7c1SDavid du Colombier snprint(str, sizeof(str), "GOK-reglist");
21059cc4ca5SDavid du Colombier switch(a->type) {
21159cc4ca5SDavid du Colombier case D_CONST:
21259cc4ca5SDavid du Colombier if(a->reg != NREG)
21359cc4ca5SDavid du Colombier break;
21459cc4ca5SDavid du Colombier if(a->sym != S)
21559cc4ca5SDavid du Colombier break;
21659cc4ca5SDavid du Colombier v = a->offset;
2170591a7c1SDavid du Colombier p = str;
2180591a7c1SDavid du Colombier e = str+sizeof(str);
21959cc4ca5SDavid du Colombier for(i=0; i<NREG; i++) {
22059cc4ca5SDavid du Colombier if(v & (1<<i)) {
2210591a7c1SDavid du Colombier if(p == str)
2220591a7c1SDavid du Colombier p = seprint(p, e, "[R%d", i);
22359cc4ca5SDavid du Colombier else
2240591a7c1SDavid du Colombier p = seprint(p, e, ",R%d", i);
22559cc4ca5SDavid du Colombier }
22659cc4ca5SDavid du Colombier }
2270591a7c1SDavid du Colombier seprint(p, e, "]");
22859cc4ca5SDavid du Colombier }
2299a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
23059cc4ca5SDavid du Colombier }
23159cc4ca5SDavid du Colombier
23259cc4ca5SDavid du Colombier int
Sconv(Fmt * fp)2339a747e4fSDavid du Colombier Sconv(Fmt *fp)
2347dd7cddfSDavid du Colombier {
2357dd7cddfSDavid du Colombier int i, c;
2367dd7cddfSDavid du Colombier char str[STRINGSZ], *p, *a;
2377dd7cddfSDavid du Colombier
2389a747e4fSDavid du Colombier a = va_arg(fp->args, char*);
2397dd7cddfSDavid du Colombier p = str;
2407dd7cddfSDavid du Colombier for(i=0; i<NSNAME; i++) {
2417dd7cddfSDavid du Colombier c = a[i] & 0xff;
2427dd7cddfSDavid du Colombier if(c >= 'a' && c <= 'z' ||
2437dd7cddfSDavid du Colombier c >= 'A' && c <= 'Z' ||
2447dd7cddfSDavid du Colombier c >= '0' && c <= '9' ||
2457dd7cddfSDavid du Colombier c == ' ' || c == '%') {
2467dd7cddfSDavid du Colombier *p++ = c;
2477dd7cddfSDavid du Colombier continue;
2487dd7cddfSDavid du Colombier }
2497dd7cddfSDavid du Colombier *p++ = '\\';
2507dd7cddfSDavid du Colombier switch(c) {
2517dd7cddfSDavid du Colombier case 0:
2527dd7cddfSDavid du Colombier *p++ = 'z';
2537dd7cddfSDavid du Colombier continue;
2547dd7cddfSDavid du Colombier case '\\':
2557dd7cddfSDavid du Colombier case '"':
2567dd7cddfSDavid du Colombier *p++ = c;
2577dd7cddfSDavid du Colombier continue;
2587dd7cddfSDavid du Colombier case '\n':
2597dd7cddfSDavid du Colombier *p++ = 'n';
2607dd7cddfSDavid du Colombier continue;
2617dd7cddfSDavid du Colombier case '\t':
2627dd7cddfSDavid du Colombier *p++ = 't';
2637dd7cddfSDavid du Colombier continue;
2647dd7cddfSDavid du Colombier case '\r':
2657dd7cddfSDavid du Colombier *p++ = 'r';
2667dd7cddfSDavid du Colombier continue;
2677dd7cddfSDavid du Colombier case '\f':
2687dd7cddfSDavid du Colombier *p++ = 'f';
2697dd7cddfSDavid du Colombier continue;
2707dd7cddfSDavid du Colombier }
2717dd7cddfSDavid du Colombier *p++ = (c>>6) + '0';
2727dd7cddfSDavid du Colombier *p++ = ((c>>3) & 7) + '0';
2737dd7cddfSDavid du Colombier *p++ = (c & 7) + '0';
2747dd7cddfSDavid du Colombier }
2757dd7cddfSDavid du Colombier *p = 0;
2769a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
2777dd7cddfSDavid du Colombier }
2787dd7cddfSDavid du Colombier
2797dd7cddfSDavid du Colombier int
Nconv(Fmt * fp)2809a747e4fSDavid du Colombier Nconv(Fmt *fp)
2817dd7cddfSDavid du Colombier {
2827dd7cddfSDavid du Colombier char str[STRINGSZ];
2837dd7cddfSDavid du Colombier Adr *a;
2847dd7cddfSDavid du Colombier Sym *s;
2857dd7cddfSDavid du Colombier
2869a747e4fSDavid du Colombier a = va_arg(fp->args, Adr*);
2877dd7cddfSDavid du Colombier s = a->sym;
2887dd7cddfSDavid du Colombier if(s == S) {
2890591a7c1SDavid du Colombier snprint(str, sizeof(str), "%ld", a->offset);
2907dd7cddfSDavid du Colombier goto out;
2917dd7cddfSDavid du Colombier }
2927dd7cddfSDavid du Colombier switch(a->name) {
2937dd7cddfSDavid du Colombier default:
2940591a7c1SDavid du Colombier snprint(str, sizeof(str), "GOK-name(%d)", a->name);
2957dd7cddfSDavid du Colombier break;
2967dd7cddfSDavid du Colombier
2977dd7cddfSDavid du Colombier case D_NONE:
2980591a7c1SDavid du Colombier snprint(str, sizeof(str), "%ld", a->offset);
2997dd7cddfSDavid du Colombier break;
3007dd7cddfSDavid du Colombier
3017dd7cddfSDavid du Colombier case D_EXTERN:
3020591a7c1SDavid du Colombier snprint(str, sizeof(str), "%s+%ld(SB)", s->name, a->offset);
3037dd7cddfSDavid du Colombier break;
3047dd7cddfSDavid du Colombier
3057dd7cddfSDavid du Colombier case D_STATIC:
3060591a7c1SDavid du Colombier snprint(str, sizeof(str), "%s<>+%ld(SB)", s->name, a->offset);
3077dd7cddfSDavid du Colombier break;
3087dd7cddfSDavid du Colombier
3097dd7cddfSDavid du Colombier case D_AUTO:
3100591a7c1SDavid du Colombier snprint(str, sizeof(str), "%s-%ld(SP)", s->name, -a->offset);
3117dd7cddfSDavid du Colombier break;
3127dd7cddfSDavid du Colombier
3137dd7cddfSDavid du Colombier case D_PARAM:
3140591a7c1SDavid du Colombier snprint(str, sizeof(str), "%s+%ld(FP)", s->name, a->offset);
3157dd7cddfSDavid du Colombier break;
3167dd7cddfSDavid du Colombier }
3177dd7cddfSDavid du Colombier out:
3189a747e4fSDavid du Colombier return fmtstrcpy(fp, str);
3197dd7cddfSDavid du Colombier }
320