--- nono/lib/bitops.h 2026/04/29 17:05:22 1.1.1.3 +++ nono/lib/bitops.h 2026/04/29 17:05:35 1.1.1.5 @@ -12,36 +12,72 @@ #include "header.h" +#if defined(HAVE___BUILTIN_BITREVERSE8) && \ + defined(HAVE___BUILTIN_BITREVERSE16) && \ + defined(HAVE___BUILTIN_BITREVERSE32) +#define HAVE___BUILTIN_BITREVERSE +#endif + +#if defined(HAVE___BUILTIN_BITREVERSE) +#define bitrev8(x) __builtin_bitreverse8(x) +#define bitrev16(x) __builtin_bitreverse16(x) +#define bitrev32(x) __builtin_bitreverse32(x) +#else extern const uint8 bitrev_table[256]; -// 8ビットを左右反転する (定数用) -static constexpr uint8 _rev8(uint8 x) +// 8ビットを左右反転する +static inline uint8 +bitrev8(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; + return bitrev_table[x]; } -// 8ビットを左右反転する (実行時用) -static inline uint8 -bitrev(uint8 x) +// 16ビットを左右反転する +static inline uint16 +bitrev16(uint16 x) { - return bitrev_table[x]; + return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8); +} + +// 32ビットを左右反転する +static inline uint32 +bitrev32(uint32 x) +{ + return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16); +} +#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) { - // TODO: 各種コンパイラごとにビルトインがあったりなかったりするらしい n &= 31; - if (n == 0) { + if (__predict_false(n == 0)) { return a; } else { return (a >> n) | (a << (32 - n)); } } +#endif // mask で指定したいずれかのビットが 0 -> 1 に変化したら true static constexpr bool