0

I'm trying to port the following function for getting LSB into plain C:

static inline int LSB(uint64_t word)
{
  int dummy1, dummy2, dummy3;

asm("        bsf     %2, %0      " "\n\t"
    "        jnz     2f          " "\n\t"
    "        bsf     %1, %0      " "\n\t"
    "        jnz     1f          " "\n\t"
    "        movl    $64, %0     " "\n\t"
    "        jmp     2f          " "\n\t"
    "1:      addl    $32,%0      " "\n\t"
    "2:                          " "\n\t"
:   "=&q"(dummy1), "=&q"(dummy2), "=&q"(dummy3)
:    "1"((int) (word >> 32)), "2"((int) word)
:    "cc");
  return (dummy1);
}

I need to get rid of the ASM code here so that I can use it in Android, i've tried a ton of possibilities but none of them seem to work.

I'm actually not completely sure what the above function does, from the name I suspect it's getting the least significant bit, though I may be wrong.

(Editor's note: yes, BSF = find the index of the lowest set bit; this whole thing emulates a 64-bit tzcnt = trailing zero count, including returning 64 for the all-zero case which __builtin_ctzll won't guarantee. The asm constraints are over-complicated: the dummy2, dummy3 outputs aren't needed, the high and low halves could be pure read-only inputs with "r" constraints.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
LachoTomov
  • 3,312
  • 30
  • 42
  • 2
    https://stackoverflow.com/a/9354899. Also works in C, for any integer type. See also https://graphics.stanford.edu/~seander/bithacks.html – Robert Harvey May 22 '20 at 14:57
  • 4
    Have you tried `__builtin_ctzll()`? – fuz May 22 '20 at 14:58
  • @fuz oh man, thank you a million times, I've been stuck on this for hours! If you want post this as an answer so I can accept it. – LachoTomov May 22 '20 at 15:00
  • 1
    @LachoTomov Have linked a suitable duplicate instead. Have fun! – fuz May 22 '20 at 15:14
  • We wouldn't drop into inline assembly to get the LSB, since that can be done by the simple expression `variable&1`. – Erik Eidt May 22 '20 at 15:26
  • @ErikEidt yes, that seems to be the case because I tried var&1 and it didn't work. So it looks like the asm code is doing something else, but unfortunately I've no idea what :) I could only make a guess from the function name :) But __builtin_ctzll() seems to do the job. – LachoTomov May 22 '20 at 15:40
  • @LachoTomov It finds the index of the least significant bit set, i.e. counts the number of trailing zeroes. – fuz May 22 '20 at 16:21
  • @fuz great, i was worried this function may not be available when compiling for other architectures, so it's good to know what it does. Thanks once again! – LachoTomov May 22 '20 at 16:41
  • @ErikEidt: This is looking for the position of the lowest *set* bit, not isolating the least-significant bit. I fixed the question title. – Peter Cordes May 22 '20 at 18:40
  • @PeterCordes, got it. least significant bit without "set" threw me. – Erik Eidt May 23 '20 at 00:35

0 Answers0