]> Cypherpunks repositories - gostls13.git/commitdiff
8-bit div and mod
authorRuss Cox <rsc@golang.org>
Mon, 10 Aug 2009 19:46:23 +0000 (12:46 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 10 Aug 2009 19:46:23 +0000 (12:46 -0700)
R=ken
OCL=32975
CL=32975

src/cmd/6g/ggen.c
test/ken/divconst.go
test/ken/modconst.go

index 629a8cd3d124768fcea3ea3b2d20187dc9be46dc..278b2ef69368d3cc36b50ccff92980e90b3882fc 100644 (file)
@@ -565,7 +565,7 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
 {
        Node ax, dx, oldax, olddx;
        Node n1, n2, n3, savl, savr;
-       int n, w, s;
+       int n, w, s, a;
        Magic m;
 
        if(nl->ullman >= UINF) {
@@ -616,8 +616,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
        case 1:
                // divide by 2
                if(op == OMOD) {
-                       if(issigned[nl->type->etype]) 
-                               goto longdiv;
+                       if(issigned[nl->type->etype])
+                               goto longmod;
                        regalloc(&n1, nl->type, res);
                        cgen(nl, &n1);
                        nodconst(&n2, nl->type, 1);
@@ -641,8 +641,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
                break;
        default:
                if(op == OMOD) {
-                       if(issigned[nl->type->etype]) 
-                               goto longdiv;
+                       if(issigned[nl->type->etype])
+                               goto longmod;
                        regalloc(&n1, nl->type, res);
                        cgen(nl, &n1);
                        nodconst(&n2, nl->type, mpgetfix(nr->val.u.xval)-1);
@@ -688,6 +688,7 @@ divbymul:
        default:
                goto longdiv;
 
+       case TUINT8:
        case TUINT16:
        case TUINT32:
        case TUINT64:
@@ -709,6 +710,13 @@ divbymul:
                gmove(&n2, &ax);                        // const->ax
 
                gins(optoas(OHMUL, nl->type), &n1, N);  // imul reg
+               if(w == 8) {
+                       // fix up 8-bit multiply
+                       Node ah, dl;
+                       nodreg(&ah, types[TUINT8], D_AH);
+                       nodreg(&dl, types[TUINT8], D_DL);
+                       gins(AMOVB, &ah, &dl);
+               }
 
                if(m.ua) {
                        // need to add numerator accounting for overflow
@@ -730,6 +738,7 @@ divbymul:
                restx(&dx, &olddx);
                return;
 
+       case TINT8:
        case TINT16:
        case TINT32:
        case TINT64:
@@ -751,6 +760,13 @@ divbymul:
                gmove(&n2, &ax);                        // const->ax
 
                gins(optoas(OHMUL, nl->type), &n1, N);  // imul reg
+               if(w == 8) {
+                       // fix up 8-bit multiply
+                       Node ah, dl;
+                       nodreg(&ah, types[TUINT8], D_AH);
+                       nodreg(&dl, types[TUINT8], D_DL);
+                       gins(AMOVB, &ah, &dl);
+               }
 
                if(m.sm < 0) {
                        // need to add numerator
@@ -795,13 +811,19 @@ longmod:
        cgen(nl, &n1);
        regalloc(&n2, nl->type, N);
        cgen_div(ODIV, &n1, nr, &n2);
+       a = optoas(OMUL, nl->type);
+       if(w == 8) {
+               // use 2-operand 16-bit multiply
+               // because there is no 2-operand 8-bit multiply
+               a = AIMULW;
+       }
        if(!smallintconst(nr)) {
                regalloc(&n3, nl->type, N);
                cgen(nr, &n3);
-               gins(optoas(OMUL, nl->type), &n3, &n2);
+               gins(a, &n3, &n2);
                regfree(&n3);
        } else
-               gins(optoas(OMUL, nl->type), nr, &n2);
+               gins(a, nr, &n2);
        gins(optoas(OSUB, nl->type), &n2, &n1);
        gmove(&n1, res);
        regfree(&n1);
@@ -908,7 +930,7 @@ ret:
 /*
  * generate byte multiply:
  *     res = nl * nr
- * no byte multiply instruction so have to do
+ * no 2-operand byte multiply instruction so have to do
  * 16-bit multiply and take bottom half.
  */
 void
index d0cbbbedcdd69bd545966b780617d46123e88735..34d7d430b4508250503dcb4475f32680ca50a6a9 100644 (file)
@@ -351,6 +351,114 @@ u16run()
        }
 }
 
+func
+i8rand() int8
+{
+       for {
+               a := int8(rand.Uint32());
+               a >>= uint(rand.Intn(8));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i8test(a,b,c int8)
+{
+       d := a/c;
+       if d != b {
+               panicln("i8", a, b, c, d);
+       }
+}
+
+func
+i8run()
+{
+       var a, b int8;
+
+       for i:=0; i<Count; i++ {
+               a = i8rand();
+
+               b = a/1;        i8test(a,b,1);
+               b = a/2;        i8test(a,b,2);
+               b = a/3;        i8test(a,b,3);
+               b = a/4;        i8test(a,b,4);
+               b = a/5;        i8test(a,b,5);
+               b = a/6;        i8test(a,b,6);
+               b = a/7;        i8test(a,b,7);
+               b = a/8;        i8test(a,b,8);
+               b = a/10;       i8test(a,b,10);
+               b = a/8;        i8test(a,b,8);
+               b = a/20;       i8test(a,b,20);
+               b = a/32;       i8test(a,b,32);
+               b = a/60;       i8test(a,b,60);
+               b = a/64;       i8test(a,b,64);
+               b = a/127;      i8test(a,b,127);
+
+               b = a/-1;       i8test(a,b,-1);
+               b = a/-2;       i8test(a,b,-2);
+               b = a/-3;       i8test(a,b,-3);
+               b = a/-4;       i8test(a,b,-4);
+               b = a/-5;       i8test(a,b,-5);
+               b = a/-6;       i8test(a,b,-6);
+               b = a/-7;       i8test(a,b,-7);
+               b = a/-8;       i8test(a,b,-8);
+               b = a/-10;      i8test(a,b,-10);
+               b = a/-8;       i8test(a,b,-8);
+               b = a/-20;      i8test(a,b,-20);
+               b = a/-32;      i8test(a,b,-32);
+               b = a/-60;      i8test(a,b,-60);
+               b = a/-64;      i8test(a,b,-64);
+               b = a/-128;     i8test(a,b,-128);
+       }
+}
+
+func
+u8rand() uint8
+{
+       a := uint8(rand.Uint32());
+       a >>= uint(rand.Intn(8));
+       return a;
+}
+
+func
+u8test(a,b,c uint8)
+{
+       d := a/c;
+       if d != b {
+               panicln("u8", a, b, c, d);
+       }
+}
+
+func
+u8run()
+{
+       var a, b uint8;
+
+       for i:=0; i<Count; i++ {
+               a = u8rand();
+
+               b = a/1;        u8test(a,b,1);
+               b = a/2;        u8test(a,b,2);
+               b = a/3;        u8test(a,b,3);
+               b = a/4;        u8test(a,b,4);
+               b = a/5;        u8test(a,b,5);
+               b = a/6;        u8test(a,b,6);
+               b = a/7;        u8test(a,b,7);
+               b = a/8;        u8test(a,b,8);
+               b = a/10;       u8test(a,b,10);
+               b = a/8;        u8test(a,b,8);
+               b = a/20;       u8test(a,b,20);
+               b = a/32;       u8test(a,b,32);
+               b = a/60;       u8test(a,b,60);
+               b = a/64;       u8test(a,b,64);
+               b = a/128;      u8test(a,b,128);
+               b = a/184;      u8test(a,b,184);
+       }
+}
+
 func   xtest()
 
 func
@@ -363,6 +471,8 @@ main()
        u32run();
        i16run();
        u16run();
+       i8run();
+       u8run();
 }
 
 func
index 812a13ca82519f8e0a83ead2a376bb9d308c45c7..7a9ebed0e4fabefcff3695125dccfee38c07db96 100644 (file)
@@ -351,6 +351,114 @@ u16run()
        }
 }
 
+func
+i8rand() int8
+{
+       for {
+               a := int8(rand.Uint32());
+               a >>= uint(rand.Intn(8));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i8test(a,b,c int8)
+{
+       d := a%c;
+       if d != b {
+               panicln("i8", a, b, c, d);
+       }
+}
+
+func
+i8run()
+{
+       var a, b int8;
+
+       for i:=0; i<Count; i++ {
+               a = i8rand();
+
+               b = a%1;        i8test(a,b,1);
+               b = a%2;        i8test(a,b,2);
+               b = a%3;        i8test(a,b,3);
+               b = a%4;        i8test(a,b,4);
+               b = a%5;        i8test(a,b,5);
+               b = a%6;        i8test(a,b,6);
+               b = a%7;        i8test(a,b,7);
+               b = a%8;        i8test(a,b,8);
+               b = a%10;       i8test(a,b,10);
+               b = a%8;        i8test(a,b,8);
+               b = a%20;       i8test(a,b,20);
+               b = a%32;       i8test(a,b,32);
+               b = a%60;       i8test(a,b,60);
+               b = a%64;       i8test(a,b,64);
+               b = a%127;      i8test(a,b,127);
+
+               b = a%-1;       i8test(a,b,-1);
+               b = a%-2;       i8test(a,b,-2);
+               b = a%-3;       i8test(a,b,-3);
+               b = a%-4;       i8test(a,b,-4);
+               b = a%-5;       i8test(a,b,-5);
+               b = a%-6;       i8test(a,b,-6);
+               b = a%-7;       i8test(a,b,-7);
+               b = a%-8;       i8test(a,b,-8);
+               b = a%-10;      i8test(a,b,-10);
+               b = a%-8;       i8test(a,b,-8);
+               b = a%-20;      i8test(a,b,-20);
+               b = a%-32;      i8test(a,b,-32);
+               b = a%-60;      i8test(a,b,-60);
+               b = a%-64;      i8test(a,b,-64);
+               b = a%-128;     i8test(a,b,-128);
+               b = a%-101;     i8test(a,b,-101);
+       }
+}
+
+func
+u8rand() uint8
+{
+       a := uint8(rand.Uint32());
+       a >>= uint(rand.Intn(8));
+       return a;
+}
+
+func
+u8test(a,b,c uint8)
+{
+       d := a%c;
+       if d != b {
+               panicln("u8", a, b, c, d);
+       }
+}
+
+func
+u8run()
+{
+       var a, b uint8;
+
+       for i:=0; i<Count; i++ {
+               a = u8rand();
+
+               b = a%1;        u8test(a,b,1);
+               b = a%2;        u8test(a,b,2);
+               b = a%3;        u8test(a,b,3);
+               b = a%4;        u8test(a,b,4);
+               b = a%5;        u8test(a,b,5);
+               b = a%6;        u8test(a,b,6);
+               b = a%7;        u8test(a,b,7);
+               b = a%8;        u8test(a,b,8);
+               b = a%10;       u8test(a,b,10);
+               b = a%8;        u8test(a,b,8);
+               b = a%20;       u8test(a,b,20);
+               b = a%32;       u8test(a,b,32);
+               b = a%60;       u8test(a,b,60);
+               b = a%64;       u8test(a,b,64);
+               b = a%127;      u8test(a,b,127);
+       }
+}
+
 func   xtest()
 
 func
@@ -363,6 +471,8 @@ main()
        u32run();
        i16run();
        u16run();
+       i8run();
+       u8run();
 }
 
 func