Commit 07044ba6 authored by Ken Thompson's avatar Ken Thompson

plateau in divide by a constant

still to do - overflow, mod

R=rsc
OCL=32927
CL=32927
parent 8b8a2bd9
......@@ -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
......
......@@ -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;
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment