Идея здесь состоит в том, чтобы загрузить операнды перед блокировкой EBX, а также избежать любой косвенной адресации при установке значения EBX для CMPXCHG8B. Я фиксирую жесткий регистр ESI для нижней половины операнда, потому что если бы я этого не сделал, GCC мог бы свободно использовать любой другой уже принятый регистр, если бы он мог доказать, что значение было равно. Регистр EDI сохраняется вручную, так как простое добавление его в закрытый список регистров дросселей GCC с «невозможными перезагрузками», вероятно, из-за высокого давления в регистре. PUSH / POP избегается при сохранении EDI, поскольку другие операнды могут быть адресованы ESP.

аюсь написать GCC Inline Asm для CMPXCHG8B для ia32. Нет я не могу использовать__sync_bool_compare_and_swap, Он должен работать с и без -FPIC.

Пока лучшее, что у меня есть (РЕДАКТИРОВАТЬ: не работает в конце концов, см. мой собственный ответ ниже для деталей)

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")

Однако я не уверен, правильно ли это на самом деле.

Я не могу"b" ((int32)(set & 0xFFFFFFFF)) для ebx_val из-за PIC, но, видимо,register asm("ebx") переменная принимается компилятором.

БОНУСпеременная ret используется для ветвления, поэтому код в конечном итоге выглядит следующим образом:

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

Любая идея, как описать выходные операнды, чтобы он стал:

cmpxchg8b [edi]
jz foo

?

Спасибо.

Ответы на вопрос(3)

Ваш ответ на вопрос