]> Cypherpunks.ru repositories - gostls13.git/commitdiff
another plateau - almost done
authorKen Thompson <ken@golang.org>
Sat, 8 Aug 2009 23:53:21 +0000 (16:53 -0700)
committerKen Thompson <ken@golang.org>
Sat, 8 Aug 2009 23:53:21 +0000 (16:53 -0700)
only need to fix up certain
denominators

R=rsc
OCL=32928
CL=32928

src/cmd/6g/ggen.c
test/ken/divconst.go
test/ken/modconst.go [new file with mode: 0644]

index 8bbd7ec4d6199b10d66027b0d1abd38f6c728c16..a3723738f55a5a8ffe4f5b843804d2344bccb48a 100644 (file)
@@ -601,16 +601,14 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
        if(n < 0)
                goto divbymul;
 
-       if(op == OMOD) {
-               // todo
-               goto longdiv;
-       }
-
        switch(n) {
        case 0:
                // divide by 1
                regalloc(&n1, nl->type, res);
                cgen(nl, &n1);
+               if(op == OMOD) {
+                       gins(optoas(OXOR, nl->type), &n1, &n1);
+               } else
                if(s)
                        gins(optoas(OMINUS, nl->type), N, &n1);
                gmove(&n1, res);
@@ -618,6 +616,17 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
                return;
        case 1:
                // divide by 2
+               if(op == OMOD) {
+                       if(issigned[nl->type->etype]) 
+                               goto longmod;
+                       regalloc(&n1, nl->type, res);
+                       cgen(nl, &n1);
+                       nodconst(&n2, nl->type, 1);
+                       gins(optoas(OAND, nl->type), &n2, &n1);
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       return;
+               }
                regalloc(&n1, nl->type, res);
                cgen(nl, &n1);
                if(!issigned[nl->type->etype])
@@ -632,6 +641,23 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
                regfree(&n2);
                break;
        default:
+               if(op == OMOD) {
+                       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);
+                       if(!smallintconst(&n2)) {
+                               regalloc(&n3, nl->type, N);
+                               gmove(&n2, &n3);
+                               gins(optoas(OAND, nl->type), &n3, &n1);
+                               regfree(&n3);
+                       } else
+                               gins(optoas(OAND, nl->type), &n2, &n1);
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       return;
+               }
                regalloc(&n1, nl->type, res);
                cgen(nl, &n1);
                if(!issigned[nl->type->etype])
@@ -657,6 +683,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
        return;
 
 divbymul:
+       // try to do division by multiply by (2^w)/d
+       // see hacker's delight chapter 10
        switch(simtype[nl->type->etype]) {
        default:
                goto longdiv;
@@ -669,14 +697,12 @@ divbymul:
                umagic(&m);
                if(m.bad)
                        break;
-               if(op == OMOD) {
-                       // todo
-                       break;
-               }
                if(m.ua != 0) {
                        // todo fixup
                        break;
                }
+               if(op == OMOD)
+                       goto longmod;
 
                savex(D_AX, &ax, &oldax, res, nl->type);
                savex(D_DX, &dx, &olddx, res, nl->type);
@@ -709,14 +735,12 @@ divbymul:
                smagic(&m);
                if(m.bad)
                        break;
-               if(op == OMOD) {
-                       // todo
-                       break;
-               }
                if(m.sm < 0) {
                        // todo fixup
                        break;
                }
+               if(op == OMOD)
+                       goto longmod;
 
                savex(D_AX, &ax, &oldax, res, nl->type);
                savex(D_DX, &dx, &olddx, res, nl->type);
@@ -751,11 +775,32 @@ divbymul:
        goto longdiv;
 
 longdiv:
+       // division and mod using (slow) hardware instruction
        savex(D_AX, &ax, &oldax, res, nl->type);
        savex(D_DX, &dx, &olddx, res, nl->type);
        dodiv(op, nl, nr, res, &ax, &dx);
        restx(&ax, &oldax);
        restx(&dx, &olddx);
+       return;
+
+longmod:
+       // mod using formula A%B = A-(A/B*B) but
+       // we know that there is a fast algorithm for A/B
+       regalloc(&n1, nl->type, res);
+       cgen(nl, &n1);
+       regalloc(&n2, nl->type, N);
+       cgen_div(ODIV, &n1, nr, &n2);
+       if(!smallintconst(nr)) {
+               regalloc(&n3, nl->type, N);
+               cgen(nr, &n3);
+               gins(optoas(OMUL, nl->type), &n3, &n2);
+               regfree(&n3);
+       } else
+               gins(optoas(OMUL, nl->type), nr, &n2);
+       gins(optoas(OSUB, nl->type), &n2, &n1);
+       gmove(&n1, res);
+       regfree(&n1);
+       regfree(&n2);
 }
 
 /*
index 9042b1e962fd1c09da35d5e1242cd4c721a30ab5..d0cbbbedcdd69bd545966b780617d46123e88735 100644 (file)
@@ -9,37 +9,363 @@ package main
 
 import "rand"
 
-func   test(a,b,c int64);
+const  Count   = 1e6
 
 func
-main()
+i64rand() int64
+{
+       for {
+               a := int64(rand.Uint32());
+               a = (a<<32) | int64(rand.Uint32());
+               a >>= uint(rand.Intn(64));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i64test(a,b,c int64)
+{
+       d := a/c;
+       if d != b {
+               panicln("i64", a, b, c, d);
+       }
+}
+
+func
+i64run()
 {
        var a, b int64;
 
-       for i:=0; i<1e6; i++ {
-               a := rand.Int63() - 1<<62;
-               b = a/1;        test(a,b,1);
-               b = a/2;        test(a,b,2);
-               b = a/3;        test(a,b,3);
-               b = a/4;        test(a,b,4);
-               b = a/5;        test(a,b,5);
-               b = a/6;        test(a,b,6);
-               b = a/7;        test(a,b,7);
-               b = a/8;        test(a,b,8);
-               b = a/16;       test(a,b,16);
-               b = a/32;       test(a,b,32);
-               b = a/64;       test(a,b,64);
-               b = a/128;      test(a,b,128);
-               b = a/256;      test(a,b,256);
-               b = a/16384;    test(a,b,16384);
+       for i:=0; i<Count; i++ {
+               a = i64rand();
+
+               b = a/1;        i64test(a,b,1);
+               b = a/2;        i64test(a,b,2);
+               b = a/3;        i64test(a,b,3);
+               b = a/4;        i64test(a,b,4);
+               b = a/5;        i64test(a,b,5);
+               b = a/6;        i64test(a,b,6);
+               b = a/7;        i64test(a,b,7);
+               b = a/8;        i64test(a,b,8);
+               b = a/10;       i64test(a,b,10);
+               b = a/16;       i64test(a,b,16);
+               b = a/20;       i64test(a,b,20);
+               b = a/32;       i64test(a,b,32);
+               b = a/60;       i64test(a,b,60);
+               b = a/64;       i64test(a,b,64);
+               b = a/128;      i64test(a,b,128);
+               b = a/256;      i64test(a,b,256);
+               b = a/16384;    i64test(a,b,16384);
+
+               b = a/-1;       i64test(a,b,-1);
+               b = a/-2;       i64test(a,b,-2);
+               b = a/-3;       i64test(a,b,-3);
+               b = a/-4;       i64test(a,b,-4);
+               b = a/-5;       i64test(a,b,-5);
+               b = a/-6;       i64test(a,b,-6);
+               b = a/-7;       i64test(a,b,-7);
+               b = a/-8;       i64test(a,b,-8);
+               b = a/-10;      i64test(a,b,-10);
+               b = a/-16;      i64test(a,b,-16);
+               b = a/-20;      i64test(a,b,-20);
+               b = a/-32;      i64test(a,b,-32);
+               b = a/-60;      i64test(a,b,-60);
+               b = a/-64;      i64test(a,b,-64);
+               b = a/-128;     i64test(a,b,-128);
+               b = a/-256;     i64test(a,b,-256);
+               b = a/-16384;   i64test(a,b,-16384);
+       }
+}
+
+func
+u64rand() uint64
+{
+       a := uint64(rand.Uint32());
+       a = (a<<32) | uint64(rand.Uint32());
+       a >>= uint(rand.Intn(64));
+       return a;
+}
+
+func
+u64test(a,b,c uint64)
+{
+       d := a/c;
+       if d != b {
+               panicln("u64", a, b, c, d);
+       }
+}
+
+func
+u64run()
+{
+       var a, b uint64;
+
+       for i:=0; i<Count; i++ {
+               a = u64rand();
+
+               b = a/1;        u64test(a,b,1);
+               b = a/2;        u64test(a,b,2);
+               b = a/3;        u64test(a,b,3);
+               b = a/4;        u64test(a,b,4);
+               b = a/5;        u64test(a,b,5);
+               b = a/6;        u64test(a,b,6);
+               b = a/7;        u64test(a,b,7);
+               b = a/8;        u64test(a,b,8);
+               b = a/10;       u64test(a,b,10);
+               b = a/16;       u64test(a,b,16);
+               b = a/20;       u64test(a,b,20);
+               b = a/32;       u64test(a,b,32);
+               b = a/60;       u64test(a,b,60);
+               b = a/64;       u64test(a,b,64);
+               b = a/128;      u64test(a,b,128);
+               b = a/256;      u64test(a,b,256);
+               b = a/16384;    u64test(a,b,16384);
+       }
+}
+
+func
+i32rand() int32
+{
+       for {
+               a := int32(rand.Uint32());
+               a >>= uint(rand.Intn(32));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i32test(a,b,c int32)
+{
+       d := a/c;
+       if d != b {
+               panicln("i32", a, b, c, d);
+       }
+}
+
+func
+i32run()
+{
+       var a, b int32;
+
+       for i:=0; i<Count; i++ {
+               a = i32rand();
+
+               b = a/1;        i32test(a,b,1);
+               b = a/2;        i32test(a,b,2);
+               b = a/3;        i32test(a,b,3);
+               b = a/4;        i32test(a,b,4);
+               b = a/5;        i32test(a,b,5);
+               b = a/6;        i32test(a,b,6);
+               b = a/7;        i32test(a,b,7);
+               b = a/8;        i32test(a,b,8);
+               b = a/10;       i32test(a,b,10);
+               b = a/16;       i32test(a,b,16);
+               b = a/20;       i32test(a,b,20);
+               b = a/32;       i32test(a,b,32);
+               b = a/60;       i32test(a,b,60);
+               b = a/64;       i32test(a,b,64);
+               b = a/128;      i32test(a,b,128);
+               b = a/256;      i32test(a,b,256);
+               b = a/16384;    i32test(a,b,16384);
+
+               b = a/-1;       i32test(a,b,-1);
+               b = a/-2;       i32test(a,b,-2);
+               b = a/-3;       i32test(a,b,-3);
+               b = a/-4;       i32test(a,b,-4);
+               b = a/-5;       i32test(a,b,-5);
+               b = a/-6;       i32test(a,b,-6);
+               b = a/-7;       i32test(a,b,-7);
+               b = a/-8;       i32test(a,b,-8);
+               b = a/-10;      i32test(a,b,-10);
+               b = a/-16;      i32test(a,b,-16);
+               b = a/-20;      i32test(a,b,-20);
+               b = a/-32;      i32test(a,b,-32);
+               b = a/-60;      i32test(a,b,-60);
+               b = a/-64;      i32test(a,b,-64);
+               b = a/-128;     i32test(a,b,-128);
+               b = a/-256;     i32test(a,b,-256);
+       }
+}
+
+func
+u32rand() uint32
+{
+       a := uint32(rand.Uint32());
+       a >>= uint(rand.Intn(32));
+       return a;
+}
+
+func
+u32test(a,b,c uint32)
+{
+       d := a/c;
+       if d != b {
+               panicln("u32", a, b, c, d);
+       }
+}
+
+func
+u32run()
+{
+       var a, b uint32;
+
+       for i:=0; i<Count; i++ {
+               a = u32rand();
+
+               b = a/1;        u32test(a,b,1);
+               b = a/2;        u32test(a,b,2);
+               b = a/3;        u32test(a,b,3);
+               b = a/4;        u32test(a,b,4);
+               b = a/5;        u32test(a,b,5);
+               b = a/6;        u32test(a,b,6);
+               b = a/7;        u32test(a,b,7);
+               b = a/8;        u32test(a,b,8);
+               b = a/10;       u32test(a,b,10);
+               b = a/16;       u32test(a,b,16);
+               b = a/20;       u32test(a,b,20);
+               b = a/32;       u32test(a,b,32);
+               b = a/60;       u32test(a,b,60);
+               b = a/64;       u32test(a,b,64);
+               b = a/128;      u32test(a,b,128);
+               b = a/256;      u32test(a,b,256);
+               b = a/16384;    u32test(a,b,16384);
+       }
+}
+
+func
+i16rand() int16
+{
+       for {
+               a := int16(rand.Uint32());
+               a >>= uint(rand.Intn(16));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i16test(a,b,c int16)
+{
+       d := a/c;
+       if d != b {
+               panicln("i16", a, b, c, d);
+       }
+}
+
+func
+i16run()
+{
+       var a, b int16;
+
+       for i:=0; i<Count; i++ {
+               a = i16rand();
+
+               b = a/1;        i16test(a,b,1);
+               b = a/2;        i16test(a,b,2);
+               b = a/3;        i16test(a,b,3);
+               b = a/4;        i16test(a,b,4);
+               b = a/5;        i16test(a,b,5);
+               b = a/6;        i16test(a,b,6);
+               b = a/7;        i16test(a,b,7);
+               b = a/8;        i16test(a,b,8);
+               b = a/10;       i16test(a,b,10);
+               b = a/16;       i16test(a,b,16);
+               b = a/20;       i16test(a,b,20);
+               b = a/32;       i16test(a,b,32);
+               b = a/60;       i16test(a,b,60);
+               b = a/64;       i16test(a,b,64);
+               b = a/128;      i16test(a,b,128);
+               b = a/256;      i16test(a,b,256);
+               b = a/16384;    i16test(a,b,16384);
+
+               b = a/-1;       i16test(a,b,-1);
+               b = a/-2;       i16test(a,b,-2);
+               b = a/-3;       i16test(a,b,-3);
+               b = a/-4;       i16test(a,b,-4);
+               b = a/-5;       i16test(a,b,-5);
+               b = a/-6;       i16test(a,b,-6);
+               b = a/-7;       i16test(a,b,-7);
+               b = a/-8;       i16test(a,b,-8);
+               b = a/-10;      i16test(a,b,-10);
+               b = a/-16;      i16test(a,b,-16);
+               b = a/-20;      i16test(a,b,-20);
+               b = a/-32;      i16test(a,b,-32);
+               b = a/-60;      i16test(a,b,-60);
+               b = a/-64;      i16test(a,b,-64);
+               b = a/-128;     i16test(a,b,-128);
+               b = a/-256;     i16test(a,b,-256);
+               b = a/-16384;   i16test(a,b,-16384);
        }
 }
 
 func
-test(a,b,c int64)
+u16rand() uint16
+{
+       a := uint16(rand.Uint32());
+       a >>= uint(rand.Intn(16));
+       return a;
+}
+
+func
+u16test(a,b,c uint16)
 {
        d := a/c;
        if d != b {
-               panicln(a, b, c, d);
+               panicln("u16", a, b, c, d);
+       }
+}
+
+func
+u16run()
+{
+       var a, b uint16;
+
+       for i:=0; i<Count; i++ {
+               a = u16rand();
+
+               b = a/1;        u16test(a,b,1);
+               b = a/2;        u16test(a,b,2);
+               b = a/3;        u16test(a,b,3);
+               b = a/4;        u16test(a,b,4);
+               b = a/5;        u16test(a,b,5);
+               b = a/6;        u16test(a,b,6);
+               b = a/7;        u16test(a,b,7);
+               b = a/8;        u16test(a,b,8);
+               b = a/10;       u16test(a,b,10);
+               b = a/16;       u16test(a,b,16);
+               b = a/20;       u16test(a,b,20);
+               b = a/32;       u16test(a,b,32);
+               b = a/60;       u16test(a,b,60);
+               b = a/64;       u16test(a,b,64);
+               b = a/128;      u16test(a,b,128);
+               b = a/256;      u16test(a,b,256);
+               b = a/16384;    u16test(a,b,16384);
        }
 }
+
+func   xtest()
+
+func
+main()
+{
+       xtest();
+       i64run();
+       u64run();
+       i32run();
+       u32run();
+       i16run();
+       u16run();
+}
+
+func
+xtest()
+{
+}
diff --git a/test/ken/modconst.go b/test/ken/modconst.go
new file mode 100644 (file)
index 0000000..812a13c
--- /dev/null
@@ -0,0 +1,371 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+package main
+
+import "rand"
+
+const  Count   = 1e6
+
+func
+i64rand() int64
+{
+       for {
+               a := int64(rand.Uint32());
+               a = (a<<32) | int64(rand.Uint32());
+               a >>= uint(rand.Intn(64));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i64test(a,b,c int64)
+{
+       d := a%c;
+       if d != b {
+               panicln("i64", a, b, c, d);
+       }
+}
+
+func
+i64run()
+{
+       var a, b int64;
+
+       for i:=0; i<Count; i++ {
+               a = i64rand();
+
+               b = a%1;        i64test(a,b,1);
+               b = a%2;        i64test(a,b,2);
+               b = a%3;        i64test(a,b,3);
+               b = a%4;        i64test(a,b,4);
+               b = a%5;        i64test(a,b,5);
+               b = a%6;        i64test(a,b,6);
+               b = a%7;        i64test(a,b,7);
+               b = a%8;        i64test(a,b,8);
+               b = a%10;       i64test(a,b,10);
+               b = a%16;       i64test(a,b,16);
+               b = a%20;       i64test(a,b,20);
+               b = a%32;       i64test(a,b,32);
+               b = a%60;       i64test(a,b,60);
+               b = a%64;       i64test(a,b,64);
+               b = a%128;      i64test(a,b,128);
+               b = a%256;      i64test(a,b,256);
+               b = a%16384;    i64test(a,b,16384);
+
+               b = a%-1;       i64test(a,b,-1);
+               b = a%-2;       i64test(a,b,-2);
+               b = a%-3;       i64test(a,b,-3);
+               b = a%-4;       i64test(a,b,-4);
+               b = a%-5;       i64test(a,b,-5);
+               b = a%-6;       i64test(a,b,-6);
+               b = a%-7;       i64test(a,b,-7);
+               b = a%-8;       i64test(a,b,-8);
+               b = a%-10;      i64test(a,b,-10);
+               b = a%-16;      i64test(a,b,-16);
+               b = a%-20;      i64test(a,b,-20);
+               b = a%-32;      i64test(a,b,-32);
+               b = a%-60;      i64test(a,b,-60);
+               b = a%-64;      i64test(a,b,-64);
+               b = a%-128;     i64test(a,b,-128);
+               b = a%-256;     i64test(a,b,-256);
+               b = a%-16384;   i64test(a,b,-16384);
+       }
+}
+
+func
+u64rand() uint64
+{
+       a := uint64(rand.Uint32());
+       a = (a<<32) | uint64(rand.Uint32());
+       a >>= uint(rand.Intn(64));
+       return a;
+}
+
+func
+u64test(a,b,c uint64)
+{
+       d := a%c;
+       if d != b {
+               panicln("u64", a, b, c, d);
+       }
+}
+
+func
+u64run()
+{
+       var a, b uint64;
+
+       for i:=0; i<Count; i++ {
+               a = u64rand();
+
+               b = a%1;        u64test(a,b,1);
+               b = a%2;        u64test(a,b,2);
+               b = a%3;        u64test(a,b,3);
+               b = a%4;        u64test(a,b,4);
+               b = a%5;        u64test(a,b,5);
+               b = a%6;        u64test(a,b,6);
+               b = a%7;        u64test(a,b,7);
+               b = a%8;        u64test(a,b,8);
+               b = a%10;       u64test(a,b,10);
+               b = a%16;       u64test(a,b,16);
+               b = a%20;       u64test(a,b,20);
+               b = a%32;       u64test(a,b,32);
+               b = a%60;       u64test(a,b,60);
+               b = a%64;       u64test(a,b,64);
+               b = a%128;      u64test(a,b,128);
+               b = a%256;      u64test(a,b,256);
+               b = a%16384;    u64test(a,b,16384);
+       }
+}
+
+func
+i32rand() int32
+{
+       for {
+               a := int32(rand.Uint32());
+               a >>= uint(rand.Intn(32));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i32test(a,b,c int32)
+{
+       d := a%c;
+       if d != b {
+               panicln("i32", a, b, c, d);
+       }
+}
+
+func
+i32run()
+{
+       var a, b int32;
+
+       for i:=0; i<Count; i++ {
+               a = i32rand();
+
+               b = a%1;        i32test(a,b,1);
+               b = a%2;        i32test(a,b,2);
+               b = a%3;        i32test(a,b,3);
+               b = a%4;        i32test(a,b,4);
+               b = a%5;        i32test(a,b,5);
+               b = a%6;        i32test(a,b,6);
+               b = a%7;        i32test(a,b,7);
+               b = a%8;        i32test(a,b,8);
+               b = a%10;       i32test(a,b,10);
+               b = a%16;       i32test(a,b,16);
+               b = a%20;       i32test(a,b,20);
+               b = a%32;       i32test(a,b,32);
+               b = a%60;       i32test(a,b,60);
+               b = a%64;       i32test(a,b,64);
+               b = a%128;      i32test(a,b,128);
+               b = a%256;      i32test(a,b,256);
+               b = a%16384;    i32test(a,b,16384);
+
+               b = a%-1;       i32test(a,b,-1);
+               b = a%-2;       i32test(a,b,-2);
+               b = a%-3;       i32test(a,b,-3);
+               b = a%-4;       i32test(a,b,-4);
+               b = a%-5;       i32test(a,b,-5);
+               b = a%-6;       i32test(a,b,-6);
+               b = a%-7;       i32test(a,b,-7);
+               b = a%-8;       i32test(a,b,-8);
+               b = a%-10;      i32test(a,b,-10);
+               b = a%-16;      i32test(a,b,-16);
+               b = a%-20;      i32test(a,b,-20);
+               b = a%-32;      i32test(a,b,-32);
+               b = a%-60;      i32test(a,b,-60);
+               b = a%-64;      i32test(a,b,-64);
+               b = a%-128;     i32test(a,b,-128);
+               b = a%-256;     i32test(a,b,-256);
+       }
+}
+
+func
+u32rand() uint32
+{
+       a := uint32(rand.Uint32());
+       a >>= uint(rand.Intn(32));
+       return a;
+}
+
+func
+u32test(a,b,c uint32)
+{
+       d := a%c;
+       if d != b {
+               panicln("u32", a, b, c, d);
+       }
+}
+
+func
+u32run()
+{
+       var a, b uint32;
+
+       for i:=0; i<Count; i++ {
+               a = u32rand();
+
+               b = a%1;        u32test(a,b,1);
+               b = a%2;        u32test(a,b,2);
+               b = a%3;        u32test(a,b,3);
+               b = a%4;        u32test(a,b,4);
+               b = a%5;        u32test(a,b,5);
+               b = a%6;        u32test(a,b,6);
+               b = a%7;        u32test(a,b,7);
+               b = a%8;        u32test(a,b,8);
+               b = a%10;       u32test(a,b,10);
+               b = a%16;       u32test(a,b,16);
+               b = a%20;       u32test(a,b,20);
+               b = a%32;       u32test(a,b,32);
+               b = a%60;       u32test(a,b,60);
+               b = a%64;       u32test(a,b,64);
+               b = a%128;      u32test(a,b,128);
+               b = a%256;      u32test(a,b,256);
+               b = a%16384;    u32test(a,b,16384);
+       }
+}
+
+func
+i16rand() int16
+{
+       for {
+               a := int16(rand.Uint32());
+               a >>= uint(rand.Intn(16));
+               if -a != a {
+                       return a;
+               }
+       }
+       return 0;       // impossible
+}
+
+func
+i16test(a,b,c int16)
+{
+       d := a%c;
+       if d != b {
+               panicln("i16", a, b, c, d);
+       }
+}
+
+func
+i16run()
+{
+       var a, b int16;
+
+       for i:=0; i<Count; i++ {
+               a = i16rand();
+
+               b = a%1;        i16test(a,b,1);
+               b = a%2;        i16test(a,b,2);
+               b = a%3;        i16test(a,b,3);
+               b = a%4;        i16test(a,b,4);
+               b = a%5;        i16test(a,b,5);
+               b = a%6;        i16test(a,b,6);
+               b = a%7;        i16test(a,b,7);
+               b = a%8;        i16test(a,b,8);
+               b = a%10;       i16test(a,b,10);
+               b = a%16;       i16test(a,b,16);
+               b = a%20;       i16test(a,b,20);
+               b = a%32;       i16test(a,b,32);
+               b = a%60;       i16test(a,b,60);
+               b = a%64;       i16test(a,b,64);
+               b = a%128;      i16test(a,b,128);
+               b = a%256;      i16test(a,b,256);
+               b = a%16384;    i16test(a,b,16384);
+
+               b = a%-1;       i16test(a,b,-1);
+               b = a%-2;       i16test(a,b,-2);
+               b = a%-3;       i16test(a,b,-3);
+               b = a%-4;       i16test(a,b,-4);
+               b = a%-5;       i16test(a,b,-5);
+               b = a%-6;       i16test(a,b,-6);
+               b = a%-7;       i16test(a,b,-7);
+               b = a%-8;       i16test(a,b,-8);
+               b = a%-10;      i16test(a,b,-10);
+               b = a%-16;      i16test(a,b,-16);
+               b = a%-20;      i16test(a,b,-20);
+               b = a%-32;      i16test(a,b,-32);
+               b = a%-60;      i16test(a,b,-60);
+               b = a%-64;      i16test(a,b,-64);
+               b = a%-128;     i16test(a,b,-128);
+               b = a%-256;     i16test(a,b,-256);
+               b = a%-16384;   i16test(a,b,-16384);
+       }
+}
+
+func
+u16rand() uint16
+{
+       a := uint16(rand.Uint32());
+       a >>= uint(rand.Intn(16));
+       return a;
+}
+
+func
+u16test(a,b,c uint16)
+{
+       d := a%c;
+       if d != b {
+               panicln("u16", a, b, c, d);
+       }
+}
+
+func
+u16run()
+{
+       var a, b uint16;
+
+       for i:=0; i<Count; i++ {
+               a = u16rand();
+
+               b = a%1;        u16test(a,b,1);
+               b = a%2;        u16test(a,b,2);
+               b = a%3;        u16test(a,b,3);
+               b = a%4;        u16test(a,b,4);
+               b = a%5;        u16test(a,b,5);
+               b = a%6;        u16test(a,b,6);
+               b = a%7;        u16test(a,b,7);
+               b = a%8;        u16test(a,b,8);
+               b = a%10;       u16test(a,b,10);
+               b = a%16;       u16test(a,b,16);
+               b = a%20;       u16test(a,b,20);
+               b = a%32;       u16test(a,b,32);
+               b = a%60;       u16test(a,b,60);
+               b = a%64;       u16test(a,b,64);
+               b = a%128;      u16test(a,b,128);
+               b = a%256;      u16test(a,b,256);
+               b = a%16384;    u16test(a,b,16384);
+       }
+}
+
+func   xtest()
+
+func
+main()
+{
+       xtest();
+       i64run();
+       u64run();
+       i32run();
+       u32run();
+       i16run();
+       u16run();
+}
+
+func
+xtest()
+{
+}