github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/math/bits/bits_test.gno (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package bits
     6  
     7  import (
     8  	"testing"
     9  )
    10  
    11  func TestLeadingZeros(t *testing.T) {
    12  	for i := 0; i < 256; i++ {
    13  		nlz := tab[i].nlz
    14  		for k := 0; k < 64-8; k++ {
    15  			x := uint64(i) << uint(k)
    16  			if x <= 1<<8-1 {
    17  				got := LeadingZeros8(uint8(x))
    18  				want := nlz - k + (8 - 8)
    19  				if x == 0 {
    20  					want = 8
    21  				}
    22  				if got != want {
    23  					t.Fatalf("LeadingZeros8(%#02x) == %d; want %d", x, got, want)
    24  				}
    25  			}
    26  
    27  			if x <= 1<<16-1 {
    28  				got := LeadingZeros16(uint16(x))
    29  				want := nlz - k + (16 - 8)
    30  				if x == 0 {
    31  					want = 16
    32  				}
    33  				if got != want {
    34  					t.Fatalf("LeadingZeros16(%#04x) == %d; want %d", x, got, want)
    35  				}
    36  			}
    37  
    38  			if x <= 1<<32-1 {
    39  				got := LeadingZeros32(uint32(x))
    40  				want := nlz - k + (32 - 8)
    41  				if x == 0 {
    42  					want = 32
    43  				}
    44  				if got != want {
    45  					t.Fatalf("LeadingZeros32(%#08x) == %d; want %d", x, got, want)
    46  				}
    47  				if UintSize == 32 {
    48  					got = LeadingZeros(uint(x))
    49  					if got != want {
    50  						t.Fatalf("LeadingZeros(%#08x) == %d; want %d", x, got, want)
    51  					}
    52  				}
    53  			}
    54  
    55  			if x <= 1<<64-1 {
    56  				got := LeadingZeros64(uint64(x))
    57  				want := nlz - k + (64 - 8)
    58  				if x == 0 {
    59  					want = 64
    60  				}
    61  				if got != want {
    62  					t.Fatalf("LeadingZeros64(%#016x) == %d; want %d", x, got, want)
    63  				}
    64  				if UintSize == 64 {
    65  					got = LeadingZeros(uint(x))
    66  					if got != want {
    67  						t.Fatalf("LeadingZeros(%#016x) == %d; want %d", x, got, want)
    68  					}
    69  				}
    70  			}
    71  		}
    72  	}
    73  }
    74  
    75  // Exported (global) variable serving as input for some
    76  // of the benchmarks to ensure side-effect free calls
    77  // are not optimized away.
    78  var Input uint64 = DeBruijn64
    79  
    80  // Exported (global) variable to store function results
    81  // during benchmarking to ensure side-effect free calls
    82  // are not optimized away.
    83  var Output int
    84  
    85  func BenchmarkLeadingZeros(b *testing.B) {
    86  	var s int
    87  	for i := 0; i < b.N; i++ {
    88  		s += LeadingZeros(uint(Input) >> (uint(i) % UintSize))
    89  	}
    90  	Output = s
    91  }
    92  
    93  func BenchmarkLeadingZeros8(b *testing.B) {
    94  	var s int
    95  	for i := 0; i < b.N; i++ {
    96  		s += LeadingZeros8(uint8(Input) >> (uint(i) % 8))
    97  	}
    98  	Output = s
    99  }
   100  
   101  func BenchmarkLeadingZeros16(b *testing.B) {
   102  	var s int
   103  	for i := 0; i < b.N; i++ {
   104  		s += LeadingZeros16(uint16(Input) >> (uint(i) % 16))
   105  	}
   106  	Output = s
   107  }
   108  
   109  func BenchmarkLeadingZeros32(b *testing.B) {
   110  	var s int
   111  	for i := 0; i < b.N; i++ {
   112  		s += LeadingZeros32(uint32(Input) >> (uint(i) % 32))
   113  	}
   114  	Output = s
   115  }
   116  
   117  func BenchmarkLeadingZeros64(b *testing.B) {
   118  	var s int
   119  	for i := 0; i < b.N; i++ {
   120  		s += LeadingZeros64(uint64(Input) >> (uint(i) % 64))
   121  	}
   122  	Output = s
   123  }
   124  
   125  func TestTrailingZeros(t *testing.T) {
   126  	for i := 0; i < 256; i++ {
   127  		ntz := tab[i].ntz
   128  		for k := 0; k < 64-8; k++ {
   129  			x := uint64(i) << uint(k)
   130  			want := ntz + k
   131  			if x <= 1<<8-1 {
   132  				got := TrailingZeros8(uint8(x))
   133  				if x == 0 {
   134  					want = 8
   135  				}
   136  				if got != want {
   137  					t.Fatalf("TrailingZeros8(%#02x) == %d; want %d", x, got, want)
   138  				}
   139  			}
   140  
   141  			if x <= 1<<16-1 {
   142  				got := TrailingZeros16(uint16(x))
   143  				if x == 0 {
   144  					want = 16
   145  				}
   146  				if got != want {
   147  					t.Fatalf("TrailingZeros16(%#04x) == %d; want %d", x, got, want)
   148  				}
   149  			}
   150  
   151  			if x <= 1<<32-1 {
   152  				got := TrailingZeros32(uint32(x))
   153  				if x == 0 {
   154  					want = 32
   155  				}
   156  				if got != want {
   157  					t.Fatalf("TrailingZeros32(%#08x) == %d; want %d", x, got, want)
   158  				}
   159  				if UintSize == 32 {
   160  					got = TrailingZeros(uint(x))
   161  					if got != want {
   162  						t.Fatalf("TrailingZeros(%#08x) == %d; want %d", x, got, want)
   163  					}
   164  				}
   165  			}
   166  
   167  			if x <= 1<<64-1 {
   168  				got := TrailingZeros64(uint64(x))
   169  				if x == 0 {
   170  					want = 64
   171  				}
   172  				if got != want {
   173  					t.Fatalf("TrailingZeros64(%#016x) == %d; want %d", x, got, want)
   174  				}
   175  				if UintSize == 64 {
   176  					got = TrailingZeros(uint(x))
   177  					if got != want {
   178  						t.Fatalf("TrailingZeros(%#016x) == %d; want %d", x, got, want)
   179  					}
   180  				}
   181  			}
   182  		}
   183  	}
   184  }
   185  
   186  func BenchmarkTrailingZeros(b *testing.B) {
   187  	var s int
   188  	for i := 0; i < b.N; i++ {
   189  		s += TrailingZeros(uint(Input) << (uint(i) % UintSize))
   190  	}
   191  	Output = s
   192  }
   193  
   194  func BenchmarkTrailingZeros8(b *testing.B) {
   195  	var s int
   196  	for i := 0; i < b.N; i++ {
   197  		s += TrailingZeros8(uint8(Input) << (uint(i) % 8))
   198  	}
   199  	Output = s
   200  }
   201  
   202  func BenchmarkTrailingZeros16(b *testing.B) {
   203  	var s int
   204  	for i := 0; i < b.N; i++ {
   205  		s += TrailingZeros16(uint16(Input) << (uint(i) % 16))
   206  	}
   207  	Output = s
   208  }
   209  
   210  func BenchmarkTrailingZeros32(b *testing.B) {
   211  	var s int
   212  	for i := 0; i < b.N; i++ {
   213  		s += TrailingZeros32(uint32(Input) << (uint(i) % 32))
   214  	}
   215  	Output = s
   216  }
   217  
   218  func BenchmarkTrailingZeros64(b *testing.B) {
   219  	var s int
   220  	for i := 0; i < b.N; i++ {
   221  		s += TrailingZeros64(uint64(Input) << (uint(i) % 64))
   222  	}
   223  	Output = s
   224  }
   225  
   226  func TestOnesCount(t *testing.T) {
   227  	var x uint64
   228  	for i := 0; i <= 64; i++ {
   229  		testOnesCount(t, x, i)
   230  		x = x<<1 | 1
   231  	}
   232  
   233  	for i := 64; i >= 0; i-- {
   234  		testOnesCount(t, x, i)
   235  		x = x << 1
   236  	}
   237  
   238  	for i := 0; i < 256; i++ {
   239  		for k := 0; k < 64-8; k++ {
   240  			testOnesCount(t, uint64(i)<<uint(k), tab[i].pop)
   241  		}
   242  	}
   243  }
   244  
   245  func testOnesCount(t *testing.T, x uint64, want int) {
   246  	if x <= 1<<8-1 {
   247  		got := OnesCount8(uint8(x))
   248  		if got != want {
   249  			t.Fatalf("OnesCount8(%#02x) == %d; want %d", uint8(x), got, want)
   250  		}
   251  	}
   252  
   253  	if x <= 1<<16-1 {
   254  		got := OnesCount16(uint16(x))
   255  		if got != want {
   256  			t.Fatalf("OnesCount16(%#04x) == %d; want %d", uint16(x), got, want)
   257  		}
   258  	}
   259  
   260  	if x <= 1<<32-1 {
   261  		got := OnesCount32(uint32(x))
   262  		if got != want {
   263  			t.Fatalf("OnesCount32(%#08x) == %d; want %d", uint32(x), got, want)
   264  		}
   265  		if UintSize == 32 {
   266  			got = OnesCount(uint(x))
   267  			if got != want {
   268  				t.Fatalf("OnesCount(%#08x) == %d; want %d", uint32(x), got, want)
   269  			}
   270  		}
   271  	}
   272  
   273  	if x <= 1<<64-1 {
   274  		got := OnesCount64(uint64(x))
   275  		if got != want {
   276  			t.Fatalf("OnesCount64(%#016x) == %d; want %d", x, got, want)
   277  		}
   278  		if UintSize == 64 {
   279  			got = OnesCount(uint(x))
   280  			if got != want {
   281  				t.Fatalf("OnesCount(%#016x) == %d; want %d", x, got, want)
   282  			}
   283  		}
   284  	}
   285  }
   286  
   287  func BenchmarkOnesCount(b *testing.B) {
   288  	var s int
   289  	for i := 0; i < b.N; i++ {
   290  		s += OnesCount(uint(Input))
   291  	}
   292  	Output = s
   293  }
   294  
   295  func BenchmarkOnesCount8(b *testing.B) {
   296  	var s int
   297  	for i := 0; i < b.N; i++ {
   298  		s += OnesCount8(uint8(Input))
   299  	}
   300  	Output = s
   301  }
   302  
   303  func BenchmarkOnesCount16(b *testing.B) {
   304  	var s int
   305  	for i := 0; i < b.N; i++ {
   306  		s += OnesCount16(uint16(Input))
   307  	}
   308  	Output = s
   309  }
   310  
   311  func BenchmarkOnesCount32(b *testing.B) {
   312  	var s int
   313  	for i := 0; i < b.N; i++ {
   314  		s += OnesCount32(uint32(Input))
   315  	}
   316  	Output = s
   317  }
   318  
   319  func BenchmarkOnesCount64(b *testing.B) {
   320  	var s int
   321  	for i := 0; i < b.N; i++ {
   322  		s += OnesCount64(uint64(Input))
   323  	}
   324  	Output = s
   325  }
   326  
   327  func TestRotateLeft(t *testing.T) {
   328  	var m uint64 = DeBruijn64
   329  
   330  	for k := uint(0); k < 128; k++ {
   331  		x8 := uint8(m)
   332  		got8 := RotateLeft8(x8, int(k))
   333  		want8 := x8<<(k&0x7) | x8>>(8-k&0x7)
   334  		if got8 != want8 {
   335  			t.Fatalf("RotateLeft8(%#02x, %d) == %#02x; want %#02x", x8, k, got8, want8)
   336  		}
   337  		got8 = RotateLeft8(want8, -int(k))
   338  		if got8 != x8 {
   339  			t.Fatalf("RotateLeft8(%#02x, -%d) == %#02x; want %#02x", want8, k, got8, x8)
   340  		}
   341  
   342  		x16 := uint16(m)
   343  		got16 := RotateLeft16(x16, int(k))
   344  		want16 := x16<<(k&0xf) | x16>>(16-k&0xf)
   345  		if got16 != want16 {
   346  			t.Fatalf("RotateLeft16(%#04x, %d) == %#04x; want %#04x", x16, k, got16, want16)
   347  		}
   348  		got16 = RotateLeft16(want16, -int(k))
   349  		if got16 != x16 {
   350  			t.Fatalf("RotateLeft16(%#04x, -%d) == %#04x; want %#04x", want16, k, got16, x16)
   351  		}
   352  
   353  		x32 := uint32(m)
   354  		got32 := RotateLeft32(x32, int(k))
   355  		want32 := x32<<(k&0x1f) | x32>>(32-k&0x1f)
   356  		if got32 != want32 {
   357  			t.Fatalf("RotateLeft32(%#08x, %d) == %#08x; want %#08x", x32, k, got32, want32)
   358  		}
   359  		got32 = RotateLeft32(want32, -int(k))
   360  		if got32 != x32 {
   361  			t.Fatalf("RotateLeft32(%#08x, -%d) == %#08x; want %#08x", want32, k, got32, x32)
   362  		}
   363  		if UintSize == 32 {
   364  			x := uint(m)
   365  			got := RotateLeft(x, int(k))
   366  			want := x<<(k&0x1f) | x>>(32-k&0x1f)
   367  			if got != want {
   368  				t.Fatalf("RotateLeft(%#08x, %d) == %#08x; want %#08x", x, k, got, want)
   369  			}
   370  			got = RotateLeft(want, -int(k))
   371  			if got != x {
   372  				t.Fatalf("RotateLeft(%#08x, -%d) == %#08x; want %#08x", want, k, got, x)
   373  			}
   374  		}
   375  
   376  		x64 := uint64(m)
   377  		got64 := RotateLeft64(x64, int(k))
   378  		want64 := x64<<(k&0x3f) | x64>>(64-k&0x3f)
   379  		if got64 != want64 {
   380  			t.Fatalf("RotateLeft64(%#016x, %d) == %#016x; want %#016x", x64, k, got64, want64)
   381  		}
   382  		got64 = RotateLeft64(want64, -int(k))
   383  		if got64 != x64 {
   384  			t.Fatalf("RotateLeft64(%#016x, -%d) == %#016x; want %#016x", want64, k, got64, x64)
   385  		}
   386  		if UintSize == 64 {
   387  			x := uint(m)
   388  			got := RotateLeft(x, int(k))
   389  			want := x<<(k&0x3f) | x>>(64-k&0x3f)
   390  			if got != want {
   391  				t.Fatalf("RotateLeft(%#016x, %d) == %#016x; want %#016x", x, k, got, want)
   392  			}
   393  			got = RotateLeft(want, -int(k))
   394  			if got != x {
   395  				t.Fatalf("RotateLeft(%#08x, -%d) == %#08x; want %#08x", want, k, got, x)
   396  			}
   397  		}
   398  	}
   399  }
   400  
   401  func BenchmarkRotateLeft(b *testing.B) {
   402  	var s uint
   403  	for i := 0; i < b.N; i++ {
   404  		s += RotateLeft(uint(Input), i)
   405  	}
   406  	Output = int(s)
   407  }
   408  
   409  func BenchmarkRotateLeft8(b *testing.B) {
   410  	var s uint8
   411  	for i := 0; i < b.N; i++ {
   412  		s += RotateLeft8(uint8(Input), i)
   413  	}
   414  	Output = int(s)
   415  }
   416  
   417  func BenchmarkRotateLeft16(b *testing.B) {
   418  	var s uint16
   419  	for i := 0; i < b.N; i++ {
   420  		s += RotateLeft16(uint16(Input), i)
   421  	}
   422  	Output = int(s)
   423  }
   424  
   425  func BenchmarkRotateLeft32(b *testing.B) {
   426  	var s uint32
   427  	for i := 0; i < b.N; i++ {
   428  		s += RotateLeft32(uint32(Input), i)
   429  	}
   430  	Output = int(s)
   431  }
   432  
   433  func BenchmarkRotateLeft64(b *testing.B) {
   434  	var s uint64
   435  	for i := 0; i < b.N; i++ {
   436  		s += RotateLeft64(uint64(Input), i)
   437  	}
   438  	Output = int(s)
   439  }
   440  
   441  func TestReverse(t *testing.T) {
   442  	// test each bit
   443  	for i := uint(0); i < 64; i++ {
   444  		testReverse(t, uint64(1)<<i, uint64(1)<<(63-i))
   445  	}
   446  
   447  	// test a few patterns
   448  	for _, test := range []struct {
   449  		x, r uint64
   450  	}{
   451  		{0, 0},
   452  		{0x1, 0x8 << 60},
   453  		{0x2, 0x4 << 60},
   454  		{0x3, 0xc << 60},
   455  		{0x4, 0x2 << 60},
   456  		{0x5, 0xa << 60},
   457  		{0x6, 0x6 << 60},
   458  		{0x7, 0xe << 60},
   459  		{0x8, 0x1 << 60},
   460  		{0x9, 0x9 << 60},
   461  		{0xa, 0x5 << 60},
   462  		{0xb, 0xd << 60},
   463  		{0xc, 0x3 << 60},
   464  		{0xd, 0xb << 60},
   465  		{0xe, 0x7 << 60},
   466  		{0xf, 0xf << 60},
   467  		{0x5686487, 0xe12616a000000000},
   468  		{0x0123456789abcdef, 0xf7b3d591e6a2c480},
   469  	} {
   470  		testReverse(t, test.x, test.r)
   471  		testReverse(t, test.r, test.x)
   472  	}
   473  }
   474  
   475  func testReverse(t *testing.T, x64, want64 uint64) {
   476  	x8 := uint8(x64)
   477  	got8 := Reverse8(x8)
   478  	want8 := uint8(want64 >> (64 - 8))
   479  	if got8 != want8 {
   480  		t.Fatalf("Reverse8(%#02x) == %#02x; want %#02x", x8, got8, want8)
   481  	}
   482  
   483  	x16 := uint16(x64)
   484  	got16 := Reverse16(x16)
   485  	want16 := uint16(want64 >> (64 - 16))
   486  	if got16 != want16 {
   487  		t.Fatalf("Reverse16(%#04x) == %#04x; want %#04x", x16, got16, want16)
   488  	}
   489  
   490  	x32 := uint32(x64)
   491  	got32 := Reverse32(x32)
   492  	want32 := uint32(want64 >> (64 - 32))
   493  	if got32 != want32 {
   494  		t.Fatalf("Reverse32(%#08x) == %#08x; want %#08x", x32, got32, want32)
   495  	}
   496  	if UintSize == 32 {
   497  		x := uint(x32)
   498  		got := Reverse(x)
   499  		want := uint(want32)
   500  		if got != want {
   501  			t.Fatalf("Reverse(%#08x) == %#08x; want %#08x", x, got, want)
   502  		}
   503  	}
   504  
   505  	got64 := Reverse64(x64)
   506  	if got64 != want64 {
   507  		t.Fatalf("Reverse64(%#016x) == %#016x; want %#016x", x64, got64, want64)
   508  	}
   509  	if UintSize == 64 {
   510  		x := uint(x64)
   511  		got := Reverse(x)
   512  		want := uint(want64)
   513  		if got != want {
   514  			t.Fatalf("Reverse(%#08x) == %#016x; want %#016x", x, got, want)
   515  		}
   516  	}
   517  }
   518  
   519  func BenchmarkReverse(b *testing.B) {
   520  	var s uint
   521  	for i := 0; i < b.N; i++ {
   522  		s += Reverse(uint(i))
   523  	}
   524  	Output = int(s)
   525  }
   526  
   527  func BenchmarkReverse8(b *testing.B) {
   528  	var s uint8
   529  	for i := 0; i < b.N; i++ {
   530  		s += Reverse8(uint8(i))
   531  	}
   532  	Output = int(s)
   533  }
   534  
   535  func BenchmarkReverse16(b *testing.B) {
   536  	var s uint16
   537  	for i := 0; i < b.N; i++ {
   538  		s += Reverse16(uint16(i))
   539  	}
   540  	Output = int(s)
   541  }
   542  
   543  func BenchmarkReverse32(b *testing.B) {
   544  	var s uint32
   545  	for i := 0; i < b.N; i++ {
   546  		s += Reverse32(uint32(i))
   547  	}
   548  	Output = int(s)
   549  }
   550  
   551  func BenchmarkReverse64(b *testing.B) {
   552  	var s uint64
   553  	for i := 0; i < b.N; i++ {
   554  		s += Reverse64(uint64(i))
   555  	}
   556  	Output = int(s)
   557  }
   558  
   559  func TestReverseBytes(t *testing.T) {
   560  	for _, test := range []struct {
   561  		x, r uint64
   562  	}{
   563  		{0, 0},
   564  		{0x01, 0x01 << 56},
   565  		{0x0123, 0x2301 << 48},
   566  		{0x012345, 0x452301 << 40},
   567  		{0x01234567, 0x67452301 << 32},
   568  		{0x0123456789, 0x8967452301 << 24},
   569  		{0x0123456789ab, 0xab8967452301 << 16},
   570  		{0x0123456789abcd, 0xcdab8967452301 << 8},
   571  		{0x0123456789abcdef, 0xefcdab8967452301 << 0},
   572  	} {
   573  		testReverseBytes(t, test.x, test.r)
   574  		testReverseBytes(t, test.r, test.x)
   575  	}
   576  }
   577  
   578  func testReverseBytes(t *testing.T, x64, want64 uint64) {
   579  	x16 := uint16(x64)
   580  	got16 := ReverseBytes16(x16)
   581  	want16 := uint16(want64 >> (64 - 16))
   582  	if got16 != want16 {
   583  		t.Fatalf("ReverseBytes16(%#04x) == %#04x; want %#04x", x16, got16, want16)
   584  	}
   585  
   586  	x32 := uint32(x64)
   587  	got32 := ReverseBytes32(x32)
   588  	want32 := uint32(want64 >> (64 - 32))
   589  	if got32 != want32 {
   590  		t.Fatalf("ReverseBytes32(%#08x) == %#08x; want %#08x", x32, got32, want32)
   591  	}
   592  	if UintSize == 32 {
   593  		x := uint(x32)
   594  		got := ReverseBytes(x)
   595  		want := uint(want32)
   596  		if got != want {
   597  			t.Fatalf("ReverseBytes(%#08x) == %#08x; want %#08x", x, got, want)
   598  		}
   599  	}
   600  
   601  	got64 := ReverseBytes64(x64)
   602  	if got64 != want64 {
   603  		t.Fatalf("ReverseBytes64(%#016x) == %#016x; want %#016x", x64, got64, want64)
   604  	}
   605  	if UintSize == 64 {
   606  		x := uint(x64)
   607  		got := ReverseBytes(x)
   608  		want := uint(want64)
   609  		if got != want {
   610  			t.Fatalf("ReverseBytes(%#016x) == %#016x; want %#016x", x, got, want)
   611  		}
   612  	}
   613  }
   614  
   615  func BenchmarkReverseBytes(b *testing.B) {
   616  	var s uint
   617  	for i := 0; i < b.N; i++ {
   618  		s += ReverseBytes(uint(i))
   619  	}
   620  	Output = int(s)
   621  }
   622  
   623  func BenchmarkReverseBytes16(b *testing.B) {
   624  	var s uint16
   625  	for i := 0; i < b.N; i++ {
   626  		s += ReverseBytes16(uint16(i))
   627  	}
   628  	Output = int(s)
   629  }
   630  
   631  func BenchmarkReverseBytes32(b *testing.B) {
   632  	var s uint32
   633  	for i := 0; i < b.N; i++ {
   634  		s += ReverseBytes32(uint32(i))
   635  	}
   636  	Output = int(s)
   637  }
   638  
   639  func BenchmarkReverseBytes64(b *testing.B) {
   640  	var s uint64
   641  	for i := 0; i < b.N; i++ {
   642  		s += ReverseBytes64(uint64(i))
   643  	}
   644  	Output = int(s)
   645  }
   646  
   647  func TestLen(t *testing.T) {
   648  	for i := 0; i < 256; i++ {
   649  		length := 8 - tab[i].nlz
   650  		for k := 0; k < 64-8; k++ {
   651  			x := uint64(i) << uint(k)
   652  			want := 0
   653  			if x != 0 {
   654  				want = length + k
   655  			}
   656  			if x <= 1<<8-1 {
   657  				got := Len8(uint8(x))
   658  				if got != want {
   659  					t.Fatalf("Len8(%#02x) == %d; want %d", x, got, want)
   660  				}
   661  			}
   662  
   663  			if x <= 1<<16-1 {
   664  				got := Len16(uint16(x))
   665  				if got != want {
   666  					t.Fatalf("Len16(%#04x) == %d; want %d", x, got, want)
   667  				}
   668  			}
   669  
   670  			if x <= 1<<32-1 {
   671  				got := Len32(uint32(x))
   672  				if got != want {
   673  					t.Fatalf("Len32(%#08x) == %d; want %d", x, got, want)
   674  				}
   675  				if UintSize == 32 {
   676  					got := Len(uint(x))
   677  					if got != want {
   678  						t.Fatalf("Len(%#08x) == %d; want %d", x, got, want)
   679  					}
   680  				}
   681  			}
   682  
   683  			if x <= 1<<64-1 {
   684  				got := Len64(uint64(x))
   685  				if got != want {
   686  					t.Fatalf("Len64(%#016x) == %d; want %d", x, got, want)
   687  				}
   688  				if UintSize == 64 {
   689  					got := Len(uint(x))
   690  					if got != want {
   691  						t.Fatalf("Len(%#016x) == %d; want %d", x, got, want)
   692  					}
   693  				}
   694  			}
   695  		}
   696  	}
   697  }
   698  
   699  const (
   700  	_M   = 1<<UintSize - 1
   701  	_M32 = 1<<32 - 1
   702  	_M64 = 1<<64 - 1
   703  )
   704  
   705  func TestAddSubUint(t *testing.T) {
   706  	test := func(msg string, f func(x, y, c uint) (z, cout uint), x, y, c, z, cout uint) {
   707  		z1, cout1 := f(x, y, c)
   708  		if z1 != z || cout1 != cout {
   709  			t.Errorf("%s: got z:cout = %#x:%#x; want %#x:%#x", msg, z1, cout1, z, cout)
   710  		}
   711  	}
   712  	for _, a := range []struct{ x, y, c, z, cout uint }{
   713  		{0, 0, 0, 0, 0},
   714  		{0, 1, 0, 1, 0},
   715  		{0, 0, 1, 1, 0},
   716  		{0, 1, 1, 2, 0},
   717  		{12345, 67890, 0, 80235, 0},
   718  		{12345, 67890, 1, 80236, 0},
   719  		{_M, 1, 0, 0, 1},
   720  		{_M, 0, 1, 0, 1},
   721  		{_M, 1, 1, 1, 1},
   722  		{_M, _M, 0, _M - 1, 1},
   723  		{_M, _M, 1, _M, 1},
   724  	} {
   725  		test("Add", Add, a.x, a.y, a.c, a.z, a.cout)
   726  		test("Add symmetric", Add, a.y, a.x, a.c, a.z, a.cout)
   727  		test("Sub", Sub, a.z, a.x, a.c, a.y, a.cout)
   728  		test("Sub symmetric", Sub, a.z, a.y, a.c, a.x, a.cout)
   729  		// The above code can't test intrinsic implementation, because the passed function is not called directly.
   730  		// The following code uses a closure to test the intrinsic version in case the function is intrinsified.
   731  		test("Add intrinsic", func(x, y, c uint) (uint, uint) { return Add(x, y, c) }, a.x, a.y, a.c, a.z, a.cout)
   732  		test("Add intrinsic symmetric", func(x, y, c uint) (uint, uint) { return Add(x, y, c) }, a.y, a.x, a.c, a.z, a.cout)
   733  		test("Sub intrinsic", func(x, y, c uint) (uint, uint) { return Sub(x, y, c) }, a.z, a.x, a.c, a.y, a.cout)
   734  		test("Sub intrinsic symmetric", func(x, y, c uint) (uint, uint) { return Sub(x, y, c) }, a.z, a.y, a.c, a.x, a.cout)
   735  
   736  	}
   737  }
   738  
   739  func TestAddSubUint32(t *testing.T) {
   740  	test := func(msg string, f func(x, y, c uint32) (z, cout uint32), x, y, c, z, cout uint32) {
   741  		z1, cout1 := f(x, y, c)
   742  		if z1 != z || cout1 != cout {
   743  			t.Errorf("%s: got z:cout = %#x:%#x; want %#x:%#x", msg, z1, cout1, z, cout)
   744  		}
   745  	}
   746  	for _, a := range []struct{ x, y, c, z, cout uint32 }{
   747  		{0, 0, 0, 0, 0},
   748  		{0, 1, 0, 1, 0},
   749  		{0, 0, 1, 1, 0},
   750  		{0, 1, 1, 2, 0},
   751  		{12345, 67890, 0, 80235, 0},
   752  		{12345, 67890, 1, 80236, 0},
   753  		{_M32, 1, 0, 0, 1},
   754  		{_M32, 0, 1, 0, 1},
   755  		{_M32, 1, 1, 1, 1},
   756  		{_M32, _M32, 0, _M32 - 1, 1},
   757  		{_M32, _M32, 1, _M32, 1},
   758  	} {
   759  		test("Add32", Add32, a.x, a.y, a.c, a.z, a.cout)
   760  		test("Add32 symmetric", Add32, a.y, a.x, a.c, a.z, a.cout)
   761  		test("Sub32", Sub32, a.z, a.x, a.c, a.y, a.cout)
   762  		test("Sub32 symmetric", Sub32, a.z, a.y, a.c, a.x, a.cout)
   763  	}
   764  }
   765  
   766  func TestAddSubUint64(t *testing.T) {
   767  	test := func(msg string, f func(x, y, c uint64) (z, cout uint64), x, y, c, z, cout uint64) {
   768  		z1, cout1 := f(x, y, c)
   769  		if z1 != z || cout1 != cout {
   770  			t.Errorf("%s: got z:cout = %#x:%#x; want %#x:%#x", msg, z1, cout1, z, cout)
   771  		}
   772  	}
   773  	for _, a := range []struct{ x, y, c, z, cout uint64 }{
   774  		{0, 0, 0, 0, 0},
   775  		{0, 1, 0, 1, 0},
   776  		{0, 0, 1, 1, 0},
   777  		{0, 1, 1, 2, 0},
   778  		{12345, 67890, 0, 80235, 0},
   779  		{12345, 67890, 1, 80236, 0},
   780  		{_M64, 1, 0, 0, 1},
   781  		{_M64, 0, 1, 0, 1},
   782  		{_M64, 1, 1, 1, 1},
   783  		{_M64, _M64, 0, _M64 - 1, 1},
   784  		{_M64, _M64, 1, _M64, 1},
   785  	} {
   786  		test("Add64", Add64, a.x, a.y, a.c, a.z, a.cout)
   787  		test("Add64 symmetric", Add64, a.y, a.x, a.c, a.z, a.cout)
   788  		test("Sub64", Sub64, a.z, a.x, a.c, a.y, a.cout)
   789  		test("Sub64 symmetric", Sub64, a.z, a.y, a.c, a.x, a.cout)
   790  		// The above code can't test intrinsic implementation, because the passed function is not called directly.
   791  		// The following code uses a closure to test the intrinsic version in case the function is intrinsified.
   792  		test("Add64 intrinsic", func(x, y, c uint64) (uint64, uint64) { return Add64(x, y, c) }, a.x, a.y, a.c, a.z, a.cout)
   793  		test("Add64 intrinsic symmetric", func(x, y, c uint64) (uint64, uint64) { return Add64(x, y, c) }, a.y, a.x, a.c, a.z, a.cout)
   794  		test("Sub64 intrinsic", func(x, y, c uint64) (uint64, uint64) { return Sub64(x, y, c) }, a.z, a.x, a.c, a.y, a.cout)
   795  		test("Sub64 intrinsic symmetric", func(x, y, c uint64) (uint64, uint64) { return Sub64(x, y, c) }, a.z, a.y, a.c, a.x, a.cout)
   796  	}
   797  }
   798  
   799  func TestAdd64OverflowPanic(t *testing.T) {
   800  	// Test that 64-bit overflow panics fire correctly.
   801  	// These are designed to improve coverage of compiler intrinsics.
   802  	tests := []func(uint64, uint64) uint64{
   803  		func(a, b uint64) uint64 {
   804  			x, c := Add64(a, b, 0)
   805  			if c > 0 {
   806  				panic("overflow")
   807  			}
   808  			return x
   809  		},
   810  		func(a, b uint64) uint64 {
   811  			x, c := Add64(a, b, 0)
   812  			if c != 0 {
   813  				panic("overflow")
   814  			}
   815  			return x
   816  		},
   817  		func(a, b uint64) uint64 {
   818  			x, c := Add64(a, b, 0)
   819  			if c == 1 {
   820  				panic("overflow")
   821  			}
   822  			return x
   823  		},
   824  		func(a, b uint64) uint64 {
   825  			x, c := Add64(a, b, 0)
   826  			if c != 1 {
   827  				return x
   828  			}
   829  			panic("overflow")
   830  		},
   831  		func(a, b uint64) uint64 {
   832  			x, c := Add64(a, b, 0)
   833  			if c == 0 {
   834  				return x
   835  			}
   836  			panic("overflow")
   837  		},
   838  	}
   839  	for _, test := range tests {
   840  		shouldPanic := func(f func()) {
   841  			defer func() {
   842  				if err := recover(); err == nil {
   843  					t.Fatalf("expected panic")
   844  				}
   845  			}()
   846  			f()
   847  		}
   848  
   849  		// overflow
   850  		shouldPanic(func() { test(_M64, 1) })
   851  		shouldPanic(func() { test(1, _M64) })
   852  		shouldPanic(func() { test(_M64, _M64) })
   853  
   854  		// no overflow
   855  		test(_M64, 0)
   856  		test(0, 0)
   857  		test(1, 1)
   858  	}
   859  }
   860  
   861  func TestSub64OverflowPanic(t *testing.T) {
   862  	// Test that 64-bit overflow panics fire correctly.
   863  	// These are designed to improve coverage of compiler intrinsics.
   864  	tests := []func(uint64, uint64) uint64{
   865  		func(a, b uint64) uint64 {
   866  			x, c := Sub64(a, b, 0)
   867  			if c > 0 {
   868  				panic("overflow")
   869  			}
   870  			return x
   871  		},
   872  		func(a, b uint64) uint64 {
   873  			x, c := Sub64(a, b, 0)
   874  			if c != 0 {
   875  				panic("overflow")
   876  			}
   877  			return x
   878  		},
   879  		func(a, b uint64) uint64 {
   880  			x, c := Sub64(a, b, 0)
   881  			if c == 1 {
   882  				panic("overflow")
   883  			}
   884  			return x
   885  		},
   886  		func(a, b uint64) uint64 {
   887  			x, c := Sub64(a, b, 0)
   888  			if c != 1 {
   889  				return x
   890  			}
   891  			panic("overflow")
   892  		},
   893  		func(a, b uint64) uint64 {
   894  			x, c := Sub64(a, b, 0)
   895  			if c == 0 {
   896  				return x
   897  			}
   898  			panic("overflow")
   899  		},
   900  	}
   901  	for _, test := range tests {
   902  		shouldPanic := func(f func()) {
   903  			defer func() {
   904  				if err := recover(); err == nil {
   905  					t.Fatalf("expected panic")
   906  				}
   907  			}()
   908  			f()
   909  		}
   910  
   911  		// overflow
   912  		shouldPanic(func() { test(0, 1) })
   913  		shouldPanic(func() { test(1, _M64) })
   914  		shouldPanic(func() { test(_M64-1, _M64) })
   915  
   916  		// no overflow
   917  		test(_M64, 0)
   918  		test(0, 0)
   919  		test(1, 1)
   920  	}
   921  }
   922  
   923  func TestMulDiv(t *testing.T) {
   924  	testMul := func(msg string, f func(x, y uint) (hi, lo uint), x, y, hi, lo uint) {
   925  		hi1, lo1 := f(x, y)
   926  		if hi1 != hi || lo1 != lo {
   927  			t.Errorf("%s: got hi:lo = %#x:%#x; want %#x:%#x", msg, hi1, lo1, hi, lo)
   928  		}
   929  	}
   930  	testDiv := func(msg string, f func(hi, lo, y uint) (q, r uint), hi, lo, y, q, r uint) {
   931  		q1, r1 := f(hi, lo, y)
   932  		if q1 != q || r1 != r {
   933  			t.Errorf("%s: got q:r = %#x:%#x; want %#x:%#x", msg, q1, r1, q, r)
   934  		}
   935  	}
   936  	for _, a := range []struct {
   937  		x, y      uint
   938  		hi, lo, r uint
   939  	}{
   940  		{1 << (UintSize - 1), 2, 1, 0, 1},
   941  		{_M, _M, _M - 1, 1, 42},
   942  	} {
   943  		testMul("Mul", Mul, a.x, a.y, a.hi, a.lo)
   944  		testMul("Mul symmetric", Mul, a.y, a.x, a.hi, a.lo)
   945  		testDiv("Div", Div, a.hi, a.lo+a.r, a.y, a.x, a.r)
   946  		testDiv("Div symmetric", Div, a.hi, a.lo+a.r, a.x, a.y, a.r)
   947  		// The above code can't test intrinsic implementation, because the passed function is not called directly.
   948  		// The following code uses a closure to test the intrinsic version in case the function is intrinsified.
   949  		testMul("Mul intrinsic", func(x, y uint) (uint, uint) { return Mul(x, y) }, a.x, a.y, a.hi, a.lo)
   950  		testMul("Mul intrinsic symmetric", func(x, y uint) (uint, uint) { return Mul(x, y) }, a.y, a.x, a.hi, a.lo)
   951  		testDiv("Div intrinsic", func(hi, lo, y uint) (uint, uint) { return Div(hi, lo, y) }, a.hi, a.lo+a.r, a.y, a.x, a.r)
   952  		testDiv("Div intrinsic symmetric", func(hi, lo, y uint) (uint, uint) { return Div(hi, lo, y) }, a.hi, a.lo+a.r, a.x, a.y, a.r)
   953  	}
   954  }
   955  
   956  func TestMulDiv32(t *testing.T) {
   957  	testMul := func(msg string, f func(x, y uint32) (hi, lo uint32), x, y, hi, lo uint32) {
   958  		hi1, lo1 := f(x, y)
   959  		if hi1 != hi || lo1 != lo {
   960  			t.Errorf("%s: got hi:lo = %#x:%#x; want %#x:%#x", msg, hi1, lo1, hi, lo)
   961  		}
   962  	}
   963  	testDiv := func(msg string, f func(hi, lo, y uint32) (q, r uint32), hi, lo, y, q, r uint32) {
   964  		q1, r1 := f(hi, lo, y)
   965  		if q1 != q || r1 != r {
   966  			t.Errorf("%s: got q:r = %#x:%#x; want %#x:%#x", msg, q1, r1, q, r)
   967  		}
   968  	}
   969  	for _, a := range []struct {
   970  		x, y      uint32
   971  		hi, lo, r uint32
   972  	}{
   973  		{1 << 31, 2, 1, 0, 1},
   974  		{0xc47dfa8c, 50911, 0x98a4, 0x998587f4, 13},
   975  		{_M32, _M32, _M32 - 1, 1, 42},
   976  	} {
   977  		testMul("Mul32", Mul32, a.x, a.y, a.hi, a.lo)
   978  		testMul("Mul32 symmetric", Mul32, a.y, a.x, a.hi, a.lo)
   979  		testDiv("Div32", Div32, a.hi, a.lo+a.r, a.y, a.x, a.r)
   980  		testDiv("Div32 symmetric", Div32, a.hi, a.lo+a.r, a.x, a.y, a.r)
   981  	}
   982  }
   983  
   984  func TestMulDiv64(t *testing.T) {
   985  	testMul := func(msg string, f func(x, y uint64) (hi, lo uint64), x, y, hi, lo uint64) {
   986  		hi1, lo1 := f(x, y)
   987  		if hi1 != hi || lo1 != lo {
   988  			t.Errorf("%s: got hi:lo = %#x:%#x; want %#x:%#x", msg, hi1, lo1, hi, lo)
   989  		}
   990  	}
   991  	testDiv := func(msg string, f func(hi, lo, y uint64) (q, r uint64), hi, lo, y, q, r uint64) {
   992  		q1, r1 := f(hi, lo, y)
   993  		if q1 != q || r1 != r {
   994  			t.Errorf("%s: got q:r = %#x:%#x; want %#x:%#x", msg, q1, r1, q, r)
   995  		}
   996  	}
   997  	for _, a := range []struct {
   998  		x, y      uint64
   999  		hi, lo, r uint64
  1000  	}{
  1001  		{1 << 63, 2, 1, 0, 1},
  1002  		{0x3626229738a3b9, 0xd8988a9f1cc4a61, 0x2dd0712657fe8, 0x9dd6a3364c358319, 13},
  1003  		{_M64, _M64, _M64 - 1, 1, 42},
  1004  	} {
  1005  		testMul("Mul64", Mul64, a.x, a.y, a.hi, a.lo)
  1006  		testMul("Mul64 symmetric", Mul64, a.y, a.x, a.hi, a.lo)
  1007  		testDiv("Div64", Div64, a.hi, a.lo+a.r, a.y, a.x, a.r)
  1008  		testDiv("Div64 symmetric", Div64, a.hi, a.lo+a.r, a.x, a.y, a.r)
  1009  		// The above code can't test intrinsic implementation, because the passed function is not called directly.
  1010  		// The following code uses a closure to test the intrinsic version in case the function is intrinsified.
  1011  		testMul("Mul64 intrinsic", func(x, y uint64) (uint64, uint64) { return Mul64(x, y) }, a.x, a.y, a.hi, a.lo)
  1012  		testMul("Mul64 intrinsic symmetric", func(x, y uint64) (uint64, uint64) { return Mul64(x, y) }, a.y, a.x, a.hi, a.lo)
  1013  		testDiv("Div64 intrinsic", func(hi, lo, y uint64) (uint64, uint64) { return Div64(hi, lo, y) }, a.hi, a.lo+a.r, a.y, a.x, a.r)
  1014  		testDiv("Div64 intrinsic symmetric", func(hi, lo, y uint64) (uint64, uint64) { return Div64(hi, lo, y) }, a.hi, a.lo+a.r, a.x, a.y, a.r)
  1015  	}
  1016  }
  1017  
  1018  func TestDivPanicOverflow(t *testing.T) {
  1019  	// Expect a panic
  1020  	defer func() {
  1021  		if err := recover(); err == nil {
  1022  			t.Error("Div should have panicked when y<=hi")
  1023  		} else if err != overflowError {
  1024  			t.Errorf("Div expected panic: %q, got: %v ", overflowError, err)
  1025  		}
  1026  	}()
  1027  	q, r := Div(1, 0, 1)
  1028  	t.Errorf("undefined q, r = %v, %v calculated when Div should have panicked", q, r)
  1029  }
  1030  
  1031  func TestDiv32PanicOverflow(t *testing.T) {
  1032  	// Expect a panic
  1033  	defer func() {
  1034  		if err := recover(); err == nil {
  1035  			t.Error("Div32 should have panicked when y<=hi")
  1036  		} else if err != overflowError {
  1037  			t.Errorf("Div32 expected panic: %q, got: %v ", overflowError, err)
  1038  		}
  1039  	}()
  1040  	q, r := Div32(1, 0, 1)
  1041  	t.Errorf("undefined q, r = %v, %v calculated when Div32 should have panicked", q, r)
  1042  }
  1043  
  1044  func TestDiv64PanicOverflow(t *testing.T) {
  1045  	// Expect a panic
  1046  	defer func() {
  1047  		if err := recover(); err == nil {
  1048  			t.Error("Div64 should have panicked when y<=hi")
  1049  		} else if err != overflowError {
  1050  			t.Errorf("Div64 expected panic: %q, got: %v ", overflowError, err)
  1051  		}
  1052  	}()
  1053  	q, r := Div64(1, 0, 1)
  1054  	t.Errorf("undefined q, r = %v, %v calculated when Div64 should have panicked", q, r)
  1055  }
  1056  
  1057  func TestDivPanicZero(t *testing.T) {
  1058  	// Expect a panic
  1059  	defer func() {
  1060  		if err := recover(); err == nil {
  1061  			t.Error("Div should have panicked when y==0")
  1062  		} else if err != divideError {
  1063  			t.Errorf("Div expected panic: %q, got: %q ", divideError, err)
  1064  		}
  1065  	}()
  1066  	q, r := Div(1, 1, 0)
  1067  	t.Errorf("undefined q, r = %v, %v calculated when Div should have panicked", q, r)
  1068  }
  1069  
  1070  func TestDiv32PanicZero(t *testing.T) {
  1071  	// Expect a panic
  1072  	defer func() {
  1073  		if err := recover(); err == nil {
  1074  			t.Error("Div32 should have panicked when y==0")
  1075  		} else if err != divideError {
  1076  			t.Errorf("Div32 expected panic: %q, got: %q ", divideError, err)
  1077  		}
  1078  	}()
  1079  	q, r := Div32(1, 1, 0)
  1080  	t.Errorf("undefined q, r = %v, %v calculated when Div32 should have panicked", q, r)
  1081  }
  1082  
  1083  func TestDiv64PanicZero(t *testing.T) {
  1084  	// Expect a panic
  1085  	defer func() {
  1086  		if err := recover(); err == nil {
  1087  			t.Error("Div64 should have panicked when y==0")
  1088  		} else if err != divideError {
  1089  			t.Errorf("Div64 expected panic: %q, got: %q ", divideError, err)
  1090  		}
  1091  	}()
  1092  	q, r := Div64(1, 1, 0)
  1093  	t.Errorf("undefined q, r = %v, %v calculated when Div64 should have panicked", q, r)
  1094  }
  1095  
  1096  func TestRem32(t *testing.T) {
  1097  	// Sanity check: for non-overflowing dividends, the result is the
  1098  	// same as the rem returned by Div32
  1099  	hi, lo, y := uint32(510510), uint32(9699690), uint32(510510+1) // ensure hi < y
  1100  	for i := 0; i < 1000; i++ {
  1101  		r := Rem32(hi, lo, y)
  1102  		_, r2 := Div32(hi, lo, y)
  1103  		if r != r2 {
  1104  			t.Errorf("Rem32(%v, %v, %v) returned %v, but Div32 returned rem %v", hi, lo, y, r, r2)
  1105  		}
  1106  		y += 13
  1107  	}
  1108  }
  1109  
  1110  func TestRem32Overflow(t *testing.T) {
  1111  	// To trigger a quotient overflow, we need y <= hi
  1112  	hi, lo, y := uint32(510510), uint32(9699690), uint32(7)
  1113  	for i := 0; i < 1000; i++ {
  1114  		r := Rem32(hi, lo, y)
  1115  		_, r2 := Div64(0, uint64(hi)<<32|uint64(lo), uint64(y))
  1116  		if r != uint32(r2) {
  1117  			t.Errorf("Rem32(%v, %v, %v) returned %v, but Div64 returned rem %v", hi, lo, y, r, r2)
  1118  		}
  1119  		y += 13
  1120  	}
  1121  }
  1122  
  1123  func TestRem64(t *testing.T) {
  1124  	// Sanity check: for non-overflowing dividends, the result is the
  1125  	// same as the rem returned by Div64
  1126  	hi, lo, y := uint64(510510), uint64(9699690), uint64(510510+1) // ensure hi < y
  1127  	for i := 0; i < 1000; i++ {
  1128  		r := Rem64(hi, lo, y)
  1129  		_, r2 := Div64(hi, lo, y)
  1130  		if r != r2 {
  1131  			t.Errorf("Rem64(%v, %v, %v) returned %v, but Div64 returned rem %v", hi, lo, y, r, r2)
  1132  		}
  1133  		y += 13
  1134  	}
  1135  }
  1136  
  1137  func TestRem64Overflow(t *testing.T) {
  1138  	Rem64Tests := []struct {
  1139  		hi, lo, y uint64
  1140  		rem       uint64
  1141  	}{
  1142  		// Testcases computed using Python 3, as:
  1143  		//   >>> hi = 42; lo = 1119; y = 42
  1144  		//   >>> ((hi<<64)+lo) % y
  1145  		{42, 1119, 42, 27},
  1146  		{42, 1119, 38, 9},
  1147  		{42, 1119, 26, 23},
  1148  		{469, 0, 467, 271},
  1149  		{469, 0, 113, 58},
  1150  		{111111, 111111, 1171, 803},
  1151  		{3968194946088682615, 3192705705065114702, 1000037, 56067},
  1152  	}
  1153  
  1154  	for _, rt := range Rem64Tests {
  1155  		if rt.hi < rt.y {
  1156  			t.Fatalf("Rem64(%v, %v, %v) is not a test with quo overflow", rt.hi, rt.lo, rt.y)
  1157  		}
  1158  		rem := Rem64(rt.hi, rt.lo, rt.y)
  1159  		if rem != rt.rem {
  1160  			t.Errorf("Rem64(%v, %v, %v) returned %v, wanted %v",
  1161  				rt.hi, rt.lo, rt.y, rem, rt.rem)
  1162  		}
  1163  	}
  1164  }
  1165  
  1166  func BenchmarkAdd(b *testing.B) {
  1167  	var z, c uint
  1168  	for i := 0; i < b.N; i++ {
  1169  		z, c = Add(uint(Input), uint(i), c)
  1170  	}
  1171  	Output = int(z + c)
  1172  }
  1173  
  1174  func BenchmarkAdd32(b *testing.B) {
  1175  	var z, c uint32
  1176  	for i := 0; i < b.N; i++ {
  1177  		z, c = Add32(uint32(Input), uint32(i), c)
  1178  	}
  1179  	Output = int(z + c)
  1180  }
  1181  
  1182  func BenchmarkAdd64(b *testing.B) {
  1183  	var z, c uint64
  1184  	for i := 0; i < b.N; i++ {
  1185  		z, c = Add64(uint64(Input), uint64(i), c)
  1186  	}
  1187  	Output = int(z + c)
  1188  }
  1189  
  1190  func BenchmarkAdd64multiple(b *testing.B) {
  1191  	z0 := uint64(Input)
  1192  	z1 := uint64(Input)
  1193  	z2 := uint64(Input)
  1194  	z3 := uint64(Input)
  1195  	for i := 0; i < b.N; i++ {
  1196  		var c uint64
  1197  		z0, c = Add64(z0, uint64(i), c)
  1198  		z1, c = Add64(z1, uint64(i), c)
  1199  		z2, c = Add64(z2, uint64(i), c)
  1200  		z3, _ = Add64(z3, uint64(i), c)
  1201  	}
  1202  	Output = int(z0 + z1 + z2 + z3)
  1203  }
  1204  
  1205  func BenchmarkSub(b *testing.B) {
  1206  	var z, c uint
  1207  	for i := 0; i < b.N; i++ {
  1208  		z, c = Sub(uint(Input), uint(i), c)
  1209  	}
  1210  	Output = int(z + c)
  1211  }
  1212  
  1213  func BenchmarkSub32(b *testing.B) {
  1214  	var z, c uint32
  1215  	for i := 0; i < b.N; i++ {
  1216  		z, c = Sub32(uint32(Input), uint32(i), c)
  1217  	}
  1218  	Output = int(z + c)
  1219  }
  1220  
  1221  func BenchmarkSub64(b *testing.B) {
  1222  	var z, c uint64
  1223  	for i := 0; i < b.N; i++ {
  1224  		z, c = Sub64(uint64(Input), uint64(i), c)
  1225  	}
  1226  	Output = int(z + c)
  1227  }
  1228  
  1229  func BenchmarkSub64multiple(b *testing.B) {
  1230  	z0 := uint64(Input)
  1231  	z1 := uint64(Input)
  1232  	z2 := uint64(Input)
  1233  	z3 := uint64(Input)
  1234  	for i := 0; i < b.N; i++ {
  1235  		var c uint64
  1236  		z0, c = Sub64(z0, uint64(i), c)
  1237  		z1, c = Sub64(z1, uint64(i), c)
  1238  		z2, c = Sub64(z2, uint64(i), c)
  1239  		z3, _ = Sub64(z3, uint64(i), c)
  1240  	}
  1241  	Output = int(z0 + z1 + z2 + z3)
  1242  }
  1243  
  1244  func BenchmarkMul(b *testing.B) {
  1245  	var hi, lo uint
  1246  	for i := 0; i < b.N; i++ {
  1247  		hi, lo = Mul(uint(Input), uint(i))
  1248  	}
  1249  	Output = int(hi + lo)
  1250  }
  1251  
  1252  func BenchmarkMul32(b *testing.B) {
  1253  	var hi, lo uint32
  1254  	for i := 0; i < b.N; i++ {
  1255  		hi, lo = Mul32(uint32(Input), uint32(i))
  1256  	}
  1257  	Output = int(hi + lo)
  1258  }
  1259  
  1260  func BenchmarkMul64(b *testing.B) {
  1261  	var hi, lo uint64
  1262  	for i := 0; i < b.N; i++ {
  1263  		hi, lo = Mul64(uint64(Input), uint64(i))
  1264  	}
  1265  	Output = int(hi + lo)
  1266  }
  1267  
  1268  func BenchmarkDiv(b *testing.B) {
  1269  	var q, r uint
  1270  	for i := 0; i < b.N; i++ {
  1271  		q, r = Div(1, uint(i), uint(Input))
  1272  	}
  1273  	Output = int(q + r)
  1274  }
  1275  
  1276  func BenchmarkDiv32(b *testing.B) {
  1277  	var q, r uint32
  1278  	for i := 0; i < b.N; i++ {
  1279  		q, r = Div32(1, uint32(i), uint32(Input))
  1280  	}
  1281  	Output = int(q + r)
  1282  }
  1283  
  1284  func BenchmarkDiv64(b *testing.B) {
  1285  	var q, r uint64
  1286  	for i := 0; i < b.N; i++ {
  1287  		q, r = Div64(1, uint64(i), uint64(Input))
  1288  	}
  1289  	Output = int(q + r)
  1290  }
  1291  
  1292  // ----------------------------------------------------------------------------
  1293  // Testing support
  1294  
  1295  type entry = struct {
  1296  	nlz, ntz, pop int
  1297  }
  1298  
  1299  // tab contains results for all uint8 values
  1300  var tab [256]entry
  1301  
  1302  func init() {
  1303  	tab[0] = entry{8, 8, 0}
  1304  	for i := 1; i < len(tab); i++ {
  1305  		// nlz
  1306  		x := i // x != 0
  1307  		n := 0
  1308  		for x&0x80 == 0 {
  1309  			n++
  1310  			x <<= 1
  1311  		}
  1312  		tab[i].nlz = n
  1313  
  1314  		// ntz
  1315  		x = i // x != 0
  1316  		n = 0
  1317  		for x&1 == 0 {
  1318  			n++
  1319  			x >>= 1
  1320  		}
  1321  		tab[i].ntz = n
  1322  
  1323  		// pop
  1324  		x = i // x != 0
  1325  		n = 0
  1326  		for x != 0 {
  1327  			n += int(x & 1)
  1328  			x >>= 1
  1329  		}
  1330  		tab[i].pop = n
  1331  	}
  1332  }