1
0
mirror of https://github.com/golang/go synced 2024-09-25 15:20:13 -06:00

cmd/6g, cmd/8g: fix two "out of fixed registers" cases.

In two cases, registers were allocated too early resulting
in exhausting of available registers when nesting these
operations.

The case of method calls was due to missing cases in igen,
which only makes calls but doesn't allocate a register for
the result.

The case of 8-bit multiplication was due to a wrong order
in register allocation when Ullman numbers were bigger on the
RHS.

Fixes #3907.
Fixes #4156.

R=rsc
CC=golang-dev, remy
https://golang.org/cl/6560054
This commit is contained in:
Rémy Oudompheng 2012-09-26 21:17:11 +02:00
parent 7936ab58f7
commit 6feb61325a
4 changed files with 74 additions and 70 deletions

View File

@ -246,10 +246,11 @@ cgen(Node *n, Node *res)
case OADD:
case OMUL:
a = optoas(n->op, nl->type);
if(a != AIMULB)
goto sbop;
cgen_bmul(n->op, nl, nr, res);
break;
if(a == AIMULB) {
cgen_bmul(n->op, nl, nr, res);
break;
}
goto sbop;
// asymmetric binary
case OSUB:
@ -840,8 +841,20 @@ igen(Node *n, Node *a, Node *res)
return;
case OCALLFUNC:
case OCALLMETH:
case OCALLINTER:
switch(n->op) {
case OCALLFUNC:
cgen_call(n, 0);
break;
case OCALLMETH:
cgen_callmeth(n, 0);
break;
case OCALLINTER:
cgen_callinter(n, N, 0);
break;
}
fp = structfirst(&flist, getoutarg(n->left->type));
cgen_call(n, 0);
memset(a, 0, sizeof *a);
a->op = OINDREG;
a->val.u.reg = D_SP;

View File

@ -978,48 +978,37 @@ ret:
/*
* generate byte multiply:
* res = nl * nr
* no 2-operand byte multiply instruction so have to do
* 16-bit multiply and take bottom half.
* there is no 2-operand byte multiply instruction so
* we do a full-width multiplication and truncate afterwards.
*/
void
cgen_bmul(int op, Node *nl, Node *nr, Node *res)
{
Node n1b, n2b, n1w, n2w;
Node n1, n2, *tmp;
Type *t;
int a;
if(nl->ullman >= nr->ullman) {
regalloc(&n1b, nl->type, res);
cgen(nl, &n1b);
regalloc(&n2b, nr->type, N);
cgen(nr, &n2b);
} else {
regalloc(&n2b, nr->type, N);
cgen(nr, &n2b);
regalloc(&n1b, nl->type, res);
cgen(nl, &n1b);
// copy from byte to full registers
t = types[TUINT64];
if(issigned[nl->type->etype])
t = types[TINT64];
// largest ullman on left.
if(nl->ullman < nr->ullman) {
tmp = nl;
nl = nr;
nr = tmp;
}
// copy from byte to short registers
t = types[TUINT16];
if(issigned[nl->type->etype])
t = types[TINT16];
regalloc(&n2w, t, &n2b);
cgen(&n2b, &n2w);
regalloc(&n1w, t, &n1b);
cgen(&n1b, &n1w);
regalloc(&n1, t, res);
cgen(nl, &n1);
regalloc(&n2, t, N);
cgen(nr, &n2);
a = optoas(op, t);
gins(a, &n2w, &n1w);
cgen(&n1w, &n1b);
cgen(&n1b, res);
regfree(&n1w);
regfree(&n2w);
regfree(&n1b);
regfree(&n2b);
gins(a, &n2, &n1);
regfree(&n2);
gmove(&n1, res);
regfree(&n1);
}
void

View File

@ -825,8 +825,20 @@ igen(Node *n, Node *a, Node *res)
return;
case OCALLFUNC:
case OCALLMETH:
case OCALLINTER:
switch(n->op) {
case OCALLFUNC:
cgen_call(n, 0);
break;
case OCALLMETH:
cgen_callmeth(n, 0);
break;
case OCALLINTER:
cgen_callinter(n, N, 0);
break;
}
fp = structfirst(&flist, getoutarg(n->left->type));
cgen_call(n, 0);
memset(a, 0, sizeof *a);
a->op = OINDREG;
a->val.u.reg = D_SP;

View File

@ -743,46 +743,36 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
/*
* generate byte multiply:
* res = nl * nr
* no byte multiply instruction so have to do
* 16-bit multiply and take bottom half.
* there is no 2-operand byte multiply instruction so
* we do a full-width multiplication and truncate afterwards.
*/
void
cgen_bmul(int op, Node *nl, Node *nr, Node *res)
{
Node n1b, n2b, n1w, n2w;
Node n1, n2, *tmp;
Type *t;
int a;
if(nl->ullman >= nr->ullman) {
regalloc(&n1b, nl->type, res);
cgen(nl, &n1b);
regalloc(&n2b, nr->type, N);
cgen(nr, &n2b);
} else {
regalloc(&n2b, nr->type, N);
cgen(nr, &n2b);
regalloc(&n1b, nl->type, res);
cgen(nl, &n1b);
// copy from byte to full registers
t = types[TUINT32];
if(issigned[nl->type->etype])
t = types[TINT32];
// largest ullman on left.
if(nl->ullman < nr->ullman) {
tmp = nl;
nl = nr;
nr = tmp;
}
// copy from byte to short registers
t = types[TUINT16];
if(issigned[nl->type->etype])
t = types[TINT16];
regalloc(&n2w, t, &n2b);
cgen(&n2b, &n2w);
regalloc(&n1w, t, &n1b);
cgen(&n1b, &n1w);
regalloc(&n1, t, res);
cgen(nl, &n1);
regalloc(&n2, t, N);
cgen(nr, &n2);
a = optoas(op, t);
gins(a, &n2w, &n1w);
cgen(&n1w, &n1b);
cgen(&n1b, res);
regfree(&n1w);
regfree(&n2w);
regfree(&n1b);
regfree(&n2b);
gins(a, &n2, &n1);
regfree(&n2);
gmove(&n1, res);
regfree(&n1);
}