Correct way to wrap CMPXCHG8B in GCC inline assembly, 32 bits

Viewed 2785

I'm trying to write GCC inline asm for CMPXCHG8B for ia32. No, I cannot use __sync_bool_compare_and_swap. It has to work with and without -fPIC.

So far the best I've (EDIT: does not work after all, see my own answer below for details) is

register int32 ebx_val asm("ebx")= set & 0xFFFFFFFF;
asm ("lock; cmpxchg8b %0;"
     "setz %1;"
     : "+m" (*a), "=q" (ret), "+A" (*cmp)
     : "r" (ebx_val), "c" ((int32)(set >> 32))
     : "flags")

However I'm not sure if this is in fact correct.

I cannot do "b" ((int32)(set & 0xFFFFFFFF)) for ebx_val due to PIC, but apparently register asm("ebx") variable is accepted by the compiler.

BONUS: the ret variable is used for branching, so the code ends up looking like this:

cmpxchg8b [edi];
setz cl;
cmp cl, 0;
je foo;

Any idea how to describe output operands so that it becomes:

cmpxchg8b [edi]
jz foo

?

Thank you.

3 Answers
Related