int thechar = '5';
char* thestring = "arm";
+LinkArch* thelinkarch = &linkarm;
vlong MAXWIDTH = (1LL<<32) - 1;
#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
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;
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);
}
}
#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)
{
p->from.etype = TINT32;
p->from.offset = off;
p->from.reg = NREG;
- p->from.sym = sym;
+ p->from.sym = linksym(sym);
p->reg = n;
a->etype = TINT32;
a->offset = widthptr+4; // skip header
a->reg = NREG;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
}
a->etype = TINT32;
a->offset = 0; // header
a->reg = NREG;
- a->sym = sym;
+ a->sym = linksym(sym);
a->node = sym->def;
}
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 = 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);
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;
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;
{
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);
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)
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;
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
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);
}
}
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)
a->type = D_FREG;
a->reg = n->val.u.reg - REGALLOC_F0;
}
- a->sym = S;
+ a->sym = nil;
break;
case OINDEX:
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;
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;
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:
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;
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:
break;
case CTINT:
case CTRUNE:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
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;
int32 v;
a = va_arg(fp->args, Addr*);
- if(a == A) {
+ if(a == nil) {
sprint(str, "<nil>");
goto conv;
}
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;
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);
int i;
i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
+ return fmtstrcpy(fp, anames5[i]);
}
char* strcond[16] =
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);
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'])
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'])
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;
break;
}
if(debug['P'])
- print(" => %A\n", p->as);
+ print(" => %nil\n", p->as);
return 1;
}
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 */
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 */
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;
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 */
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;
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 */
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))
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))
return 2;
}
}
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->from, v, s, 1))
return 1;
if(!copyas(&p->to, v))
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))
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);
return 0;
case AB: /* funny */
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
return 0;
case ARET: /* funny */
- if(s != A)
+ if(s != nil)
return 1;
return 3;
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)
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;
case ATEXT: /* funny */
if(v->type == D_REG)
- if(v->reg == (uchar)REGARG)
+ if(v->reg == REGARG)
return 3;
return 0;
}
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);
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)
void
addreg(Adr *a, int rn)
{
- a->sym = 0;
+ a->sym = nil;
a->name = D_NONE;
a->type = D_REG;
a->reg = rn;
int thechar = '6';
char* thestring = "amd64";
+LinkArch* thelinkarch = &linkamd64;
vlong MAXWIDTH = 1LL<<50;
#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;
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);
}
}
#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)
{
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;
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];
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;
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 = 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);
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;
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;
{
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);
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)
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
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;
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);
}
}
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)
case OREGISTER:
a->type = n->val.u.reg;
- a->sym = S;
+ a->sym = nil;
break;
// case OINDEX:
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);
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:
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) {
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:
break;
case CTINT:
case CTRUNE:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
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;
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:
int i;
i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
+ return fmtstrcpy(fp, anames6[i]);
}
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;
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)
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'])
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'])
switch(p->as) {
case AJMP:
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
return 0;
case ARET:
- if(s != A)
+ if(s != nil)
return 1;
return 3;
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;
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;
}
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);
return;
p = r->prog;
- t = copyu(p, v0, A);
+ t = copyu(p, v0, nil);
switch(t) {
case 0: // miss
case 1: // use
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;
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
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;
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;
void
addreg(Adr *a, int rn)
{
-
- a->sym = 0;
+ a->sym = nil;
a->offset = 0;
a->type = rn;
int thechar = '8';
char* thestring = "386";
+LinkArch* thelinkarch = &link386;
vlong MAXWIDTH = (1LL<<32) - 1;
#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
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;
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);
}
}
#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)
{
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;
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;
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;
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 = 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);
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;
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;
{
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;
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)
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;
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
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);
}
}
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;
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;
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;
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:
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) {
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:
break;
case CTINT:
case CTRUNE:
- a->sym = S;
+ a->sym = nil;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
break;
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;
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:
int i;
i = va_arg(fp->args, int);
- return fmtstrcpy(fp, anames[i]);
+ return fmtstrcpy(fp, anames8[i]);
}
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;
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'])
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'])
switch(p->as) {
case AJMP:
- if(s != A) {
+ if(s != nil) {
if(copysub(&p->to, v, s, 1))
return 1;
return 0;
return 0;
case ARET:
- if(s != A)
+ if(s != nil)
return 1;
return 3;
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;
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;
}
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);
return;
p = r->prog;
- t = copyu(p, v0, A);
+ t = copyu(p, v0, nil);
switch(t) {
case 0: // miss
case 1: // use
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;
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
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;
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;
void
addreg(Adr *a, int rn)
{
-
- a->sym = 0;
+ a->sym = nil;
a->offset = 0;
a->type = rn;
}
print(" '%s'", d->name);
s = pkglookup(d->name, d->pkg);
- print(" %lS\n", s);
+ print(" %S\n", s);
}
}
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*
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>");
// license that can be found in the LICENSE file.
#include <bio.h>
+#include <link.h>
#undef OAPPEND
STRINGSZ = 200,
MAXALIGN = 7,
UINF = 100,
- HISTSZ = 10,
PRIME1 = 3,
int32 block; // blocknumber to catch redeclaration
int32 lastlineno; // last declaration for diagnostic
Pkg* origpkg; // original package for . import
+ LSym* lsym;
};
#define S ((Sym*)0)
Node* n;
};
-typedef struct Hist Hist;
-struct Hist
-{
- Hist* link;
- char* name;
- int32 line;
- int32 offset;
-};
-#define H ((Hist*)0)
-
// Node ops.
enum
{
int ua; // output - adder
};
-typedef struct Prog Prog;
-#pragma incomplete Prog
-
struct Label
{
uchar used;
EXTERN int32 lexlineno;
EXTERN int32 lineno;
EXTERN int32 prevlineno;
-EXTERN char* pathname;
-EXTERN Hist* hist;
-EXTERN Hist* ehist;
EXTERN char* infile;
EXTERN char* outfile;
extern int thechar;
extern char* thestring;
+extern LinkArch* thelinkarch;
EXTERN int use_sse;
EXTERN char* hunk;
EXTERN int flag_race;
EXTERN int flag_largemodel;
EXTERN int noescape;
+EXTERN Link* ctxt;
EXTERN int nointerface;
EXTERN int fieldtrack_enabled;
/*
* 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);
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
*/
#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;
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*);
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*
signal(SIGSEGV, fault);
#endif
+ ctxt = linknew(thelinkarch);
+
localpkg = mkpkg(strlit(""));
localpkg->prefix = "\"\"";
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)
fakeimport();
return;
}
- prefix = pathname;
+ prefix = ctxt->pathname;
if(localimport != nil)
prefix = localimport;
cleanbuf = mal(strlen(prefix) + strlen(path->s) + 2);
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;
* architecture-independent object file output
*/
-static void outhist(Biobuf *b);
static void dumpglobls(void);
void
dumpexport();
Bprint(bout, "\n!\n");
- outhist(bout);
+ linkouthist(ctxt, bout);
externs = nil;
if(externdcl != nil)
externdcl = tmp;
dumpdata();
- dumpfuncs();
+ linkwritefuncs(ctxt, bout);
Bterm(bout);
}
}
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;
-
- 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;
- }
-}
-
-#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;
+ char *p;
+
+ 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);
}
- bits |= (uint64)(exp+1022L) << 52;
- *ieee = bits;
+ return s->lsym;
}
int
breakpc = P;
pl = newplist();
- pl->name = curfn->nname;
+ pl->name = linksym(curfn->nname->sym);
setlineno(curfn);
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;
}
}
// 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");
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]))
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);
}
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);
}
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++)
void
linehist(char *file, int32 off, int relative)
{
- Hist *h;
- char *cp;
-
if(debug['i']) {
if(file != nil) {
if(off < 0)
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