Cortex-M3以上でN == 2^n判定とビット列反転を参考に、x86 での判定を探してみた。
算術演算と論理演算で判定
C
int is_pow2n(unsigned x)
{
return ((x != 0) && (x == (x & -x)));
}
BSF/BSR 命令で判定
BSF/BSR
int is_pow2n(unsigned x)
{
unsigned p, q;
if (x == 0) return 0;
__asm__ ("bsf %1,%0": "=r" (p) : "X" (x));
__asm__ ("bsr %1,%0": "=r" (q) : "X" (x));
return (p == q);
}
LZCNT/TZCNT 命令が使用可能な場合
LZCNT/TZCNT
int is_pow2n(unsigned x)
{
unsigned p, q;
__asm__ ("lzcnt %1,%0": "=r" (p) : "X" (x));
__asm__ ("tzcnt %1,%0": "=r" (q) : "X" (x));
return ((p + q) == 31);
}
POPCNT 命令が使用可能な場合
POPCNT
int is_pow2n(unsigned x)
{
unsigned n;
__asm__ ("popcnt %1,%0": "=r" (n) : "X" (x));
return (n == 1);
}