1
0
mirror of https://github.com/golang/go synced 2024-11-26 06:47:58 -07:00

plateau in divide by a constant

still to do - overflow, mod

R=rsc
OCL=32927
CL=32927
This commit is contained in:
Ken Thompson 2009-08-08 15:26:09 -07:00
parent 8b8a2bd945
commit 07044ba6e5
3 changed files with 53 additions and 8 deletions

View File

@ -657,7 +657,6 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
return;
divbymul:
goto longdiv;
switch(simtype[nl->type->etype]) {
default:
goto longdiv;
@ -678,7 +677,29 @@ goto longdiv;
// todo fixup
break;
}
break;
savex(D_AX, &ax, &oldax, res, nl->type);
savex(D_DX, &dx, &olddx, res, nl->type);
savex(D_CX, &cx, &oldcx, res, nl->type);
regalloc(&n1, nl->type, N);
cgen(nl, &n1); // num -> reg(n1)
nodconst(&n2, nl->type, m.um);
gmove(&n2, &ax); // const->ax
gins(optoas(OHMUL, nl->type), &n1, N); // imul reg
nodconst(&n2, nl->type, m.s);
gins(optoas(ORSH, nl->type), &n2, &dx); // shift dx
regfree(&n1);
gmove(&dx, res);
restx(&ax, &oldax);
restx(&dx, &olddx);
restx(&cx, &oldcx);
return;
case TINT16:
case TINT32:
@ -707,7 +728,7 @@ goto longdiv;
nodconst(&n2, nl->type, m.sm);
gmove(&n2, &ax); // const->ax
gins(optoas(OMUL, nl->type), &n1, N); // imul reg
gins(optoas(OHMUL, nl->type), &n1, N); // imul reg
nodconst(&n2, nl->type, m.s);
gins(optoas(ORSH, nl->type), &n2, &dx); // shift dx

View File

@ -1473,28 +1473,50 @@ optoas(int op, Type *t)
a = ASARQ;
break;
case CASE(OHMUL, TINT8):
case CASE(OMUL, TINT8):
case CASE(OMUL, TUINT8):
a = AIMULB;
break;
case CASE(OHMUL, TINT16):
case CASE(OMUL, TINT16):
case CASE(OMUL, TUINT16):
a = AIMULW;
break;
case CASE(OHMUL, TINT32):
case CASE(OMUL, TINT32):
case CASE(OMUL, TUINT32):
case CASE(OMUL, TPTR32):
a = AIMULL;
break;
case CASE(OHMUL, TINT64):
case CASE(OMUL, TINT64):
case CASE(OMUL, TUINT64):
case CASE(OMUL, TPTR64):
a = AIMULQ;
break;
case CASE(OHMUL, TUINT8):
a = AMULB;
break;
case CASE(OHMUL, TUINT16):
a = AMULW;
break;
case CASE(OHMUL, TUINT32):
case CASE(OHMUL, TPTR32):
a = AMULL;
break;
case CASE(OHMUL, TUINT64):
case CASE(OHMUL, TPTR64):
a = AMULQ;
break;
case CASE(OMUL, TFLOAT32):
a = AMULSS;
break;
@ -1930,8 +1952,8 @@ void
smagic(Magic *m)
{
int p;
uint64 ad, anc, delta, q1, r1, q2, r2, t, two31;
uint64 mask;
uint64 ad, anc, delta, q1, r1, q2, r2, t;
uint64 mask, two31;
m->bad = 0;
switch(m->w) {
@ -2013,6 +2035,8 @@ smagic(Magic *m)
}
m->sm = q2+1;
if(m->sm & two31)
m->sm |= ~mask;
m->s = p-m->w;
}
@ -2020,8 +2044,8 @@ void
umagic(Magic *m)
{
int p;
uint64 nc, delta, q1, r1, q2, r2, two31;
uint64 mask;
uint64 nc, delta, q1, r1, q2, r2;
uint64 mask, two31;
m->bad = 0;
m->ua = 0;

View File

@ -343,7 +343,7 @@ enum
OKEY, OPARAM,
OLEN,
OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT,
OMUL, ODIV, OMOD, OLSH, ORSH, OHMUL, OAND, OANDNOT,
ONEW,
ONOT, OCOM, OPLUS, OMINUS,
OOROR,