cmd/5g, cmd/6g: pass the full torture test.

The patch adds more cases to agenr to allocate registers later,
and makes 6g generate addresses for sgen in something else than
SI and DI. It avoids a complex save/restore sequence that
amounts to allocate a register before descending in subtrees.

Fixes #4207.

R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/6817080
This commit is contained in:
Rémy Oudompheng 2012-11-12 23:56:11 +01:00
parent 80f4ff226f
commit eb4f4d16ae
4 changed files with 57 additions and 34 deletions

View file

@ -893,6 +893,21 @@ agenr(Node *n, Node *a, Node *res)
nr = n->right;
switch(n->op) {
case ODOT:
case ODOTPTR:
case OCALLFUNC:
case OCALLMETH:
case OCALLINTER:
igen(n, &n1, res);
regalloc(a, types[tptr], &n1);
agen(&n1, a);
regfree(&n1);
break;
case OIND:
cgenr(n->left, a, res);
break;
case OINDEX:
p2 = nil; // to be patched to panicindex.
w = n->type->width;

View file

@ -361,6 +361,7 @@ regalloc(Node *n, Type *t, Node *o)
regpc[i] = (uintptr)getcallerpc(&n);
goto out;
}
print("registers allocated at\n");
for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
print("%d %p\n", i, regpc[i]);
yyerror("out of fixed registers");

View file

@ -576,6 +576,21 @@ agenr(Node *n, Node *a, Node *res)
nr = n->right;
switch(n->op) {
case ODOT:
case ODOTPTR:
case OCALLFUNC:
case OCALLMETH:
case OCALLINTER:
igen(n, &n1, res);
regalloc(a, types[tptr], &n1);
agen(&n1, a);
regfree(&n1);
break;
case OIND:
cgenr(n->left, a, res);
break;
case OINDEX:
freelen = 0;
w = n->type->width;
@ -1309,7 +1324,7 @@ stkof(Node *n)
void
sgen(Node *n, Node *ns, int64 w)
{
Node nodl, nodr, oldl, oldr, cx, oldcx, tmp;
Node nodl, nodr, nodsi, noddi, cx, oldcx, tmp;
int32 c, q, odst, osrc;
if(debug['g']) {
@ -1353,22 +1368,18 @@ sgen(Node *n, Node *ns, int64 w)
}
if(n->ullman >= ns->ullman) {
savex(D_SI, &nodr, &oldr, N, types[tptr]);
agen(n, &nodr);
regalloc(&nodr, types[tptr], &nodr); // mark nodr as live
savex(D_DI, &nodl, &oldl, N, types[tptr]);
agen(ns, &nodl);
regfree(&nodr);
agenr(n, &nodr, N);
agenr(ns, &nodl, N);
} else {
savex(D_DI, &nodl, &oldl, N, types[tptr]);
agen(ns, &nodl);
regalloc(&nodl, types[tptr], &nodl); // mark nodl as live
savex(D_SI, &nodr, &oldr, N, types[tptr]);
agen(n, &nodr);
regfree(&nodl);
agenr(ns, &nodl, N);
agenr(n, &nodr, N);
}
nodreg(&noddi, types[tptr], D_DI);
nodreg(&nodsi, types[tptr], D_SI);
gmove(&nodl, &noddi);
gmove(&nodr, &nodsi);
regfree(&nodl);
regfree(&nodr);
c = w % 8; // bytes
q = w / 8; // quads
@ -1425,9 +1436,6 @@ sgen(Node *n, Node *ns, int64 w)
}
}
restx(&nodl, &oldl);
restx(&nodr, &oldr);
restx(&cx, &oldcx);
}

View file

@ -279,12 +279,12 @@ func ChainAssertArrayIndex(u *UArr) J {
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].(*UArr).
Children[0].(*UArr).
Children[0]
}
@ -295,21 +295,20 @@ type UArrPtr struct {
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].(*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]
}