From 07044ba6e5d1c6bde66da93dd9a63e6ab4c941fc Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Sat, 8 Aug 2009 15:26:09 -0700 Subject: [PATCH] plateau in divide by a constant still to do - overflow, mod R=rsc OCL=32927 CL=32927 --- src/cmd/6g/ggen.c | 27 ++++++++++++++++++++++++--- src/cmd/6g/gsubr.c | 32 ++++++++++++++++++++++++++++---- src/cmd/gc/go.h | 2 +- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c index b0fa9c7255..8bbd7ec4d6 100644 --- a/src/cmd/6g/ggen.c +++ b/src/cmd/6g/ggen.c @@ -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 diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index c9d7980ebc..f7c80f50e3 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -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; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 3ddeca1dff..c0c4354b87 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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, -- 2.48.1