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) ...@@ -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; ...@@ -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; ...@@ -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
......
...@@ -1473,28 +1473,50 @@ optoas(int op, Type *t) ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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;
......
...@@ -343,7 +343,7 @@ enum ...@@ -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,
......
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