diff options
| author | Richard Miller <miller.research@gmail.com> | 2020-11-09 11:36:14 +0000 |
|---|---|---|
| committer | Richard Miller <miller.research@gmail.com> | 2020-11-09 11:36:14 +0000 |
| commit | 6e84dc968bc4eaf047fbefcba2f670940718dda8 (patch) | |
| tree | 523d2f81946b1e0abe4afddf1d2fce7e1525b7d7 /utils/il/list.c | |
| parent | 2a571cc0ece4073eb56d5ccfc3e061a09a353e13 (diff) | |
Add toolchain for riscv (ia ic il) and riscv64 (ja jc jl)
Because the rv64 ISA is very nearly a proper superset of rv32, the
compilers ic and jc are actually the same program, which compiles
to .i or .j depending on how it is invoked; similarly for ia/ja and
il/jl. It is also possible to invoke ia/ic/il with a '-j' option to
specify 64-bit behaviour.
Diffstat (limited to 'utils/il/list.c')
| -rw-r--r-- | utils/il/list.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/utils/il/list.c b/utils/il/list.c new file mode 100644 index 00000000..93989a97 --- /dev/null +++ b/utils/il/list.c @@ -0,0 +1,252 @@ +#include "l.h" + +void +listinit(void) +{ + + fmtinstall('A', Aconv); + fmtinstall('D', Dconv); + fmtinstall('P', Pconv); + fmtinstall('S', Sconv); + fmtinstall('N', Nconv); +} + +void +prasm(Prog *p) +{ + print("%P\n", p); +} + +int +Pconv(Fmt *fp) +{ + char str[STRINGSZ], *s; + Prog *p; + int a; + + p = va_arg(fp->args, Prog*); + curp = p; + a = p->as; + if(a == ADATA || a == ADYNT || a == AINIT) + sprint(str, "(%ld) %A %D/%d,%D", + p->line, a, &p->from, p->reg, &p->to); + else{ + s = str; + s += sprint(s, "(%ld)", p->line); + if(p->reg == NREG) + sprint(s, " %A %D,%D", + a, &p->from, &p->to); + else + if(p->from.type != D_FREG) + sprint(s, " %A %D,R%d,%D", + a, &p->from, p->reg, &p->to); + else + sprint(s, " %A %D,F%d,%D", + a, &p->from, p->reg, &p->to); + } + return fmtstrcpy(fp, str); +} + +int +Aconv(Fmt *fp) +{ + char *s; + int a; + + a = va_arg(fp->args, int); + s = "???"; + if(a >= AXXX && a < ALAST) + s = anames[a]; + return fmtstrcpy(fp, s); +} + +int +Dconv(Fmt *fp) +{ + char str[STRINGSZ]; + Adr *a; + long v; + + a = va_arg(fp->args, Adr*); + switch(a->type) { + + default: + sprint(str, "GOK-type(%d)", a->type); + break; + + case D_NONE: + str[0] = 0; + if(a->name != D_NONE || a->reg != NREG || a->sym != S) + sprint(str, "%N(R%d)(NONE)", a, a->reg); + break; + + case D_CONST: + if(a->reg == NREG) + sprint(str, "$%N", a); + else + sprint(str, "$%N(R%d)", a, a->reg); + break; + + case D_VCONST: + sprint(str, "$%lld", *a->vval); + break; + + case D_OREG: + if(a->reg != NREG) + sprint(str, "%N(R%d)", a, a->reg); + else + sprint(str, "%N", a); + break; + + case D_REG: + sprint(str, "R%d", a->reg); + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_FREG: + sprint(str, "F%d", a->reg); + if(a->name != D_NONE || a->sym != S) + sprint(str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_CTLREG: + sprint(str, "CSR(0x%lx)", a->offset); + break; + + case D_BRANCH: /* botch */ + if(curp->cond != P) { + v = curp->cond->pc + INITTEXT; + if(a->sym != S) + sprint(str, "%s+%.5lux(BRANCH)", a->sym->name, v); + else + sprint(str, "%.5lux(BRANCH)", v); + } else + if(a->sym != S) + sprint(str, "%s+%ld(APC)", a->sym->name, a->offset); + else + sprint(str, "%ld(APC)", a->offset); + break; + + case D_FCONST: + sprint(str, "$%e", ieeedtod(a->ieee)); + break; + + case D_SCONST: + sprint(str, "$\"%S\"", a->sval); + break; + } + return fmtstrcpy(fp, str); +} + +int +Nconv(Fmt *fp) +{ + char str[STRINGSZ]; + Adr *a; + Sym *s; + + a = va_arg(fp->args, Adr*); + s = a->sym; + switch(a->name) { + default: + sprint(str, "GOK-name(%d)", a->name); + break; + + case D_NONE: + sprint(str, "%ld", a->offset); + break; + + case D_EXTERN: + if(s == S) + sprint(str, "%ld(SB)", a->offset); + else + sprint(str, "%s+%ld(SB)", s->name, a->offset); + break; + + case D_STATIC: + if(s == S) + sprint(str, "<>+%ld(SB)", a->offset); + else + sprint(str, "%s<>+%ld(SB)", s->name, a->offset); + break; + + case D_AUTO: + if(s == S) + sprint(str, "%ld(SP)", a->offset); + else + sprint(str, "%s-%ld(SP)", s->name, -a->offset); + break; + + case D_PARAM: + if(s == S) + sprint(str, "%ld(FP)", a->offset); + else + sprint(str, "%s+%ld(FP)", s->name, a->offset); + break; + } + + return fmtstrcpy(fp, str); +} + +int +Sconv(Fmt *fp) +{ + int i, c; + char str[STRINGSZ], *p, *a; + + a = va_arg(fp->args, char*); + p = str; + for(i=0; i<sizeof(long); i++) { + c = a[i] & 0xff; + if(c >= 'a' && c <= 'z' || + c >= 'A' && c <= 'Z' || + c >= '0' && c <= '9' || + c == ' ' || c == '%') { + *p++ = c; + continue; + } + *p++ = '\\'; + switch(c) { + case 0: + *p++ = 'z'; + continue; + case '\\': + case '"': + *p++ = c; + continue; + case '\n': + *p++ = 'n'; + continue; + case '\t': + *p++ = 't'; + continue; + } + *p++ = (c>>6) + '0'; + *p++ = ((c>>3) & 7) + '0'; + *p++ = (c & 7) + '0'; + } + *p = 0; + return fmtstrcpy(fp, str); +} + +void +diag(char *fmt, ...) +{ + char buf[STRINGSZ], *tn; + va_list arg; + + tn = "??none??"; + if(curtext != P && curtext->from.sym != S) + tn = curtext->from.sym->name; + va_start(arg, fmt); + vseprint(buf, buf+sizeof(buf), fmt, arg); + va_end(arg); + print("%s: %s\n", tn, buf); + + nerrors++; + if(nerrors > 10) { + print("too many errors\n"); + errorexit(); + } +} |
