Commit 2cae0591 authored by Anthony Martin's avatar Anthony Martin Committed by Russ Cox

cmd/cc, cmd/gc, cmd/ld: consolidate print format routines

We now use the %A, %D, %P, and %R routines from liblink
across the board.

Fixes #7178.
Fixes #7055.

LGTM=iant
R=golang-codereviews, gobot, rsc, dave, iant, remyoudompheng
CC=golang-codereviews
https://golang.org/cl/49170043
parent 14c5c8a9
......@@ -95,7 +95,6 @@ struct Prog
Addr to;
// for 5g, 6g, 8g internal use
uint32 loc; // TODO: merge with pc?
void* opt;
// for 5l, 6l, 8l internal use
......@@ -565,3 +564,13 @@ extern char* anames8[];
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
......@@ -3,15 +3,3 @@
// 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*
......@@ -51,6 +51,12 @@ systemtype(int sys)
#endif
}
int
Lconv(Fmt *fp)
{
return linklinefmt(ctxt, fp);
}
void
main(int argc, char *argv[])
{
......@@ -65,6 +71,7 @@ main(int argc, char *argv[])
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit5();
fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
......
......@@ -50,7 +50,6 @@ typedef struct Case Case;
typedef struct C1 C1;
typedef struct Multab Multab;
typedef struct Hintab Hintab;
typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
......@@ -90,14 +89,6 @@ struct Hintab
char hint[10];
};
struct Var
{
int32 offset;
LSym* sym;
char name;
char etype;
};
struct Reg
{
int32 pc;
......@@ -203,7 +194,6 @@ EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
......@@ -292,13 +282,6 @@ void outcode(void);
* 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
......@@ -349,11 +332,3 @@ void predicate(void);
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*
......@@ -35,32 +35,5 @@
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);
}
......@@ -39,5 +39,5 @@ betypeinit(void)
zprog.from.reg = NREG;
zprog.to = zprog.from;
listinit();
listinit5();
}
......@@ -117,16 +117,6 @@ void datastring(char*, int, Addr*);
/*
* 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*
......@@ -846,7 +846,7 @@ expandchecks(Prog *firstp)
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;
......
......@@ -50,7 +50,7 @@ clearp(Prog *p)
p->to.type = D_NONE;
p->to.name = D_NONE;
p->to.reg = NREG;
p->loc = pcloc;
p->pc = pcloc;
pcloc++;
}
......@@ -138,7 +138,7 @@ patch(Prog *p, Prog *to)
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*
......
// 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);
}
......@@ -1291,9 +1291,9 @@ dumpit(char *str, Flow *r0, int isreg)
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");
......@@ -1302,7 +1302,7 @@ dumpit(char *str, Flow *r0, int isreg)
// if(r1 != nil) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
// print(" %.4ud", r1->prog->loc);
// print(" %.4ud", r1->prog->pc);
// print("\n");
// }
}
......
......@@ -142,24 +142,9 @@ EXTERN uint32 stroffset;
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);
......@@ -167,7 +152,6 @@ void adddynsym(Link *ctxt, LSym *s);
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);
......
......@@ -36,351 +36,10 @@
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)
{
......@@ -409,83 +68,3 @@ 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();
}
}
......@@ -57,6 +57,12 @@ pathchar(void)
return '/';
}
int
Lconv(Fmt *fp)
{
return linklinefmt(ctxt, fp);
}
void
main(int argc, char *argv[])
{
......@@ -71,6 +77,7 @@ main(int argc, char *argv[])
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit6();
fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
......
......@@ -48,7 +48,6 @@
typedef struct Case Case;
typedef struct C1 C1;
typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
typedef struct Renv Renv;
......@@ -83,14 +82,6 @@ struct C1
int32 label;
};
struct Var
{
vlong offset;
LSym* sym;
char name;
char etype;
};
struct Reg
{
int32 pc;
......@@ -203,7 +194,6 @@ EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
......@@ -292,13 +282,6 @@ void outcode(void);
* 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
......@@ -372,14 +355,6 @@ void mulgen(Type*, Node*, Node*);
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);
......@@ -34,32 +34,5 @@
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);
}
......@@ -37,5 +37,5 @@ betypeinit(void)
zprog.from.scale = 0;
zprog.to = zprog.from;
listinit();
listinit6();
}
......@@ -114,14 +114,6 @@ void datagostring(Strlit*, Addr*);
/*
* 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*
......@@ -1101,8 +1101,8 @@ expandchecks(Prog *firstp)
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;
......
......@@ -46,7 +46,7 @@ clearp(Prog *p)
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
p->loc = pcloc;
p->pc = pcloc;
pcloc++;
}
......@@ -136,7 +136,7 @@ patch(Prog *p, Prog *to)
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*
......
// 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);
}
......@@ -466,7 +466,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1 = mal(sizeof(*p1));
clearp(p1);
p1->loc = 9999;
p1->pc = 9999;
p = r->f.prog;
p1->link = p->link;
......@@ -1174,14 +1174,14 @@ dumpit(char *str, Flow *r0, int isreg)
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");
// }
}
......
......@@ -76,13 +76,7 @@ enum
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];
......@@ -96,19 +90,13 @@ EXTERN int32 symsize;
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);
......@@ -122,13 +110,6 @@ vlong rnd(vlong v, vlong r);
#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
{
......
......@@ -33,370 +33,13 @@
#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)
{
......@@ -422,40 +65,3 @@ 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;
}
......@@ -57,6 +57,12 @@ pathchar(void)
return '/';
}
int
Lconv(Fmt *fp)
{
return linklinefmt(ctxt, fp);
}
void
main(int argc, char *argv[])
{
......@@ -71,6 +77,7 @@ main(int argc, char *argv[])
ctxt->bso = &bstdout;
Binit(&bstdout, 1, OWRITE);
listinit8();
fmtinstall('L', Lconv);
ensuresymb(NSYMB);
memset(debug, 0, sizeof(debug));
......
......@@ -48,7 +48,6 @@
typedef struct Case Case;
typedef struct C1 C1;
typedef struct Var Var;
typedef struct Reg Reg;
typedef struct Rgn Rgn;
typedef struct Renv Renv;
......@@ -84,14 +83,6 @@ struct C1
int32 label;
};
struct Var
{
int32 offset;
LSym* sym;
char name;
char etype;
};
struct Reg
{
int32 pc;
......@@ -203,7 +194,6 @@ EXTERN Reg* firstr;
EXTERN Reg* lastr;
EXTERN Reg zreg;
EXTERN Reg* freer;
EXTERN Var var[NVAR];
EXTERN int32* idom;
EXTERN Reg** rpo2r;
EXTERN int32 maxnr;
......@@ -297,13 +287,6 @@ void outcode(void);
* 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
......@@ -377,14 +360,6 @@ void mulgen(Type*, Node*, Node*);
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
......@@ -35,31 +35,4 @@ void
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);
}
......@@ -37,5 +37,5 @@ betypeinit(void)
zprog.from.scale = 0;
zprog.to = zprog.from;
listinit();
listinit8();
}
......@@ -131,14 +131,6 @@ void datagostring(Strlit*, Addr*);
/*
* 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*
......@@ -1207,8 +1207,8 @@ expandchecks(Prog *firstp)
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;
......
......@@ -48,7 +48,7 @@ clearp(Prog *p)
p->from.index = D_NONE;
p->to.type = D_NONE;
p->to.index = D_NONE;
p->loc = pcloc;
p->pc = pcloc;
pcloc++;
}
......@@ -137,7 +137,7 @@ patch(Prog *p, Prog *to)
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*
......
// 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);
}
......@@ -155,8 +155,6 @@ int32 FtoB(int);
int BtoR(int32);
int BtoF(int32);
#pragma varargck type "D" Adr*
/*
* prog.c
*/
......
......@@ -435,7 +435,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1 = mal(sizeof(*p1));
clearp(p1);
p1->loc = 9999;
p1->pc = 9999;
p = r->f.prog;
p1->link = p->link;
......@@ -1139,14 +1139,14 @@ dumpit(char *str, Flow *r0, int isreg)
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");
// }
}
......
......@@ -60,15 +60,7 @@ enum
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];
......@@ -81,19 +73,13 @@ EXTERN LSym* symlist;
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);
......
......@@ -36,297 +36,10 @@
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)
{
......@@ -352,27 +65,3 @@ 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();
}
}
......@@ -55,6 +55,7 @@ typedef struct Bits Bits;
typedef struct Bvec Bvec;
typedef struct Dynimp Dynimp;
typedef struct Dynexp Dynexp;
typedef struct Var Var;
typedef Rune TRune; /* target system type */
......@@ -83,6 +84,14 @@ struct Bvec
uint32 b[];
};
struct Var
{
vlong offset;
LSym* sym;
char name;
char etype;
};
struct Node
{
Node* left;
......@@ -518,6 +527,7 @@ EXTERN int warnreach;
EXTERN Bits zbits;
EXTERN Fmt pragcgobuf;
EXTERN Biobuf bstdout;
EXTERN Var var[NVAR];
extern char *onames[], *tnames[], *gnames[];
extern char *cnames[], *qnames[], *bnames[];
......@@ -595,6 +605,7 @@ int FNconv(Fmt*);
int Oconv(Fmt*);
int Qconv(Fmt*);
int VBconv(Fmt*);
int Bconv(Fmt*);
void setinclude(char*);
/*
......@@ -806,6 +817,7 @@ int machcap(Node*);
#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
......
......@@ -1316,6 +1316,7 @@ cinit(void)
fmtinstall('Q', Qconv);
fmtinstall('|', VBconv);
fmtinstall('U', Uconv);
fmtinstall('B', Bconv);
}
int
......@@ -1487,6 +1488,32 @@ VBconv(Fmt *fp)
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)
{
......
......@@ -1507,31 +1507,24 @@ void nopout(Prog*);
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*
/*
......
......@@ -491,8 +491,8 @@ struct TempVar
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
};
......@@ -754,10 +754,10 @@ mergewalk(TempVar *v, TempFlow *r0, uint32 gen)
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;
}
}
......
......@@ -1443,3 +1443,27 @@ undef(void)
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();
}
}
......@@ -141,8 +141,9 @@ struct Header {
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
......@@ -271,3 +272,6 @@ void wputl(ushort w);
void xdefine(char *p, int t, vlong v);
void zerosig(char *sp);
void archinit(void);
void diag(char *fmt, ...);
#pragma varargck argpos diag 1
......@@ -43,17 +43,25 @@ static int Aconv(Fmt *fp);
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);
}
......@@ -64,6 +72,8 @@ static char *extra [] = {
".GT", ".LE", "", ".NV",
};
static Prog* bigP;
static int
Pconv(Fmt *fp)
{
......@@ -72,6 +82,7 @@ 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]);
......@@ -85,26 +96,27 @@ Pconv(Fmt *fp)
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);
}
......@@ -192,10 +204,12 @@ Dconv(Fmt *fp)
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:
......@@ -288,6 +302,17 @@ DSconv(Fmt *fp)
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)
{
......
......@@ -58,16 +58,22 @@ enum
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)
{
......@@ -75,27 +81,29 @@ 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);
}
......@@ -150,10 +158,12 @@ Dconv(Fmt *fp)
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:
......
......@@ -45,16 +45,22 @@ enum
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)
{
......@@ -62,27 +68,29 @@ 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);
}
......@@ -137,10 +145,12 @@ Dconv(Fmt *fp)
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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment