diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
commit | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch) | |
tree | c0650497e988f47be9c6f2324fa692a52dea82e1 /src/cmd/5l/list.c | |
parent | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff) | |
download | golang-upstream/60.tar.gz |
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/cmd/5l/list.c')
-rw-r--r-- | src/cmd/5l/list.c | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/src/cmd/5l/list.c b/src/cmd/5l/list.c new file mode 100644 index 000000000..fa838215b --- /dev/null +++ b/src/cmd/5l/list.c @@ -0,0 +1,487 @@ +// Inferno utils/5l/list.h +// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.c +// +// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. +// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) +// Portions Copyright © 1997-1999 Vita Nuova Limited +// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) +// Portions Copyright © 2004,2006 Bruce Ellis +// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) +// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others +// Portions Copyright © 2009 The Go Authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Printing. + +#include "l.h" +#include "../ld/lib.h" + +void +listinit(void) +{ + + fmtinstall('A', Aconv); + fmtinstall('C', Cconv); + fmtinstall('D', Dconv); + fmtinstall('P', Pconv); + fmtinstall('S', Sconv); + fmtinstall('N', Nconv); + fmtinstall('O', Oconv); // C_type constants + fmtinstall('I', Iconv); +} + +void +prasm(Prog *p) +{ + print("%P\n", p); +} + +int +Pconv(Fmt *fp) +{ + Prog *p; + int a; + + p = va_arg(fp->args, Prog*); + curp = p; + a = p->as; + switch(a) { + default: + fmtprint(fp, "(%d)", p->line); + if(p->reg == NREG) + fmtprint(fp, " %A%C %D,%D", + a, p->scond, &p->from, &p->to); + else + if(p->from.type != D_FREG) + fmtprint(fp, " %A%C %D,R%d,%D", + a, p->scond, &p->from, p->reg, &p->to); + else + fmtprint(fp, " %A%C %D,F%d,%D", + a, p->scond, &p->from, p->reg, &p->to); + break; + + case ASWPW: + case ASWPBU: + fmtprint(fp, "(%d) %A%C R%d,%D,%D", + p->line, a, p->scond, p->reg, &p->from, &p->to); + break; + + case ADATA: + case AINIT_: + case ADYNT_: + fmtprint(fp, "(%d) %A%C %D/%d,%D", + p->line, a, p->scond, &p->from, p->reg, &p->to); + break; + + case AWORD: + fmtprint(fp, "(%d) WORD %D", p->line, &p->to); + break; + + case ADWORD: + fmtprint(fp, "(%d) DWORD %D %D", p->line, &p->from, &p->to); + break; + } + + if(p->spadj) + fmtprint(fp, " (spadj%+d)", p->spadj); + + return 0; +} + +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); +} + +char* strcond[16] = +{ + ".EQ", + ".NE", + ".HS", + ".LO", + ".MI", + ".PL", + ".VS", + ".VC", + ".HI", + ".LS", + ".GE", + ".LT", + ".GT", + ".LE", + "", + ".NV" +}; + +int +Cconv(Fmt *fp) +{ + char s[20]; + int c; + + c = va_arg(fp->args, int); + strcpy(s, strcond[c & C_SCOND]); + if(c & C_SBIT) + strcat(s, ".S"); + if(c & C_PBIT) + strcat(s, ".P"); + if(c & C_WBIT) + strcat(s, ".W"); + if(c & C_UBIT) /* ambiguous with FBIT */ + strcat(s, ".U"); + return fmtstrcpy(fp, s); +} + +int +Dconv(Fmt *fp) +{ + char str[STRINGSZ]; + char *op; + Adr *a; + int32 v; + + a = va_arg(fp->args, Adr*); + switch(a->type) { + + default: + snprint(str, sizeof str, "GOK-type(%d)", a->type); + break; + + case D_NONE: + str[0] = 0; + if(a->name != D_NONE || a->reg != NREG || a->sym != S) + snprint(str, sizeof str, "%N(R%d)(NONE)", a, a->reg); + break; + + case D_CONST: + if(a->reg == NREG) + snprint(str, sizeof str, "$%N", a); + else + snprint(str, sizeof str, "$%N(R%d)", a, a->reg); + break; + + case D_CONST2: + snprint(str, sizeof str, "$%d-%d", a->offset, a->offset2); + break; + + case D_SHIFT: + v = a->offset; + op = "<<>>->@>" + (((v>>5) & 3) << 1); + if(v & (1<<4)) + snprint(str, sizeof str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15); + else + snprint(str, sizeof str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31); + if(a->reg != NREG) + seprint(str+strlen(str), str+sizeof str, "(R%d)", a->reg); + break; + + case D_OCONST: + snprint(str, sizeof str, "$*$%N", a); + if(a->reg != NREG) + snprint(str, sizeof str, "%N(R%d)(CONST)", a, a->reg); + break; + + case D_OREG: + if(a->reg != NREG) + snprint(str, sizeof str, "%N(R%d)", a, a->reg); + else + snprint(str, sizeof str, "%N", a); + break; + + case D_REG: + snprint(str, sizeof str, "R%d", a->reg); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_REGREG: + snprint(str, sizeof str, "(R%d,R%d)", a->reg, (int)a->offset); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_FREG: + snprint(str, sizeof str, "F%d", a->reg); + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof str, "%N(R%d)(REG)", a, a->reg); + break; + + case D_PSR: + switch(a->reg) { + case 0: + snprint(str, sizeof str, "CPSR"); + break; + case 1: + snprint(str, sizeof str, "SPSR"); + break; + default: + snprint(str, sizeof str, "PSR%d", a->reg); + break; + } + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof str, "%N(PSR%d)(REG)", a, a->reg); + break; + + case D_FPCR: + switch(a->reg){ + case 0: + snprint(str, sizeof str, "FPSR"); + break; + case 1: + snprint(str, sizeof str, "FPCR"); + break; + default: + snprint(str, sizeof str, "FCR%d", a->reg); + break; + } + if(a->name != D_NONE || a->sym != S) + snprint(str, sizeof str, "%N(FCR%d)(REG)", a, a->reg); + + break; + + case D_BRANCH: /* botch */ + if(curp->cond != P) { + v = curp->cond->pc; + if(a->sym != S) + snprint(str, sizeof str, "%s+%.5ux(BRANCH)", a->sym->name, v); + else + snprint(str, sizeof str, "%.5ux(BRANCH)", v); + } else + if(a->sym != S) + snprint(str, sizeof str, "%s+%d(APC)", a->sym->name, a->offset); + else + snprint(str, sizeof str, "%d(APC)", a->offset); + break; + + case D_FCONST: + snprint(str, sizeof str, "$%e", ieeedtod(&a->ieee)); + break; + + case D_SCONST: + snprint(str, sizeof 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, "%d", a->offset); + break; + + case D_EXTERN: + if(s == S) + sprint(str, "%d(SB)", a->offset); + else + sprint(str, "%s+%d(SB)", s->name, a->offset); + break; + + case D_STATIC: + if(s == S) + sprint(str, "<>+%d(SB)", a->offset); + else + sprint(str, "%s<>+%d(SB)", s->name, a->offset); + break; + + case D_AUTO: + if(s == S) + sprint(str, "%d(SP)", a->offset); + else + sprint(str, "%s-%d(SP)", s->name, -a->offset); + break; + + case D_PARAM: + if(s == S) + sprint(str, "%d(FP)", a->offset); + else + sprint(str, "%s+%d(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(int32); 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); +} + +int +Iconv(Fmt *fp) +{ + int i, n; + uint32 *p; + char *s; + Fmt fmt; + + n = fp->prec; + fp->prec = 0; + if(!(fp->flags&FmtPrec) || n < 0) + return fmtstrcpy(fp, "%I"); + fp->flags &= ~FmtPrec; + p = va_arg(fp->args, uint32*); + + // format into temporary buffer and + // call fmtstrcpy to handle padding. + fmtstrinit(&fmt); + for(i=0; i<n/4; i++) { + if(i > 0) + fmtprint(&fmt, " "); + fmtprint(&fmt, "%.8ux", *p++); + } + s = fmtstrflush(&fmt); + fmtstrcpy(fp, s); + free(s); + return 0; +} + +static char* +cnames[] = +{ + [C_ADDR] = "C_ADDR", + [C_FAUTO] = "C_FAUTO", + [C_ZFCON] = "C_SFCON", + [C_SFCON] = "C_SFCON", + [C_LFCON] = "C_LFCON", + [C_FCR] = "C_FCR", + [C_FOREG] = "C_FOREG", + [C_FREG] = "C_FREG", + [C_GOK] = "C_GOK", + [C_HAUTO] = "C_HAUTO", + [C_HFAUTO] = "C_HFAUTO", + [C_HFOREG] = "C_HFOREG", + [C_HOREG] = "C_HOREG", + [C_HREG] = "C_HREG", + [C_LACON] = "C_LACON", + [C_LAUTO] = "C_LAUTO", + [C_LBRA] = "C_LBRA", + [C_LCON] = "C_LCON", + [C_LOREG] = "C_LOREG", + [C_NCON] = "C_NCON", + [C_NONE] = "C_NONE", + [C_PC] = "C_PC", + [C_PSR] = "C_PSR", + [C_RACON] = "C_RACON", + [C_RCON] = "C_RCON", + [C_REG] = "C_REG", + [C_REGREG] = "C_REGREG", + [C_ROREG] = "C_ROREG", + [C_SAUTO] = "C_SAUTO", + [C_SBRA] = "C_SBRA", + [C_SCON] = "C_SCON", + [C_SHIFT] = "C_SHIFT", + [C_SOREG] = "C_SOREG", + [C_SP] = "C_SP", + [C_SROREG] = "C_SROREG" +}; + +int +Oconv(Fmt *fp) +{ + char buf[500]; + int o; + + o = va_arg(fp->args, int); + if(o < 0 || o >= nelem(cnames) || cnames[o] == nil) { + snprint(buf, sizeof(buf), "C_%d", o); + return fmtstrcpy(fp, buf); + } + return fmtstrcpy(fp, cnames[o]); +} + +void +diag(char *fmt, ...) +{ + char buf[STRINGSZ], *tn, *sep; + va_list arg; + + tn = ""; + sep = ""; + if(cursym != S) { + tn = cursym->name; + sep = ": "; + } + va_start(arg, fmt); + vseprint(buf, buf+sizeof(buf), fmt, arg); + va_end(arg); + print("%s%s%s\n", tn, sep, buf); + + nerrors++; + if(nerrors > 20) { + print("too many errors\n"); + errorexit(); + } +} |