【发布时间】:2010-09-26 05:44:00
【问题描述】:
以下代码在 GCC 中调用 clz/ctz 的内置函数,并且在其他系统上具有 C 版本。显然,如果系统有内置的 clz/ctz 指令,如 x86 和 ARM,则 C 版本有点欠佳。
#ifdef __GNUC__
#define clz(x) __builtin_clz(x)
#define ctz(x) __builtin_ctz(x)
#else
static uint32_t ALWAYS_INLINE popcnt( uint32_t x )
{
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static uint32_t ALWAYS_INLINE clz( uint32_t x )
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - popcnt(x);
}
static uint32_t ALWAYS_INLINE ctz( uint32_t x )
{
return popcnt((x & -x) - 1);
}
#endif
我需要调用哪些函数,需要包含哪些标头等,以便在此处为 MSVC 添加适当的 ifdef?我已经看过this page,但我不完全确定#pragma 的用途(它是必需的吗?)以及它对编译的MSVC 版本要求有什么限制。作为一个没有真正使用 MSVC 的人,我也不知道这些内在函数在其他架构上是否具有 C 等价物,或者在#defining 它们时是否也必须 #ifdef x86/x86_64。
【问题讨论】:
-
您上面提到的页面指的是一个属于 .NET 运行时的函数,您是要为 .NET 构建程序还是作为本机 Windows 可执行文件?
-
这是一个原生的 Windows 可执行文件——我问的部分原因是我发现现在很难找到真正谈论 C 的 Microsoft 文档页面。
-
Libcxx 实现github.com/llvm-mirror/libcxx/blob/…
标签: c visual-c++ intrinsics