Reputation: 23
I'm trying to implement in log2 for integer in C++ in NaCl, I used the asm way as the nacl documentation said it's the only permitted way to write ASM, which is as follow
int log2(int x) {
int ret;
asm ( "\tbsr %1, %0\n"
: "=r"(ret)
: "r" (x)
);
return y;
}
, but turns out ARM does not support this instruction, so I want to write another version for ARM only. Is there any way to do that?
Btw, I found one solution to this particular function already, which is by using
static inline int log2(int x) {
return sizeof(int) * 8 - __builtin_clz(x) - 1;
}
mentioned in another post, so my question is purely about the way to give different implementation for different CPU Architecture. ( I've tried #ifdef ARCH_ARM, but it didn't work)
Upvotes: 2
Views: 167
Reputation: 11002
chromium native client use NACL_BUILD_ARCH
to discriminate between x86, arm and mips : https://chromium.googlesource.com/chromium/chromium/+/trunk/components/nacl/nacl_defines.gypi
(NB: you can't use it if you're using PNaCl)
ex: (from 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
Also, bsr
has an equivalent in arm if I recall correctly : http://fgiesen.wordpress.com/2013/10/18/bit-scanning-equivalencies/
Upvotes: 1