我试图在log2中实现NaCl中的C ++中的整数,我使用asm方式,因为nacl文档说它是唯一允许编写ASM的方法,如下所示
int log2(int x) {
int ret;
asm ( "\tbsr %1, %0\n"
: "=r"(ret)
: "r" (x)
);
return y;
}
,但事实证明ARM不支持此指令,因此我只想为ARM编写另一个版本。有没有办法做到这一点?
顺便说一句,我已经找到了这个特定功能的一个解决方案,即使用
static inline int log2(int x) {
return sizeof(int) * 8 - __builtin_clz(x) - 1;
}
在另一篇文章中提到过,所以我的问题纯粹是关于为不同的CPU架构提供不同实现的方法。 (我已尝试#ifdef ARCH_ARM,但它没有用)
答案 0 :(得分:1)
chrome native客户端使用NACL_BUILD_ARCH
来区分x86,arm和mips:https://chromium.googlesource.com/chromium/chromium/+/trunk/components/nacl/nacl_defines.gypi
(注意:如果您使用的是PNaCl,则无法使用它)
ex :(来自here)
#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
if (regs->prog_ctr >= NaClUserToSys(nap, NACL_TRAMPOLINE_START) &&
regs->prog_ctr < NaClUserToSys(nap, NACL_TRAMPOLINE_END)) {
*unwind_case = NACL_UNWIND_in_trampoline;
regs->stack_ptr += 8; /* Pop user return address */
return 1;
}
#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
if (regs->prog_ctr >= NACL_TRAMPOLINE_START &&
regs->prog_ctr < NACL_TRAMPOLINE_END) {
*unwind_case = NACL_UNWIND_in_trampoline;
regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->lr);
return 1;
}
#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
if (regs->prog_ctr >= NACL_TRAMPOLINE_START &&
regs->prog_ctr < NACL_TRAMPOLINE_END) {
*unwind_case = NACL_UNWIND_in_trampoline;
regs->prog_ctr = NaClSandboxCodeAddr(nap, regs->return_addr);
return 1;
}
#endif
此外,如果我没记错的话,bsr
还有同等效力:http://fgiesen.wordpress.com/2013/10/18/bit-scanning-equivalencies/