XCode and _bittest function

XCode and _bittest function

本文关键字:function bittest and XCode      更新时间:2023-10-16

我有一个为Win32开发的C++项目,我想将其移植到OSX。代码使用_bittest_bittest64等函数,但我在 XCode 头文件中没有找到相同的函数。

这些功能的替代方案是什么?可能有良好的工作填充物。该项目确实是一个遗产,目前不需要额外的性能。

_bittest 和_bittest64符号是编译器内部函数,它们发出位测试指令,特别是 x86bt,以检查从零开始的索引处的位值。

使用内存操作数,bt具有疯狂的CISC位串行为,其中位索引可以超出寻址模式选择的内存的dword/qword。 这很慢,这就是为什么编译器会首先将操作数加载到寄存器中的原因。 但这就是 MSVC 内在的用途。 否则,它就不需要是内在的。

以下C++与bt指令的寄存器参数版本的行为相匹配,将移位计数包装在寄存器宽度处,即有效地只查看低位。 (如果b为 <32 或 <64,则与 MSVC 内部匹配。请参阅更新的代码和注释,讨论如何实现 MSVC 语义,使其在指向的longlong long之外进行访问。

另请注意,long

在 x64 Windows ABI 中是 32 位类型,但在 x86-64 System V ABI 中是 64 位类型(您在 OS X 上使用,除非您构建过时的 32 位代码(。 您可能希望将代码更改为int32_tuint32_t以避免在每个long中留下未使用的位,具体取决于您的使用方式。

inline
unsigned char bittest(long const *a, long b)
{
auto const value{ *a };
auto const mask{ 1L << (b&31) };
auto const masked_value{ value & mask };
return unsigned char{ masked_value != 0 };
}
inline
unsigned char bittest64(long long const *a, long long b)
{
auto const value{ *a };
auto const mask{ 1LL << (b&63) };
auto const masked_value{ value & mask };
return unsigned char{ masked_value != 0 };
}

我不知道有任何具有相同功能的 GCC 或 Clang 内联函数。如果需要,你可以改用从函数实现发出汇编指令,但使用内存操作数bt很慢,所以通常最好以纯C++实现,让编译器做得很好。

更新:

在讨论了从内部函数发出的代码之后,很明显,之前提出的替换代码仅涵盖了部分功能。特别是,内部函数允许在*a占用的内存之外索引位。以下实现也说明了这一点。

inline
unsigned char bittest(std::int32_t const *a, std::int32_t b)
{
auto const bits{ reinterpret_cast<unsigned char const*>(a) };
auto const value{ bits[b >> 3] };
auto const mask{ (unsigned char)(1 << (b & 7)) };
return (value & mask) != 0;
}
inline
unsigned char bittest64(std::int64_t const *a, std::int64_t b)
{
auto const bits{ reinterpret_cast<unsigned char const*>(a) };
auto const value{ bits[b >> 3] };
auto const mask{ (unsigned char)(1 << (b & 7)) };
return (value & mask) != 0;
}