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:
parent
a7735f8a16
commit
86987055a3
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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*);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user