mirror of https://github.com/golang/go.git
cmd/5g, cmd/6g, cmd/8g: use liblink
Preparation for golang.org/s/go13linker work. This CL does not build by itself. It depends on 35740044 and 35790044 and will be submitted at the same time. R=iant CC=golang-dev https://golang.org/cl/34590045
This commit is contained in:
parent
76a8c873cf
commit
f606c1be80
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
int thechar = '5';
|
||||
char* thestring = "arm";
|
||||
LinkArch* thelinkarch = &linkarm;
|
||||
|
||||
vlong MAXWIDTH = (1LL<<32) - 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,44 +9,6 @@
|
|||
#include "../gc/go.h"
|
||||
#include "../5l/5.out.h"
|
||||
|
||||
typedef struct Addr Addr;
|
||||
|
||||
struct Addr
|
||||
{
|
||||
int32 offset;
|
||||
int32 offset2;
|
||||
|
||||
union {
|
||||
double dval;
|
||||
vlong vval;
|
||||
Prog* branch;
|
||||
char sval[NSNAME];
|
||||
} u;
|
||||
|
||||
Sym* sym;
|
||||
Sym* gotype;
|
||||
Node* node;
|
||||
int width;
|
||||
uchar type;
|
||||
char name;
|
||||
uchar reg;
|
||||
uchar etype;
|
||||
};
|
||||
#define A ((Addr*)0)
|
||||
|
||||
struct Prog
|
||||
{
|
||||
uint32 loc; // pc offset in this func
|
||||
uint32 lineno; // source line that generated this
|
||||
Prog* link; // next instruction in this func
|
||||
void* opt; // for optimizer passes
|
||||
short as; // opcode
|
||||
uchar reg; // doubles as width in DATA op
|
||||
uchar scond;
|
||||
Addr from; // src address
|
||||
Addr to; // dst address
|
||||
};
|
||||
|
||||
#define TEXTFLAG reg
|
||||
|
||||
#define REGALLOC_R0 0
|
||||
|
|
@ -58,7 +20,6 @@ EXTERN int32 dynloc;
|
|||
EXTERN uchar reg[REGALLOC_FMAX+1];
|
||||
EXTERN int32 pcloc; // instruction counter
|
||||
EXTERN Strlit emptystring;
|
||||
extern char* anames[];
|
||||
EXTERN Prog zprog;
|
||||
EXTERN Node* newproc;
|
||||
EXTERN Node* deferproc;
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ cgen_ret(Node *n)
|
|||
if(n->op == ORETJMP) {
|
||||
p->to.name = D_EXTERN;
|
||||
p->to.type = D_CONST;
|
||||
p->to.sym = n->left->sym;
|
||||
p->to.sym = linksym(n->left->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,235 +32,6 @@
|
|||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
|
||||
void
|
||||
zname(Biobuf *b, Sym *s, int t)
|
||||
{
|
||||
BPUTC(b, ANAME); /* as */
|
||||
BPUTC(b, t); /* type */
|
||||
BPUTC(b, s->sym); /* sym */
|
||||
|
||||
Bputname(b, s);
|
||||
}
|
||||
|
||||
void
|
||||
zfile(Biobuf *b, char *p, int n)
|
||||
{
|
||||
BPUTC(b, ANAME);
|
||||
BPUTC(b, D_FILE);
|
||||
BPUTC(b, 1);
|
||||
BPUTC(b, '<');
|
||||
Bwrite(b, p, n);
|
||||
BPUTC(b, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zhist(Biobuf *b, int line, vlong offset)
|
||||
{
|
||||
Addr a;
|
||||
|
||||
BPUTC(b, AHISTORY);
|
||||
BPUTC(b, C_SCOND_NONE);
|
||||
BPUTC(b, NREG);
|
||||
BPUTLE4(b, line);
|
||||
zaddr(b, &zprog.from, 0, 0);
|
||||
a = zprog.to;
|
||||
if(offset != 0) {
|
||||
a.offset = offset;
|
||||
a.type = D_CONST;
|
||||
}
|
||||
zaddr(b, &a, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zaddr(Biobuf *b, Addr *a, int s, int gotype)
|
||||
{
|
||||
int32 l;
|
||||
uint64 e;
|
||||
int i;
|
||||
char *n;
|
||||
|
||||
switch(a->type) {
|
||||
case D_STATIC:
|
||||
case D_AUTO:
|
||||
case D_EXTERN:
|
||||
case D_PARAM:
|
||||
// TODO(kaib): remove once everything seems to work
|
||||
fatal("We should no longer generate these as types");
|
||||
|
||||
default:
|
||||
BPUTC(b, a->type);
|
||||
BPUTC(b, a->reg);
|
||||
BPUTC(b, s);
|
||||
BPUTC(b, a->name);
|
||||
BPUTC(b, gotype);
|
||||
}
|
||||
|
||||
switch(a->type) {
|
||||
default:
|
||||
print("unknown type %d in zaddr\n", a->type);
|
||||
|
||||
case D_NONE:
|
||||
case D_REG:
|
||||
case D_FREG:
|
||||
case D_PSR:
|
||||
break;
|
||||
|
||||
case D_CONST2:
|
||||
l = a->offset2;
|
||||
BPUTLE4(b, l); // fall through
|
||||
case D_OREG:
|
||||
case D_CONST:
|
||||
case D_SHIFT:
|
||||
case D_STATIC:
|
||||
case D_AUTO:
|
||||
case D_EXTERN:
|
||||
case D_PARAM:
|
||||
l = a->offset;
|
||||
BPUTLE4(b, l);
|
||||
break;
|
||||
|
||||
case D_BRANCH:
|
||||
if(a->u.branch == nil)
|
||||
fatal("unpatched branch");
|
||||
a->offset = a->u.branch->loc;
|
||||
l = a->offset;
|
||||
BPUTLE4(b, l);
|
||||
break;
|
||||
|
||||
case D_SCONST:
|
||||
n = a->u.sval;
|
||||
for(i=0; i<NSNAME; i++) {
|
||||
BPUTC(b, *n);
|
||||
n++;
|
||||
}
|
||||
break;
|
||||
|
||||
case D_REGREG:
|
||||
case D_REGREG2:
|
||||
BPUTC(b, a->offset);
|
||||
break;
|
||||
|
||||
case D_FCONST:
|
||||
ieeedtod(&e, a->u.dval);
|
||||
BPUTLE4(b, e);
|
||||
BPUTLE4(b, e >> 32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct { Sym *sym; short type; } h[NSYM];
|
||||
int sym;
|
||||
} z;
|
||||
|
||||
static void
|
||||
zsymreset(void)
|
||||
{
|
||||
for(z.sym=0; z.sym<NSYM; z.sym++) {
|
||||
z.h[z.sym].sym = S;
|
||||
z.h[z.sym].type = 0;
|
||||
}
|
||||
z.sym = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zsym(Sym *s, int t, int *new)
|
||||
{
|
||||
int i;
|
||||
|
||||
*new = 0;
|
||||
if(s == S)
|
||||
return 0;
|
||||
|
||||
i = s->sym;
|
||||
if(i < 0 || i >= NSYM)
|
||||
i = 0;
|
||||
if(z.h[i].type == t && z.h[i].sym == s)
|
||||
return i;
|
||||
i = z.sym;
|
||||
s->sym = i;
|
||||
zname(bout, s, t);
|
||||
z.h[i].sym = s;
|
||||
z.h[i].type = t;
|
||||
if(++z.sym >= NSYM)
|
||||
z.sym = 1;
|
||||
*new = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
zsymaddr(Addr *a, int *new)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = a->name;
|
||||
if(t == D_ADDR)
|
||||
t = a->name;
|
||||
return zsym(a->sym, t, new);
|
||||
}
|
||||
|
||||
void
|
||||
dumpfuncs(void)
|
||||
{
|
||||
Plist *pl;
|
||||
int sf, st, gf, gt, new;
|
||||
Sym *s;
|
||||
Prog *p;
|
||||
|
||||
zsymreset();
|
||||
|
||||
// fix up pc
|
||||
pcloc = 0;
|
||||
for(pl=plist; pl!=nil; pl=pl->link) {
|
||||
if(isblank(pl->name))
|
||||
continue;
|
||||
for(p=pl->firstpc; p!=P; p=p->link) {
|
||||
p->loc = pcloc;
|
||||
if(p->as != ADATA && p->as != AGLOBL)
|
||||
pcloc++;
|
||||
}
|
||||
}
|
||||
|
||||
// put out functions
|
||||
for(pl=plist; pl!=nil; pl=pl->link) {
|
||||
if(isblank(pl->name))
|
||||
continue;
|
||||
|
||||
// -S prints code; -SS prints code and data
|
||||
if(debug['S'] && (pl->name || debug['S']>1)) {
|
||||
s = S;
|
||||
if(pl->name != N)
|
||||
s = pl->name->sym;
|
||||
print("\n--- prog list \"%S\" ---\n", s);
|
||||
for(p=pl->firstpc; p!=P; p=p->link)
|
||||
print("%P\n", p);
|
||||
}
|
||||
|
||||
for(p=pl->firstpc; p!=P; p=p->link) {
|
||||
for(;;) {
|
||||
sf = zsymaddr(&p->from, &new);
|
||||
gf = zsym(p->from.gotype, D_EXTERN, &new);
|
||||
if(new && sf == gf)
|
||||
continue;
|
||||
st = zsymaddr(&p->to, &new);
|
||||
if(new && (st == sf || st == gf))
|
||||
continue;
|
||||
gt = zsym(p->to.gotype, D_EXTERN, &new);
|
||||
if(new && (gt == sf || gt == gf || gt == st))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
BPUTC(bout, p->as);
|
||||
BPUTC(bout, p->scond);
|
||||
BPUTC(bout, p->reg);
|
||||
BPUTLE4(bout, p->lineno);
|
||||
zaddr(bout, &p->from, sf, gf);
|
||||
zaddr(bout, &p->to, st, gt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dsname(Sym *sym, int off, char *t, int n)
|
||||
{
|
||||
|
|
@ -272,7 +43,7 @@ dsname(Sym *sym, int off, char *t, int n)
|
|||
p->from.etype = TINT32;
|
||||
p->from.offset = off;
|
||||
p->from.reg = NREG;
|
||||
p->from.sym = sym;
|
||||
p->from.sym = linksym(sym);
|
||||
|
||||
p->reg = n;
|
||||
|
||||
|
|
@ -299,7 +70,7 @@ datastring(char *s, int len, Addr *a)
|
|||
a->etype = TINT32;
|
||||
a->offset = widthptr+4; // skip header
|
||||
a->reg = NREG;
|
||||
a->sym = sym;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +89,7 @@ datagostring(Strlit *sval, Addr *a)
|
|||
a->etype = TINT32;
|
||||
a->offset = 0; // header
|
||||
a->reg = NREG;
|
||||
a->sym = sym;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +172,7 @@ dstringptr(Sym *s, int off, char *str)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = widthptr;
|
||||
|
||||
|
|
@ -425,7 +196,7 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = widthptr;
|
||||
datagostring(lit, &p->to);
|
||||
|
|
@ -462,7 +233,7 @@ duintxx(Sym *s, int off, uint64 v, int wid)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = wid;
|
||||
p->to.type = D_CONST;
|
||||
|
|
@ -483,12 +254,12 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = widthptr;
|
||||
p->to.type = D_CONST;
|
||||
p->to.name = D_EXTERN;
|
||||
p->to.sym = x;
|
||||
p->to.sym = linksym(x);
|
||||
p->to.offset = xoff;
|
||||
off += widthptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -162,12 +162,7 @@ newplist(void)
|
|||
{
|
||||
Plist *pl;
|
||||
|
||||
pl = mal(sizeof(*pl));
|
||||
if(plist == nil)
|
||||
plist = pl;
|
||||
else
|
||||
plast->link = pl;
|
||||
plast = pl;
|
||||
pl = linknewplist(ctxt);
|
||||
|
||||
pc = mal(sizeof(*pc));
|
||||
clearp(pc);
|
||||
|
|
@ -200,8 +195,8 @@ ggloblnod(Node *nam)
|
|||
|
||||
p = gins(AGLOBL, nam, N);
|
||||
p->lineno = nam->lineno;
|
||||
p->from.gotype = ngotype(nam);
|
||||
p->to.sym = S;
|
||||
p->from.gotype = linksym(ngotype(nam));
|
||||
p->to.sym = nil;
|
||||
p->to.type = D_CONST;
|
||||
p->to.offset = nam->type->width;
|
||||
if(nam->readonly)
|
||||
|
|
@ -228,7 +223,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
|
|||
p = gins(AGLOBL, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->to.type = D_CONST;
|
||||
p->to.name = D_NONE;
|
||||
p->to.offset = width;
|
||||
|
|
@ -246,7 +241,7 @@ gtrack(Sym *s)
|
|||
p = gins(AUSEFIELD, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -275,7 +270,7 @@ afunclit(Addr *a, Node *n)
|
|||
if(a->type == D_CONST && a->name == D_EXTERN || a->type == D_REG) {
|
||||
a->type = D_OREG;
|
||||
if(n->op == ONAME)
|
||||
a->sym = n->sym;
|
||||
a->sym = linksym(n->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1196,10 +1191,12 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
|
|||
void
|
||||
naddr(Node *n, Addr *a, int canemitcode)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
a->type = D_NONE;
|
||||
a->name = D_NONE;
|
||||
a->reg = NREG;
|
||||
a->gotype = S;
|
||||
a->gotype = nil;
|
||||
a->node = N;
|
||||
a->etype = 0;
|
||||
if(n == N)
|
||||
|
|
@ -1223,7 +1220,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->type = D_FREG;
|
||||
a->reg = n->val.u.reg - REGALLOC_F0;
|
||||
}
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
break;
|
||||
|
||||
case OINDEX:
|
||||
|
|
@ -1250,7 +1247,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
case OINDREG:
|
||||
a->type = D_OREG;
|
||||
a->reg = n->val.u.reg;
|
||||
a->sym = n->sym;
|
||||
a->sym = linksym(n->sym);
|
||||
a->offset = n->xoffset;
|
||||
break;
|
||||
|
||||
|
|
@ -1260,7 +1257,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->etype = simtype[n->left->type->etype];
|
||||
a->width = n->left->type->width;
|
||||
a->offset = n->xoffset;
|
||||
a->sym = n->left->sym;
|
||||
a->sym = linksym(n->left->sym);
|
||||
a->type = D_OREG;
|
||||
a->name = D_PARAM;
|
||||
a->node = n->left->orig;
|
||||
|
|
@ -1270,12 +1267,12 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->type = D_OREG;
|
||||
a->reg = 7;
|
||||
a->offset = n->xoffset;
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
break;
|
||||
|
||||
case OCFUNC:
|
||||
naddr(n->left, a, canemitcode);
|
||||
a->sym = n->left->sym;
|
||||
a->sym = linksym(n->left->sym);
|
||||
break;
|
||||
|
||||
case ONAME:
|
||||
|
|
@ -1287,17 +1284,17 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->width = n->type->width;
|
||||
}
|
||||
a->offset = n->xoffset;
|
||||
a->sym = n->sym;
|
||||
s = n->sym;
|
||||
a->node = n->orig;
|
||||
//if(a->node >= (Node*)&n)
|
||||
// fatal("stack node");
|
||||
if(a->sym == S)
|
||||
a->sym = lookup(".noname");
|
||||
if(s == S)
|
||||
s = lookup(".noname");
|
||||
if(n->method) {
|
||||
if(n->type != T)
|
||||
if(n->type->sym != S)
|
||||
if(n->type->sym->pkg != nil)
|
||||
a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
|
||||
s = pkglookup(s->name, n->type->sym->pkg);
|
||||
}
|
||||
|
||||
a->type = D_OREG;
|
||||
|
|
@ -1317,9 +1314,10 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
case PFUNC:
|
||||
a->name = D_EXTERN;
|
||||
a->type = D_CONST;
|
||||
a->sym = funcsym(a->sym);
|
||||
s = funcsym(s);
|
||||
break;
|
||||
}
|
||||
a->sym = linksym(s);
|
||||
break;
|
||||
|
||||
case OLITERAL:
|
||||
|
|
@ -1333,7 +1331,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = mpgetfix(n->val.u.xval);
|
||||
break;
|
||||
|
|
@ -1341,12 +1339,12 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
datagostring(n->val.u.sval, a);
|
||||
break;
|
||||
case CTBOOL:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = n->val.u.bval;
|
||||
break;
|
||||
case CTNIL:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = 0;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ Dconv(Fmt *fp)
|
|||
int32 v;
|
||||
|
||||
a = va_arg(fp->args, Addr*);
|
||||
if(a == A) {
|
||||
if(a == nil) {
|
||||
sprint(str, "<nil>");
|
||||
goto conv;
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ Dconv(Fmt *fp)
|
|||
|
||||
case D_NONE:
|
||||
str[0] = 0;
|
||||
if(a->name != D_NONE || a->reg != NREG || a->sym != S)
|
||||
if(a->name != D_NONE || a->reg != NREG || a->sym != nil)
|
||||
sprint(str, "%M(R%d)(NONE)", a, a->reg);
|
||||
break;
|
||||
|
||||
|
|
@ -143,36 +143,36 @@ Dconv(Fmt *fp)
|
|||
|
||||
case D_REG:
|
||||
sprint(str, "R%d", a->reg);
|
||||
if(a->name != D_NONE || a->sym != S)
|
||||
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 != S)
|
||||
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 != S)
|
||||
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 != S)
|
||||
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 != S)
|
||||
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 != S)
|
||||
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);
|
||||
|
|
@ -208,7 +208,7 @@ Aconv(Fmt *fp)
|
|||
int i;
|
||||
|
||||
i = va_arg(fp->args, int);
|
||||
return fmtstrcpy(fp, anames[i]);
|
||||
return fmtstrcpy(fp, anames5[i]);
|
||||
}
|
||||
|
||||
char* strcond[16] =
|
||||
|
|
@ -323,19 +323,19 @@ Mconv(Fmt *fp)
|
|||
break;
|
||||
|
||||
case D_EXTERN:
|
||||
snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%d(SB)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_STATIC:
|
||||
snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS<>+%d(SB)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_AUTO:
|
||||
snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%d(SP)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_PARAM:
|
||||
snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%d(FP)", a->sym, a->offset);
|
||||
break;
|
||||
}
|
||||
return fmtstrcpy(fp, str);
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||
if(debug['P'])
|
||||
print("; merge; f=%d", f);
|
||||
}
|
||||
t = copyu(p, v2, A);
|
||||
t = copyu(p, v2, nil);
|
||||
switch(t) {
|
||||
case 2: /* rar, can't split */
|
||||
if(debug['P'])
|
||||
|
|
@ -435,7 +435,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||
break;
|
||||
}
|
||||
if(!f) {
|
||||
t = copyu(p, v1, A);
|
||||
t = copyu(p, v1, nil);
|
||||
if(!f && (t == 2 || t == 3 || t == 4)) {
|
||||
f = 1;
|
||||
if(debug['P'])
|
||||
|
|
@ -479,7 +479,7 @@ constprop(Adr *c1, Adr *v1, Flow *r)
|
|||
if(debug['P'])
|
||||
print("; sub%D/%D", &p->from, v1);
|
||||
p->from = *v1;
|
||||
} else if(copyu(p, v1, A) > 1) {
|
||||
} else if(copyu(p, v1, nil) > 1) {
|
||||
if(debug['P'])
|
||||
print("; %Dset; return\n", v1);
|
||||
return;
|
||||
|
|
@ -545,7 +545,7 @@ gotit:
|
|||
break;
|
||||
}
|
||||
if(debug['P'])
|
||||
print(" => %A\n", p->as);
|
||||
print(" => %nil\n", p->as);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -592,10 +592,10 @@ shiftprop(Flow *r)
|
|||
p1 = r1->prog;
|
||||
if(debug['P'])
|
||||
print("\n%P", p1);
|
||||
switch(copyu(p1, &p->to, A)) {
|
||||
switch(copyu(p1, &p->to, nil)) {
|
||||
case 0: /* not used or set */
|
||||
if((p->from.type == D_REG && copyu(p1, &p->from, A) > 1) ||
|
||||
(a.type == D_REG && copyu(p1, &a, A) > 1))
|
||||
if((p->from.type == D_REG && copyu(p1, &p->from, nil) > 1) ||
|
||||
(a.type == D_REG && copyu(p1, &a, nil) > 1))
|
||||
FAIL("args modified");
|
||||
continue;
|
||||
case 3: /* set, not used */
|
||||
|
|
@ -663,7 +663,7 @@ shiftprop(Flow *r)
|
|||
p1 = r1->prog;
|
||||
if(debug['P'])
|
||||
print("\n%P", p1);
|
||||
switch(copyu(p1, &p->to, A)) {
|
||||
switch(copyu(p1, &p->to, nil)) {
|
||||
case 0: /* not used or set */
|
||||
continue;
|
||||
case 3: /* set, not used */
|
||||
|
|
@ -719,7 +719,7 @@ findpre(Flow *r, Adr *v)
|
|||
for(r1=uniqp(r); r1!=nil; r=r1,r1=uniqp(r)) {
|
||||
if(uniqs(r1) != r)
|
||||
return nil;
|
||||
switch(copyu(r1->prog, v, A)) {
|
||||
switch(copyu(r1->prog, v, nil)) {
|
||||
case 1: /* used */
|
||||
case 2: /* read-alter-rewrite */
|
||||
return nil;
|
||||
|
|
@ -745,7 +745,7 @@ findinc(Flow *r, Flow *r2, Adr *v)
|
|||
for(r1=uniqs(r); r1!=nil && r1!=r2; r=r1,r1=uniqs(r)) {
|
||||
if(uniqp(r1) != r)
|
||||
return nil;
|
||||
switch(copyu(r1->prog, v, A)) {
|
||||
switch(copyu(r1->prog, v, nil)) {
|
||||
case 0: /* not touched */
|
||||
continue;
|
||||
case 4: /* set and used */
|
||||
|
|
@ -787,7 +787,7 @@ nochange(Flow *r, Flow *r2, Prog *p)
|
|||
for(; r!=nil && r!=r2; r=uniqs(r)) {
|
||||
p = r->prog;
|
||||
for(i=0; i<n; i++)
|
||||
if(copyu(p, &a[i], A) > 1)
|
||||
if(copyu(p, &a[i], nil) > 1)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -800,7 +800,7 @@ findu1(Flow *r, Adr *v)
|
|||
if(r->active)
|
||||
return 0;
|
||||
r->active = 1;
|
||||
switch(copyu(r->prog, v, A)) {
|
||||
switch(copyu(r->prog, v, nil)) {
|
||||
case 1: /* used */
|
||||
case 2: /* read-alter-rewrite */
|
||||
case 4: /* set and used */
|
||||
|
|
@ -936,14 +936,14 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
switch(p->as) {
|
||||
|
||||
default:
|
||||
print("copyu: can't find %A\n", p->as);
|
||||
print("copyu: can't find %nil\n", p->as);
|
||||
return 2;
|
||||
|
||||
case AMOVM:
|
||||
if(v->type != D_REG)
|
||||
return 0;
|
||||
if(p->from.type == D_CONST) { /* read reglist, read/rar */
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(p->from.offset&(1<<v->reg))
|
||||
return 1;
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
|
|
@ -958,7 +958,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
if(p->from.offset&(1<<v->reg))
|
||||
return 1;
|
||||
} else { /* read/rar, write reglist */
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(p->to.offset&(1<<v->reg))
|
||||
return 1;
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
|
|
@ -1003,7 +1003,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
return 2;
|
||||
}
|
||||
}
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
if(!copyas(&p->to, v))
|
||||
|
|
@ -1063,7 +1063,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
case ACMN:
|
||||
case ACASE:
|
||||
case ATST: /* read,, */
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
if(copysub1(p, v, s, 1))
|
||||
|
|
@ -1108,7 +1108,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
case ABLT:
|
||||
case ABGT:
|
||||
case ABLE:
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
return copysub1(p, v, s, 1);
|
||||
|
|
@ -1120,7 +1120,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
return 0;
|
||||
|
||||
case AB: /* funny */
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -1130,7 +1130,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
return 0;
|
||||
|
||||
case ARET: /* funny */
|
||||
if(s != A)
|
||||
if(s != nil)
|
||||
return 1;
|
||||
return 3;
|
||||
|
||||
|
|
@ -1138,7 +1138,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
if(v->type == D_REG) {
|
||||
if(v->reg <= REGEXT && v->reg > exregoffset)
|
||||
return 2;
|
||||
if(v->reg == (uchar)REGARG)
|
||||
if(v->reg == REGARG)
|
||||
return 2;
|
||||
}
|
||||
if(v->type == D_FREG)
|
||||
|
|
@ -1147,7 +1147,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
if(p->from.type == D_REG && v->type == D_REG && p->from.reg == v->reg)
|
||||
return 2;
|
||||
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -1158,7 +1158,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
|
||||
case ATEXT: /* funny */
|
||||
if(v->type == D_REG)
|
||||
if(v->reg == (uchar)REGARG)
|
||||
if(v->reg == REGARG)
|
||||
return 3;
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -522,12 +522,12 @@ brk:
|
|||
}
|
||||
|
||||
if(p->as == AMOVW && vreg != 0) {
|
||||
if(p->from.sym != S)
|
||||
if(p->from.sym != nil)
|
||||
if(p->from.name == D_AUTO || p->from.name == D_PARAM) {
|
||||
p->from.offset += vreg;
|
||||
// print("%P adjusting from %d %d\n", p, vreg, p->from.type);
|
||||
}
|
||||
if(p->to.sym != S)
|
||||
if(p->to.sym != nil)
|
||||
if(p->to.name == D_AUTO || p->to.name == D_PARAM) {
|
||||
p->to.offset += vreg;
|
||||
// print("%P adjusting to %d %d\n", p, vreg, p->from.type);
|
||||
|
|
@ -595,11 +595,11 @@ addmove(Reg *r, int bn, int rn, int f)
|
|||
a = &p1->to;
|
||||
a->name = v->name;
|
||||
a->node = v->node;
|
||||
a->sym = v->node->sym;
|
||||
a->sym = linksym(v->node->sym);
|
||||
a->offset = v->offset;
|
||||
a->etype = v->etype;
|
||||
a->type = D_OREG;
|
||||
if(a->etype == TARRAY || a->sym == S)
|
||||
if(a->etype == TARRAY || a->sym == nil)
|
||||
a->type = D_CONST;
|
||||
|
||||
if(v->addr)
|
||||
|
|
@ -1171,7 +1171,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
|
|||
void
|
||||
addreg(Adr *a, int rn)
|
||||
{
|
||||
a->sym = 0;
|
||||
a->sym = nil;
|
||||
a->name = D_NONE;
|
||||
a->type = D_REG;
|
||||
a->reg = rn;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
int thechar = '6';
|
||||
char* thestring = "amd64";
|
||||
LinkArch* thelinkarch = &linkamd64;
|
||||
|
||||
vlong MAXWIDTH = 1LL<<50;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,48 +9,12 @@
|
|||
#include "../gc/go.h"
|
||||
#include "../6l/6.out.h"
|
||||
|
||||
typedef struct Addr Addr;
|
||||
|
||||
struct Addr
|
||||
{
|
||||
vlong offset;
|
||||
|
||||
union {
|
||||
double dval;
|
||||
vlong vval;
|
||||
Prog* branch;
|
||||
char sval[NSNAME];
|
||||
} u;
|
||||
|
||||
Sym* gotype;
|
||||
Sym* sym;
|
||||
Node* node;
|
||||
int64 width;
|
||||
uchar type;
|
||||
uchar index;
|
||||
uchar etype;
|
||||
uchar scale; /* doubles as width in DATA op */
|
||||
};
|
||||
#define A ((Addr*)0)
|
||||
|
||||
struct Prog
|
||||
{
|
||||
short as; // opcode
|
||||
uint32 loc; // pc offset in this func
|
||||
uint32 lineno; // source line that generated this
|
||||
Addr from; // src address
|
||||
Addr to; // dst address
|
||||
Prog* link; // next instruction in this func
|
||||
void* opt; // for optimizer passes
|
||||
};
|
||||
|
||||
#define TEXTFLAG from.scale
|
||||
|
||||
EXTERN int32 dynloc;
|
||||
EXTERN uchar reg[D_NONE];
|
||||
EXTERN int32 pcloc; // instruction counter
|
||||
EXTERN Strlit emptystring;
|
||||
extern char* anames[];
|
||||
EXTERN Prog zprog;
|
||||
EXTERN Node* newproc;
|
||||
EXTERN Node* deferproc;
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ cgen_ret(Node *n)
|
|||
p = gins(ARET, N, N);
|
||||
if(n->op == ORETJMP) {
|
||||
p->to.type = D_EXTERN;
|
||||
p->to.sym = n->left->sym;
|
||||
p->to.sym = linksym(n->left->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,231 +32,6 @@
|
|||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
|
||||
void
|
||||
zname(Biobuf *b, Sym *s, int t)
|
||||
{
|
||||
BPUTLE2(b, ANAME); /* as */
|
||||
BPUTC(b, t); /* type */
|
||||
BPUTC(b, s->sym); /* sym */
|
||||
|
||||
Bputname(b, s);
|
||||
}
|
||||
|
||||
void
|
||||
zfile(Biobuf *b, char *p, int n)
|
||||
{
|
||||
BPUTLE2(b, ANAME);
|
||||
BPUTC(b, D_FILE);
|
||||
BPUTC(b, 1);
|
||||
BPUTC(b, '<');
|
||||
Bwrite(b, p, n);
|
||||
BPUTC(b, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zhist(Biobuf *b, int line, vlong offset)
|
||||
{
|
||||
Addr a;
|
||||
|
||||
BPUTLE2(b, AHISTORY);
|
||||
BPUTLE4(b, line);
|
||||
zaddr(b, &zprog.from, 0, 0);
|
||||
a = zprog.to;
|
||||
if(offset != 0) {
|
||||
a.offset = offset;
|
||||
a.type = D_CONST;
|
||||
}
|
||||
zaddr(b, &a, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zaddr(Biobuf *b, Addr *a, int s, int gotype)
|
||||
{
|
||||
int32 l;
|
||||
uint64 e;
|
||||
int i, t;
|
||||
char *n;
|
||||
|
||||
t = 0;
|
||||
if(a->index != D_NONE || a->scale != 0)
|
||||
t |= T_INDEX;
|
||||
if(s != 0)
|
||||
t |= T_SYM;
|
||||
if(gotype != 0)
|
||||
t |= T_GOTYPE;
|
||||
|
||||
switch(a->type) {
|
||||
|
||||
case D_BRANCH:
|
||||
if(a->u.branch == nil)
|
||||
fatal("unpatched branch");
|
||||
a->offset = a->u.branch->loc;
|
||||
|
||||
default:
|
||||
t |= T_TYPE;
|
||||
|
||||
case D_NONE:
|
||||
if(a->offset != 0) {
|
||||
t |= T_OFFSET;
|
||||
l = a->offset;
|
||||
if((vlong)l != a->offset)
|
||||
t |= T_64;
|
||||
}
|
||||
break;
|
||||
case D_FCONST:
|
||||
t |= T_FCONST;
|
||||
break;
|
||||
case D_SCONST:
|
||||
t |= T_SCONST;
|
||||
break;
|
||||
}
|
||||
BPUTC(b, t);
|
||||
|
||||
if(t & T_INDEX) { /* implies index, scale */
|
||||
BPUTC(b, a->index);
|
||||
BPUTC(b, a->scale);
|
||||
}
|
||||
if(t & T_OFFSET) { /* implies offset */
|
||||
l = a->offset;
|
||||
BPUTLE4(b, l);
|
||||
if(t & T_64) {
|
||||
l = a->offset>>32;
|
||||
BPUTLE4(b, l);
|
||||
}
|
||||
}
|
||||
if(t & T_SYM) /* implies sym */
|
||||
BPUTC(b, s);
|
||||
if(t & T_FCONST) {
|
||||
ieeedtod(&e, a->u.dval);
|
||||
BPUTLE4(b, e);
|
||||
BPUTLE4(b, e >> 32);
|
||||
return;
|
||||
}
|
||||
if(t & T_SCONST) {
|
||||
n = a->u.sval;
|
||||
for(i=0; i<NSNAME; i++) {
|
||||
BPUTC(b, *n);
|
||||
n++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(t & T_TYPE)
|
||||
BPUTC(b, a->type);
|
||||
if(t & T_GOTYPE)
|
||||
BPUTC(b, gotype);
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct { Sym *sym; short type; } h[NSYM];
|
||||
int sym;
|
||||
} z;
|
||||
|
||||
static void
|
||||
zsymreset(void)
|
||||
{
|
||||
for(z.sym=0; z.sym<NSYM; z.sym++) {
|
||||
z.h[z.sym].sym = S;
|
||||
z.h[z.sym].type = 0;
|
||||
}
|
||||
z.sym = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zsym(Sym *s, int t, int *new)
|
||||
{
|
||||
int i;
|
||||
|
||||
*new = 0;
|
||||
if(s == S)
|
||||
return 0;
|
||||
|
||||
i = s->sym;
|
||||
if(i < 0 || i >= NSYM)
|
||||
i = 0;
|
||||
if(z.h[i].type == t && z.h[i].sym == s)
|
||||
return i;
|
||||
i = z.sym;
|
||||
s->sym = i;
|
||||
zname(bout, s, t);
|
||||
z.h[i].sym = s;
|
||||
z.h[i].type = t;
|
||||
if(++z.sym >= NSYM)
|
||||
z.sym = 1;
|
||||
*new = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
zsymaddr(Addr *a, int *new)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = a->type;
|
||||
if(t == D_ADDR)
|
||||
t = a->index;
|
||||
return zsym(a->sym, t, new);
|
||||
}
|
||||
|
||||
void
|
||||
dumpfuncs(void)
|
||||
{
|
||||
Plist *pl;
|
||||
int sf, st, gf, gt, new;
|
||||
Sym *s;
|
||||
Prog *p;
|
||||
|
||||
zsymreset();
|
||||
|
||||
// fix up pc
|
||||
pcloc = 0;
|
||||
for(pl=plist; pl!=nil; pl=pl->link) {
|
||||
if(isblank(pl->name))
|
||||
continue;
|
||||
for(p=pl->firstpc; p!=P; p=p->link) {
|
||||
p->loc = pcloc;
|
||||
if(p->as != ADATA && p->as != AGLOBL)
|
||||
pcloc++;
|
||||
}
|
||||
}
|
||||
|
||||
// put out functions
|
||||
for(pl=plist; pl!=nil; pl=pl->link) {
|
||||
if(isblank(pl->name))
|
||||
continue;
|
||||
|
||||
// -S prints code; -SS prints code and data
|
||||
if(debug['S'] && (pl->name || debug['S']>1)) {
|
||||
s = S;
|
||||
if(pl->name != N)
|
||||
s = pl->name->sym;
|
||||
print("\n--- prog list \"%S\" ---\n", s);
|
||||
for(p=pl->firstpc; p!=P; p=p->link)
|
||||
print("%P\n", p);
|
||||
}
|
||||
|
||||
for(p=pl->firstpc; p!=P; p=p->link) {
|
||||
for(;;) {
|
||||
sf = zsymaddr(&p->from, &new);
|
||||
gf = zsym(p->from.gotype, D_EXTERN, &new);
|
||||
if(new && sf == gf)
|
||||
continue;
|
||||
st = zsymaddr(&p->to, &new);
|
||||
if(new && (st == sf || st == gf))
|
||||
continue;
|
||||
gt = zsym(p->to.gotype, D_EXTERN, &new);
|
||||
if(new && (gt == sf || gt == gf || gt == st))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
BPUTLE2(bout, p->as);
|
||||
BPUTLE4(bout, p->lineno);
|
||||
zaddr(bout, &p->from, sf, gf);
|
||||
zaddr(bout, &p->to, st, gt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dsname(Sym *s, int off, char *t, int n)
|
||||
{
|
||||
|
|
@ -267,7 +42,7 @@ dsname(Sym *s, int off, char *t, int n)
|
|||
p->from.index = D_NONE;
|
||||
p->from.offset = off;
|
||||
p->from.scale = n;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
|
||||
p->to.type = D_SCONST;
|
||||
p->to.index = D_NONE;
|
||||
|
|
@ -286,7 +61,7 @@ datastring(char *s, int len, Addr *a)
|
|||
|
||||
sym = stringsym(s, len);
|
||||
a->type = D_EXTERN;
|
||||
a->sym = sym;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
a->offset = widthptr+widthint; // skip header
|
||||
a->etype = simtype[TINT];
|
||||
|
|
@ -303,7 +78,7 @@ datagostring(Strlit *sval, Addr *a)
|
|||
|
||||
sym = stringsym(sval->s, sval->len);
|
||||
a->type = D_EXTERN;
|
||||
a->sym = sym;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
a->offset = 0; // header
|
||||
a->etype = TINT32;
|
||||
|
|
@ -377,7 +152,7 @@ dstringptr(Sym *s, int off, char *str)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
|
||||
|
|
@ -402,7 +177,7 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
datagostring(lit, &p->to);
|
||||
|
|
@ -440,7 +215,7 @@ duintxx(Sym *s, int off, uint64 v, int wid)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = wid;
|
||||
p->to.type = D_CONST;
|
||||
|
|
@ -461,12 +236,12 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
p->to.type = D_ADDR;
|
||||
p->to.index = D_EXTERN;
|
||||
p->to.sym = x;
|
||||
p->to.sym = linksym(x);
|
||||
p->to.offset = xoff;
|
||||
off += widthptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -160,12 +160,7 @@ newplist(void)
|
|||
{
|
||||
Plist *pl;
|
||||
|
||||
pl = mal(sizeof(*pl));
|
||||
if(plist == nil)
|
||||
plist = pl;
|
||||
else
|
||||
plast->link = pl;
|
||||
plast = pl;
|
||||
pl = linknewplist(ctxt);
|
||||
|
||||
pc = mal(sizeof(*pc));
|
||||
clearp(pc);
|
||||
|
|
@ -198,8 +193,8 @@ ggloblnod(Node *nam)
|
|||
|
||||
p = gins(AGLOBL, nam, N);
|
||||
p->lineno = nam->lineno;
|
||||
p->from.gotype = ngotype(nam);
|
||||
p->to.sym = S;
|
||||
p->from.gotype = linksym(ngotype(nam));
|
||||
p->to.sym = nil;
|
||||
p->to.type = D_CONST;
|
||||
p->to.offset = nam->type->width;
|
||||
if(nam->readonly)
|
||||
|
|
@ -216,7 +211,7 @@ gtrack(Sym *s)
|
|||
p = gins(AUSEFIELD, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -237,7 +232,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
|
|||
p = gins(AGLOBL, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->to.type = D_CONST;
|
||||
p->to.index = D_NONE;
|
||||
p->to.offset = width;
|
||||
|
|
@ -272,7 +267,7 @@ afunclit(Addr *a, Node *n)
|
|||
if(a->type == D_ADDR && a->index == D_EXTERN) {
|
||||
a->type = D_EXTERN;
|
||||
a->index = D_NONE;
|
||||
a->sym = n->sym;
|
||||
a->sym = linksym(n->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1098,10 +1093,12 @@ fixlargeoffset(Node *n)
|
|||
void
|
||||
naddr(Node *n, Addr *a, int canemitcode)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
a->scale = 0;
|
||||
a->index = D_NONE;
|
||||
a->type = D_NONE;
|
||||
a->gotype = S;
|
||||
a->gotype = nil;
|
||||
a->node = N;
|
||||
a->width = 0;
|
||||
if(n == N)
|
||||
|
|
@ -1119,7 +1116,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
|
||||
case OREGISTER:
|
||||
a->type = n->val.u.reg;
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
break;
|
||||
|
||||
// case OINDEX:
|
||||
|
|
@ -1144,7 +1141,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
|
||||
case OINDREG:
|
||||
a->type = n->val.u.reg+D_INDIR;
|
||||
a->sym = n->sym;
|
||||
a->sym = linksym(n->sym);
|
||||
a->offset = n->xoffset;
|
||||
if(a->offset != (int32)a->offset)
|
||||
yyerror("offset %lld too large for OINDREG", a->offset);
|
||||
|
|
@ -1156,20 +1153,20 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->etype = simtype[n->left->type->etype];
|
||||
a->width = n->left->type->width;
|
||||
a->offset = n->xoffset;
|
||||
a->sym = n->left->sym;
|
||||
a->sym = linksym(n->left->sym);
|
||||
a->type = D_PARAM;
|
||||
a->node = n->left->orig;
|
||||
break;
|
||||
|
||||
case OCLOSUREVAR:
|
||||
a->type = D_DX+D_INDIR;
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->offset = n->xoffset;
|
||||
break;
|
||||
|
||||
case OCFUNC:
|
||||
naddr(n->left, a, canemitcode);
|
||||
a->sym = n->left->sym;
|
||||
a->sym = linksym(n->left->sym);
|
||||
break;
|
||||
|
||||
case ONAME:
|
||||
|
|
@ -1177,17 +1174,17 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
if(n->type != T)
|
||||
a->etype = simtype[n->type->etype];
|
||||
a->offset = n->xoffset;
|
||||
a->sym = n->sym;
|
||||
s = n->sym;
|
||||
a->node = n->orig;
|
||||
//if(a->node >= (Node*)&n)
|
||||
// fatal("stack node");
|
||||
if(a->sym == S)
|
||||
a->sym = lookup(".noname");
|
||||
if(s == S)
|
||||
s = lookup(".noname");
|
||||
if(n->method) {
|
||||
if(n->type != T)
|
||||
if(n->type->sym != S)
|
||||
if(n->type->sym->pkg != nil)
|
||||
a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
|
||||
s = pkglookup(s->name, n->type->sym->pkg);
|
||||
}
|
||||
|
||||
switch(n->class) {
|
||||
|
|
@ -1207,9 +1204,10 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->index = D_EXTERN;
|
||||
a->type = D_ADDR;
|
||||
a->width = widthptr;
|
||||
a->sym = funcsym(a->sym);
|
||||
s = funcsym(s);
|
||||
break;
|
||||
}
|
||||
a->sym = linksym(s);
|
||||
break;
|
||||
|
||||
case OLITERAL:
|
||||
|
|
@ -1223,7 +1221,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = mpgetfix(n->val.u.xval);
|
||||
break;
|
||||
|
|
@ -1231,12 +1229,12 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
datagostring(n->val.u.sval, a);
|
||||
break;
|
||||
case CTBOOL:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = n->val.u.bval;
|
||||
break;
|
||||
case CTNIL:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = 0;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -114,19 +114,19 @@ Dconv(Fmt *fp)
|
|||
break;
|
||||
|
||||
case D_EXTERN:
|
||||
snprint(str, sizeof(str), "%S+%lld(SB)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%lld(SB)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_STATIC:
|
||||
snprint(str, sizeof(str), "%S<>+%lld(SB)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS<>+%lld(SB)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_AUTO:
|
||||
snprint(str, sizeof(str), "%S+%lld(SP)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%lld(SP)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_PARAM:
|
||||
snprint(str, sizeof(str), "%S+%lld(FP)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%lld(FP)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_CONST:
|
||||
|
|
@ -314,7 +314,7 @@ Aconv(Fmt *fp)
|
|||
int i;
|
||||
|
||||
i = va_arg(fp->args, int);
|
||||
return fmtstrcpy(fp, anames[i]);
|
||||
return fmtstrcpy(fp, anames6[i]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ peep(Prog *firstp)
|
|||
case ALEAL:
|
||||
case ALEAQ:
|
||||
if(regtyp(&p->to))
|
||||
if(p->from.sym != S)
|
||||
if(p->from.sym != nil)
|
||||
if(p->from.index == D_NONE || p->from.index == D_CONST)
|
||||
conprop(r);
|
||||
break;
|
||||
|
|
@ -306,7 +306,7 @@ pushback(Flow *r0)
|
|||
if(p->as != ANOP) {
|
||||
if(!regconsttyp(&p->from) || !regtyp(&p->to))
|
||||
break;
|
||||
if(copyu(p, &p0->to, A) || copyu(p0, &p->to, A))
|
||||
if(copyu(p, &p0->to, nil) || copyu(p0, &p->to, nil))
|
||||
break;
|
||||
}
|
||||
if(p->as == ACALL)
|
||||
|
|
@ -682,7 +682,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||
if(debug['P'])
|
||||
print("; merge; f=%d", f);
|
||||
}
|
||||
t = copyu(p, v2, A);
|
||||
t = copyu(p, v2, nil);
|
||||
switch(t) {
|
||||
case 2: /* rar, can't split */
|
||||
if(debug['P'])
|
||||
|
|
@ -720,7 +720,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||
break;
|
||||
}
|
||||
if(!f) {
|
||||
t = copyu(p, v1, A);
|
||||
t = copyu(p, v1, nil);
|
||||
if(!f && (t == 2 || t == 3 || t == 4)) {
|
||||
f = 1;
|
||||
if(debug['P'])
|
||||
|
|
@ -751,7 +751,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
|
||||
switch(p->as) {
|
||||
case AJMP:
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -761,7 +761,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
return 0;
|
||||
|
||||
case ARET:
|
||||
if(s != A)
|
||||
if(s != nil)
|
||||
return 1;
|
||||
return 3;
|
||||
|
||||
|
|
@ -773,7 +773,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
if(v->type == p->from.type)
|
||||
return 2;
|
||||
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -803,7 +803,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
|
||||
if(info.flags & RightWrite) {
|
||||
if(copyas(&p->to, v)) {
|
||||
if(s != A)
|
||||
if(s != nil)
|
||||
return copysub(&p->from, v, s, 1);
|
||||
if(copyau(&p->from, v))
|
||||
return 4;
|
||||
|
|
@ -812,7 +812,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
}
|
||||
|
||||
if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
return copysub(&p->to, v, s, 1);
|
||||
|
|
@ -940,7 +940,7 @@ loop:
|
|||
return;
|
||||
|
||||
p = r->prog;
|
||||
t = copyu(p, v0, A);
|
||||
t = copyu(p, v0, nil);
|
||||
switch(t) {
|
||||
case 0: // miss
|
||||
case 1: // use
|
||||
|
|
@ -956,7 +956,7 @@ loop:
|
|||
if(p->from.node == p0->from.node)
|
||||
if(p->from.offset == p0->from.offset)
|
||||
if(p->from.scale == p0->from.scale)
|
||||
if(p->from.u.vval == p0->from.u.vval)
|
||||
if(p->from.type == D_FCONST && p->from.u.dval == p0->from.u.dval)
|
||||
if(p->from.index == p0->from.index) {
|
||||
excise(r);
|
||||
goto loop;
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ addmove(Reg *r, int bn, int rn, int f)
|
|||
a->etype = v->etype;
|
||||
a->type = v->name;
|
||||
a->node = v->node;
|
||||
a->sym = v->node->sym;
|
||||
a->sym = linksym(v->node->sym);
|
||||
|
||||
// need to clean this up with wptr and
|
||||
// some of the defaults
|
||||
|
|
@ -905,7 +905,7 @@ regset(Reg *r, uint32 bb)
|
|||
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
|
||||
if(v.type == 0)
|
||||
fatal("zero v.type for %#ux", b);
|
||||
c = copyu(r->f.prog, &v, A);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 3)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
|
|
@ -924,7 +924,7 @@ reguse(Reg *r, uint32 bb)
|
|||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
|
||||
c = copyu(r->f.prog, &v, A);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 1 || c == 2 || c == 4)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
|
|
@ -1066,8 +1066,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
|
|||
void
|
||||
addreg(Adr *a, int rn)
|
||||
{
|
||||
|
||||
a->sym = 0;
|
||||
a->sym = nil;
|
||||
a->offset = 0;
|
||||
a->type = rn;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
int thechar = '8';
|
||||
char* thestring = "386";
|
||||
LinkArch* thelinkarch = &link386;
|
||||
|
||||
vlong MAXWIDTH = (1LL<<32) - 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,42 +9,6 @@
|
|||
#include "../gc/go.h"
|
||||
#include "../8l/8.out.h"
|
||||
|
||||
typedef struct Addr Addr;
|
||||
|
||||
struct Addr
|
||||
{
|
||||
int32 offset;
|
||||
int32 offset2;
|
||||
|
||||
union {
|
||||
double dval;
|
||||
vlong vval;
|
||||
Prog* branch;
|
||||
char sval[NSNAME];
|
||||
} u;
|
||||
|
||||
Sym* gotype;
|
||||
Sym* sym;
|
||||
Node* node;
|
||||
int width;
|
||||
uchar type;
|
||||
uchar index;
|
||||
uchar etype;
|
||||
uchar scale; /* doubles as width in DATA op */
|
||||
};
|
||||
#define A ((Addr*)0)
|
||||
|
||||
struct Prog
|
||||
{
|
||||
short as; // opcode
|
||||
uint32 loc; // pc offset in this func
|
||||
uint32 lineno; // source line that generated this
|
||||
Addr from; // src address
|
||||
Addr to; // dst address
|
||||
Prog* link; // next instruction in this func
|
||||
void* opt; // for optimizer passes
|
||||
};
|
||||
|
||||
#define TEXTFLAG from.scale
|
||||
|
||||
// foptoas flags
|
||||
|
|
@ -59,7 +23,6 @@ EXTERN int32 dynloc;
|
|||
EXTERN uchar reg[D_NONE];
|
||||
EXTERN int32 pcloc; // instruction counter
|
||||
EXTERN Strlit emptystring;
|
||||
extern char* anames[];
|
||||
EXTERN Prog zprog;
|
||||
EXTERN Node* newproc;
|
||||
EXTERN Node* deferproc;
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ cgen_ret(Node *n)
|
|||
p = gins(ARET, N, N);
|
||||
if(n->op == ORETJMP) {
|
||||
p->to.type = D_EXTERN;
|
||||
p->to.sym = n->left->sym;
|
||||
p->to.sym = linksym(n->left->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,229 +32,6 @@
|
|||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
|
||||
void
|
||||
zname(Biobuf *b, Sym *s, int t)
|
||||
{
|
||||
BPUTLE2(b, ANAME); /* as */
|
||||
BPUTC(b, t); /* type */
|
||||
BPUTC(b, s->sym); /* sym */
|
||||
|
||||
Bputname(b, s);
|
||||
}
|
||||
|
||||
void
|
||||
zfile(Biobuf *b, char *p, int n)
|
||||
{
|
||||
BPUTLE2(b, ANAME);
|
||||
BPUTC(b, D_FILE);
|
||||
BPUTC(b, 1);
|
||||
BPUTC(b, '<');
|
||||
Bwrite(b, p, n);
|
||||
BPUTC(b, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zhist(Biobuf *b, int line, vlong offset)
|
||||
{
|
||||
Addr a;
|
||||
|
||||
BPUTLE2(b, AHISTORY);
|
||||
BPUTLE4(b, line);
|
||||
zaddr(b, &zprog.from, 0, 0);
|
||||
a = zprog.to;
|
||||
if(offset != 0) {
|
||||
a.offset = offset;
|
||||
a.type = D_CONST;
|
||||
}
|
||||
zaddr(b, &a, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
zaddr(Biobuf *b, Addr *a, int s, int gotype)
|
||||
{
|
||||
int32 l;
|
||||
uint64 e;
|
||||
int i, t;
|
||||
char *n;
|
||||
|
||||
t = 0;
|
||||
if(a->index != D_NONE || a->scale != 0)
|
||||
t |= T_INDEX;
|
||||
if(s != 0)
|
||||
t |= T_SYM;
|
||||
if(gotype != 0)
|
||||
t |= T_GOTYPE;
|
||||
|
||||
switch(a->type) {
|
||||
|
||||
case D_BRANCH:
|
||||
if(a->u.branch == nil)
|
||||
fatal("unpatched branch");
|
||||
a->offset = a->u.branch->loc;
|
||||
|
||||
default:
|
||||
t |= T_TYPE;
|
||||
|
||||
case D_NONE:
|
||||
if(a->offset != 0)
|
||||
t |= T_OFFSET;
|
||||
if(a->offset2 != 0)
|
||||
t |= T_OFFSET2;
|
||||
break;
|
||||
case D_FCONST:
|
||||
t |= T_FCONST;
|
||||
break;
|
||||
case D_SCONST:
|
||||
t |= T_SCONST;
|
||||
break;
|
||||
}
|
||||
BPUTC(b, t);
|
||||
|
||||
if(t & T_INDEX) { /* implies index, scale */
|
||||
BPUTC(b, a->index);
|
||||
BPUTC(b, a->scale);
|
||||
}
|
||||
if(t & T_OFFSET) { /* implies offset */
|
||||
l = a->offset;
|
||||
BPUTLE4(b, l);
|
||||
}
|
||||
if(t & T_OFFSET2) { /* implies offset */
|
||||
l = a->offset2;
|
||||
BPUTLE4(b, l);
|
||||
}
|
||||
if(t & T_SYM) /* implies sym */
|
||||
BPUTC(b, s);
|
||||
if(t & T_FCONST) {
|
||||
ieeedtod(&e, a->u.dval);
|
||||
BPUTLE4(b, e);
|
||||
BPUTLE4(b, e >> 32);
|
||||
return;
|
||||
}
|
||||
if(t & T_SCONST) {
|
||||
n = a->u.sval;
|
||||
for(i=0; i<NSNAME; i++) {
|
||||
BPUTC(b, *n);
|
||||
n++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(t & T_TYPE)
|
||||
BPUTC(b, a->type);
|
||||
if(t & T_GOTYPE)
|
||||
BPUTC(b, gotype);
|
||||
}
|
||||
|
||||
static struct {
|
||||
struct { Sym *sym; short type; } h[NSYM];
|
||||
int sym;
|
||||
} z;
|
||||
|
||||
static void
|
||||
zsymreset(void)
|
||||
{
|
||||
for(z.sym=0; z.sym<NSYM; z.sym++) {
|
||||
z.h[z.sym].sym = S;
|
||||
z.h[z.sym].type = 0;
|
||||
}
|
||||
z.sym = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
zsym(Sym *s, int t, int *new)
|
||||
{
|
||||
int i;
|
||||
|
||||
*new = 0;
|
||||
if(s == S)
|
||||
return 0;
|
||||
|
||||
i = s->sym;
|
||||
if(i < 0 || i >= NSYM)
|
||||
i = 0;
|
||||
if(z.h[i].type == t && z.h[i].sym == s)
|
||||
return i;
|
||||
i = z.sym;
|
||||
s->sym = i;
|
||||
zname(bout, s, t);
|
||||
z.h[i].sym = s;
|
||||
z.h[i].type = t;
|
||||
if(++z.sym >= NSYM)
|
||||
z.sym = 1;
|
||||
*new = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
zsymaddr(Addr *a, int *new)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = a->type;
|
||||
if(t == D_ADDR)
|
||||
t = a->index;
|
||||
return zsym(a->sym, t, new);
|
||||
}
|
||||
|
||||
void
|
||||
dumpfuncs(void)
|
||||
{
|
||||
Plist *pl;
|
||||
int sf, st, gf, gt, new;
|
||||
Sym *s;
|
||||
Prog *p;
|
||||
|
||||
zsymreset();
|
||||
|
||||
// fix up pc
|
||||
pcloc = 0;
|
||||
for(pl=plist; pl!=nil; pl=pl->link) {
|
||||
if(isblank(pl->name))
|
||||
continue;
|
||||
for(p=pl->firstpc; p!=P; p=p->link) {
|
||||
p->loc = pcloc;
|
||||
if(p->as != ADATA && p->as != AGLOBL)
|
||||
pcloc++;
|
||||
}
|
||||
}
|
||||
|
||||
// put out functions
|
||||
for(pl=plist; pl!=nil; pl=pl->link) {
|
||||
if(isblank(pl->name))
|
||||
continue;
|
||||
|
||||
// -S prints code; -SS prints code and data
|
||||
if(debug['S'] && (pl->name || debug['S']>1)) {
|
||||
s = S;
|
||||
if(pl->name != N)
|
||||
s = pl->name->sym;
|
||||
print("\n--- prog list \"%S\" ---\n", s);
|
||||
for(p=pl->firstpc; p!=P; p=p->link)
|
||||
print("%P\n", p);
|
||||
}
|
||||
|
||||
for(p=pl->firstpc; p!=P; p=p->link) {
|
||||
for(;;) {
|
||||
sf = zsymaddr(&p->from, &new);
|
||||
gf = zsym(p->from.gotype, D_EXTERN, &new);
|
||||
if(new && sf == gf)
|
||||
continue;
|
||||
st = zsymaddr(&p->to, &new);
|
||||
if(new && (st == sf || st == gf))
|
||||
continue;
|
||||
gt = zsym(p->to.gotype, D_EXTERN, &new);
|
||||
if(new && (gt == sf || gt == gf || gt == st))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
BPUTLE2(bout, p->as);
|
||||
BPUTLE4(bout, p->lineno);
|
||||
zaddr(bout, &p->from, sf, gf);
|
||||
zaddr(bout, &p->to, st, gt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dsname(Sym *s, int off, char *t, int n)
|
||||
{
|
||||
|
|
@ -265,7 +42,7 @@ dsname(Sym *s, int off, char *t, int n)
|
|||
p->from.index = D_NONE;
|
||||
p->from.offset = off;
|
||||
p->from.scale = n;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
|
||||
p->to.type = D_SCONST;
|
||||
p->to.index = D_NONE;
|
||||
|
|
@ -284,7 +61,7 @@ datastring(char *s, int len, Addr *a)
|
|||
|
||||
sym = stringsym(s, len);
|
||||
a->type = D_EXTERN;
|
||||
a->sym = sym;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
a->offset = widthptr+4; // skip header
|
||||
a->etype = TINT32;
|
||||
|
|
@ -301,7 +78,7 @@ datagostring(Strlit *sval, Addr *a)
|
|||
|
||||
sym = stringsym(sval->s, sval->len);
|
||||
a->type = D_EXTERN;
|
||||
a->sym = sym;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
a->offset = 0; // header
|
||||
a->etype = TINT32;
|
||||
|
|
@ -386,7 +163,7 @@ dstringptr(Sym *s, int off, char *str)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
|
||||
|
|
@ -411,7 +188,7 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
datagostring(lit, &p->to);
|
||||
|
|
@ -450,7 +227,7 @@ duintxx(Sym *s, int off, uint64 v, int wid)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = wid;
|
||||
p->to.type = D_CONST;
|
||||
|
|
@ -471,12 +248,12 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
|
|||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
p->to.type = D_ADDR;
|
||||
p->to.index = D_EXTERN;
|
||||
p->to.sym = x;
|
||||
p->to.sym = linksym(x);
|
||||
p->to.offset = xoff;
|
||||
off += widthptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -161,13 +161,8 @@ newplist(void)
|
|||
{
|
||||
Plist *pl;
|
||||
|
||||
pl = mal(sizeof(*pl));
|
||||
if(plist == nil)
|
||||
plist = pl;
|
||||
else
|
||||
plast->link = pl;
|
||||
plast = pl;
|
||||
|
||||
pl = linknewplist(ctxt);
|
||||
|
||||
pc = mal(sizeof(*pc));
|
||||
clearp(pc);
|
||||
pl->firstpc = pc;
|
||||
|
|
@ -199,8 +194,8 @@ ggloblnod(Node *nam)
|
|||
|
||||
p = gins(AGLOBL, nam, N);
|
||||
p->lineno = nam->lineno;
|
||||
p->from.gotype = ngotype(nam);
|
||||
p->to.sym = S;
|
||||
p->from.gotype = linksym(ngotype(nam));
|
||||
p->to.sym = nil;
|
||||
p->to.type = D_CONST;
|
||||
p->to.offset = nam->type->width;
|
||||
if(nam->readonly)
|
||||
|
|
@ -227,7 +222,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
|
|||
p = gins(AGLOBL, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
p->to.type = D_CONST;
|
||||
p->to.index = D_NONE;
|
||||
p->to.offset = width;
|
||||
|
|
@ -245,7 +240,7 @@ gtrack(Sym *s)
|
|||
p = gins(AUSEFIELD, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.sym = s;
|
||||
p->from.sym = linksym(s);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -273,7 +268,7 @@ afunclit(Addr *a, Node *n)
|
|||
if(a->type == D_ADDR && a->index == D_EXTERN) {
|
||||
a->type = D_EXTERN;
|
||||
a->index = D_NONE;
|
||||
a->sym = n->sym;
|
||||
a->sym = linksym(n->sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2178,10 +2173,12 @@ gins(int as, Node *f, Node *t)
|
|||
void
|
||||
naddr(Node *n, Addr *a, int canemitcode)
|
||||
{
|
||||
Sym *s;
|
||||
|
||||
a->scale = 0;
|
||||
a->index = D_NONE;
|
||||
a->type = D_NONE;
|
||||
a->gotype = S;
|
||||
a->gotype = nil;
|
||||
a->node = N;
|
||||
if(n == N)
|
||||
return;
|
||||
|
|
@ -2193,12 +2190,12 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
|
||||
case OREGISTER:
|
||||
a->type = n->val.u.reg;
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
break;
|
||||
|
||||
case OINDREG:
|
||||
a->type = n->val.u.reg+D_INDIR;
|
||||
a->sym = n->sym;
|
||||
a->sym = linksym(n->sym);
|
||||
a->offset = n->xoffset;
|
||||
break;
|
||||
|
||||
|
|
@ -2208,7 +2205,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->etype = n->left->type->etype;
|
||||
a->width = n->left->type->width;
|
||||
a->offset = n->xoffset;
|
||||
a->sym = n->left->sym;
|
||||
a->sym = linksym(n->left->sym);
|
||||
a->type = D_PARAM;
|
||||
a->node = n->left->orig;
|
||||
break;
|
||||
|
|
@ -2216,12 +2213,12 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
case OCLOSUREVAR:
|
||||
a->type = D_DX+D_INDIR;
|
||||
a->offset = n->xoffset;
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
break;
|
||||
|
||||
case OCFUNC:
|
||||
naddr(n->left, a, canemitcode);
|
||||
a->sym = n->left->sym;
|
||||
a->sym = linksym(n->left->sym);
|
||||
break;
|
||||
|
||||
case ONAME:
|
||||
|
|
@ -2233,17 +2230,17 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
a->width = n->type->width;
|
||||
}
|
||||
a->offset = n->xoffset;
|
||||
a->sym = n->sym;
|
||||
s = n->sym;
|
||||
a->node = n->orig;
|
||||
//if(a->node >= (Node*)&n)
|
||||
// fatal("stack node");
|
||||
if(a->sym == S)
|
||||
a->sym = lookup(".noname");
|
||||
if(s == S)
|
||||
s = lookup(".noname");
|
||||
if(n->method) {
|
||||
if(n->type != T)
|
||||
if(n->type->sym != S)
|
||||
if(n->type->sym->pkg != nil)
|
||||
a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
|
||||
s = pkglookup(s->name, n->type->sym->pkg);
|
||||
}
|
||||
|
||||
switch(n->class) {
|
||||
|
|
@ -2262,9 +2259,10 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
case PFUNC:
|
||||
a->index = D_EXTERN;
|
||||
a->type = D_ADDR;
|
||||
a->sym = funcsym(a->sym);
|
||||
s = funcsym(s);
|
||||
break;
|
||||
}
|
||||
a->sym = linksym(s);
|
||||
break;
|
||||
|
||||
case OLITERAL:
|
||||
|
|
@ -2278,7 +2276,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = mpgetfix(n->val.u.xval);
|
||||
break;
|
||||
|
|
@ -2286,12 +2284,12 @@ naddr(Node *n, Addr *a, int canemitcode)
|
|||
datagostring(n->val.u.sval, a);
|
||||
break;
|
||||
case CTBOOL:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = n->val.u.bval;
|
||||
break;
|
||||
case CTNIL:
|
||||
a->sym = S;
|
||||
a->sym = nil;
|
||||
a->type = D_CONST;
|
||||
a->offset = 0;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -111,19 +111,19 @@ Dconv(Fmt *fp)
|
|||
break;
|
||||
|
||||
case D_EXTERN:
|
||||
snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%d(SB)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_STATIC:
|
||||
snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS<>+%d(SB)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_AUTO:
|
||||
snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%d(SP)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_PARAM:
|
||||
snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
|
||||
snprint(str, sizeof(str), "%lS+%d(FP)", a->sym, a->offset);
|
||||
break;
|
||||
|
||||
case D_CONST:
|
||||
|
|
@ -266,7 +266,7 @@ Aconv(Fmt *fp)
|
|||
int i;
|
||||
|
||||
i = va_arg(fp->args, int);
|
||||
return fmtstrcpy(fp, anames[i]);
|
||||
return fmtstrcpy(fp, anames8[i]);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ peep(Prog *firstp)
|
|||
switch(p->as) {
|
||||
case ALEAL:
|
||||
if(regtyp(&p->to))
|
||||
if(p->from.sym != S)
|
||||
if(p->from.sym != nil)
|
||||
if(p->from.index == D_NONE || p->from.index == D_CONST)
|
||||
conprop(r);
|
||||
break;
|
||||
|
|
@ -478,7 +478,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||
if(debug['P'])
|
||||
print("; merge; f=%d", f);
|
||||
}
|
||||
t = copyu(p, v2, A);
|
||||
t = copyu(p, v2, nil);
|
||||
switch(t) {
|
||||
case 2: /* rar, can't split */
|
||||
if(debug['P'])
|
||||
|
|
@ -516,7 +516,7 @@ copy1(Adr *v1, Adr *v2, Flow *r, int f)
|
|||
break;
|
||||
}
|
||||
if(!f) {
|
||||
t = copyu(p, v1, A);
|
||||
t = copyu(p, v1, nil);
|
||||
if(!f && (t == 2 || t == 3 || t == 4)) {
|
||||
f = 1;
|
||||
if(debug['P'])
|
||||
|
|
@ -547,7 +547,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
|
||||
switch(p->as) {
|
||||
case AJMP:
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -557,7 +557,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
return 0;
|
||||
|
||||
case ARET:
|
||||
if(s != A)
|
||||
if(s != nil)
|
||||
return 1;
|
||||
return 3;
|
||||
|
||||
|
|
@ -569,7 +569,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
if(v->type == p->from.type)
|
||||
return 2;
|
||||
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->to, v, s, 1))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
@ -599,7 +599,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
|
||||
if(info.flags & RightWrite) {
|
||||
if(copyas(&p->to, v)) {
|
||||
if(s != A)
|
||||
if(s != nil)
|
||||
return copysub(&p->from, v, s, 1);
|
||||
if(copyau(&p->from, v))
|
||||
return 4;
|
||||
|
|
@ -608,7 +608,7 @@ copyu(Prog *p, Adr *v, Adr *s)
|
|||
}
|
||||
|
||||
if(info.flags & (LeftAddr|LeftRead|LeftWrite|RightAddr|RightRead|RightWrite)) {
|
||||
if(s != A) {
|
||||
if(s != nil) {
|
||||
if(copysub(&p->from, v, s, 1))
|
||||
return 1;
|
||||
return copysub(&p->to, v, s, 1);
|
||||
|
|
@ -727,7 +727,7 @@ loop:
|
|||
return;
|
||||
|
||||
p = r->prog;
|
||||
t = copyu(p, v0, A);
|
||||
t = copyu(p, v0, nil);
|
||||
switch(t) {
|
||||
case 0: // miss
|
||||
case 1: // use
|
||||
|
|
@ -743,7 +743,7 @@ loop:
|
|||
if(p->from.node == p0->from.node)
|
||||
if(p->from.offset == p0->from.offset)
|
||||
if(p->from.scale == p0->from.scale)
|
||||
if(p->from.u.vval == p0->from.u.vval)
|
||||
if(p->from.type == D_FCONST && p->from.u.dval == p0->from.u.dval)
|
||||
if(p->from.index == p0->from.index) {
|
||||
excise(r);
|
||||
goto loop;
|
||||
|
|
|
|||
|
|
@ -449,7 +449,7 @@ addmove(Reg *r, int bn, int rn, int f)
|
|||
a->etype = v->etype;
|
||||
a->type = v->name;
|
||||
a->node = v->node;
|
||||
a->sym = v->node->sym;
|
||||
a->sym = linksym(v->node->sym);
|
||||
|
||||
// need to clean this up with wptr and
|
||||
// some of the defaults
|
||||
|
|
@ -876,7 +876,7 @@ regset(Reg *r, uint32 bb)
|
|||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFF ? BtoR(b): BtoF(b);
|
||||
c = copyu(r->f.prog, &v, A);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 3)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
|
|
@ -895,7 +895,7 @@ reguse(Reg *r, uint32 bb)
|
|||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFF ? BtoR(b): BtoF(b);
|
||||
c = copyu(r->f.prog, &v, A);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 1 || c == 2 || c == 4)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
|
|
@ -1037,8 +1037,7 @@ paint3(Reg *r, int bn, int32 rb, int rn)
|
|||
void
|
||||
addreg(Adr *a, int rn)
|
||||
{
|
||||
|
||||
a->sym = 0;
|
||||
a->sym = nil;
|
||||
a->offset = 0;
|
||||
a->type = rn;
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ dumpdcl(char *st)
|
|||
}
|
||||
print(" '%s'", d->name);
|
||||
s = pkglookup(d->name, d->pkg);
|
||||
print(" %lS\n", s);
|
||||
print(" %S\n", s);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,75 +102,7 @@ setfmode(unsigned long *flags)
|
|||
static int
|
||||
Lconv(Fmt *fp)
|
||||
{
|
||||
struct
|
||||
{
|
||||
Hist* incl; /* start of this include file */
|
||||
int32 idel; /* delta line number to apply to include */
|
||||
Hist* line; /* start of this #line directive */
|
||||
int32 ldel; /* delta line number to apply to #line */
|
||||
} a[HISTSZ];
|
||||
int32 lno, d;
|
||||
int i, n;
|
||||
Hist *h;
|
||||
|
||||
lno = va_arg(fp->args, int32);
|
||||
|
||||
n = 0;
|
||||
for(h=hist; h!=H; h=h->link) {
|
||||
if(h->offset < 0)
|
||||
continue;
|
||||
if(lno < h->line)
|
||||
break;
|
||||
if(h->name) {
|
||||
if(h->offset > 0) {
|
||||
// #line directive
|
||||
if(n > 0 && n < HISTSZ) {
|
||||
a[n-1].line = h;
|
||||
a[n-1].ldel = h->line - h->offset + 1;
|
||||
}
|
||||
} else {
|
||||
// beginning of file
|
||||
if(n < HISTSZ) {
|
||||
a[n].incl = h;
|
||||
a[n].idel = h->line;
|
||||
a[n].line = 0;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
n--;
|
||||
if(n > 0 && n < HISTSZ) {
|
||||
d = h->line - a[n].incl->line;
|
||||
a[n-1].ldel += d;
|
||||
a[n-1].idel += d;
|
||||
}
|
||||
}
|
||||
|
||||
if(n > HISTSZ)
|
||||
n = HISTSZ;
|
||||
|
||||
for(i=n-1; i>=0; i--) {
|
||||
if(i != n-1) {
|
||||
if(fp->flags & ~(FmtWidth|FmtPrec))
|
||||
break;
|
||||
fmtprint(fp, " ");
|
||||
}
|
||||
if(debug['L'] || (fp->flags&FmtLong))
|
||||
fmtprint(fp, "%s/", pathname);
|
||||
if(a[i].line)
|
||||
fmtprint(fp, "%s:%d[%s:%d]",
|
||||
a[i].line->name, lno-a[i].ldel+1,
|
||||
a[i].incl->name, lno-a[i].idel+1);
|
||||
else
|
||||
fmtprint(fp, "%s:%d",
|
||||
a[i].incl->name, lno-a[i].idel+1);
|
||||
lno = a[i].incl->line - 1; // now print out start of this file
|
||||
}
|
||||
if(n == 0)
|
||||
fmtprint(fp, "<unknown line number>");
|
||||
|
||||
return 0;
|
||||
return linklinefmt(ctxt, fp);
|
||||
}
|
||||
|
||||
static char*
|
||||
|
|
@ -1580,6 +1512,9 @@ Sconv(Fmt *fp)
|
|||
int r, sm;
|
||||
unsigned long sf;
|
||||
|
||||
if(fp->flags&FmtLong)
|
||||
return linksymfmt(fp);
|
||||
|
||||
s = va_arg(fp->args, Sym*);
|
||||
if(s == S)
|
||||
return fmtstrcpy(fp, "<S>");
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <bio.h>
|
||||
#include <link.h>
|
||||
|
||||
#undef OAPPEND
|
||||
|
||||
|
|
@ -31,7 +32,6 @@ enum
|
|||
STRINGSZ = 200,
|
||||
MAXALIGN = 7,
|
||||
UINF = 100,
|
||||
HISTSZ = 10,
|
||||
|
||||
PRIME1 = 3,
|
||||
|
||||
|
|
@ -395,6 +395,7 @@ struct Sym
|
|||
int32 block; // blocknumber to catch redeclaration
|
||||
int32 lastlineno; // last declaration for diagnostic
|
||||
Pkg* origpkg; // original package for . import
|
||||
LSym* lsym;
|
||||
};
|
||||
#define S ((Sym*)0)
|
||||
|
||||
|
|
@ -423,16 +424,6 @@ struct Iter
|
|||
Node* n;
|
||||
};
|
||||
|
||||
typedef struct Hist Hist;
|
||||
struct Hist
|
||||
{
|
||||
Hist* link;
|
||||
char* name;
|
||||
int32 line;
|
||||
int32 offset;
|
||||
};
|
||||
#define H ((Hist*)0)
|
||||
|
||||
// Node ops.
|
||||
enum
|
||||
{
|
||||
|
|
@ -807,9 +798,6 @@ struct Magic
|
|||
int ua; // output - adder
|
||||
};
|
||||
|
||||
typedef struct Prog Prog;
|
||||
#pragma incomplete Prog
|
||||
|
||||
struct Label
|
||||
{
|
||||
uchar used;
|
||||
|
|
@ -862,9 +850,6 @@ EXTERN Io pushedio;
|
|||
EXTERN int32 lexlineno;
|
||||
EXTERN int32 lineno;
|
||||
EXTERN int32 prevlineno;
|
||||
EXTERN char* pathname;
|
||||
EXTERN Hist* hist;
|
||||
EXTERN Hist* ehist;
|
||||
|
||||
EXTERN char* infile;
|
||||
EXTERN char* outfile;
|
||||
|
|
@ -968,6 +953,7 @@ EXTERN Node* nblank;
|
|||
|
||||
extern int thechar;
|
||||
extern char* thestring;
|
||||
extern LinkArch* thelinkarch;
|
||||
EXTERN int use_sse;
|
||||
|
||||
EXTERN char* hunk;
|
||||
|
|
@ -983,6 +969,7 @@ EXTERN char* flag_installsuffix;
|
|||
EXTERN int flag_race;
|
||||
EXTERN int flag_largemodel;
|
||||
EXTERN int noescape;
|
||||
EXTERN Link* ctxt;
|
||||
|
||||
EXTERN int nointerface;
|
||||
EXTERN int fieldtrack_enabled;
|
||||
|
|
@ -1262,7 +1249,7 @@ int sigfig(Mpflt *a);
|
|||
/*
|
||||
* obj.c
|
||||
*/
|
||||
void Bputname(Biobuf *b, Sym *s);
|
||||
void Bputname(Biobuf *b, LSym *s);
|
||||
int duint16(Sym *s, int off, uint16 v);
|
||||
int duint32(Sym *s, int off, uint32 v);
|
||||
int duint64(Sym *s, int off, uint64 v);
|
||||
|
|
@ -1270,8 +1257,8 @@ int duint8(Sym *s, int off, uint8 v);
|
|||
int duintptr(Sym *s, int off, uint64 v);
|
||||
int dsname(Sym *s, int off, char *dat, int ndat);
|
||||
void dumpobj(void);
|
||||
void ieeedtod(uint64 *ieee, double native);
|
||||
Sym* stringsym(char*, int);
|
||||
LSym* linksym(Sym*);
|
||||
|
||||
/*
|
||||
* order.c
|
||||
|
|
@ -1463,18 +1450,6 @@ int candiscard(Node*);
|
|||
*/
|
||||
#define P ((Prog*)0)
|
||||
|
||||
typedef struct Plist Plist;
|
||||
struct Plist
|
||||
{
|
||||
Node* name;
|
||||
Prog* firstpc;
|
||||
int recur;
|
||||
Plist* link;
|
||||
};
|
||||
|
||||
EXTERN Plist* plist;
|
||||
EXTERN Plist* plast;
|
||||
|
||||
EXTERN Prog* continpc;
|
||||
EXTERN Prog* breakpc;
|
||||
EXTERN Prog* pc;
|
||||
|
|
@ -1504,7 +1479,6 @@ int dstringptr(Sym *s, int off, char *str);
|
|||
int dsymptr(Sym *s, int off, Sym *x, int xoff);
|
||||
int duintxx(Sym *s, int off, uint64 v, int wid);
|
||||
void dumpdata(void);
|
||||
void dumpfuncs(void);
|
||||
void fixautoused(Prog*);
|
||||
void gdata(Node*, Node*, int);
|
||||
void gdatacomplex(Node*, Mpcplx*);
|
||||
|
|
@ -1523,9 +1497,6 @@ Node* nodarg(Type*, int);
|
|||
void nopout(Prog*);
|
||||
void patch(Prog*, Prog*);
|
||||
Prog* unpatch(Prog*);
|
||||
void zfile(Biobuf *b, char *p, int n);
|
||||
void zhist(Biobuf *b, int line, vlong offset);
|
||||
void zname(Biobuf *b, Sym *s, int t);
|
||||
|
||||
#pragma varargck type "A" int
|
||||
#pragma varargck type "B" Mpint*
|
||||
|
|
|
|||
|
|
@ -189,6 +189,8 @@ main(int argc, char *argv[])
|
|||
signal(SIGSEGV, fault);
|
||||
#endif
|
||||
|
||||
ctxt = linknew(thelinkarch);
|
||||
|
||||
localpkg = mkpkg(strlit(""));
|
||||
localpkg->prefix = "\"\"";
|
||||
|
||||
|
|
@ -319,20 +321,6 @@ main(int argc, char *argv[])
|
|||
sysfatal("unsupported setting GO386=%s", p);
|
||||
}
|
||||
|
||||
pathname = mal(1000);
|
||||
if(getwd(pathname, 999) == 0)
|
||||
strcpy(pathname, "/???");
|
||||
|
||||
if(yy_isalpha(pathname[0]) && pathname[1] == ':') {
|
||||
// On Windows.
|
||||
windows = 1;
|
||||
|
||||
// Canonicalize path by converting \ to / (Windows accepts both).
|
||||
for(p=pathname; *p; p++)
|
||||
if(*p == '\\')
|
||||
*p = '/';
|
||||
}
|
||||
|
||||
fmtinstallgo();
|
||||
betypeinit();
|
||||
if(widthptr == 0)
|
||||
|
|
@ -702,7 +690,7 @@ importfile(Val *f, int line)
|
|||
fakeimport();
|
||||
return;
|
||||
}
|
||||
prefix = pathname;
|
||||
prefix = ctxt->pathname;
|
||||
if(localimport != nil)
|
||||
prefix = localimport;
|
||||
cleanbuf = mal(strlen(prefix) + strlen(path->s) + 2);
|
||||
|
|
@ -1528,7 +1516,7 @@ getlinepragma(void)
|
|||
goto out;
|
||||
|
||||
// try to avoid allocating file name over and over
|
||||
for(h=hist; h!=H; h=h->link) {
|
||||
for(h=ctxt->hist; h!=nil; h=h->link) {
|
||||
if(h->name != nil && strcmp(h->name, lexbuf) == 0) {
|
||||
linehist(h->name, n, 0);
|
||||
goto out;
|
||||
|
|
|
|||
182
src/cmd/gc/obj.c
182
src/cmd/gc/obj.c
|
|
@ -10,7 +10,6 @@
|
|||
* architecture-independent object file output
|
||||
*/
|
||||
|
||||
static void outhist(Biobuf *b);
|
||||
static void dumpglobls(void);
|
||||
|
||||
void
|
||||
|
|
@ -31,7 +30,7 @@ dumpobj(void)
|
|||
dumpexport();
|
||||
Bprint(bout, "\n!\n");
|
||||
|
||||
outhist(bout);
|
||||
linkouthist(ctxt, bout);
|
||||
|
||||
externs = nil;
|
||||
if(externdcl != nil)
|
||||
|
|
@ -48,7 +47,7 @@ dumpobj(void)
|
|||
externdcl = tmp;
|
||||
|
||||
dumpdata();
|
||||
dumpfuncs();
|
||||
linkwritefuncs(ctxt, bout);
|
||||
|
||||
Bterm(bout);
|
||||
}
|
||||
|
|
@ -84,175 +83,28 @@ dumpglobls(void)
|
|||
}
|
||||
|
||||
void
|
||||
Bputname(Biobuf *b, Sym *s)
|
||||
Bputname(Biobuf *b, LSym *s)
|
||||
{
|
||||
Bprint(b, "%s", s->pkg->prefix);
|
||||
BPUTC(b, '.');
|
||||
Bwrite(b, s->name, strlen(s->name)+1);
|
||||
}
|
||||
|
||||
static void
|
||||
outzfile(Biobuf *b, char *p)
|
||||
LSym*
|
||||
linksym(Sym *s)
|
||||
{
|
||||
char *q, *q2;
|
||||
char *p;
|
||||
|
||||
while(p) {
|
||||
q = utfrune(p, '/');
|
||||
if(windows) {
|
||||
q2 = utfrune(p, '\\');
|
||||
if(q2 && (!q || q2 < q))
|
||||
q = q2;
|
||||
}
|
||||
if(!q) {
|
||||
zfile(b, p, strlen(p));
|
||||
return;
|
||||
}
|
||||
if(q > p)
|
||||
zfile(b, p, q-p);
|
||||
p = q + 1;
|
||||
if(s == nil)
|
||||
return nil;
|
||||
if(s->lsym != nil)
|
||||
return s->lsym;
|
||||
if(isblanksym(s))
|
||||
s->lsym = linklookup(ctxt, "_", 0);
|
||||
else {
|
||||
p = smprint("%s.%s", s->pkg->prefix, s->name);
|
||||
s->lsym = linklookup(ctxt, p, 0);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
#define isdelim(c) (c == '/' || c == '\\')
|
||||
|
||||
static void
|
||||
outwinname(Biobuf *b, Hist *h, char *ds, char *p)
|
||||
{
|
||||
if(isdelim(p[0])) {
|
||||
// full rooted name
|
||||
zfile(b, ds, 3); // leading "c:/"
|
||||
outzfile(b, p+1);
|
||||
} else {
|
||||
// relative name
|
||||
if(h->offset >= 0 && pathname && pathname[1] == ':') {
|
||||
if(tolowerrune(ds[0]) == tolowerrune(pathname[0])) {
|
||||
// using current drive
|
||||
zfile(b, pathname, 3); // leading "c:/"
|
||||
outzfile(b, pathname+3);
|
||||
} else {
|
||||
// using drive other then current,
|
||||
// we don't have any simple way to
|
||||
// determine current working directory
|
||||
// there, therefore will output name as is
|
||||
zfile(b, ds, 2); // leading "c:"
|
||||
}
|
||||
}
|
||||
outzfile(b, p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
outhist(Biobuf *b)
|
||||
{
|
||||
Hist *h;
|
||||
char *p, ds[] = {'c', ':', '/', 0};
|
||||
char *tofree;
|
||||
int n;
|
||||
static int first = 1;
|
||||
static char *goroot, *goroot_final;
|
||||
|
||||
if(first) {
|
||||
// Decide whether we need to rewrite paths from $GOROOT to $GOROOT_FINAL.
|
||||
first = 0;
|
||||
goroot = getenv("GOROOT");
|
||||
goroot_final = getenv("GOROOT_FINAL");
|
||||
if(goroot == nil)
|
||||
goroot = "";
|
||||
if(goroot_final == nil)
|
||||
goroot_final = goroot;
|
||||
if(strcmp(goroot, goroot_final) == 0) {
|
||||
goroot = nil;
|
||||
goroot_final = nil;
|
||||
}
|
||||
}
|
||||
|
||||
tofree = nil;
|
||||
for(h = hist; h != H; h = h->link) {
|
||||
p = h->name;
|
||||
if(p) {
|
||||
if(goroot != nil) {
|
||||
n = strlen(goroot);
|
||||
if(strncmp(p, goroot, strlen(goroot)) == 0 && p[n] == '/') {
|
||||
tofree = smprint("%s%s", goroot_final, p+n);
|
||||
p = tofree;
|
||||
}
|
||||
}
|
||||
if(windows) {
|
||||
// if windows variable is set, then, we know already,
|
||||
// pathname is started with windows drive specifier
|
||||
// and all '\' were replaced with '/' (see lex.c)
|
||||
if(isdelim(p[0]) && isdelim(p[1])) {
|
||||
// file name has network name in it,
|
||||
// like \\server\share\dir\file.go
|
||||
zfile(b, "//", 2); // leading "//"
|
||||
outzfile(b, p+2);
|
||||
} else if(p[1] == ':') {
|
||||
// file name has drive letter in it
|
||||
ds[0] = p[0];
|
||||
outwinname(b, h, ds, p+2);
|
||||
} else {
|
||||
// no drive letter in file name
|
||||
outwinname(b, h, pathname, p);
|
||||
}
|
||||
} else {
|
||||
if(p[0] == '/') {
|
||||
// full rooted name, like /home/rsc/dir/file.go
|
||||
zfile(b, "/", 1); // leading "/"
|
||||
outzfile(b, p+1);
|
||||
} else {
|
||||
// relative name, like dir/file.go
|
||||
if(h->offset >= 0 && pathname && pathname[0] == '/') {
|
||||
zfile(b, "/", 1); // leading "/"
|
||||
outzfile(b, pathname+1);
|
||||
}
|
||||
outzfile(b, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
zhist(b, h->line, h->offset);
|
||||
if(tofree) {
|
||||
free(tofree);
|
||||
tofree = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ieeedtod(uint64 *ieee, double native)
|
||||
{
|
||||
double fr, ho, f;
|
||||
int exp;
|
||||
uint32 h, l;
|
||||
uint64 bits;
|
||||
|
||||
if(native < 0) {
|
||||
ieeedtod(ieee, -native);
|
||||
*ieee |= 1ULL<<63;
|
||||
return;
|
||||
}
|
||||
if(native == 0) {
|
||||
*ieee = 0;
|
||||
return;
|
||||
}
|
||||
fr = frexp(native, &exp);
|
||||
f = 2097152L; /* shouldn't use fp constants here */
|
||||
fr = modf(fr*f, &ho);
|
||||
h = ho;
|
||||
h &= 0xfffffL;
|
||||
f = 65536L;
|
||||
fr = modf(fr*f, &ho);
|
||||
l = ho;
|
||||
l <<= 16;
|
||||
l |= (int32)(fr*f);
|
||||
bits = ((uint64)h<<32) | l;
|
||||
if(exp < -1021) {
|
||||
// gradual underflow
|
||||
bits |= 1LL<<52;
|
||||
bits >>= -1021 - exp;
|
||||
exp = -1022;
|
||||
}
|
||||
bits |= (uint64)(exp+1022L) << 52;
|
||||
*ieee = bits;
|
||||
return s->lsym;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ compile(Node *fn)
|
|||
breakpc = P;
|
||||
|
||||
pl = newplist();
|
||||
pl->name = curfn->nname;
|
||||
pl->name = linksym(curfn->nname->sym);
|
||||
|
||||
setlineno(curfn);
|
||||
|
||||
|
|
@ -176,7 +176,7 @@ compile(Node *fn)
|
|||
case PPARAMOUT:
|
||||
nodconst(&nod1, types[TUINTPTR], l->n->type->width);
|
||||
p = gins(ATYPE, l->n, &nod1);
|
||||
p->from.gotype = ngotype(l->n);
|
||||
p->from.gotype = linksym(ngotype(l->n));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ blockrpocmp(const void *p1, const void *p2)
|
|||
// A pattern matcher for call instructions. Returns true when the instruction
|
||||
// is a call to a specific package qualified function name.
|
||||
static int
|
||||
iscall(Prog *prog, Sym *name)
|
||||
iscall(Prog *prog, LSym *name)
|
||||
{
|
||||
if(prog == nil)
|
||||
fatal("iscall: prog is nil");
|
||||
|
|
@ -313,14 +313,14 @@ iscall(Prog *prog, Sym *name)
|
|||
static int
|
||||
isselectcommcasecall(Prog *prog)
|
||||
{
|
||||
static Sym* names[5];
|
||||
static LSym* names[5];
|
||||
int32 i;
|
||||
|
||||
if(names[0] == nil) {
|
||||
names[0] = pkglookup("selectsend", runtimepkg);
|
||||
names[1] = pkglookup("selectrecv", runtimepkg);
|
||||
names[2] = pkglookup("selectrecv2", runtimepkg);
|
||||
names[3] = pkglookup("selectdefault", runtimepkg);
|
||||
names[0] = linksym(pkglookup("selectsend", runtimepkg));
|
||||
names[1] = linksym(pkglookup("selectrecv", runtimepkg));
|
||||
names[2] = linksym(pkglookup("selectrecv2", runtimepkg));
|
||||
names[3] = linksym(pkglookup("selectdefault", runtimepkg));
|
||||
}
|
||||
for(i = 0; names[i] != nil; i++)
|
||||
if(iscall(prog, names[i]))
|
||||
|
|
@ -332,10 +332,10 @@ isselectcommcasecall(Prog *prog)
|
|||
static int
|
||||
isnewselect(Prog *prog)
|
||||
{
|
||||
static Sym *sym;
|
||||
static LSym *sym;
|
||||
|
||||
if(sym == nil)
|
||||
sym = pkglookup("newselect", runtimepkg);
|
||||
sym = linksym(pkglookup("newselect", runtimepkg));
|
||||
return iscall(prog, sym);
|
||||
}
|
||||
|
||||
|
|
@ -343,20 +343,20 @@ isnewselect(Prog *prog)
|
|||
static int
|
||||
isselectgocall(Prog *prog)
|
||||
{
|
||||
static Sym *sym;
|
||||
static LSym *sym;
|
||||
|
||||
if(sym == nil)
|
||||
sym = pkglookup("selectgo", runtimepkg);
|
||||
sym = linksym(pkglookup("selectgo", runtimepkg));
|
||||
return iscall(prog, sym);
|
||||
}
|
||||
|
||||
static int
|
||||
isdeferreturn(Prog *prog)
|
||||
{
|
||||
static Sym *sym;
|
||||
static LSym *sym;
|
||||
|
||||
if(sym == nil)
|
||||
sym = pkglookup("deferreturn", runtimepkg);
|
||||
sym = linksym(pkglookup("deferreturn", runtimepkg));
|
||||
return iscall(prog, sym);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,9 @@ noreturn(Prog *p)
|
|||
symlist[4] = pkglookup("panicwrap", runtimepkg);
|
||||
}
|
||||
|
||||
s = p->to.sym;
|
||||
if(p->to.node == nil)
|
||||
return 0;
|
||||
s = p->to.node->sym;
|
||||
if(s == S)
|
||||
return 0;
|
||||
for(i=0; symlist[i]!=S; i++)
|
||||
|
|
|
|||
|
|
@ -258,9 +258,6 @@ fatal(char *fmt, ...)
|
|||
void
|
||||
linehist(char *file, int32 off, int relative)
|
||||
{
|
||||
Hist *h;
|
||||
char *cp;
|
||||
|
||||
if(debug['i']) {
|
||||
if(file != nil) {
|
||||
if(off < 0)
|
||||
|
|
@ -274,25 +271,10 @@ linehist(char *file, int32 off, int relative)
|
|||
print("end of import");
|
||||
print(" at line %L\n", lexlineno);
|
||||
}
|
||||
|
||||
if(off < 0 && file[0] != '/' && !relative) {
|
||||
cp = mal(strlen(file) + strlen(pathname) + 2);
|
||||
sprint(cp, "%s/%s", pathname, file);
|
||||
file = cp;
|
||||
}
|
||||
|
||||
h = mal(sizeof(Hist));
|
||||
h->name = file;
|
||||
h->line = lexlineno;
|
||||
h->offset = off;
|
||||
h->link = H;
|
||||
if(ehist == H) {
|
||||
hist = h;
|
||||
ehist = h;
|
||||
return;
|
||||
}
|
||||
ehist->link = h;
|
||||
ehist = h;
|
||||
|
||||
if(off < 0 && file[0] != '/' && !relative)
|
||||
file = smprint("%s/%s", ctxt->pathname, file);
|
||||
linklinehist(ctxt, lexlineno, file, off);
|
||||
}
|
||||
|
||||
int32
|
||||
|
|
|
|||
Loading…
Reference in New Issue