mirror of
https://github.com/golang/go
synced 2024-11-22 06:54:39 -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 OADD:
|
||||
case OMUL:
|
||||
fatal("cgen OMUL not implemented");
|
||||
// a = optoas(n->op, nl->type);
|
||||
// if(a != AIMULB)
|
||||
// goto sbop;
|
||||
// cgen_bmul(n->op, nl, nr, res);
|
||||
break;
|
||||
a = optoas(n->op, nl->type);
|
||||
goto sbop;
|
||||
|
||||
// asymmetric binary
|
||||
case OSUB:
|
||||
@ -345,224 +341,227 @@ ret:
|
||||
void
|
||||
agen(Node *n, Node *res)
|
||||
{
|
||||
fatal("agen not implemented");
|
||||
// Node *nl, *nr;
|
||||
// Node n1, n2, n3, tmp;
|
||||
// Prog *p1;
|
||||
// uint32 w;
|
||||
// uint64 v;
|
||||
// Type *t;
|
||||
Node *nl, *nr;
|
||||
Node n1, n2, n3, tmp;
|
||||
Prog *p1;
|
||||
uint32 w;
|
||||
uint64 v;
|
||||
Type *t;
|
||||
|
||||
// if(debug['g']) {
|
||||
// dump("\nagen-res", res);
|
||||
// dump("agen-r", n);
|
||||
// }
|
||||
// if(n == N || n->type == T)
|
||||
// return;
|
||||
if(debug['g']) {
|
||||
dump("\nagen-res", res);
|
||||
dump("agen-r", n);
|
||||
}
|
||||
if(n == N || n->type == T)
|
||||
return;
|
||||
|
||||
// if(!isptr[res->type->etype])
|
||||
// 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;
|
||||
// }
|
||||
if(!isptr[res->type->etype])
|
||||
fatal("agen: not tptr: %T", res->type);
|
||||
|
||||
// nl = n->left;
|
||||
// nr = n->right;
|
||||
while(n->op == OCONVNOP)
|
||||
n = n->left;
|
||||
|
||||
// switch(n->op) {
|
||||
// default:
|
||||
// fatal("agen: unknown op %N", n);
|
||||
// break;
|
||||
if(n->addable) {
|
||||
memset(&n1, 0, sizeof n1);
|
||||
n1.op = OADDR;
|
||||
n1.left = n;
|
||||
regalloc(&n2, types[tptr], res);
|
||||
gins(AMOVW, &n1, &n2);
|
||||
gmove(&n2, res);
|
||||
regfree(&n2);
|
||||
goto ret;
|
||||
}
|
||||
|
||||
// case OCALLMETH:
|
||||
// cgen_callmeth(n, 0);
|
||||
// cgen_aret(n, res);
|
||||
// break;
|
||||
nl = n->left;
|
||||
nr = n->right;
|
||||
|
||||
// case OCALLINTER:
|
||||
// cgen_callinter(n, res, 0);
|
||||
// cgen_aret(n, res);
|
||||
// break;
|
||||
switch(n->op) {
|
||||
default:
|
||||
fatal("agen: unknown op %N", n);
|
||||
break;
|
||||
|
||||
// case OCALL:
|
||||
// cgen_call(n, 0);
|
||||
// cgen_aret(n, res);
|
||||
// break;
|
||||
case OCALLMETH:
|
||||
cgen_callmeth(n, 0);
|
||||
cgen_aret(n, res);
|
||||
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.
|
||||
// case OINDEX:
|
||||
// w = n->type->width;
|
||||
// if(nr->addable)
|
||||
// goto irad;
|
||||
// if(nl->addable) {
|
||||
// if(!isconst(nr, CTINT)) {
|
||||
// regalloc(&n1, nr->type, N);
|
||||
// cgen(nr, &n1);
|
||||
// }
|
||||
// regalloc(&n3, types[tptr], res);
|
||||
// agen(nl, &n3);
|
||||
// goto index;
|
||||
// }
|
||||
// cgen(nr, res);
|
||||
// tempname(&tmp, nr->type);
|
||||
// gmove(res, &tmp);
|
||||
case OINDEX:
|
||||
w = n->type->width;
|
||||
if(nr->addable)
|
||||
goto irad;
|
||||
if(nl->addable) {
|
||||
if(!isconst(nr, CTINT)) {
|
||||
regalloc(&n1, nr->type, N);
|
||||
cgen(nr, &n1);
|
||||
}
|
||||
regalloc(&n3, types[tptr], res);
|
||||
agen(nl, &n3);
|
||||
goto index;
|
||||
}
|
||||
cgen(nr, res);
|
||||
tempname(&tmp, nr->type);
|
||||
gmove(res, &tmp);
|
||||
|
||||
// irad:
|
||||
// regalloc(&n3, types[tptr], res);
|
||||
// agen(nl, &n3);
|
||||
// if(!isconst(nr, CTINT)) {
|
||||
// regalloc(&n1, nr->type, N);
|
||||
// cgen(nr, &n1);
|
||||
// }
|
||||
// goto index;
|
||||
irad:
|
||||
regalloc(&n3, types[tptr], res);
|
||||
agen(nl, &n3);
|
||||
if(!isconst(nr, CTINT)) {
|
||||
regalloc(&n1, nr->type, N);
|
||||
cgen(nr, &n1);
|
||||
}
|
||||
goto index;
|
||||
|
||||
// index:
|
||||
// // &a is in &n3 (allocated in res)
|
||||
// // i is in &n1 (if not constant)
|
||||
// // w is width
|
||||
index:
|
||||
// &a is in &n3 (allocated in res)
|
||||
// i is in &n1 (if not constant)
|
||||
// w is width
|
||||
|
||||
// if(w == 0)
|
||||
// fatal("index is zero width");
|
||||
if(w == 0)
|
||||
fatal("index is zero width");
|
||||
|
||||
// // constant index
|
||||
// if(isconst(nr, CTINT)) {
|
||||
// v = mpgetfix(nr->val.u.xval);
|
||||
// if(isslice(nl->type)) {
|
||||
// constant index
|
||||
if(isconst(nr, CTINT)) {
|
||||
v = mpgetfix(nr->val.u.xval);
|
||||
if(isslice(nl->type)) {
|
||||
|
||||
// if(!debug['B']) {
|
||||
// n1 = n3;
|
||||
// n1.op = OINDREG;
|
||||
// n1.type = types[tptr];
|
||||
// n1.xoffset = Array_nel;
|
||||
// nodconst(&n2, types[TUINT64], v);
|
||||
// gins(optoas(OCMP, types[TUINT32]), &n1, &n2);
|
||||
// p1 = gbranch(optoas(OGT, types[TUINT32]), T);
|
||||
// ginscall(throwindex, 0);
|
||||
// patch(p1, pc);
|
||||
// }
|
||||
if(!debug['B']) {
|
||||
n1 = n3;
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[tptr];
|
||||
n1.xoffset = Array_nel;
|
||||
nodconst(&n2, types[TUINT64], v);
|
||||
gins(optoas(OCMP, types[TUINT32]), &n1, &n2);
|
||||
p1 = gbranch(optoas(OGT, types[TUINT32]), T);
|
||||
ginscall(throwindex, 0);
|
||||
patch(p1, pc);
|
||||
}
|
||||
|
||||
// n1 = n3;
|
||||
// n1.op = OINDREG;
|
||||
// n1.type = types[tptr];
|
||||
// n1.xoffset = Array_array;
|
||||
// gmove(&n1, &n3);
|
||||
// } else
|
||||
// if(!debug['B']) {
|
||||
// if(v < 0)
|
||||
// yyerror("out of bounds on array");
|
||||
// else
|
||||
// if(v >= nl->type->bound)
|
||||
// yyerror("out of bounds on array");
|
||||
// }
|
||||
n1 = n3;
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[tptr];
|
||||
n1.xoffset = Array_array;
|
||||
gmove(&n1, &n3);
|
||||
} else
|
||||
if(!debug['B']) {
|
||||
if(v < 0)
|
||||
yyerror("out of bounds on array");
|
||||
else
|
||||
if(v >= nl->type->bound)
|
||||
yyerror("out of bounds on array");
|
||||
}
|
||||
|
||||
// nodconst(&n2, types[tptr], v*w);
|
||||
// gins(optoas(OADD, types[tptr]), &n2, &n3);
|
||||
nodconst(&n2, types[tptr], v*w);
|
||||
gins(optoas(OADD, types[tptr]), &n2, &n3);
|
||||
|
||||
// gmove(&n3, res);
|
||||
// regfree(&n3);
|
||||
// break;
|
||||
// }
|
||||
gmove(&n3, res);
|
||||
regfree(&n3);
|
||||
break;
|
||||
}
|
||||
|
||||
// // type of the index
|
||||
// t = types[TUINT64];
|
||||
// if(issigned[n1.type->etype])
|
||||
// t = types[TINT64];
|
||||
// type of the index
|
||||
t = types[TUINT64];
|
||||
if(issigned[n1.type->etype])
|
||||
t = types[TINT64];
|
||||
|
||||
// regalloc(&n2, t, &n1); // i
|
||||
// gmove(&n1, &n2);
|
||||
// regfree(&n1);
|
||||
regalloc(&n2, t, &n1); // i
|
||||
gmove(&n1, &n2);
|
||||
regfree(&n1);
|
||||
|
||||
// if(!debug['B']) {
|
||||
// // check bounds
|
||||
// if(isslice(nl->type)) {
|
||||
// n1 = n3;
|
||||
// n1.op = OINDREG;
|
||||
// n1.type = types[tptr];
|
||||
// n1.xoffset = Array_nel;
|
||||
// } else
|
||||
// nodconst(&n1, types[TUINT64], nl->type->bound);
|
||||
// gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
|
||||
// p1 = gbranch(optoas(OLT, types[TUINT32]), T);
|
||||
// ginscall(throwindex, 0);
|
||||
// patch(p1, pc);
|
||||
// }
|
||||
if(!debug['B']) {
|
||||
// check bounds
|
||||
if(isslice(nl->type)) {
|
||||
n1 = n3;
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[tptr];
|
||||
n1.xoffset = Array_nel;
|
||||
} else
|
||||
nodconst(&n1, types[TUINT64], nl->type->bound);
|
||||
gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
|
||||
p1 = gbranch(optoas(OLT, types[TUINT32]), T);
|
||||
ginscall(throwindex, 0);
|
||||
patch(p1, pc);
|
||||
}
|
||||
|
||||
// if(isslice(nl->type)) {
|
||||
// n1 = n3;
|
||||
// n1.op = OINDREG;
|
||||
// n1.type = types[tptr];
|
||||
// n1.xoffset = Array_array;
|
||||
// gmove(&n1, &n3);
|
||||
// }
|
||||
if(isslice(nl->type)) {
|
||||
n1 = n3;
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[tptr];
|
||||
n1.xoffset = Array_array;
|
||||
gmove(&n1, &n3);
|
||||
}
|
||||
|
||||
// if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
// p1 = gins(ALEAQ, &n2, &n3);
|
||||
// p1->from.scale = w;
|
||||
// p1->from.index = p1->from.type;
|
||||
// p1->from.type = p1->to.type + D_INDIR;
|
||||
// } else {
|
||||
// nodconst(&n1, t, w);
|
||||
// gins(optoas(OMUL, t), &n1, &n2);
|
||||
// gins(optoas(OADD, types[tptr]), &n2, &n3);
|
||||
// gmove(&n3, res);
|
||||
// }
|
||||
if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
memset(&tmp, 0, sizeof tmp);
|
||||
tmp.op = OADDR;
|
||||
tmp.left = &n2;
|
||||
p1 = gins(AMOVW, &tmp, &n3);
|
||||
p1->from.scale = w;
|
||||
} else {
|
||||
nodconst(&n1, t, w);
|
||||
gins(optoas(OMUL, t), &n1, &n2);
|
||||
gins(optoas(OADD, types[tptr]), &n2, &n3);
|
||||
gmove(&n3, res);
|
||||
}
|
||||
|
||||
// gmove(&n3, res);
|
||||
// regfree(&n2);
|
||||
// regfree(&n3);
|
||||
// break;
|
||||
gmove(&n3, res);
|
||||
regfree(&n2);
|
||||
regfree(&n3);
|
||||
break;
|
||||
|
||||
// case ONAME:
|
||||
// // should only get here with names in this func.
|
||||
// if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
|
||||
// dump("bad agen", n);
|
||||
// fatal("agen: bad ONAME funcdepth %d != %d",
|
||||
// n->funcdepth, funcdepth);
|
||||
// }
|
||||
case ONAME:
|
||||
// should only get here with names in this func.
|
||||
if(n->funcdepth > 0 && n->funcdepth != funcdepth) {
|
||||
dump("bad agen", n);
|
||||
fatal("agen: bad ONAME funcdepth %d != %d",
|
||||
n->funcdepth, funcdepth);
|
||||
}
|
||||
|
||||
// // should only get here for heap vars or paramref
|
||||
// if(!(n->class & PHEAP) && n->class != PPARAMREF) {
|
||||
// dump("bad agen", n);
|
||||
// fatal("agen: bad ONAME class %#x", n->class);
|
||||
// }
|
||||
// cgen(n->heapaddr, res);
|
||||
// if(n->xoffset != 0) {
|
||||
// nodconst(&n1, types[TINT64], n->xoffset);
|
||||
// gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
// }
|
||||
// break;
|
||||
// should only get here for heap vars or paramref
|
||||
if(!(n->class & PHEAP) && n->class != PPARAMREF) {
|
||||
dump("bad agen", n);
|
||||
fatal("agen: bad ONAME class %#x", n->class);
|
||||
}
|
||||
cgen(n->heapaddr, res);
|
||||
if(n->xoffset != 0) {
|
||||
nodconst(&n1, types[TINT64], n->xoffset);
|
||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
}
|
||||
break;
|
||||
|
||||
// case OIND:
|
||||
// cgen(nl, res);
|
||||
// break;
|
||||
case OIND:
|
||||
cgen(nl, res);
|
||||
break;
|
||||
|
||||
// case ODOT:
|
||||
// agen(nl, res);
|
||||
// if(n->xoffset != 0) {
|
||||
// nodconst(&n1, types[TINT64], n->xoffset);
|
||||
// gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
// }
|
||||
// break;
|
||||
case ODOT:
|
||||
agen(nl, res);
|
||||
if(n->xoffset != 0) {
|
||||
nodconst(&n1, types[TINT64], n->xoffset);
|
||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
}
|
||||
break;
|
||||
|
||||
// case ODOTPTR:
|
||||
// cgen(nl, res);
|
||||
// if(n->xoffset != 0) {
|
||||
// nodconst(&n1, types[TINT64], n->xoffset);
|
||||
// gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
case ODOTPTR:
|
||||
cgen(nl, res);
|
||||
if(n->xoffset != 0) {
|
||||
nodconst(&n1, types[TINT64], n->xoffset);
|
||||
gins(optoas(OADD, types[tptr]), &n1, res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// ret:
|
||||
// ;
|
||||
ret:
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -821,45 +820,47 @@ stkof(Node *n)
|
||||
void
|
||||
sgen(Node *n, Node *ns, int32 w)
|
||||
{
|
||||
fatal("sgen not implemented");
|
||||
// Node nodl, nodr;
|
||||
// int32 c, q, odst, osrc;
|
||||
Node nodl, nodr, ndat, nend;
|
||||
int32 c, q, odst, osrc;
|
||||
Prog *p;
|
||||
|
||||
// if(debug['g']) {
|
||||
// print("\nsgen w=%d\n", w);
|
||||
// dump("r", n);
|
||||
// dump("res", ns);
|
||||
// }
|
||||
// if(w == 0)
|
||||
// return;
|
||||
// if(n->ullman >= UINF && ns->ullman >= UINF) {
|
||||
// fatal("sgen UINF");
|
||||
// }
|
||||
if(debug['g']) {
|
||||
print("\nsgen w=%d\n", w);
|
||||
dump("r", n);
|
||||
dump("res", ns);
|
||||
}
|
||||
if(w == 0)
|
||||
return;
|
||||
if(n->ullman >= UINF && ns->ullman >= UINF) {
|
||||
fatal("sgen UINF");
|
||||
}
|
||||
|
||||
// if(w < 0)
|
||||
// fatal("sgen copy %d", w);
|
||||
if(w < 0)
|
||||
fatal("sgen copy %d", w);
|
||||
|
||||
// // offset on the stack
|
||||
// osrc = stkof(n);
|
||||
// odst = stkof(ns);
|
||||
// offset on the stack
|
||||
osrc = stkof(n);
|
||||
odst = stkof(ns);
|
||||
|
||||
// nodreg(&nodl, types[tptr], D_DI);
|
||||
// nodreg(&nodr, types[tptr], D_SI);
|
||||
regalloc(&nodl, types[tptr], N);
|
||||
regalloc(&nodr, types[tptr], N);
|
||||
regalloc(&ndat, types[TUINT32], N);
|
||||
|
||||
// if(n->ullman >= ns->ullman) {
|
||||
// agen(n, &nodr);
|
||||
// agen(ns, &nodl);
|
||||
// } else {
|
||||
// agen(ns, &nodl);
|
||||
// agen(n, &nodr);
|
||||
// }
|
||||
if(n->ullman >= ns->ullman) {
|
||||
agen(n, &nodr);
|
||||
agen(ns, &nodl);
|
||||
} else {
|
||||
agen(ns, &nodl);
|
||||
agen(n, &nodr);
|
||||
}
|
||||
|
||||
// c = w % 8; // bytes
|
||||
// q = w / 8; // quads
|
||||
c = w % 4; // bytes
|
||||
q = w / 4; // quads
|
||||
|
||||
// // if we are copying forward on the stack and
|
||||
// // the src and dst overlap, then reverse direction
|
||||
// if(osrc < odst && odst < osrc+w) {
|
||||
// if we are copying forward on the stack and
|
||||
// the src and dst overlap, then reverse direction
|
||||
if(osrc < odst && odst < osrc+w) {
|
||||
fatal("sgen reverse copy not implemented");
|
||||
// // reverse direction
|
||||
// gins(ASTD, N, N); // set direction flag
|
||||
// if(c > 0) {
|
||||
@ -885,19 +886,48 @@ sgen(Node *n, Node *ns, int32 w)
|
||||
// }
|
||||
// // we leave with the flag clear
|
||||
// gins(ACLD, N, N);
|
||||
// } else {
|
||||
// // normal direction
|
||||
// if(q >= 4) {
|
||||
// gconreg(AMOVQ, q, D_CX);
|
||||
// gins(AREP, N, N); // repeat
|
||||
// gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
|
||||
// } else
|
||||
// while(q > 0) {
|
||||
// gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
|
||||
// q--;
|
||||
// }
|
||||
} else {
|
||||
// normal direction
|
||||
if(q >= 4) {
|
||||
regalloc(&nend, types[TUINT32], N);
|
||||
p = gins(AMOVW, &nodl, &nend);
|
||||
p->from.type = D_CONST;
|
||||
p->from.offset = 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) {
|
||||
|
||||
// gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
|
||||
// c -= 4;
|
||||
// }
|
||||
@ -905,5 +935,8 @@ sgen(Node *n, Node *ns, int32 w)
|
||||
// gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
|
||||
// c--;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
regfree(&nodl);
|
||||
regfree(&nodr);
|
||||
regfree(&ndat);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ betypeinit(void)
|
||||
zprog.scond = C_SCOND_NONE;
|
||||
zprog.reg = NREG;
|
||||
zprog.from.type = D_NONE;
|
||||
zprog.from.index = D_NONE;
|
||||
zprog.from.name = D_NONE;
|
||||
zprog.from.reg = NREG;
|
||||
zprog.from.scale = 0;
|
||||
zprog.to = zprog.from;
|
||||
|
@ -26,8 +26,8 @@ struct Addr
|
||||
Sym* sym;
|
||||
int width;
|
||||
uchar type;
|
||||
char name;
|
||||
char reg;
|
||||
uchar index;
|
||||
uchar etype;
|
||||
uchar scale; /* doubles as width in DATA op */
|
||||
};
|
||||
@ -148,6 +148,7 @@ void datastring(char*, int, Addr*);
|
||||
*/
|
||||
int Aconv(Fmt*);
|
||||
int Dconv(Fmt*);
|
||||
int Mconv(Fmt*);
|
||||
int Pconv(Fmt*);
|
||||
int Rconv(Fmt*);
|
||||
int Yconv(Fmt*);
|
||||
|
@ -259,27 +259,26 @@ ret:
|
||||
void
|
||||
cgen_callret(Node *n, Node *res)
|
||||
{
|
||||
fatal("cgen_callret not implemented");
|
||||
// Node nod;
|
||||
// Type *fp, *t;
|
||||
// Iter flist;
|
||||
Node nod;
|
||||
Type *fp, *t;
|
||||
Iter flist;
|
||||
|
||||
// t = n->left->type;
|
||||
// if(t->etype == TPTR32 || t->etype == TPTR64)
|
||||
// t = t->type;
|
||||
t = n->left->type;
|
||||
if(t->etype == TPTR32 || t->etype == TPTR64)
|
||||
t = t->type;
|
||||
|
||||
// fp = structfirst(&flist, getoutarg(t));
|
||||
// if(fp == T)
|
||||
// fatal("cgen_callret: nil");
|
||||
fp = structfirst(&flist, getoutarg(t));
|
||||
if(fp == T)
|
||||
fatal("cgen_callret: nil");
|
||||
|
||||
// memset(&nod, 0, sizeof(nod));
|
||||
// nod.op = OINDREG;
|
||||
// nod.val.u.reg = D_SP;
|
||||
// nod.addable = 1;
|
||||
memset(&nod, 0, sizeof(nod));
|
||||
nod.op = OINDREG;
|
||||
nod.val.u.reg = REGSP;
|
||||
nod.addable = 1;
|
||||
|
||||
// nod.xoffset = fp->width;
|
||||
// nod.type = fp->type;
|
||||
// cgen_as(res, &nod);
|
||||
nod.xoffset = fp->width;
|
||||
nod.type = fp->type;
|
||||
cgen_as(res, &nod);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -370,25 +369,31 @@ cgen_asop(Node *n)
|
||||
case OOR:
|
||||
a = optoas(n->etype, nl->type);
|
||||
if(nl->addable) {
|
||||
regalloc(&n2, nr->type, N);
|
||||
cgen(nr, &n2);
|
||||
gins(a, &n2, nl);
|
||||
regalloc(&n2, nl->type, N);
|
||||
regalloc(&n3, nr->type, N);
|
||||
cgen(nl, &n2);
|
||||
cgen(nr, &n3);
|
||||
gins(a, &n3, &n2);
|
||||
cgen(&n2, nl);
|
||||
regfree(&n2);
|
||||
regfree(&n3);
|
||||
goto ret;
|
||||
}
|
||||
if(nr->ullman < UINF)
|
||||
if(sudoaddable(a, nl, &addr)) {
|
||||
regalloc(&n2, nr->type, N);
|
||||
cgen(nr, &n2);
|
||||
p1 = gins(a, &n2, N);
|
||||
p1->to = addr;
|
||||
regfree(&n2);
|
||||
sudoclean();
|
||||
goto ret;
|
||||
fatal("cgen_asop sudoaddable not implemented");
|
||||
// regalloc(&n2, nr->type, N);
|
||||
// cgen(nr, &n2);
|
||||
// p1 = gins(a, &n2, N);
|
||||
// p1->to = addr;
|
||||
// regfree(&n2);
|
||||
// sudoclean();
|
||||
// goto ret;
|
||||
}
|
||||
}
|
||||
|
||||
hard:
|
||||
fatal("cgen_asop hard not implemented");
|
||||
if(nr->ullman > nl->ullman) {
|
||||
regalloc(&n2, nr->type, N);
|
||||
cgen(nr, &n2);
|
||||
@ -573,7 +578,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
|
||||
// regfree(&n1);
|
||||
// regfree(&n2);
|
||||
|
||||
// ret:
|
||||
//ret:
|
||||
// ;
|
||||
}
|
||||
|
||||
@ -736,7 +741,6 @@ gen_as_init(Node *nr, Node *nl)
|
||||
|
||||
p = gins(ADATA, &nam, nr->left);
|
||||
p->from.scale = types[tptr]->width;
|
||||
p->to.index = p->to.type;
|
||||
p->to.type = D_ADDR;
|
||||
//print("%P\n", p);
|
||||
|
||||
@ -806,7 +810,6 @@ lit:
|
||||
p = gins(ADATA, &nam, N);
|
||||
datastring(nr->val.u.sval->s, nr->val.u.sval->len, &p->to);
|
||||
p->from.scale = types[tptr]->width;
|
||||
p->to.index = p->to.type;
|
||||
p->to.type = D_ADDR;
|
||||
//print("%P\n", p);
|
||||
|
||||
|
@ -92,16 +92,14 @@ zaddr(Biobuf *b, Addr *a, int s)
|
||||
case D_AUTO:
|
||||
case D_EXTERN:
|
||||
case D_PARAM:
|
||||
Bputc(b, D_OREG);
|
||||
Bputc(b, a->reg);
|
||||
Bputc(b, s);
|
||||
Bputc(b, a->type);
|
||||
break;
|
||||
// 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, D_NONE);
|
||||
Bputc(b, a->name);
|
||||
}
|
||||
|
||||
switch(a->type) {
|
||||
@ -112,6 +110,7 @@ zaddr(Biobuf *b, Addr *a, int s)
|
||||
case D_REG:
|
||||
case D_FREG:
|
||||
case D_PSR:
|
||||
case D_ADDR:
|
||||
break;
|
||||
|
||||
case D_CONST2:
|
||||
@ -206,7 +205,7 @@ dumpfuncs(void)
|
||||
sf = 0;
|
||||
t = p->from.type;
|
||||
if(t == D_ADDR)
|
||||
t = p->from.index;
|
||||
t = p->from.name;
|
||||
if(h[sf].type == t)
|
||||
if(h[sf].sym == s)
|
||||
break;
|
||||
@ -228,7 +227,7 @@ dumpfuncs(void)
|
||||
st = 0;
|
||||
t = p->to.type;
|
||||
if(t == D_ADDR)
|
||||
t = p->to.index;
|
||||
t = p->to.name;
|
||||
if(h[st].type == t)
|
||||
if(h[st].sym == s)
|
||||
break;
|
||||
@ -312,7 +311,6 @@ dumpdata(void)
|
||||
void
|
||||
datastring(char *s, int len, Addr *a)
|
||||
{
|
||||
fatal("datastring not implemented");
|
||||
int w;
|
||||
Prog *p;
|
||||
Addr ac, ao;
|
||||
@ -324,22 +322,24 @@ datastring(char *s, int len, Addr *a)
|
||||
|
||||
// string
|
||||
memset(&ao, 0, sizeof(ao));
|
||||
ao.type = D_STATIC;
|
||||
ao.index = D_NONE;
|
||||
ao.type = D_OREG;
|
||||
ao.name = D_STATIC;
|
||||
ao.etype = TINT32;
|
||||
ao.offset = 0; // fill in
|
||||
ao.reg = NREG;
|
||||
|
||||
// constant
|
||||
memset(&ac, 0, sizeof(ac));
|
||||
ac.type = D_CONST;
|
||||
ac.index = D_NONE;
|
||||
ac.name = D_NONE;
|
||||
ac.offset = 0; // fill in
|
||||
ac.reg = NREG;
|
||||
|
||||
// huge strings are made static to avoid long names.
|
||||
if(len > 100) {
|
||||
snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
|
||||
ao.sym = lookup(namebuf);
|
||||
ao.type = D_STATIC;
|
||||
ao.name = D_STATIC;
|
||||
} else {
|
||||
if(len > 0 && s[len-1] == '\0')
|
||||
len--;
|
||||
@ -349,7 +349,7 @@ datastring(char *s, int len, Addr *a)
|
||||
len++;
|
||||
snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
|
||||
ao.sym = pkglookup(namebuf, "string");
|
||||
ao.type = D_EXTERN;
|
||||
ao.name = D_EXTERN;
|
||||
}
|
||||
*a = ao;
|
||||
|
||||
@ -377,9 +377,9 @@ datastring(char *s, int len, Addr *a)
|
||||
memmove(p->to.sval, s+w, p->from.scale);
|
||||
}
|
||||
p = pc;
|
||||
ggloblsym(ao.sym, len, ao.type == D_EXTERN);
|
||||
if(ao.type == D_STATIC)
|
||||
p->from.type = D_STATIC;
|
||||
ggloblsym(ao.sym, len, ao.name == D_EXTERN);
|
||||
if(ao.name == D_STATIC)
|
||||
p->from.name = D_STATIC;
|
||||
text();
|
||||
}
|
||||
|
||||
@ -401,36 +401,37 @@ datagostring(Strlit *sval, Addr *a)
|
||||
|
||||
// constant
|
||||
ac.type = D_CONST;
|
||||
ac.index = D_NONE;
|
||||
ac.name = D_NONE;
|
||||
ac.offset = 0; // fill in
|
||||
ac.reg = NREG;
|
||||
|
||||
// string len+ptr
|
||||
ao.type = D_STATIC; // fill in
|
||||
ao.index = D_NONE;
|
||||
ao.type = D_OREG;
|
||||
ao.name = D_STATIC; // fill in
|
||||
ao.etype = TINT32;
|
||||
ao.sym = nil; // fill in
|
||||
ao.reg = NREG;
|
||||
|
||||
// $string len+ptr
|
||||
datastring(sval->s, sval->len, &ap);
|
||||
ap.index = ap.type;
|
||||
|
||||
ap.type = D_ADDR;
|
||||
ap.etype = TINT32;
|
||||
|
||||
wi = types[TUINT32]->width;
|
||||
wp = types[tptr]->width;
|
||||
|
||||
if(ap.index == D_STATIC) {
|
||||
if(ap.name == D_STATIC) {
|
||||
// huge strings are made static to avoid long names
|
||||
snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
|
||||
ao.sym = lookup(namebuf);
|
||||
ao.type = D_STATIC;
|
||||
ao.name = D_STATIC;
|
||||
} else {
|
||||
// small strings get named by their contents,
|
||||
// so that multiple modules using the same string
|
||||
// can share it.
|
||||
snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
|
||||
ao.sym = pkglookup(namebuf, "go.string");
|
||||
ao.type = D_EXTERN;
|
||||
ao.name = D_EXTERN;
|
||||
}
|
||||
|
||||
*a = ao;
|
||||
@ -457,8 +458,8 @@ datagostring(Strlit *sval, Addr *a)
|
||||
|
||||
p = pc;
|
||||
ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
|
||||
if(ao.type == D_STATIC)
|
||||
p->from.type = D_STATIC;
|
||||
if(ao.name == D_STATIC)
|
||||
p->from.name = D_STATIC;
|
||||
text();
|
||||
}
|
||||
|
||||
@ -469,14 +470,13 @@ dstringptr(Sym *s, int off, char *str)
|
||||
|
||||
off = rnd(off, widthptr);
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
|
||||
datastring(str, strlen(str)+1, &p->to);
|
||||
p->to.index = p->to.type;
|
||||
p->to.type = D_ADDR;
|
||||
p->to.etype = TINT32;
|
||||
off += widthptr;
|
||||
@ -492,13 +492,13 @@ duintxx(Sym *s, int off, uint64 v, int wid)
|
||||
off = rnd(off, wid);
|
||||
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.offset = off;
|
||||
p->from.scale = wid;
|
||||
p->to.type = D_CONST;
|
||||
p->to.index = D_NONE;
|
||||
p->to.name = D_NONE;
|
||||
p->to.offset = v;
|
||||
off += wid;
|
||||
|
||||
@ -531,13 +531,13 @@ dsymptr(Sym *s, int off, Sym *x)
|
||||
off = rnd(off, widthptr);
|
||||
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_EXTERN;
|
||||
p->from.index = D_NONE;
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = s;
|
||||
p->from.offset = off;
|
||||
p->from.scale = widthptr;
|
||||
p->to.type = D_ADDR;
|
||||
p->to.index = D_EXTERN;
|
||||
p->to.name = D_EXTERN;
|
||||
p->to.sym = x;
|
||||
p->to.offset = 0;
|
||||
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_PSR:
|
||||
case D_FPCR:
|
||||
case D_ADDR:
|
||||
break;
|
||||
|
||||
case D_REGREG:
|
||||
|
Loading…
Reference in New Issue
Block a user