]> Cypherpunks repositories - gostls13.git/commitdiff
plateau in divide by a constant
authorKen Thompson <ken@golang.org>
Sat, 8 Aug 2009 22:26:09 +0000 (15:26 -0700)
committerKen Thompson <ken@golang.org>
Sat, 8 Aug 2009 22:26:09 +0000 (15:26 -0700)
still to do - overflow, mod

R=rsc
OCL=32927
CL=32927

src/cmd/6g/ggen.c
src/cmd/6g/gsubr.c
src/cmd/gc/go.h

index b0fa9c725537e1d0eca0c20b61fcdbdaf0d345b7..8bbd7ec4d6199b10d66027b0d1abd38f6c728c16 100644 (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
index c9d7980ebc0feabb4d18d0e0807e56bf228db0f6..f7c80f50e3825f75693793cf92170c5e4378a039 100644 (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;
index 3ddeca1dffc36597da02b64687f3f98a15ccf62c..c0c4354b875608c7059292f30daca4aa48598ecd 100644 (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,