|
|
nono 1.7.0
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
//
// 各種ビット操作
//
#pragma once
#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ビットを左右反転する
inline uint8
bitrev8(uint8 x)
{
return bitrev_table[x];
}
// 16ビットを左右反転する
inline uint16
bitrev16(uint16 x)
{
return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8);
}
// 32ビットを左右反転する
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
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
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
constexpr bool
bit_rising(uint before, uint after, uint mask)
{
// before が 0 で mask が 1 のビットだけを立てる。
// それが 1 で after が 1 なら立ち上がり。
return (~before & mask) & after;
}
// mask で指定したいずれかのビットが 1 -> 0 に変化したら true
constexpr bool
bit_falling(uint before, uint after, uint mask)
{
// before が 1 で mask が 1 のビットだけを立てる。
// それが 1 で after が 0 なら立ち下がり。
return (before & mask) & ~after;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.