--- nono/lib/bitops.h 2026/04/29 17:04:57 1.1 +++ nono/lib/bitops.h 2026/04/29 17:05:26 1.1.1.4 @@ -4,34 +4,65 @@ // Licensed under nono-license.txt // +// +// 各種ビット操作 +// + #pragma once #include "header.h" +#if defined(HAVE___BUILTIN_BITREVERSE8) +#define bitrev(x) __builtin_bitreverse8(x) +#else extern const uint8 bitrev_table[256]; -// 8ビットを左右反転する (定数用) -static constexpr uint8 _rev8(uint8 x) -{ - x = ((x & 0x0f) << 4) | ((x >> 4) & 0x0f); - x = ((x & 0x33) << 2) | ((x >> 2) & 0x33); - x = ((x & 0x55) << 1) | ((x >> 1) & 0x55); - return x; -} - -// 8ビットを左右反転する (実行時用) +// 8ビットを左右反転する static inline uint8 bitrev(uint8 x) { return bitrev_table[x]; } +#endif + +// 左ローテート +#if defined(HAVE___BUILTIN_ROTATELEFT32) +#define ROL32(a, n) __builtin_rotateleft32(a, n) +#else +static inline uint32 +ROL32(uint32 a, int n) +{ + n &= 31; + if (__predict_false(n == 0)) { + return a; + } else { + return (a << n) | (a >> (32 - n)); + } +} +#endif + +// 右ローテート +#if defined(HAVE___BUILTIN_ROTATERIGHT32) +#define ROR32(a, n) __builtin_rotateright32(a, n) +#else +static inline uint32 +ROR32(uint32 a, int n) +{ + n &= 31; + if (__predict_false(n == 0)) { + return a; + } else { + return (a >> n) | (a << (32 - n)); + } +} +#endif // mask で指定したいずれかのビットが 0 -> 1 に変化したら true static constexpr bool bit_rising(uint before, uint after, uint mask) { - // before が 0 で mask が 1 のビットだけを立てる - // それが 1 で after が 1 なら立ち上がり + // before が 0 で mask が 1 のビットだけを立てる。 + // それが 1 で after が 1 なら立ち上がり。 return (~before & mask) & after; } @@ -39,7 +70,7 @@ bit_rising(uint before, uint after, uint static constexpr bool bit_falling(uint before, uint after, uint mask) { - // before が 1 で mask が 1 のビットだけを立てる - // それが 1 で after が 0 なら立ち下がり + // before が 1 で mask が 1 のビットだけを立てる。 + // それが 1 で after が 0 なら立ち下がり。 return (before & mask) & ~after; }