From 7583c350b893a83d0fdd5c0e3437fd724cae0c02 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Sun, 9 Feb 2020 19:25:27 +1100 Subject: [PATCH] compiler/math.bits: use max u64 consts --- vlib/compiler/aparser.v | 7 +- vlib/crypto/rand/utils.v | 2 +- vlib/math/bits/bits.v | 164 ++++++++++++++++++----------------- vlib/math/bits/bits_tables.v | 8 +- 4 files changed, 94 insertions(+), 87 deletions(-) diff --git a/vlib/compiler/aparser.v b/vlib/compiler/aparser.v index e01013056b..844947d7cd 100644 --- a/vlib/compiler/aparser.v +++ b/vlib/compiler/aparser.v @@ -778,7 +778,12 @@ fn (p mut Parser) const_decl() { // Do not do this when building a module, otherwise the consts // will not be accessible. if p.pref.build_mode != .build_module && is_compile_time_const(p.cgen.cur_line) { - p.cgen.const_defines << '#define $name $p.cgen.cur_line' + mut const_val := p.cgen.cur_line + // fix `warning: integer literal is too large to be represented in a signed integer type` + if typ == 'u64' { + const_val = 'UINT64_C($const_val)' + } + p.cgen.const_defines << '#define $name $const_val' p.cgen.resetln('') p.fgen_nl() continue diff --git a/vlib/crypto/rand/utils.v b/vlib/crypto/rand/utils.v index 9f0a8ef7da..27091115b2 100644 --- a/vlib/crypto/rand/utils.v +++ b/vlib/crypto/rand/utils.v @@ -10,7 +10,7 @@ import( ) pub fn int_u64(max u64) ?u64 { - bitlen := bits.len64(max) + bitlen := bits.len_64(max) if bitlen == 0 { return u64(0) } diff --git a/vlib/math/bits/bits.v b/vlib/math/bits/bits.v index 0fc1c65cc1..184e7a35bc 100644 --- a/vlib/math/bits/bits.v +++ b/vlib/math/bits/bits.v @@ -24,53 +24,60 @@ const ( m3 = 0x00ff00ff00ff00ff // etc. m4 = 0x0000ffff0000ffff ) + +const ( + // save importing math mod just for these + max_u32 = 4294967295 + max_u64 = 18446744073709551615 +) + // --- LeadingZeros --- -// leading_zeros8 returns the number of leading zero bits in x; the result is 8 for x == 0. -pub fn leading_zeros8(x byte) int { - return 8 - len8(x) +// leading_zeros_8 returns the number of leading zero bits in x; the result is 8 for x == 0. +pub fn leading_zeros_8(x byte) int { + return 8 - len_8(x) } -// leading_zeros16 returns the number of leading zero bits in x; the result is 16 for x == 0. -pub fn leading_zeros16(x u16) int { - return 16 - len16(x) +// leading_zeros_16 returns the number of leading zero bits in x; the result is 16 for x == 0. +pub fn leading_zeros_16(x u16) int { + return 16 - len_16(x) } -// leading_zeros32 returns the number of leading zero bits in x; the result is 32 for x == 0. -pub fn leading_zeros32(x u32) int { - return 32 - len32(x) +// leading_zeros_32 returns the number of leading zero bits in x; the result is 32 for x == 0. +pub fn leading_zeros_32(x u32) int { + return 32 - len_32(x) } -// leading_zeros64 returns the number of leading zero bits in x; the result is 64 for x == 0. -pub fn leading_zeros64(x u64) int { - return 64 - len64(x) +// leading_zeros_64 returns the number of leading zero bits in x; the result is 64 for x == 0. +pub fn leading_zeros_64(x u64) int { + return 64 - len_64(x) } // --- TrailingZeros --- -// trailing_zeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0. -pub fn trailing_zeros8(x byte) int { - return int(ntz8_tab[x]) +// trailing_zeros_8 returns the number of trailing zero bits in x; the result is 8 for x == 0. +pub fn trailing_zeros_8(x byte) int { + return int(ntz_8_tab[x]) } -// trailing_zeros16 returns the number of trailing zero bits in x; the result is 16 for x == 0. -pub fn trailing_zeros16(x u16) int { +// trailing_zeros_16 returns the number of trailing zero bits in x; the result is 16 for x == 0. +pub fn trailing_zeros_16(x u16) int { if x == 0 { return 16 } - // see comment in trailing_zeros64 + // see comment in trailing_zeros_64 return int(de_bruijn32tab[u32(x & -x) * de_bruijn32>>(32 - 5)]) } -// trailing_zeros32 returns the number of trailing zero bits in x; the result is 32 for x == 0. -pub fn trailing_zeros32(x u32) int { +// trailing_zeros_32 returns the number of trailing zero bits in x; the result is 32 for x == 0. +pub fn trailing_zeros_32(x u32) int { if x == 0 { return 32 } - // see comment in trailing_zeros64 + // see comment in trailing_zeros_64 return int(de_bruijn32tab[(x & -x) * de_bruijn32>>(32 - 5)]) } -// trailing_zeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0. -pub fn trailing_zeros64(x u64) int { +// trailing_zeros_64 returns the number of trailing zero bits in x; the result is 64 for x == 0. +pub fn trailing_zeros_64(x u64) int { if x == 0 { return 64 } @@ -89,23 +96,23 @@ pub fn trailing_zeros64(x u64) int { } // --- OnesCount --- -// ones_count8 returns the number of one bits ("population count") in x. -pub fn ones_count8(x byte) int { - return int(pop8_tab[x]) +// ones_count_8 returns the number of one bits ("population count") in x. +pub fn ones_count_8(x byte) int { + return int(pop_8_tab[x]) } -// ones_count16 returns the number of one bits ("population count") in x. -pub fn ones_count16(x u16) int { - return int(pop8_tab[x>>8] + pop8_tab[x & u16(0xff)]) +// ones_count_16 returns the number of one bits ("population count") in x. +pub fn ones_count_16(x u16) int { + return int(pop_8_tab[x>>8] + pop_8_tab[x & u16(0xff)]) } -// ones_count32 returns the number of one bits ("population count") in x. -pub fn ones_count32(x u32) int { - return int(pop8_tab[x>>24] + pop8_tab[x>>16 & 0xff] + pop8_tab[x>>8 & 0xff] + pop8_tab[x & u32(0xff)]) +// ones_count_32 returns the number of one bits ("population count") in x. +pub fn ones_count_32(x u32) int { + return int(pop_8_tab[x>>24] + pop_8_tab[x>>16 & 0xff] + pop_8_tab[x>>8 & 0xff] + pop_8_tab[x & u32(0xff)]) } -// ones_count64 returns the number of one bits ("population count") in x. -pub fn ones_count64(x u64) int { +// ones_count_64 returns the number of one bits ("population count") in x. +pub fn ones_count_64(x u64) int { // Implementation: Parallel summing of adjacent bits. // See "Hacker's Delight", Chap. 5: Counting Bits. // The following pattern shows the general approach: @@ -125,10 +132,9 @@ pub fn ones_count64(x u64) int { // Per "Hacker's Delight", the first line can be simplified // more, but it saves at best one instruction, so we leave // it alone for clarity. - m := u64(1<<64) - 1 - mut y := (x>>u64(1) & (m0 & m)) + (x & (m0 & m)) - y = (y>>u64(2) & (m1 & m)) + (y & (m1 & m)) - y = ((y>>4) + y) & (m2 & m) + mut y := (x>>u64(1) & (m0 & max_u64)) + (x & (m0 & max_u64)) + y = (y>>u64(2) & (m1 & max_u64)) + (y & (m1 & max_u64)) + y = ((y>>4) + y) & (m2 & max_u64) y += y>>8 y += y>>16 y += y>>32 @@ -181,87 +187,83 @@ pub fn rotate_left_64(x u64, k int) u64 { } // --- Reverse --- -// reverse8 returns the value of x with its bits in reversed order. +// reverse_8 returns the value of x with its bits in reversed order. [inline] -pub fn reverse8(x byte) byte { - return rev8_tab[x] +pub fn reverse_8(x byte) byte { + return rev_8_tab[x] } -// reverse16 returns the value of x with its bits in reversed order. +// reverse_16 returns the value of x with its bits in reversed order. [inline] -pub fn reverse16(x u16) u16 { - return u16(rev8_tab[x>>8]) | (u16(rev8_tab[x & u16(0xff)])<<8) +pub fn reverse_16(x u16) u16 { + return u16(rev_8_tab[x>>8]) | (u16(rev_8_tab[x & u16(0xff)])<<8) } -// reverse32 returns the value of x with its bits in reversed order. +// reverse_32 returns the value of x with its bits in reversed order. [inline] -pub fn reverse32(x u32) u32 { - m := u64(1<<32) - 1 - mut y := (x>>u32(1) & (m0 & m) | ((x & (m0 & m))<<1)) - y = (y>>u32(2) & (m1 & m) | ((y & (m1 & m))<>u32(4) & (m2 & m) | ((y & (m2 & m))<>u32(1) & (m0 & max_u32) | ((x & (m0 & max_u32))<<1)) + y = (y>>u32(2) & (m1 & max_u32) | ((y & (m1 & max_u32))<>u32(4) & (m2 & max_u32) | ((y & (m2 & max_u32))<>u64(1) & (m0 & m) | ((x & (m0 & m))<<1)) - y = (y>>u64(2) & (m1 & m) | ((y & (m1 & m))<<2)) - y = (y>>u64(4) & (m2 & m) | ((y & (m2 & m))<<4)) - return reverse_bytes64(y) +pub fn reverse_64(x u64) u64 { + mut y := (x>>u64(1) & (m0 & max_u64) | ((x & (m0 & max_u64))<<1)) + y = (y>>u64(2) & (m1 & max_u64) | ((y & (m1 & max_u64))<<2)) + y = (y>>u64(4) & (m2 & max_u64) | ((y & (m2 & max_u64))<<4)) + return reverse_bytes_64(y) } // --- ReverseBytes --- -// reverse_bytes16 returns the value of x with its bytes in reversed order. +// reverse_bytes_16 returns the value of x with its bytes in reversed order. // // This function's execution time does not depend on the inputs. [inline] -pub fn reverse_bytes16(x u16) u16 { +pub fn reverse_bytes_16(x u16) u16 { return (x>>8) | (x<<8) } -// reverse_bytes32 returns the value of x with its bytes in reversed order. +// reverse_bytes_32 returns the value of x with its bytes in reversed order. // // This function's execution time does not depend on the inputs. [inline] -pub fn reverse_bytes32(x u32) u32 { - m := u64(1<<32) - 1 - y := (x>>u32(8) & (m3 & m) | ((x & (m3 & m))<>u32(8) & (m3 & max_u32) | ((x & (m3 & max_u32))<>16) | (y<<16) } -// reverse_bytes64 returns the value of x with its bytes in reversed order. +// reverse_bytes_64 returns the value of x with its bytes in reversed order. // // This function's execution time does not depend on the inputs. [inline] -pub fn reverse_bytes64(x u64) u64 { - m := u64(1<<64) - 1 - mut y := (x>>u64(8) & (m3 & m) | ((x & (m3 & m))<>u64(16) & (m4 & m) | ((y & (m4 & m))<>u64(8) & (m3 & max_u64) | ((x & (m3 & max_u64))<>u64(16) & (m4 & max_u64) | ((y & (m4 & max_u64))<>32) | (y<<32) } // --- Len --- -// len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0. -pub fn len8(x byte) int { - return int(len8_tab[x]) +// len_8 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +pub fn len_8(x byte) int { + return int(len_8_tab[x]) } -// len16 returns the minimum number of bits required to represent x; the result is 0 for x == 0. -pub fn len16(x u16) int { +// len_16 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +pub fn len_16(x u16) int { mut y := x mut n := 0 if y >= 1<<8 { y >>= 8 n = 8 } - return n + int(len8_tab[y]) + return n + int(len_8_tab[y]) } -// len32 returns the minimum number of bits required to represent x; the result is 0 for x == 0. -pub fn len32(x u32) int { +// len_32 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +pub fn len_32(x u32) int { mut y := x mut n := 0 if y >= 1<<16 { @@ -272,11 +274,11 @@ pub fn len32(x u32) int { y >>= 8 n += 8 } - return n + int(len8_tab[y]) + return n + int(len_8_tab[y]) } -// len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0. -pub fn len64(x u64) int { +// len_64 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +pub fn len_64(x u64) int { mut y := x mut n := 0 if y >= u64(1)<>= 8 n += 8 } - return n + int(len8_tab[y]) + return n + int(len_8_tab[y]) } diff --git a/vlib/math/bits/bits_tables.v b/vlib/math/bits/bits_tables.v index b3f247bf3f..c1c5563093 100644 --- a/vlib/math/bits/bits_tables.v +++ b/vlib/math/bits/bits_tables.v @@ -4,7 +4,7 @@ module bits const ( - ntz8_tab = [byte(0x08), 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, + ntz_8_tab = [byte(0x08), 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, @@ -21,7 +21,7 @@ const ( 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, ] - pop8_tab = [byte(0x00), 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, + pop_8_tab = [byte(0x00), 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, @@ -38,7 +38,7 @@ const ( 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08, ] - rev8_tab = [byte(0x00), 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + rev_8_tab = [byte(0x00), 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, @@ -55,7 +55,7 @@ const ( 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, ] - len8_tab = [byte(0x00), 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + len_8_tab = [byte(0x00), 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,