summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2009-08-08 15:26:09 -0700
committerKen Thompson <ken@golang.org>2009-08-08 15:26:09 -0700
commit776248f05db6a08c45d2f5a9d835296697b61136 (patch)
tree678b669e6f7370e26260df738056bbcbef4ff8fd
parentea777a65fcd2cc592cd5a9e9b8d5fee4c12f3c6d (diff)
downloadgolang-776248f05db6a08c45d2f5a9d835296697b61136.tar.gz
plateau in divide by a constant
still to do - overflow, mod R=rsc OCL=32927 CL=32927
-rw-r--r--src/cmd/6g/ggen.c27
-rw-r--r--src/cmd/6g/gsubr.c32
-rw-r--r--src/cmd/gc/go.h2
3 files changed, 53 insertions, 8 deletions
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index b0fa9c725..8bbd7ec4d 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 c9d7980eb..f7c80f50e 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 3ddeca1df..c0c4354b8 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,