Addr to;
// for 5g, 6g, 8g internal use
- uint32 loc; // TODO: merge with pc?
void* opt;
// for 5l, 6l, 8l internal use
extern LinkArch link386;
extern LinkArch linkamd64;
extern LinkArch linkarm;
+
+#pragma varargck type "A" int
+#pragma varargck type "D" Addr*
+#pragma varargck type "lD" Addr*
+#pragma varargck type "P" Prog*
+#pragma varargck type "R" int
+
+// TODO(ality): remove this workaround.
+// It's here because Pconv in liblink/list?.c references %L.
+#pragma varargck type "L" int32
// license that can be found in the LICENSE file.
#include "../link.h"
-
-#pragma varargck type "@" Addr*
-#pragma varargck type "A" int
-#pragma varargck type "$" char*
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
-#pragma varargck type "L" int
-#pragma varargck type "lS" LSym*
-#pragma varargck type "M" Addr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
#endif
}
+int
+Lconv(Fmt *fp)
+{
+ return linklinefmt(ctxt, fp);
+}
+
void
main(int argc, char *argv[])
{
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit5();
+ fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
typedef struct C1 C1;
typedef struct Multab Multab;
typedef struct Hintab Hintab;
-typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
char hint[10];
};
-struct Var
-{
- int32 offset;
- LSym* sym;
- char name;
- char etype;
-};
-
struct Reg
{
int32 pc;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
-EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
* list
*/
void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Nconv(Fmt*);
-int Bconv(Fmt*);
-int Rconv(Fmt*);
/*
* reg.c
int isbranch(Prog *);
int predicable(Prog *p);
int modifiescpsr(Prog *p);
-
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Addr*
-#pragma varargck type "N" Addr*
-#pragma varargck type "R" Addr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "S" char*
void
listinit(void)
{
- fmtinstall('B', Bconv);
listinit5();
}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == nil) {
- sprint(ss, "$%d", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
zprog.from.reg = NREG;
zprog.to = zprog.from;
- listinit();
+ listinit5();
}
/*
* list.c
*/
-int Aconv(Fmt*);
-int Cconv(Fmt*);
-int Dconv(Fmt*);
-int Mconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Yconv(Fmt*);
void listinit(void);
void zaddr(Biobuf*, Addr*, int, int);
-
-#pragma varargck type "D" Addr*
-#pragma varargck type "M" Addr*
p1->link = p->link;
p->link = p1;
p1->lineno = p->lineno;
- p1->loc = 9999;
+ p1->pc = 9999;
p1->as = AMOVW;
p1->from.type = D_REG;
p1->from.reg = reg;
p->to.type = D_NONE;
p->to.name = D_NONE;
p->to.reg = NREG;
- p->loc = pcloc;
+ p->pc = pcloc;
pcloc++;
}
if(p->to.type != D_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
- p->to.offset = to->loc;
+ p->to.offset = to->pc;
}
Prog*
+++ /dev/null
-// Derived from Inferno utils/5c/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5c/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.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-// TODO(kaib): make 5g/list.c congruent with 5l/list.c
-
-static int sconsize;
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv); // as
- fmtinstall('C', Cconv); // conditional execution bit
- fmtinstall('P', Pconv); // Prog*
- fmtinstall('D', Dconv); // Addr*
- fmtinstall('Y', Yconv); // sconst
- fmtinstall('R', Rconv); // register
- fmtinstall('M', Mconv); // names
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ], str1[STRINGSZ];
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- sconsize = 8;
- switch(p->as) {
- default:
- snprint(str1, sizeof(str1), "%A%C", p->as, p->scond);
- if(p->reg == NREG && p->as != AGLOBL)
- snprint(str, sizeof(str), "%.4d (%L) %-7s %D,%D",
- p->loc, p->lineno, str1, &p->from, &p->to);
- else
- if (p->from.type != D_FREG) {
- snprint(str, sizeof(str), "%.4d (%L) %-7s %D,R%d,%D",
- p->loc, p->lineno, str1, &p->from, p->reg, &p->to);
- } else
- snprint(str, sizeof(str), "%.4d (%L) %-7A%C %D,F%d,%D",
- p->loc, p->lineno, p->as, p->scond, &p->from, p->reg, &p->to);
- break;
-
- case ADATA:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
- p->loc, p->lineno, p->as, &p->from, p->reg, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ];
- const char *op;
- Addr *a;
- int i;
- int32 v;
-
- a = va_arg(fp->args, Addr*);
- if(a == nil) {
- sprint(str, "<nil>");
- goto conv;
- }
- i = a->type;
- switch(i) {
-
- 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 != nil)
- sprint(str, "%M(R%d)(NONE)", a, a->reg);
- break;
-
- case D_CONST:
- if(a->reg != NREG)
- sprint(str, "$%M(R%d)", a, a->reg);
- else
- sprint(str, "$%M", a);
- break;
-
- case D_CONST2:
- sprint(str, "$%d-%d", a->offset, a->offset2);
- break;
-
- case D_SHIFT:
- v = a->offset;
- op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
- if(v & (1<<4))
- sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
- else
- sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
- if(a->reg != NREG)
- sprint(str+strlen(str), "(R%d)", a->reg);
- break;
-
- case D_OCONST:
- sprint(str, "$*$%M", a);
- if(a->reg != NREG)
- sprint(str, "%M(R%d)(CONST)", a, a->reg);
- break;
-
- case D_OREG:
- if(a->reg != NREG)
- sprint(str, "%M(R%d)", a, a->reg);
- else
- sprint(str, "%M", a);
- break;
-
- case D_REG:
- sprint(str, "R%d", a->reg);
- if(a->name != D_NONE || a->sym != nil)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_REGREG:
- sprint(str, "(R%d,R%d)", a->reg, (int)a->offset);
- if(a->name != D_NONE || a->sym != nil)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_REGREG2:
- sprint(str, "R%d,R%d", a->reg, (int)a->offset);
- if(a->name != D_NONE || a->sym != nil)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_FREG:
- sprint(str, "F%d", a->reg);
- if(a->name != D_NONE || a->sym != nil)
- sprint(str, "%M(R%d)(REG)", a, a->reg);
- break;
-
- case D_BRANCH:
- if(a->u.branch == P || a->u.branch->loc == 0) {
- if(a->sym != nil)
- sprint(str, "%s+%d(APC)", a->sym->name, a->offset);
- else
- sprint(str, "%d(APC)", a->offset);
- } else
- if(a->sym != nil)
- sprint(str, "%s+%d(APC)", a->sym->name, a->u.branch->loc);
- else
- sprint(str, "%d(APC)", a->u.branch->loc);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
- break;
-
- // TODO(kaib): Add back
-// case D_ADDR:
-// a->type = a->index;
-// a->index = D_NONE;
-// snprint(str, sizeof(str), "$%D", a);
-// a->index = a->type;
-// a->type = D_ADDR;
-// goto conv;
- }
-conv:
- fmtstrcpy(fp, str);
- if(a->gotype)
- fmtprint(fp, "{%s}", a->gotype->name);
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames5[i]);
-}
-
-char* strcond[16] =
-{
- ".EQ",
- ".NE",
- ".HS",
- ".LO",
- ".MI",
- ".PL",
- ".VS",
- ".VC",
- ".HI",
- ".LS",
- ".GE",
- ".LT",
- ".GT",
- ".LE",
- "",
- ".NV"
-};
-
-int
-Cconv(Fmt *fp)
-{
- char s[STRINGSZ];
- 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
-Yconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sconsize; i++) {
- c = a[i] & 0xff;
- if((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9')) {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- default:
- if(c < 040 || c >= 0177)
- break; /* not portable */
- p[-1] = c;
- continue;
- 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
-Rconv(Fmt *fp)
-{
- int r;
- char str[STRINGSZ];
-
- r = va_arg(fp->args, int);
- snprint(str, sizeof(str), "R%d", r);
- return fmtstrcpy(fp, str);
-}
-
-int
-Mconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Addr *a;
-
- a = va_arg(fp->args, Addr*);
- switch(a->name) {
- default:
- snprint(str, sizeof(str), "GOK-name(%d)", a->name);
- break;
-
- case D_NONE:
- snprint(str, sizeof(str), "%d", a->offset);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof(str), "%lS+%d(SB)", a->sym, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof(str), "%lS<>+%d(SB)", a->sym, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof(str), "%lS+%d(SP)", a->sym, a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof(str), "%lS+%d(FP)", a->sym, a->offset);
- break;
- }
- return fmtstrcpy(fp, str);
-}
if(r1 != nil) {
print(" pred:");
for(; r1 != nil; r1 = r1->p2link)
- print(" %.4ud", r1->prog->loc);
+ print(" %.4ud", r1->prog->pc);
if(r->p1 != nil)
- print(" (and %.4ud)", r->p1->prog->loc);
+ print(" (and %.4ud)", r->p1->prog->pc);
else
print(" (only)");
print("\n");
// if(r1 != nil) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4ud", r1->prog->loc);
+// print(" %.4ud", r1->prog->pc);
// print("\n");
// }
}
EXTERN int32 symsize;
EXTERN int armsize;
-#pragma varargck type "A" int
-#pragma varargck type "C" int
-#pragma varargck type "D" Addr*
-#pragma varargck type "I" uchar*
-#pragma varargck type "N" Addr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "S" char*
-#pragma varargck type "Z" char*
-#pragma varargck type "i" char*
-
-int Aconv(Fmt *fp);
-int Cconv(Fmt *fp);
-int Dconv(Fmt *fp);
+#pragma varargck type "I" uint32*
+
int Iconv(Fmt *fp);
-int Nconv(Fmt *fp);
-int Oconv(Fmt *fp);
-int Pconv(Fmt *fp);
-int Sconv(Fmt *fp);
void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rel, LSym *s, Reloc *r);
int archreloc(Reloc *r, LSym *s, vlong *val);
void asmb(void);
void cput(int32 c);
-void diag(char *fmt, ...);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
void hput(int32 l);
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
+ listinit5();
fmtinstall('I', Iconv);
}
-static Prog *curp;
-
-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->lineno);
- if(p->reg == NREG && p->as != AGLOBL)
- 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->lineno, 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->lineno, a, p->scond, &p->from, p->reg, &p->to);
- break;
-
- case AWORD:
- fmtprint(fp, "(%d) WORD %D", p->lineno, &p->to);
- break;
-
- case ADWORD:
- fmtprint(fp, "(%d) DWORD %D %D", p->lineno, &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 = anames5[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];
- const char *op;
- Addr *a;
- int32 v;
-
- a = va_arg(fp->args, Addr*);
- 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_REGREG2:
- 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->pcond != P) {
- v = curp->pcond->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, "$%.17g", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof str, "$\"%S\"", a->u.sval);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Nconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Addr *a;
- LSym *s;
-
- a = va_arg(fp->args, Addr*);
- 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)
{
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_LCONADDR] = "C_LCONADDR",
- [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_REGREG2] = "C_REGREG2",
- [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[1024], *tn, *sep;
- va_list arg;
-
- tn = "";
- sep = "";
- if(ctxt->cursym != S) {
- tn = ctxt->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();
- }
-}
return '/';
}
+int
+Lconv(Fmt *fp)
+{
+ return linklinefmt(ctxt, fp);
+}
+
void
main(int argc, char *argv[])
{
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit6();
+ fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
typedef struct Case Case;
typedef struct C1 C1;
-typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
typedef struct Renv Renv;
int32 label;
};
-struct Var
-{
- vlong offset;
- LSym* sym;
- char name;
- char etype;
-};
-
struct Reg
{
int32 pc;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
-EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
* list
*/
void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Rconv(Fmt*);
-int Xconv(Fmt*);
-int Bconv(Fmt*);
/*
* reg.c
void genmuladd(Node*, Node*, int, Node*);
void shiftit(Type*, Node*, Node*);
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-
#define D_X7 (D_X0+7)
void fgopcode(int, Node*, Node*, int, int);
void
listinit(void)
{
- fmtinstall('B', Bconv);
listinit6();
}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == nil) {
- sprint(ss, "$%lld", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
zprog.from.scale = 0;
zprog.to = zprog.from;
- listinit();
+ listinit6();
}
/*
* list.c
*/
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Yconv(Fmt*);
void listinit(void);
void zaddr(Biobuf*, Addr*, int, int);
-
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
p->link = p1;
p1->lineno = p->lineno;
p2->lineno = p->lineno;
- p1->loc = 9999;
- p2->loc = 9999;
+ p1->pc = 9999;
+ p2->pc = 9999;
p->as = ACMPQ;
p->to.type = D_CONST;
p->to.offset = 0;
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
- p->loc = pcloc;
+ p->pc = pcloc;
pcloc++;
}
if(p->to.type != D_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
- p->to.offset = to->loc;
+ p->to.offset = to->pc;
}
Prog*
+++ /dev/null
-// Derived from Inferno utils/6c/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6c/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.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-static int sconsize;
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv); // as
- fmtinstall('P', Pconv); // Prog*
- fmtinstall('D', Dconv); // Addr*
- fmtinstall('R', Rconv); // reg
- fmtinstall('Y', Yconv); // sconst
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
- char scale[40];
-
- p = va_arg(fp->args, Prog*);
- sconsize = 8;
- scale[0] = '\0';
- if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
- snprint(scale, sizeof scale, "%d,", p->from.scale);
- switch(p->as) {
- default:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
-
- case ADATA:
- sconsize = p->from.scale;
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
- p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
- break;
-
- case ATEXT:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Addr *a;
- int i;
- uint32 d1, d2;
-
- a = va_arg(fp->args, Addr*);
- i = a->type;
- if(i >= D_INDIR) {
- if(a->offset)
- snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof(str), "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- if(a->offset)
- snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
- else
- snprint(str, sizeof(str), "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(a->u.branch == nil)
- snprint(str, sizeof(str), "<nil>");
- else
- snprint(str, sizeof(str), "%d", a->u.branch->loc);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof(str), "%lS+%lld(SB)", a->sym, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof(str), "%lS<>+%lld(SB)", a->sym, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof(str), "%lS+%lld(SP)", a->sym, a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof(str), "%lS+%lld(FP)", a->sym, a->offset);
- break;
-
- case D_CONST:
- if(fp->flags & FmtLong) {
- d1 = a->offset & 0xffffffffLL;
- d2 = (a->offset>>32) & 0xffffffffLL;
- snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
- break;
- }
- snprint(str, sizeof(str), "$%lld", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof(str), "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
- if(a->gotype)
- fmtprint(fp, "{%s}", a->gotype->name);
- return 0;
-}
-
-static char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
- "SPB",
- "BPB",
- "SIB",
- "DIB",
- "R8B",
- "R9B",
- "R10B",
- "R11B",
- "R12B",
- "R13B",
- "R14B",
- "R15B",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
- "R8",
- "R9",
- "R10",
- "R11",
- "R12",
- "R13",
- "R14",
- "R15",
-
- "AH",
- "CH",
- "DH",
- "BH",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "M0",
- "M1",
- "M2",
- "M3",
- "M4",
- "M5",
- "M6",
- "M7",
-
- "X0",
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
- "X8",
- "X9",
- "X10",
- "X11",
- "X12",
- "X13",
- "X14",
- "X15",
-
- "CS", /* [D_CS] */
- "SS",
- "DS",
- "ES",
- "FS",
- "GS",
-
- "GDTR", /* [D_GDTR] */
- "IDTR", /* [D_IDTR] */
- "LDTR", /* [D_LDTR] */
- "MSW", /* [D_MSW] */
- "TASK", /* [D_TASK] */
-
- "CR0", /* [D_CR] */
- "CR1",
- "CR2",
- "CR3",
- "CR4",
- "CR5",
- "CR6",
- "CR7",
- "CR8",
- "CR9",
- "CR10",
- "CR11",
- "CR12",
- "CR13",
- "CR14",
- "CR15",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
- snprint(str, sizeof(str), "BAD_R(%d)", r);
- return fmtstrcpy(fp, str);
- }
- return fmtstrcpy(fp, regstr[r]);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames6[i]);
-}
-
-
-int
-Yconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sconsize; i++) {
- c = a[i] & 0xff;
- if((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9')) {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- default:
- if(c < 040 || c >= 0177)
- break; /* not portable */
- p[-1] = c;
- continue;
- 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);
-}
p1 = mal(sizeof(*p1));
clearp(p1);
- p1->loc = 9999;
+ p1->pc = 9999;
p = r->f.prog;
p1->link = p->link;
if(r1 != nil) {
print(" pred:");
for(; r1 != nil; r1 = r1->p2link)
- print(" %.4ud", r1->prog->loc);
+ print(" %.4ud", r1->prog->pc);
print("\n");
}
// r1 = r->s1;
// if(r1 != R) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4ud", r1->prog->loc);
+// print(" %.4ud", r1->prog->pc);
// print("\n");
// }
}
MAXHIST = 40, /* limit of path elements for history symbols */
};
-#pragma varargck type "A" uint
-#pragma varargck type "D" Addr*
#pragma varargck type "I" uchar*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-#pragma varargck type "i" char*
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN vlong textstksiz;
EXTERN vlong textarg;
-int Aconv(Fmt *fp);
-int Dconv(Fmt *fp);
int Iconv(Fmt *fp);
-int Pconv(Fmt *fp);
-int Rconv(Fmt *fp);
-int Sconv(Fmt *fp);
void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rela, LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val);
void asmb(void);
-void diag(char *fmt, ...);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
void listinit(void);
#define WPUT(a) wputl(a)
#define VPUT(a) vputl(a)
-#pragma varargck type "D" Addr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "Z" char*
-#pragma varargck type "A" int
-#pragma varargck argpos diag 1
-
/* Used by ../ld/dwarf.c */
enum
{
#include "l.h"
#include "../ld/lib.h"
-static Prog* bigP;
-
void
listinit(void)
{
-
- fmtinstall('R', Rconv);
- fmtinstall('A', Aconv);
- fmtinstall('D', Dconv);
- fmtinstall('S', Sconv);
- fmtinstall('P', Pconv);
+ listinit6();
fmtinstall('I', Iconv);
}
-int
-Pconv(Fmt *fp)
-{
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- bigP = p;
- switch(p->as) {
- case ATEXT:
- if(p->from.scale) {
- fmtprint(fp, "(%d) %A %D,%d,%lD",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- fmtprint(fp, "(%d) %A %D,%lD",
- p->lineno, p->as, &p->from, &p->to);
- break;
- default:
- fmtprint(fp, "(%d) %A %D,%D",
- p->lineno, p->as, &p->from, &p->to);
- break;
- case ADATA:
- case AINIT_:
- case ADYNT_:
- fmtprint(fp, "(%d) %A %D/%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- bigP = P;
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames6[i]);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Addr *a;
- int i;
-
- a = va_arg(fp->args, Addr*);
- i = a->type;
-
- if(fp->flags & FmtLong) {
- if(i != D_CONST) {
- // ATEXT dst is not constant
- snprint(str, sizeof(str), "!!%D", a);
- goto brk;
- }
- parsetextconst(a->offset);
- if(textarg == 0) {
- snprint(str, sizeof(str), "$%lld", textstksiz);
- goto brk;
- }
- snprint(str, sizeof(str), "$%lld-%lld", textstksiz, textarg);
- goto brk;
- }
-
- if(i >= D_INDIR) {
- if(a->offset)
- snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof(str), "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- if(a->offset)
- snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
- else
- snprint(str, sizeof(str), "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(bigP != P && bigP->pcond != P)
- if(a->sym != S)
- snprint(str, sizeof(str), "%llux+%s", bigP->pcond->pc,
- a->sym->name);
- else
- snprint(str, sizeof(str), "%llux", bigP->pcond->pc);
- else
- snprint(str, sizeof(str), "%lld(PC)", a->offset);
- break;
-
- case D_EXTERN:
- if(a->sym) {
- snprint(str, sizeof(str), "%s+%lld(SB)", a->sym->name, a->offset);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!+%lld(SB)", a->offset);
- break;
-
- case D_STATIC:
- if(a->sym) {
- snprint(str, sizeof(str), "%s<%d>+%lld(SB)", a->sym->name,
- a->sym->version, a->offset);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!<999>+%lld(SB)", a->offset);
- break;
-
- case D_AUTO:
- if(a->sym) {
- snprint(str, sizeof(str), "%s+%lld(SP)", a->sym->name, a->offset);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!+%lld(SP)", a->offset);
- break;
-
- case D_PARAM:
- if(a->sym) {
- snprint(str, sizeof(str), "%s+%lld(%s)", a->sym->name, a->offset, paramspace);
- break;
- }
- snprint(str, sizeof(str), "!!noname!!+%lld(%s)", a->offset, paramspace);
- break;
-
- case D_CONST:
- snprint(str, sizeof(str), "$%lld", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17g)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%S\"", a->u.sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof(str), "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- snprint(s, sizeof(s), "(%R*%d)", a->index, a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
-// if(a->gotype)
-// fmtprint(fp, "«%s»", a->gotype->name);
- return 0;
-
-}
-
-char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
- "SPB",
- "BPB",
- "SIB",
- "DIB",
- "R8B",
- "R9B",
- "R10B",
- "R11B",
- "R12B",
- "R13B",
- "R14B",
- "R15B",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
- "R8",
- "R9",
- "R10",
- "R11",
- "R12",
- "R13",
- "R14",
- "R15",
-
- "AH",
- "CH",
- "DH",
- "BH",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "M0",
- "M1",
- "M2",
- "M3",
- "M4",
- "M5",
- "M6",
- "M7",
-
- "X0",
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
- "X8",
- "X9",
- "X10",
- "X11",
- "X12",
- "X13",
- "X14",
- "X15",
-
- "CS", /* [D_CS] */
- "SS",
- "DS",
- "ES",
- "FS",
- "GS",
-
- "GDTR", /* [D_GDTR] */
- "IDTR", /* [D_IDTR] */
- "LDTR", /* [D_LDTR] */
- "MSW", /* [D_MSW] */
- "TASK", /* [D_TASK] */
-
- "CR0", /* [D_CR] */
- "CR1",
- "CR2",
- "CR3",
- "CR4",
- "CR5",
- "CR6",
- "CR7",
- "CR8",
- "CR9",
- "CR10",
- "CR11",
- "CR12",
- "CR13",
- "CR14",
- "CR15",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_AL && r <= D_NONE)
- snprint(str, sizeof(str), "%s", regstr[r-D_AL]);
- else
- snprint(str, sizeof(str), "gok(%d)", r);
-
- 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(double); i++) {
- c = a[i] & 0xff;
- if(c >= 'a' && c <= 'z' ||
- c >= 'A' && c <= 'Z' ||
- c >= '0' && c <= '9') {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- default:
- if(c < 040 || c >= 0177)
- break; /* not portable */
- p[-1] = c;
- continue;
- 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)
{
free(s);
return 0;
}
-
-void
-diag(char *fmt, ...)
-{
- char buf[1024], *tn, *sep;
- va_list arg;
-
- tn = "";
- sep = "";
- if(ctxt->cursym != S) {
- tn = ctxt->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();
- }
-}
-
-void
-parsetextconst(vlong arg)
-{
- textstksiz = arg & 0xffffffffLL;
- if(textstksiz & 0x80000000LL)
- textstksiz = -(-textstksiz & 0xffffffffLL);
-
- textarg = (arg >> 32) & 0xffffffffLL;
- if(textarg & 0x80000000LL)
- textarg = 0;
- textarg = (textarg+7) & ~7LL;
-}
return '/';
}
+int
+Lconv(Fmt *fp)
+{
+ return linklinefmt(ctxt, fp);
+}
+
void
main(int argc, char *argv[])
{
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit8();
+ fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
typedef struct Case Case;
typedef struct C1 C1;
-typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
typedef struct Renv Renv;
int32 label;
};
-struct Var
-{
- int32 offset;
- LSym* sym;
- char name;
- char etype;
-};
-
struct Reg
{
int32 pc;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
-EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
* list
*/
void listinit(void);
-int Pconv(Fmt*);
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Sconv(Fmt*);
-int Rconv(Fmt*);
-int Xconv(Fmt*);
-int Bconv(Fmt*);
/*
* reg.c
void genmuladd(Node*, Node*, int, Node*);
void shiftit(Type*, Node*, Node*);
-#pragma varargck type "A" int
-#pragma varargck type "B" Bits
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-
/* wrecklessly steal a field */
#define rplink label
listinit(void)
{
listinit8();
- fmtinstall('B', Bconv);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == nil) {
- sprint(ss, "$%d", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
}
zprog.from.scale = 0;
zprog.to = zprog.from;
- listinit();
+ listinit8();
}
/*
* list.c
*/
-int Aconv(Fmt*);
-int Dconv(Fmt*);
-int Pconv(Fmt*);
-int Rconv(Fmt*);
-int Yconv(Fmt*);
void listinit(void);
void zaddr(Biobuf*, Addr*, int, int);
-
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
p->link = p1;
p1->lineno = p->lineno;
p2->lineno = p->lineno;
- p1->loc = 9999;
- p2->loc = 9999;
+ p1->pc = 9999;
+ p2->pc = 9999;
p->as = ACMPL;
p->to.type = D_CONST;
p->to.offset = 0;
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
- p->loc = pcloc;
+ p->pc = pcloc;
pcloc++;
}
if(p->to.type != D_BRANCH)
fatal("patch: not a branch");
p->to.u.branch = to;
- p->to.offset = to->loc;
+ p->to.offset = to->pc;
}
Prog*
+++ /dev/null
-// Derived from Inferno utils/8c/list.c
-// http://code.google.com/p/inferno-os/source/browse/utils/8c/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.
-
-#include <u.h>
-#include <libc.h>
-#include "gg.h"
-
-static int sconsize;
-void
-listinit(void)
-{
-
- fmtinstall('A', Aconv); // as
- fmtinstall('P', Pconv); // Prog*
- fmtinstall('D', Dconv); // Addr*
- fmtinstall('R', Rconv); // reg
- fmtinstall('Y', Yconv); // sconst
-}
-
-int
-Pconv(Fmt *fp)
-{
- char str[STRINGSZ];
- Prog *p;
- char scale[40];
-
- p = va_arg(fp->args, Prog*);
- sconsize = 8;
- scale[0] = '\0';
- if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
- snprint(scale, sizeof scale, "%d,", p->from.scale);
- switch(p->as) {
- default:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
-
- case ADATA:
- sconsize = p->from.scale;
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
- p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
- break;
-
- case ATEXT:
- snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
- p->loc, p->lineno, p->as, &p->from, scale, &p->to);
- break;
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Addr *a;
- int i;
- uint32 d1, d2;
-
- a = va_arg(fp->args, Addr*);
- i = a->type;
- if(i >= D_INDIR) {
- if(a->offset)
- snprint(str, sizeof(str), "%lld(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof(str), "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- if(a->offset)
- snprint(str, sizeof(str), "$%lld,%R", a->offset, i);
- else
- snprint(str, sizeof(str), "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(a->u.branch == nil)
- snprint(str, sizeof(str), "<nil>");
- else
- snprint(str, sizeof(str), "%d", a->u.branch->loc);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof(str), "%lS+%lld(SB)", a->sym, a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof(str), "%lS<>+%lld(SB)", a->sym, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof(str), "%lS+%lld(SP)", a->sym, a->offset);
- break;
-
- case D_PARAM:
- snprint(str, sizeof(str), "%lS+%lld(FP)", a->sym, a->offset);
- break;
-
- case D_CONST:
- if(fp->flags & FmtLong) {
- d1 = a->offset;
- d2 = a->offset2;
- snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
- break;
- }
- snprint(str, sizeof(str), "$%lld", a->offset);
- break;
-
- case D_FCONST:
- snprint(str, sizeof(str), "$(%.17e)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof(str), "$\"%Y\"", a->u.sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof(str), "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- snprint(s, sizeof(s), "(%R*%d)", (int)a->index, (int)a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
- if(a->gotype)
- fmtprint(fp, "{%s}", a->gotype->name);
- return 0;
-}
-
-static char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
-
- "AH", /* [D_AH] */
- "CH",
- "DH",
- "BH",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "CS", /* [D_CS] */
- "SS",
- "DS",
- "ES",
- "FS",
- "GS",
-
- "GDTR", /* [D_GDTR] */
- "IDTR", /* [D_IDTR] */
- "LDTR", /* [D_LDTR] */
- "MSW", /* [D_MSW] */
- "TASK", /* [D_TASK] */
-
- "CR0", /* [D_CR] */
- "CR1",
- "CR2",
- "CR3",
- "CR4",
- "CR5",
- "CR6",
- "CR7",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "X0", /* [D_X0] */
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r < 0 || r >= nelem(regstr) || regstr[r] == nil) {
- snprint(str, sizeof(str), "BAD_R(%d)", r);
- return fmtstrcpy(fp, str);
- }
- return fmtstrcpy(fp, regstr[r]);
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames8[i]);
-}
-
-
-int
-Yconv(Fmt *fp)
-{
- int i, c;
- char str[STRINGSZ], *p, *a;
-
- a = va_arg(fp->args, char*);
- p = str;
- for(i=0; i<sconsize; i++) {
- c = a[i] & 0xff;
- if((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9')) {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- default:
- if(c < 040 || c >= 0177)
- break; /* not portable */
- p[-1] = c;
- continue;
- 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 BtoR(int32);
int BtoF(int32);
-#pragma varargck type "D" Adr*
-
/*
* prog.c
*/
p1 = mal(sizeof(*p1));
clearp(p1);
- p1->loc = 9999;
+ p1->pc = 9999;
p = r->f.prog;
p1->link = p->link;
if(r1 != nil) {
print(" pred:");
for(; r1 != nil; r1 = r->p2link)
- print(" %.4ud", r1->prog->loc);
+ print(" %.4ud", r1->prog->pc);
print("\n");
}
// r1 = r->s1;
// if(r1 != nil) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4ud", r1->prog->loc);
+// print(" %.4ud", r1->prog->pc);
// print("\n");
// }
}
MAXHIST = 40, /* limit of path elements for history symbols */
};
-#pragma varargck type "A" int
-#pragma varargck type "D" Addr*
#pragma varargck type "I" uchar*
-#pragma varargck type "P" Prog*
-#pragma varargck type "R" int
-#pragma varargck type "S" char*
-#pragma varargck type "Y" LSym*
-#pragma varargck type "Z" char*
-#pragma varargck type "i" char*
EXTERN LSym* datap;
EXTERN int debug[128];
EXTERN int32 symsize;
EXTERN int32 textsize;
-int Aconv(Fmt *fp);
-int Dconv(Fmt *fp);
int Iconv(Fmt *fp);
-int Pconv(Fmt *fp);
-int Rconv(Fmt *fp);
-int Sconv(Fmt *fp);
void adddynlib(char *lib);
void adddynrel(LSym *s, Reloc *r);
void adddynrela(LSym *rela, LSym *s, Reloc *r);
void adddynsym(Link *ctxt, LSym *s);
int archreloc(Reloc *r, LSym *s, vlong *val);
void asmb(void);
-void diag(char *fmt, ...);
int elfreloc1(Reloc *r, vlong sectoff);
void elfsetupplt(void);
void listinit(void);
void
listinit(void)
{
-
- fmtinstall('R', Rconv);
- fmtinstall('A', Aconv);
- fmtinstall('D', Dconv);
- fmtinstall('S', Sconv);
- fmtinstall('P', Pconv);
+ listinit8();
fmtinstall('I', Iconv);
}
-static Prog *bigP;
-
-int
-Pconv(Fmt *fp)
-{
- Prog *p;
-
- p = va_arg(fp->args, Prog*);
- bigP = p;
- switch(p->as) {
- case ATEXT:
- if(p->from.scale) {
- fmtprint(fp, "(%d) %A %D,%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- default:
- fmtprint(fp, "(%d) %A %D,%D",
- p->lineno, p->as, &p->from, &p->to);
- break;
- case ADATA:
- case AINIT_:
- case ADYNT_:
- fmtprint(fp, "(%d) %A %D/%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
- break;
- }
- bigP = P;
- return 0;
-}
-
-int
-Aconv(Fmt *fp)
-{
- int i;
-
- i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames8[i]);
-}
-
-char*
-xsymname(LSym *s)
-{
- if(s == nil)
- return "!!noname!!";
- return s->name;
-}
-
-int
-Dconv(Fmt *fp)
-{
- char str[STRINGSZ], s[STRINGSZ];
- Addr *a;
- int i;
-
- a = va_arg(fp->args, Addr*);
- i = a->type;
- if(i >= D_INDIR && i < 2*D_INDIR) {
- if(a->offset)
- snprint(str, sizeof str, "%lld(%R)", a->offset, i-D_INDIR);
- else
- snprint(str, sizeof str, "(%R)", i-D_INDIR);
- goto brk;
- }
- switch(i) {
-
- default:
- snprint(str, sizeof str, "%R", i);
- break;
-
- case D_NONE:
- str[0] = 0;
- break;
-
- case D_BRANCH:
- if(bigP != P && bigP->pcond != P)
- if(a->sym != S)
- snprint(str, sizeof str, "%llux+%s", bigP->pcond->pc,
- a->sym->name);
- else
- snprint(str, sizeof str, "%llux", bigP->pcond->pc);
- else
- snprint(str, sizeof str, "%lld(PC)", a->offset);
- break;
-
- case D_EXTERN:
- snprint(str, sizeof str, "%s+%lld(SB)", xsymname(a->sym), a->offset);
- break;
-
- case D_STATIC:
- snprint(str, sizeof str, "%s<%d>+%lld(SB)", xsymname(a->sym),
- a->sym->version, a->offset);
- break;
-
- case D_AUTO:
- snprint(str, sizeof str, "%s+%lld(SP)", xsymname(a->sym), a->offset);
- break;
-
- case D_PARAM:
- if(a->sym)
- snprint(str, sizeof str, "%s+%lld(FP)", a->sym->name, a->offset);
- else
- snprint(str, sizeof str, "%lld(FP)", a->offset);
- break;
-
- case D_CONST:
- snprint(str, sizeof str, "$%lld", a->offset);
- break;
-
- case D_CONST2:
- snprint(str, sizeof str, "$%lld-%d", a->offset, a->offset2);
- break;
-
- case D_FCONST:
- snprint(str, sizeof str, "$(%.17g)", a->u.dval);
- break;
-
- case D_SCONST:
- snprint(str, sizeof str, "$\"%S\"", a->u.sval);
- break;
-
- case D_ADDR:
- a->type = a->index;
- a->index = D_NONE;
- snprint(str, sizeof str, "$%D", a);
- a->index = a->type;
- a->type = D_ADDR;
- goto conv;
- }
-brk:
- if(a->index != D_NONE) {
- sprint(s, "(%R*%d)", (int)a->index, a->scale);
- strcat(str, s);
- }
-conv:
- fmtstrcpy(fp, str);
-// if(a->gotype)
-// fmtprint(fp, "«%s»", a->gotype->name);
- return 0;
-}
-
-char* regstr[] =
-{
- "AL", /* [D_AL] */
- "CL",
- "DL",
- "BL",
- "AH",
- "CH",
- "DH",
- "BH",
-
- "AX", /* [D_AX] */
- "CX",
- "DX",
- "BX",
- "SP",
- "BP",
- "SI",
- "DI",
-
- "F0", /* [D_F0] */
- "F1",
- "F2",
- "F3",
- "F4",
- "F5",
- "F6",
- "F7",
-
- "CS", /* [D_CS] */
- "SS",
- "DS",
- "ES",
- "FS",
- "GS",
-
- "GDTR", /* [D_GDTR] */
- "IDTR", /* [D_IDTR] */
- "LDTR", /* [D_LDTR] */
- "MSW", /* [D_MSW] */
- "TASK", /* [D_TASK] */
-
- "CR0", /* [D_CR] */
- "CR1",
- "CR2",
- "CR3",
- "CR4",
- "CR5",
- "CR6",
- "CR7",
-
- "DR0", /* [D_DR] */
- "DR1",
- "DR2",
- "DR3",
- "DR4",
- "DR5",
- "DR6",
- "DR7",
-
- "TR0", /* [D_TR] */
- "TR1",
- "TR2",
- "TR3",
- "TR4",
- "TR5",
- "TR6",
- "TR7",
-
- "X0",
- "X1",
- "X2",
- "X3",
- "X4",
- "X5",
- "X6",
- "X7",
-
- "NONE", /* [D_NONE] */
-};
-
-int
-Rconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int r;
-
- r = va_arg(fp->args, int);
- if(r >= D_AL && r <= D_NONE)
- sprint(str, "%s", regstr[r-D_AL]);
- else
- sprint(str, "gok(%d)", r);
-
- 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(double); i++) {
- c = a[i] & 0xff;
- if(c >= 'a' && c <= 'z' ||
- c >= 'A' && c <= 'Z' ||
- c >= '0' && c <= '9') {
- *p++ = c;
- continue;
- }
- *p++ = '\\';
- switch(c) {
- default:
- if(c < 040 || c >= 0177)
- break; /* not portable */
- p[-1] = c;
- continue;
- 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)
{
free(s);
return 0;
}
-
-void
-diag(char *fmt, ...)
-{
- char buf[1024], *tn, *sep;
- va_list arg;
-
- tn = "";
- sep = "";
- if(ctxt->cursym != S) {
- tn = ctxt->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();
- }
-}
typedef struct Bvec Bvec;
typedef struct Dynimp Dynimp;
typedef struct Dynexp Dynexp;
+typedef struct Var Var;
typedef Rune TRune; /* target system type */
uint32 b[];
};
+struct Var
+{
+ vlong offset;
+ LSym* sym;
+ char name;
+ char etype;
+};
+
struct Node
{
Node* left;
EXTERN Bits zbits;
EXTERN Fmt pragcgobuf;
EXTERN Biobuf bstdout;
+EXTERN Var var[NVAR];
extern char *onames[], *tnames[], *gnames[];
extern char *cnames[], *qnames[], *bnames[];
int Oconv(Fmt*);
int Qconv(Fmt*);
int VBconv(Fmt*);
+int Bconv(Fmt*);
void setinclude(char*);
/*
#pragma varargck argpos diag 2
#pragma varargck argpos yyerror 1
+#pragma varargck type "B" Bits
#pragma varargck type "F" Node*
#pragma varargck type "L" int32
#pragma varargck type "Q" int32
fmtinstall('Q', Qconv);
fmtinstall('|', VBconv);
fmtinstall('U', Uconv);
+ fmtinstall('B', Bconv);
}
int
return fmtstrcpy(fp, str);
}
+int
+Bconv(Fmt *fp)
+{
+ char str[STRINGSZ], ss[STRINGSZ], *s;
+ Bits bits;
+ int i;
+
+ str[0] = 0;
+ bits = va_arg(fp->args, Bits);
+ while(bany(&bits)) {
+ i = bnum(bits);
+ if(str[0])
+ strcat(str, " ");
+ if(var[i].sym == nil) {
+ sprint(ss, "$%lld", var[i].offset);
+ s = ss;
+ } else
+ s = var[i].sym->name;
+ if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
+ break;
+ strcat(str, s);
+ bits.b[i/32] &= ~(1L << (i%32));
+ }
+ return fmtstrcpy(fp, str);
+}
+
void
setinclude(char *p)
{
void patch(Prog*, Prog*);
Prog* unpatch(Prog*);
-#pragma varargck type "A" int
#pragma varargck type "B" Mpint*
-#pragma varargck type "D" Addr*
-#pragma varargck type "lD" Addr*
#pragma varargck type "E" int
#pragma varargck type "E" uint
#pragma varargck type "F" Mpflt*
#pragma varargck type "H" NodeList*
#pragma varargck type "J" Node*
-#pragma varargck type "lL" int
-#pragma varargck type "lL" uint
-#pragma varargck type "L" int
-#pragma varargck type "L" uint
+#pragma varargck type "lL" int32
+#pragma varargck type "L" int32
#pragma varargck type "N" Node*
#pragma varargck type "lN" Node*
+#pragma varargck type "O" int
#pragma varargck type "O" uint
-#pragma varargck type "P" Prog*
#pragma varargck type "Q" Bits
-#pragma varargck type "R" int
#pragma varargck type "S" Sym*
-#pragma varargck type "lS" Sym*
+#pragma varargck type "lS" LSym*
#pragma varargck type "T" Type*
#pragma varargck type "lT" Type*
#pragma varargck type "V" Val*
-#pragma varargck type "Y" char*
#pragma varargck type "Z" Strlit*
/*
TempFlow *use; // use list, chained through TempFlow.uselink
TempVar *freelink; // next free temp in Type.opt list
TempVar *merge; // merge var with this one
- uint32 start; // smallest Prog.loc in live range
- uint32 end; // largest Prog.loc in live range
+ vlong start; // smallest Prog.pc in live range
+ vlong end; // largest Prog.pc in live range
uchar addr; // address taken - no accurate end
uchar removed; // removed from program
};
break;
r1->f.active = gen;
p = r1->f.prog;
- if(v->end < p->loc)
- v->end = p->loc;
+ if(v->end < p->pc)
+ v->end = p->pc;
if(r1 == v->def) {
- v->start = p->loc;
+ v->start = p->pc;
break;
}
}
if(nerrors > 0)
errorexit();
}
+
+void
+diag(char *fmt, ...)
+{
+ char buf[1024], *tn, *sep;
+ va_list arg;
+
+ tn = "";
+ sep = "";
+ if(ctxt->cursym != S) {
+ tn = ctxt->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();
+ }
+}
EXTERN char* headstring;
extern Header headers[];
-#pragma varargck type "O" int
#pragma varargck type "Y" LSym*
+#pragma varargck type "Z" char*
+#pragma varargck type "i" char*
// buffered output
void xdefine(char *p, int t, vlong v);
void zerosig(char *sp);
void archinit(void);
+void diag(char *fmt, ...);
+
+#pragma varargck argpos diag 1
static int Dconv(Fmt *fp);
static int Mconv(Fmt *fp);
static int Pconv(Fmt *fp);
+static int Rconv(Fmt *fp);
static int RAconv(Fmt *fp);
static int DSconv(Fmt *fp);
+#pragma varargck type "$" char*
+#pragma varargck type "M" Addr*
+#pragma varargck type "@" Addr*
+
void
listinit5(void)
{
fmtinstall('A', Aconv);
+ fmtinstall('D', Dconv);
fmtinstall('P', Pconv);
+ fmtinstall('R', Rconv);
+
+ // for internal use
fmtinstall('$', DSconv);
fmtinstall('M', Mconv);
- fmtinstall('D', Dconv);
fmtinstall('@', RAconv);
}
".GT", ".LE", "", ".NV",
};
+static Prog* bigP;
+
static int
Pconv(Fmt *fp)
{
int a, s;
p = va_arg(fp->args, Prog*);
+ bigP = p;
a = p->as;
s = p->scond;
strcpy(sc, extra[s & C_SCOND]);
strcat(sc, ".U");
if(a == AMOVM) {
if(p->from.type == D_CONST)
- sprint(str, " %A%s %@,%D", a, sc, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %@,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
else
if(p->to.type == D_CONST)
- sprint(str, " %A%s %D,%@", a, sc, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %D,%@", p->pc, p->lineno, a, sc, &p->from, &p->to);
else
- sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
} else
if(a == ADATA)
- sprint(str, " %A %D/%d,%D", a, &p->from, p->reg, &p->to);
+ sprint(str, "%.5lld (%L) %A %D/%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else
if(p->as == ATEXT)
- sprint(str, " %A %D,%d,%D", a, &p->from, p->reg, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
else
if(p->reg == NREG)
- sprint(str, " %A%s %D,%D", a, sc, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
else
if(p->from.type != D_FREG)
- sprint(str, " %A%s %D,R%d,%D", a, sc, &p->from, p->reg, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %D,R%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
else
- sprint(str, " %A%s %D,F%d,%D", a, sc, &p->from, p->reg, &p->to);
+ sprint(str, "%.5lld (%L) %A%s %D,F%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
+ bigP = nil;
return fmtstrcpy(fp, str);
}
case D_BRANCH:
if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name);
+ else if(bigP != nil && bigP->pcond != nil)
+ sprint(str, "%lld", bigP->pcond->pc);
else if(a->u.branch != nil)
- sprint(str, "%#llx", a->u.branch->pc);
+ sprint(str, "%lld", a->u.branch->pc);
else
- sprint(str, "%d(PC)", (int)(a->offset/*-pc*/));
+ sprint(str, "%lld(PC)", a->offset/*-pc*/);
break;
case D_FCONST:
return fmtstrcpy(fp, str);
}
+static int
+Rconv(Fmt *fp)
+{
+ int r;
+ char str[STRINGSZ];
+
+ r = va_arg(fp->args, int);
+ sprint(str, "R%d", r);
+ return fmtstrcpy(fp, str);
+}
+
static int
Mconv(Fmt *fp)
{
STRINGSZ = 1000
};
+#pragma varargck type "$" char*
+
void
listinit6(void)
{
fmtinstall('A', Aconv);
- fmtinstall('P', Pconv);
- fmtinstall('$', DSconv);
fmtinstall('D', Dconv);
+ fmtinstall('P', Pconv);
fmtinstall('R', Rconv);
+
+ // for internal use
+ fmtinstall('$', DSconv);
}
+static Prog* bigP;
+
static int
Pconv(Fmt *fp)
{
Prog *p;
p = va_arg(fp->args, Prog*);
+ bigP = p;
switch(p->as) {
case ADATA:
- sprint(str, "(%L) %A %D/%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
+ sprint(str, "%.5lld (%L) %A %D/%d,%D",
+ p->pc, p->lineno, p->as, &p->from, p->from.scale, &p->to);
break;
case ATEXT:
if(p->from.scale) {
- sprint(str, "(%L) %A %D,%d,%lD",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%d,%lD",
+ p->pc, p->lineno, p->as, &p->from, p->from.scale, &p->to);
break;
}
- sprint(str, "(%L) %A %D,%lD",
- p->lineno, p->as, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%lD",
+ p->pc, p->lineno, p->as, &p->from, &p->to);
break;
default:
- sprint(str, "(%L) %A %D,%D",
- p->lineno, p->as, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%D",
+ p->pc, p->lineno, p->as, &p->from, &p->to);
break;
}
+ bigP = nil;
return fmtstrcpy(fp, str);
}
case D_BRANCH:
if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name);
+ else if(bigP != nil && bigP->pcond != nil)
+ sprint(str, "%lld", bigP->pcond->pc);
else if(a->u.branch != nil)
- sprint(str, "%#llx", a->u.branch->pc);
+ sprint(str, "%lld", a->u.branch->pc);
else
- sprint(str, "%lld", a->offset);
+ sprint(str, "%lld(PC)", a->offset);
break;
case D_EXTERN:
STRINGSZ = 1000
};
+#pragma varargck type "$" char*
+
void
listinit8(void)
{
fmtinstall('A', Aconv);
- fmtinstall('P', Pconv);
- fmtinstall('$', DSconv);
fmtinstall('D', Dconv);
+ fmtinstall('P', Pconv);
fmtinstall('R', Rconv);
+
+ // for internal use
+ fmtinstall('$', DSconv);
}
+static Prog* bigP;
+
static int
Pconv(Fmt *fp)
{
Prog *p;
p = va_arg(fp->args, Prog*);
+ bigP = p;
switch(p->as) {
case ADATA:
- sprint(str, "(%L) %A %D/%d,%D",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
+ sprint(str, "%.5lld (%L) %A %D/%d,%D",
+ p->pc, p->lineno, p->as, &p->from, p->from.scale, &p->to);
break;
case ATEXT:
if(p->from.scale) {
- sprint(str, "(%L) %A %D,%d,%lD",
- p->lineno, p->as, &p->from, p->from.scale, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%d,%lD",
+ p->pc, p->lineno, p->as, &p->from, p->from.scale, &p->to);
break;
}
- sprint(str, "(%L) %A %D,%lD",
- p->lineno, p->as, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%lD",
+ p->pc, p->lineno, p->as, &p->from, &p->to);
break;
default:
- sprint(str, "(%L) %A %D,%D",
- p->lineno, p->as, &p->from, &p->to);
+ sprint(str, "%.5lld (%L) %A %D,%D",
+ p->pc, p->lineno, p->as, &p->from, &p->to);
break;
}
+ bigP = nil;
return fmtstrcpy(fp, str);
}
case D_BRANCH:
if(a->sym != nil)
sprint(str, "%s(SB)", a->sym->name);
+ else if(bigP != nil && bigP->pcond != nil)
+ sprint(str, "%lld", bigP->pcond->pc);
else if(a->u.branch != nil)
- sprint(str, "%#llx", a->u.branch->pc);
+ sprint(str, "%lld", a->u.branch->pc);
else
- sprint(str, "%lld", a->offset);
+ sprint(str, "%lld(PC)", a->offset);
break;
case D_EXTERN: