1
0
mirror of https://github.com/golang/go synced 2024-11-26 09:48:14 -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; return;
divbymul: divbymul:
goto longdiv;
switch(simtype[nl->type->etype]) { switch(simtype[nl->type->etype]) {
default: default:
goto longdiv; goto longdiv;
@ -678,7 +677,29 @@ goto longdiv;
// todo fixup // todo fixup
break; 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 TINT16:
case TINT32: case TINT32:
@ -707,7 +728,7 @@ goto longdiv;
nodconst(&n2, nl->type, m.sm); nodconst(&n2, nl->type, m.sm);
gmove(&n2, &ax); // const->ax 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); nodconst(&n2, nl->type, m.s);
gins(optoas(ORSH, nl->type), &n2, &dx); // shift dx gins(optoas(ORSH, nl->type), &n2, &dx); // shift dx

View File

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

View File

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