1
0
mirror of https://github.com/golang/go synced 2024-11-20 04:54:44 -07:00

agen, sgen, cgen_callret, cgen_asop, D_ADDR handling, gmove

8bit and 16bit, some optoas, replaced Addr.index with
Addr.name

empty function compiles, mutex compiles

R=rsc
APPROVED=rsc
DELTA=908  (83 added, 41 deleted, 784 changed)
OCL=31127
CL=31188
This commit is contained in:
Kai Backman 2009-07-06 06:42:37 -07:00
parent a7735f8a16
commit 86987055a3
7 changed files with 803 additions and 761 deletions

View File

@ -176,12 +176,8 @@ cgen(Node *n, Node *res)
case OXOR: case OXOR:
case OADD: case OADD:
case OMUL: case OMUL:
fatal("cgen OMUL not implemented"); a = optoas(n->op, nl->type);
// a = optoas(n->op, nl->type); goto sbop;
// if(a != AIMULB)
// goto sbop;
// cgen_bmul(n->op, nl, nr, res);
break;
// asymmetric binary // asymmetric binary
case OSUB: case OSUB:
@ -345,224 +341,227 @@ ret:
void void
agen(Node *n, Node *res) agen(Node *n, Node *res)
{ {
fatal("agen not implemented"); Node *nl, *nr;
// Node *nl, *nr; Node n1, n2, n3, tmp;
// Node n1, n2, n3, tmp; Prog *p1;
// Prog *p1; uint32 w;
// uint32 w; uint64 v;
// uint64 v; Type *t;
// Type *t;
// if(debug['g']) { if(debug['g']) {
// dump("\nagen-res", res); dump("\nagen-res", res);
// dump("agen-r", n); dump("agen-r", n);
// } }
// if(n == N || n->type == T) if(n == N || n->type == T)
// return; return;
// if(!isptr[res->type->etype]) if(!isptr[res->type->etype])
// fatal("agen: not tptr: %T", res->type); fatal("agen: not tptr: %T", res->type);
//
// while(n->op == OCONVNOP)
// n = n->left;
//
// if(n->addable) {
// regalloc(&n1, types[tptr], res);
// gins(ALEAQ, n, &n1);
// gmove(&n1, res);
// regfree(&n1);
// goto ret;
// }
// nl = n->left; while(n->op == OCONVNOP)
// nr = n->right; n = n->left;
// switch(n->op) { if(n->addable) {
// default: memset(&n1, 0, sizeof n1);
// fatal("agen: unknown op %N", n); n1.op = OADDR;
// break; n1.left = n;
regalloc(&n2, types[tptr], res);
gins(AMOVW, &n1, &n2);
gmove(&n2, res);
regfree(&n2);
goto ret;
}
// case OCALLMETH: nl = n->left;
// cgen_callmeth(n, 0); nr = n->right;
// cgen_aret(n, res);
// break;
// case OCALLINTER: switch(n->op) {
// cgen_callinter(n, res, 0); default:
// cgen_aret(n, res); fatal("agen: unknown op %N", n);
// break; break;
// case OCALL: case OCALLMETH:
// cgen_call(n, 0); cgen_callmeth(n, 0);
// cgen_aret(n, res); cgen_aret(n, res);
// break; break;
case OCALLINTER:
cgen_callinter(n, res, 0);
cgen_aret(n, res);
break;
case OCALL:
cgen_call(n, 0);
cgen_aret(n, res);
break;
// TODO(kaib): Use the OINDEX case from 8g instead of this one. // TODO(kaib): Use the OINDEX case from 8g instead of this one.
// case OINDEX: case OINDEX:
// w = n->type->width; w = n->type->width;
// if(nr->addable) if(nr->addable)
// goto irad; goto irad;
// if(nl->addable) { if(nl->addable) {
// if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
// regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
// cgen(nr, &n1); cgen(nr, &n1);
// } }
// regalloc(&n3, types[tptr], res); regalloc(&n3, types[tptr], res);
// agen(nl, &n3); agen(nl, &n3);
// goto index; goto index;
// } }
// cgen(nr, res); cgen(nr, res);
// tempname(&tmp, nr->type); tempname(&tmp, nr->type);
// gmove(res, &tmp); gmove(res, &tmp);
// irad: irad:
// regalloc(&n3, types[tptr], res); regalloc(&n3, types[tptr], res);
// agen(nl, &n3); agen(nl, &n3);
// if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
// regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
// cgen(nr, &n1); cgen(nr, &n1);
// } }
// goto index; goto index;
// index: index:
// // &a is in &n3 (allocated in res) // &a is in &n3 (allocated in res)
// // i is in &n1 (if not constant) // i is in &n1 (if not constant)
// // w is width // w is width
// if(w == 0) if(w == 0)
// fatal("index is zero width"); fatal("index is zero width");
// // constant index // constant index
// if(isconst(nr, CTINT)) { if(isconst(nr, CTINT)) {
// v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
// if(isslice(nl->type)) { if(isslice(nl->type)) {
// if(!debug['B']) { if(!debug['B']) {
// n1 = n3; n1 = n3;
// n1.op = OINDREG; n1.op = OINDREG;
// n1.type = types[tptr]; n1.type = types[tptr];
// n1.xoffset = Array_nel; n1.xoffset = Array_nel;
// nodconst(&n2, types[TUINT64], v); nodconst(&n2, types[TUINT64], v);
// gins(optoas(OCMP, types[TUINT32]), &n1, &n2); gins(optoas(OCMP, types[TUINT32]), &n1, &n2);
// p1 = gbranch(optoas(OGT, types[TUINT32]), T); p1 = gbranch(optoas(OGT, types[TUINT32]), T);
// ginscall(throwindex, 0); ginscall(throwindex, 0);
// patch(p1, pc); patch(p1, pc);
// } }
// n1 = n3; n1 = n3;
// n1.op = OINDREG; n1.op = OINDREG;
// n1.type = types[tptr]; n1.type = types[tptr];
// n1.xoffset = Array_array; n1.xoffset = Array_array;
// gmove(&n1, &n3); gmove(&n1, &n3);
// } else } else
// if(!debug['B']) { if(!debug['B']) {
// if(v < 0) if(v < 0)
// yyerror("out of bounds on array"); yyerror("out of bounds on array");
// else else
// if(v >= nl->type->bound) if(v >= nl->type->bound)
// yyerror("out of bounds on array"); yyerror("out of bounds on array");
// } }
// nodconst(&n2, types[tptr], v*w); nodconst(&n2, types[tptr], v*w);
// gins(optoas(OADD, types[tptr]), &n2, &n3); gins(optoas(OADD, types[tptr]), &n2, &n3);
// gmove(&n3, res); gmove(&n3, res);
// regfree(&n3); regfree(&n3);
// break; break;
// } }
// // type of the index // type of the index
// t = types[TUINT64]; t = types[TUINT64];
// if(issigned[n1.type->etype]) if(issigned[n1.type->etype])
// t = types[TINT64]; t = types[TINT64];
// regalloc(&n2, t, &n1); // i regalloc(&n2, t, &n1); // i
// gmove(&n1, &n2); gmove(&n1, &n2);
// regfree(&n1); regfree(&n1);
// if(!debug['B']) { if(!debug['B']) {
// // check bounds // check bounds
// if(isslice(nl->type)) { if(isslice(nl->type)) {
// n1 = n3; n1 = n3;
// n1.op = OINDREG; n1.op = OINDREG;
// n1.type = types[tptr]; n1.type = types[tptr];
// n1.xoffset = Array_nel; n1.xoffset = Array_nel;
// } else } else
// nodconst(&n1, types[TUINT64], nl->type->bound); nodconst(&n1, types[TUINT64], nl->type->bound);
// gins(optoas(OCMP, types[TUINT32]), &n2, &n1); gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
// p1 = gbranch(optoas(OLT, types[TUINT32]), T); p1 = gbranch(optoas(OLT, types[TUINT32]), T);
// ginscall(throwindex, 0); ginscall(throwindex, 0);
// patch(p1, pc); patch(p1, pc);
// } }
// if(isslice(nl->type)) { if(isslice(nl->type)) {
// n1 = n3; n1 = n3;
// n1.op = OINDREG; n1.op = OINDREG;
// n1.type = types[tptr]; n1.type = types[tptr];
// n1.xoffset = Array_array; n1.xoffset = Array_array;
// gmove(&n1, &n3); gmove(&n1, &n3);
// } }
// if(w == 1 || w == 2 || w == 4 || w == 8) { if(w == 1 || w == 2 || w == 4 || w == 8) {
// p1 = gins(ALEAQ, &n2, &n3); memset(&tmp, 0, sizeof tmp);
// p1->from.scale = w; tmp.op = OADDR;
// p1->from.index = p1->from.type; tmp.left = &n2;
// p1->from.type = p1->to.type + D_INDIR; p1 = gins(AMOVW, &tmp, &n3);
// } else { p1->from.scale = w;
// nodconst(&n1, t, w); } else {
// gins(optoas(OMUL, t), &n1, &n2); nodconst(&n1, t, w);
// gins(optoas(OADD, types[tptr]), &n2, &n3); gins(optoas(OMUL, t), &n1, &n2);
// gmove(&n3, res); gins(optoas(OADD, types[tptr]), &n2, &n3);
// } gmove(&n3, res);
}
// gmove(&n3, res); gmove(&n3, res);
// regfree(&n2); regfree(&n2);
// regfree(&n3); regfree(&n3);
// break; break;
// case ONAME: case ONAME:
// // should only get here with names in this func. // should only get here with names in this func.
// if(n->funcdepth > 0 && n->funcdepth != funcdepth) { if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
// dump("bad agen", n); dump("bad agen", n);
// fatal("agen: bad ONAME funcdepth %d != %d", fatal("agen: bad ONAME funcdepth %d != %d",
// n->funcdepth, funcdepth); n->funcdepth, funcdepth);
// } }
// // should only get here for heap vars or paramref // should only get here for heap vars or paramref
// if(!(n->class & PHEAP) && n->class != PPARAMREF) { if(!(n->class & PHEAP) && n->class != PPARAMREF) {
// dump("bad agen", n); dump("bad agen", n);
// fatal("agen: bad ONAME class %#x", n->class); fatal("agen: bad ONAME class %#x", n->class);
// } }
// cgen(n->heapaddr, res); cgen(n->heapaddr, res);
// if(n->xoffset != 0) { if(n->xoffset != 0) {
// nodconst(&n1, types[TINT64], n->xoffset); nodconst(&n1, types[TINT64], n->xoffset);
// gins(optoas(OADD, types[tptr]), &n1, res); gins(optoas(OADD, types[tptr]), &n1, res);
// } }
// break; break;
// case OIND: case OIND:
// cgen(nl, res); cgen(nl, res);
// break; break;
// case ODOT: case ODOT:
// agen(nl, res); agen(nl, res);
// if(n->xoffset != 0) { if(n->xoffset != 0) {
// nodconst(&n1, types[TINT64], n->xoffset); nodconst(&n1, types[TINT64], n->xoffset);
// gins(optoas(OADD, types[tptr]), &n1, res); gins(optoas(OADD, types[tptr]), &n1, res);
// } }
// break; break;
// case ODOTPTR: case ODOTPTR:
// cgen(nl, res); cgen(nl, res);
// if(n->xoffset != 0) { if(n->xoffset != 0) {
// nodconst(&n1, types[TINT64], n->xoffset); nodconst(&n1, types[TINT64], n->xoffset);
// gins(optoas(OADD, types[tptr]), &n1, res); gins(optoas(OADD, types[tptr]), &n1, res);
// } }
// break; break;
// } }
// ret: ret:
// ; ;
} }
/* /*
@ -821,45 +820,47 @@ stkof(Node *n)
void void
sgen(Node *n, Node *ns, int32 w) sgen(Node *n, Node *ns, int32 w)
{ {
fatal("sgen not implemented"); Node nodl, nodr, ndat, nend;
// Node nodl, nodr; int32 c, q, odst, osrc;
// int32 c, q, odst, osrc; Prog *p;
// if(debug['g']) { if(debug['g']) {
// print("\nsgen w=%d\n", w); print("\nsgen w=%d\n", w);
// dump("r", n); dump("r", n);
// dump("res", ns); dump("res", ns);
// } }
// if(w == 0) if(w == 0)
// return; return;
// if(n->ullman >= UINF && ns->ullman >= UINF) { if(n->ullman >= UINF && ns->ullman >= UINF) {
// fatal("sgen UINF"); fatal("sgen UINF");
// } }
// if(w < 0) if(w < 0)
// fatal("sgen copy %d", w); fatal("sgen copy %d", w);
// // offset on the stack // offset on the stack
// osrc = stkof(n); osrc = stkof(n);
// odst = stkof(ns); odst = stkof(ns);
// nodreg(&nodl, types[tptr], D_DI); regalloc(&nodl, types[tptr], N);
// nodreg(&nodr, types[tptr], D_SI); regalloc(&nodr, types[tptr], N);
regalloc(&ndat, types[TUINT32], N);
// if(n->ullman >= ns->ullman) { if(n->ullman >= ns->ullman) {
// agen(n, &nodr); agen(n, &nodr);
// agen(ns, &nodl); agen(ns, &nodl);
// } else { } else {
// agen(ns, &nodl); agen(ns, &nodl);
// agen(n, &nodr); agen(n, &nodr);
// } }
// c = w % 8; // bytes c = w % 4; // bytes
// q = w / 8; // quads q = w / 4; // quads
// // if we are copying forward on the stack and // if we are copying forward on the stack and
// // the src and dst overlap, then reverse direction // the src and dst overlap, then reverse direction
// if(osrc < odst && odst < osrc+w) { if(osrc < odst && odst < osrc+w) {
fatal("sgen reverse copy not implemented");
// // reverse direction // // reverse direction
// gins(ASTD, N, N); // set direction flag // gins(ASTD, N, N); // set direction flag
// if(c > 0) { // if(c > 0) {
@ -885,19 +886,48 @@ sgen(Node *n, Node *ns, int32 w)
// } // }
// // we leave with the flag clear // // we leave with the flag clear
// gins(ACLD, N, N); // gins(ACLD, N, N);
// } else { } else {
// // normal direction // normal direction
// if(q >= 4) { if(q >= 4) {
// gconreg(AMOVQ, q, D_CX); regalloc(&nend, types[TUINT32], N);
// gins(AREP, N, N); // repeat p = gins(AMOVW, &nodl, &nend);
// gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+ p->from.type = D_CONST;
// } else p->from.offset = q;
// while(q > 0) {
// gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
// q--;
// }
p = gins(AMOVW, &nodl, &ndat);
p->from.type = D_OREG;
p->from.offset = 4;
p->scond |= C_PBIT;
p = gins(AMOVW, &ndat, &nodr);
p->to.type = D_OREG;
p->to.offset = 4;
p->scond |= C_PBIT;
gins(ACMP, &nodl, &nend);
fatal("sgen loop not implemented");
p = gins(ABNE, N, N);
// TODO(PC offset)
regfree(&nend);
} else
while(q > 0) {
p = gins(AMOVW, &nodl, &ndat);
p->from.type = D_OREG;
p->from.offset = 4;
p->scond |= C_PBIT;
p = gins(AMOVW, &ndat, &nodr);
p->to.type = D_OREG;
p->to.offset = 4;
p->scond |= C_PBIT;
q--;
}
if (c != 0)
fatal("sgen character copy not implemented");
// if(c >= 4) { // if(c >= 4) {
// gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+ // gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
// c -= 4; // c -= 4;
// } // }
@ -905,5 +935,8 @@ sgen(Node *n, Node *ns, int32 w)
// gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+ // gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
// c--; // c--;
// } // }
// } }
regfree(&nodl);
regfree(&nodr);
regfree(&ndat);
} }

View File

@ -32,7 +32,7 @@ betypeinit(void)
zprog.scond = C_SCOND_NONE; zprog.scond = C_SCOND_NONE;
zprog.reg = NREG; zprog.reg = NREG;
zprog.from.type = D_NONE; zprog.from.type = D_NONE;
zprog.from.index = D_NONE; zprog.from.name = D_NONE;
zprog.from.reg = NREG; zprog.from.reg = NREG;
zprog.from.scale = 0; zprog.from.scale = 0;
zprog.to = zprog.from; zprog.to = zprog.from;

View File

@ -26,8 +26,8 @@ struct Addr
Sym* sym; Sym* sym;
int width; int width;
uchar type; uchar type;
char name;
char reg; char reg;
uchar index;
uchar etype; uchar etype;
uchar scale; /* doubles as width in DATA op */ uchar scale; /* doubles as width in DATA op */
}; };
@ -148,6 +148,7 @@ void datastring(char*, int, Addr*);
*/ */
int Aconv(Fmt*); int Aconv(Fmt*);
int Dconv(Fmt*); int Dconv(Fmt*);
int Mconv(Fmt*);
int Pconv(Fmt*); int Pconv(Fmt*);
int Rconv(Fmt*); int Rconv(Fmt*);
int Yconv(Fmt*); int Yconv(Fmt*);

View File

@ -259,27 +259,26 @@ ret:
void void
cgen_callret(Node *n, Node *res) cgen_callret(Node *n, Node *res)
{ {
fatal("cgen_callret not implemented"); Node nod;
// Node nod; Type *fp, *t;
// Type *fp, *t; Iter flist;
// Iter flist;
// t = n->left->type; t = n->left->type;
// if(t->etype == TPTR32 || t->etype == TPTR64) if(t->etype == TPTR32 || t->etype == TPTR64)
// t = t->type; t = t->type;
// fp = structfirst(&flist, getoutarg(t)); fp = structfirst(&flist, getoutarg(t));
// if(fp == T) if(fp == T)
// fatal("cgen_callret: nil"); fatal("cgen_callret: nil");
// memset(&nod, 0, sizeof(nod)); memset(&nod, 0, sizeof(nod));
// nod.op = OINDREG; nod.op = OINDREG;
// nod.val.u.reg = D_SP; nod.val.u.reg = REGSP;
// nod.addable = 1; nod.addable = 1;
// nod.xoffset = fp->width; nod.xoffset = fp->width;
// nod.type = fp->type; nod.type = fp->type;
// cgen_as(res, &nod); cgen_as(res, &nod);
} }
/* /*
@ -370,25 +369,31 @@ cgen_asop(Node *n)
case OOR: case OOR:
a = optoas(n->etype, nl->type); a = optoas(n->etype, nl->type);
if(nl->addable) { if(nl->addable) {
regalloc(&n2, nr->type, N); regalloc(&n2, nl->type, N);
cgen(nr, &n2); regalloc(&n3, nr->type, N);
gins(a, &n2, nl); cgen(nl, &n2);
cgen(nr, &n3);
gins(a, &n3, &n2);
cgen(&n2, nl);
regfree(&n2); regfree(&n2);
regfree(&n3);
goto ret; goto ret;
} }
if(nr->ullman < UINF) if(nr->ullman < UINF)
if(sudoaddable(a, nl, &addr)) { if(sudoaddable(a, nl, &addr)) {
regalloc(&n2, nr->type, N); fatal("cgen_asop sudoaddable not implemented");
cgen(nr, &n2); // regalloc(&n2, nr->type, N);
p1 = gins(a, &n2, N); // cgen(nr, &n2);
p1->to = addr; // p1 = gins(a, &n2, N);
regfree(&n2); // p1->to = addr;
sudoclean(); // regfree(&n2);
goto ret; // sudoclean();
// goto ret;
} }
} }
hard: hard:
fatal("cgen_asop hard not implemented");
if(nr->ullman > nl->ullman) { if(nr->ullman > nl->ullman) {
regalloc(&n2, nr->type, N); regalloc(&n2, nr->type, N);
cgen(nr, &n2); cgen(nr, &n2);
@ -573,7 +578,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
// regfree(&n1); // regfree(&n1);
// regfree(&n2); // regfree(&n2);
// ret: //ret:
// ; // ;
} }
@ -736,7 +741,6 @@ gen_as_init(Node *nr, Node *nl)
p = gins(ADATA, &nam, nr->left); p = gins(ADATA, &nam, nr->left);
p->from.scale = types[tptr]->width; p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR; p->to.type = D_ADDR;
//print("%P\n", p); //print("%P\n", p);
@ -806,7 +810,6 @@ lit:
p = gins(ADATA, &nam, N); p = gins(ADATA, &nam, N);
datastring(nr->val.u.sval->s, nr->val.u.sval->len, &p->to); datastring(nr->val.u.sval->s, nr->val.u.sval->len, &p->to);
p->from.scale = types[tptr]->width; p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR; p->to.type = D_ADDR;
//print("%P\n", p); //print("%P\n", p);

View File

@ -92,16 +92,14 @@ zaddr(Biobuf *b, Addr *a, int s)
case D_AUTO: case D_AUTO:
case D_EXTERN: case D_EXTERN:
case D_PARAM: case D_PARAM:
Bputc(b, D_OREG); // TODO(kaib): remove once everything seems to work
Bputc(b, a->reg); fatal("We should no longer generate these as types");
Bputc(b, s);
Bputc(b, a->type);
break;
default: default:
Bputc(b, a->type); Bputc(b, a->type);
Bputc(b, a->reg); Bputc(b, a->reg);
Bputc(b, s); Bputc(b, s);
Bputc(b, D_NONE); Bputc(b, a->name);
} }
switch(a->type) { switch(a->type) {
@ -112,6 +110,7 @@ zaddr(Biobuf *b, Addr *a, int s)
case D_REG: case D_REG:
case D_FREG: case D_FREG:
case D_PSR: case D_PSR:
case D_ADDR:
break; break;
case D_CONST2: case D_CONST2:
@ -206,7 +205,7 @@ dumpfuncs(void)
sf = 0; sf = 0;
t = p->from.type; t = p->from.type;
if(t == D_ADDR) if(t == D_ADDR)
t = p->from.index; t = p->from.name;
if(h[sf].type == t) if(h[sf].type == t)
if(h[sf].sym == s) if(h[sf].sym == s)
break; break;
@ -228,7 +227,7 @@ dumpfuncs(void)
st = 0; st = 0;
t = p->to.type; t = p->to.type;
if(t == D_ADDR) if(t == D_ADDR)
t = p->to.index; t = p->to.name;
if(h[st].type == t) if(h[st].type == t)
if(h[st].sym == s) if(h[st].sym == s)
break; break;
@ -312,7 +311,6 @@ dumpdata(void)
void void
datastring(char *s, int len, Addr *a) datastring(char *s, int len, Addr *a)
{ {
fatal("datastring not implemented");
int w; int w;
Prog *p; Prog *p;
Addr ac, ao; Addr ac, ao;
@ -324,22 +322,24 @@ datastring(char *s, int len, Addr *a)
// string // string
memset(&ao, 0, sizeof(ao)); memset(&ao, 0, sizeof(ao));
ao.type = D_STATIC; ao.type = D_OREG;
ao.index = D_NONE; ao.name = D_STATIC;
ao.etype = TINT32; ao.etype = TINT32;
ao.offset = 0; // fill in ao.offset = 0; // fill in
ao.reg = NREG;
// constant // constant
memset(&ac, 0, sizeof(ac)); memset(&ac, 0, sizeof(ac));
ac.type = D_CONST; ac.type = D_CONST;
ac.index = D_NONE; ac.name = D_NONE;
ac.offset = 0; // fill in ac.offset = 0; // fill in
ac.reg = NREG;
// huge strings are made static to avoid long names. // huge strings are made static to avoid long names.
if(len > 100) { if(len > 100) {
snprint(namebuf, sizeof(namebuf), ".string.%d", gen++); snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
ao.sym = lookup(namebuf); ao.sym = lookup(namebuf);
ao.type = D_STATIC; ao.name = D_STATIC;
} else { } else {
if(len > 0 && s[len-1] == '\0') if(len > 0 && s[len-1] == '\0')
len--; len--;
@ -349,7 +349,7 @@ datastring(char *s, int len, Addr *a)
len++; len++;
snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit); snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
ao.sym = pkglookup(namebuf, "string"); ao.sym = pkglookup(namebuf, "string");
ao.type = D_EXTERN; ao.name = D_EXTERN;
} }
*a = ao; *a = ao;
@ -377,9 +377,9 @@ datastring(char *s, int len, Addr *a)
memmove(p->to.sval, s+w, p->from.scale); memmove(p->to.sval, s+w, p->from.scale);
} }
p = pc; p = pc;
ggloblsym(ao.sym, len, ao.type == D_EXTERN); ggloblsym(ao.sym, len, ao.name == D_EXTERN);
if(ao.type == D_STATIC) if(ao.name == D_STATIC)
p->from.type = D_STATIC; p->from.name = D_STATIC;
text(); text();
} }
@ -401,36 +401,37 @@ datagostring(Strlit *sval, Addr *a)
// constant // constant
ac.type = D_CONST; ac.type = D_CONST;
ac.index = D_NONE; ac.name = D_NONE;
ac.offset = 0; // fill in ac.offset = 0; // fill in
ac.reg = NREG;
// string len+ptr // string len+ptr
ao.type = D_STATIC; // fill in ao.type = D_OREG;
ao.index = D_NONE; ao.name = D_STATIC; // fill in
ao.etype = TINT32; ao.etype = TINT32;
ao.sym = nil; // fill in ao.sym = nil; // fill in
ao.reg = NREG;
// $string len+ptr // $string len+ptr
datastring(sval->s, sval->len, &ap); datastring(sval->s, sval->len, &ap);
ap.index = ap.type;
ap.type = D_ADDR; ap.type = D_ADDR;
ap.etype = TINT32; ap.etype = TINT32;
wi = types[TUINT32]->width; wi = types[TUINT32]->width;
wp = types[tptr]->width; wp = types[tptr]->width;
if(ap.index == D_STATIC) { if(ap.name == D_STATIC) {
// huge strings are made static to avoid long names // huge strings are made static to avoid long names
snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen); snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
ao.sym = lookup(namebuf); ao.sym = lookup(namebuf);
ao.type = D_STATIC; ao.name = D_STATIC;
} else { } else {
// small strings get named by their contents, // small strings get named by their contents,
// so that multiple modules using the same string // so that multiple modules using the same string
// can share it. // can share it.
snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval); snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
ao.sym = pkglookup(namebuf, "go.string"); ao.sym = pkglookup(namebuf, "go.string");
ao.type = D_EXTERN; ao.name = D_EXTERN;
} }
*a = ao; *a = ao;
@ -457,8 +458,8 @@ datagostring(Strlit *sval, Addr *a)
p = pc; p = pc;
ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN); ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
if(ao.type == D_STATIC) if(ao.name == D_STATIC)
p->from.type = D_STATIC; p->from.name = D_STATIC;
text(); text();
} }
@ -469,14 +470,13 @@ dstringptr(Sym *s, int off, char *str)
off = rnd(off, widthptr); off = rnd(off, widthptr);
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = D_OREG;
p->from.index = D_NONE; p->from.name = D_EXTERN;
p->from.sym = s; p->from.sym = s;
p->from.offset = off; p->from.offset = off;
p->from.scale = widthptr; p->from.scale = widthptr;
datastring(str, strlen(str)+1, &p->to); datastring(str, strlen(str)+1, &p->to);
p->to.index = p->to.type;
p->to.type = D_ADDR; p->to.type = D_ADDR;
p->to.etype = TINT32; p->to.etype = TINT32;
off += widthptr; off += widthptr;
@ -492,13 +492,13 @@ duintxx(Sym *s, int off, uint64 v, int wid)
off = rnd(off, wid); off = rnd(off, wid);
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = D_OREG;
p->from.index = D_NONE; p->from.name = D_EXTERN;
p->from.sym = s; p->from.sym = s;
p->from.offset = off; p->from.offset = off;
p->from.scale = wid; p->from.scale = wid;
p->to.type = D_CONST; p->to.type = D_CONST;
p->to.index = D_NONE; p->to.name = D_NONE;
p->to.offset = v; p->to.offset = v;
off += wid; off += wid;
@ -531,13 +531,13 @@ dsymptr(Sym *s, int off, Sym *x)
off = rnd(off, widthptr); off = rnd(off, widthptr);
p = gins(ADATA, N, N); p = gins(ADATA, N, N);
p->from.type = D_EXTERN; p->from.type = D_OREG;
p->from.index = D_NONE; p->from.name = D_EXTERN;
p->from.sym = s; p->from.sym = s;
p->from.offset = off; p->from.offset = off;
p->from.scale = widthptr; p->from.scale = widthptr;
p->to.type = D_ADDR; p->to.type = D_ADDR;
p->to.index = D_EXTERN; p->to.name = D_EXTERN;
p->to.sym = x; p->to.sym = x;
p->to.offset = 0; p->to.offset = 0;
off += widthptr; off += widthptr;

File diff suppressed because it is too large Load Diff

View File

@ -539,6 +539,7 @@ zaddr(Biobuf *f, Adr *a, Sym *h[])
case D_FREG: case D_FREG:
case D_PSR: case D_PSR:
case D_FPCR: case D_FPCR:
case D_ADDR:
break; break;
case D_REGREG: case D_REGREG: