mirror of
https://github.com/golang/go
synced 2024-11-11 21:10:21 -07:00
cmd/5g, cmd/6g, cmd/8g: fix out of registers.
This patch is enough to fix compilation of exp/types tests but only passes a stripped down version of the appripriate torture test. Update #4207. R=dave, nigeltao, rsc, golang-dev CC=golang-dev https://golang.org/cl/6621061
This commit is contained in:
parent
bcf88de5ff
commit
7e144bcab0
@ -313,7 +313,7 @@ cgen(Node *n, Node *res)
|
||||
regalloc(&n2, n->type, &n1);
|
||||
n1.op = OINDREG;
|
||||
n1.type = n->type;
|
||||
n1.xoffset = 0;
|
||||
n1.xoffset += 0;
|
||||
gmove(&n1, &n2);
|
||||
gmove(&n2, res);
|
||||
regfree(&n1);
|
||||
@ -349,7 +349,7 @@ cgen(Node *n, Node *res)
|
||||
regalloc(&n2, types[TUINT32], &n1);
|
||||
n1.op = OINDREG;
|
||||
n1.type = types[TUINT32];
|
||||
n1.xoffset = Array_nel;
|
||||
n1.xoffset += Array_nel;
|
||||
gmove(&n1, &n2);
|
||||
gmove(&n2, res);
|
||||
regfree(&n1);
|
||||
@ -405,7 +405,7 @@ cgen(Node *n, Node *res)
|
||||
// Pick it up again after the call.
|
||||
rg = -1;
|
||||
if(n->ullman >= UINF) {
|
||||
if(res->op == OREGISTER || res->op == OINDREG) {
|
||||
if(res != N && (res->op == OREGISTER || res->op == OINDREG)) {
|
||||
rg = res->val.u.reg;
|
||||
reg[rg]--;
|
||||
}
|
||||
@ -890,6 +890,83 @@ ret:
|
||||
void
|
||||
igen(Node *n, Node *a, Node *res)
|
||||
{
|
||||
Node n1;
|
||||
Prog *p1;
|
||||
int r;
|
||||
|
||||
if(debug['g']) {
|
||||
dump("\nigen-n", n);
|
||||
}
|
||||
switch(n->op) {
|
||||
case ODOT:
|
||||
igen(n->left, a, res);
|
||||
a->xoffset += n->xoffset;
|
||||
a->type = n->type;
|
||||
return;
|
||||
|
||||
case ODOTPTR:
|
||||
if(n->left->addable
|
||||
|| n->left->op == OCALLFUNC
|
||||
|| n->left->op == OCALLMETH
|
||||
|| n->left->op == OCALLINTER) {
|
||||
// igen-able nodes.
|
||||
igen(n->left, &n1, res);
|
||||
regalloc(a, types[tptr], &n1);
|
||||
gmove(&n1, a);
|
||||
regfree(&n1);
|
||||
} else {
|
||||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
if(n->left->type->type->width >= unmappedzero) {
|
||||
regalloc(&n1, types[tptr], N);
|
||||
gmove(a, &n1);
|
||||
p1 = gins(AMOVW, &n1, &n1);
|
||||
p1->from.type = D_OREG;
|
||||
p1->from.offset = 0;
|
||||
regfree(&n1);
|
||||
}
|
||||
}
|
||||
a->op = OINDREG;
|
||||
a->xoffset = n->xoffset;
|
||||
a->type = n->type;
|
||||
return;
|
||||
|
||||
case OCALLMETH:
|
||||
case OCALLFUNC:
|
||||
case OCALLINTER:
|
||||
// Release res so that it is available for cgen_call.
|
||||
// Pick it up again after the call.
|
||||
r = -1;
|
||||
if(n->ullman >= UINF) {
|
||||
if(res != N && (res->op == OREGISTER || res->op == OINDREG)) {
|
||||
r = res->val.u.reg;
|
||||
reg[r]--;
|
||||
}
|
||||
}
|
||||
switch(n->op) {
|
||||
case OCALLMETH:
|
||||
cgen_callmeth(n, 0);
|
||||
break;
|
||||
case OCALLFUNC:
|
||||
cgen_call(n, 0);
|
||||
break;
|
||||
case OCALLINTER:
|
||||
cgen_callinter(n, N, 0);
|
||||
break;
|
||||
}
|
||||
if(r >= 0)
|
||||
reg[r]++;
|
||||
regalloc(a, types[tptr], res);
|
||||
cgen_aret(n, a);
|
||||
a->op = OINDREG;
|
||||
a->type = n->type;
|
||||
return;
|
||||
}
|
||||
|
||||
regalloc(a, types[tptr], res);
|
||||
agen(n, a);
|
||||
a->op = OINDREG;
|
||||
@ -905,8 +982,12 @@ igen(Node *n, Node *a, Node *res)
|
||||
void
|
||||
agenr(Node *n, Node *a, Node *res)
|
||||
{
|
||||
regalloc(a, types[tptr], res);
|
||||
agen(n, a);
|
||||
Node n1;
|
||||
|
||||
igen(n, &n1, res);
|
||||
regalloc(a, types[tptr], N);
|
||||
agen(&n1, a);
|
||||
regfree(&n1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -605,13 +605,14 @@ agen(Node *n, Node *res)
|
||||
cgen(nr, &n1);
|
||||
}
|
||||
if(!isconst(nl, CTSTR)) {
|
||||
if(isfixedarray(nl->type)) {
|
||||
regalloc(&n3, types[tptr], res);
|
||||
if(isfixedarray(nl->type))
|
||||
agen(nl, &n3);
|
||||
else {
|
||||
} else {
|
||||
igen(nl, &nlen, res);
|
||||
nlen.type = types[tptr];
|
||||
nlen.xoffset += Array_array;
|
||||
regalloc(&n3, types[tptr], res);
|
||||
gmove(&nlen, &n3);
|
||||
nlen.type = types[simtype[TUINT]];
|
||||
nlen.xoffset += Array_nel-Array_array;
|
||||
@ -624,10 +625,10 @@ agen(Node *n, Node *res)
|
||||
nr = &tmp;
|
||||
irad:
|
||||
if(!isconst(nl, CTSTR)) {
|
||||
if(isfixedarray(nl->type)) {
|
||||
regalloc(&n3, types[tptr], res);
|
||||
if(isfixedarray(nl->type))
|
||||
agen(nl, &n3);
|
||||
else {
|
||||
} else {
|
||||
if(!nl->addable) {
|
||||
// igen will need an addressable node.
|
||||
tempname(&tmp2, nl->type);
|
||||
@ -637,6 +638,7 @@ agen(Node *n, Node *res)
|
||||
igen(nl, &nlen, res);
|
||||
nlen.type = types[tptr];
|
||||
nlen.xoffset += Array_array;
|
||||
regalloc(&n3, types[tptr], res);
|
||||
gmove(&nlen, &n3);
|
||||
nlen.type = types[simtype[TUINT]];
|
||||
nlen.xoffset += Array_nel-Array_array;
|
||||
@ -814,8 +816,11 @@ igen(Node *n, Node *a, Node *res)
|
||||
{
|
||||
Type *fp;
|
||||
Iter flist;
|
||||
Node n1, n2;
|
||||
Node n1;
|
||||
|
||||
if(debug['g']) {
|
||||
dump("\nigen-n", n);
|
||||
}
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
if((n->class&PHEAP) || n->class == PPARAMREF)
|
||||
@ -838,8 +843,19 @@ igen(Node *n, Node *a, Node *res)
|
||||
return;
|
||||
|
||||
case ODOTPTR:
|
||||
if(n->left->addable
|
||||
|| n->left->op == OCALLFUNC
|
||||
|| n->left->op == OCALLMETH
|
||||
|| n->left->op == OCALLINTER) {
|
||||
// igen-able nodes.
|
||||
igen(n->left, &n1, res);
|
||||
regalloc(a, types[tptr], &n1);
|
||||
gmove(&n1, a);
|
||||
regfree(&n1);
|
||||
} else {
|
||||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
@ -887,18 +903,22 @@ igen(Node *n, Node *a, Node *res)
|
||||
if(isfixedarray(n->left->type) ||
|
||||
(isptr[n->left->type->etype] && isfixedarray(n->left->left->type)))
|
||||
if(isconst(n->right, CTINT)) {
|
||||
nodconst(&n1, types[TINT64], 0);
|
||||
n2 = *n;
|
||||
n2.right = &n1;
|
||||
|
||||
// Compute &a.
|
||||
if(!isptr[n->left->type->etype])
|
||||
igen(n->left, a, res);
|
||||
else {
|
||||
igen(n->left, &n1, res);
|
||||
regalloc(a, types[tptr], res);
|
||||
agen(&n2, a);
|
||||
gmove(&n1, a);
|
||||
regfree(&n1);
|
||||
a->op = OINDREG;
|
||||
a->xoffset = mpgetfix(n->right->val.u.xval)*n->type->width;
|
||||
a->type = n->type;
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute &a[i] as &a + i*width.
|
||||
a->type = n->type;
|
||||
a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
regalloc(a, types[tptr], res);
|
||||
|
@ -802,6 +802,9 @@ igen(Node *n, Node *a, Node *res)
|
||||
Iter flist;
|
||||
Node n1;
|
||||
|
||||
if(debug['g']) {
|
||||
dump("\nigen-n", n);
|
||||
}
|
||||
switch(n->op) {
|
||||
case ONAME:
|
||||
if((n->class&PHEAP) || n->class == PPARAMREF)
|
||||
@ -824,8 +827,19 @@ igen(Node *n, Node *a, Node *res)
|
||||
return;
|
||||
|
||||
case ODOTPTR:
|
||||
if(n->left->addable
|
||||
|| n->left->op == OCALLFUNC
|
||||
|| n->left->op == OCALLMETH
|
||||
|| n->left->op == OCALLINTER) {
|
||||
// igen-able nodes.
|
||||
igen(n->left, &n1, res);
|
||||
regalloc(a, types[tptr], &n1);
|
||||
gmove(&n1, a);
|
||||
regfree(&n1);
|
||||
} else {
|
||||
regalloc(a, types[tptr], res);
|
||||
cgen(n->left, a);
|
||||
}
|
||||
if(n->xoffset != 0) {
|
||||
// explicit check for nil if struct is large enough
|
||||
// that we might derive too big a pointer.
|
||||
|
@ -170,6 +170,74 @@ func ChainUNoAssert(u *U) *U {
|
||||
Child(0).(*U)
|
||||
}
|
||||
|
||||
// Type assertions and slice indexing. See issue 4207.
|
||||
func ChainAssertIndex(u *U) J {
|
||||
return u.
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0].(*U).
|
||||
Children[0]
|
||||
}
|
||||
|
||||
type UArr struct {
|
||||
Children [2]J
|
||||
}
|
||||
|
||||
func (u *UArr) Child(n int) J { return u.Children[n] }
|
||||
|
||||
func ChainAssertArrayIndex(u *UArr) J {
|
||||
return u.
|
||||
Children[0].(*UArr).
|
||||
Children[0].(*UArr).
|
||||
Children[0].(*UArr).
|
||||
Children[0].(*UArr).
|
||||
Children[0].(*UArr).
|
||||
Children[0].(*UArr).
|
||||
Children[0].(*UArr).
|
||||
// Children[0].(*UArr).
|
||||
// Children[0].(*UArr).
|
||||
// Children[0].(*UArr).
|
||||
// Children[0].(*UArr).
|
||||
// Children[0].(*UArr).
|
||||
// Children[0].(*UArr).
|
||||
Children[0]
|
||||
}
|
||||
|
||||
type UArrPtr struct {
|
||||
Children *[2]J
|
||||
}
|
||||
|
||||
func (u *UArrPtr) Child(n int) J { return u.Children[n] }
|
||||
|
||||
func ChainAssertArrayptrIndex(u *UArrPtr) J {
|
||||
// TODO: don't crash on longer chains.
|
||||
return u.
|
||||
Children[0].(*UArrPtr).
|
||||
Children[0].(*UArrPtr).
|
||||
Children[0].(*UArrPtr).
|
||||
Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
// Children[0].(*UArrPtr).
|
||||
Children[0]
|
||||
}
|
||||
|
||||
// Chains of divisions. See issue 4201.
|
||||
|
||||
func ChainDiv(a, b int) int {
|
||||
|
Loading…
Reference in New Issue
Block a user