diff --git a/src/util/BitReverse.cxx b/src/util/BitReverse.cxx index 29ffb49eb..0564c2c51 100644 --- a/src/util/BitReverse.cxx +++ b/src/util/BitReverse.cxx @@ -19,13 +19,13 @@ #include "BitReverse.hxx" -/** - * @see http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable - */ -const uint8_t bit_reverse_table[256] = +static constexpr BitReverseTable +GenerateBitReverseTable() noexcept { -#define R2(n) n, n + 2*64, n + 1*64, n + 3*64 -#define R4(n) R2(n), R2(n + 2*16), R2(n + 1*16), R2(n + 3*16) -#define R6(n) R4(n), R4(n + 2*4 ), R4(n + 1*4 ), R4(n + 3*4 ) - R6(0), R6(2), R6(1), R6(3) -}; + BitReverseTable table{}; + for (unsigned i = 0; i < 256; ++i) + table.data[i] = BitReverseMultiplyModulus(i); + return table; +} + +const BitReverseTable bit_reverse_table = GenerateBitReverseTable(); diff --git a/src/util/BitReverse.hxx b/src/util/BitReverse.hxx index c67d8a68e..f8e9cf63b 100644 --- a/src/util/BitReverse.hxx +++ b/src/util/BitReverse.hxx @@ -24,13 +24,30 @@ #include -extern const uint8_t bit_reverse_table[256]; +/** + * @see http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv + */ +constexpr uint8_t +BitReverseMultiplyModulus(uint8_t _in) noexcept +{ + uint64_t in = _in; + return uint8_t((in * 0x0202020202ULL & 0x010884422010ULL) % 1023); +} + +/* in order to avoid including in this header, this `struct` + is a workaround for GenerateBitReverseTable() being able to return + the plain array */ +struct BitReverseTable { + uint8_t data[256]; +}; + +extern const BitReverseTable bit_reverse_table; gcc_const static inline uint8_t bit_reverse(uint8_t x) noexcept { - return bit_reverse_table[x]; + return bit_reverse_table.data[x]; } #endif