Есть ли инструкция по сборке x86, которая выполняет как «xadd», так и «adc reg, 0»?

Недавно я узнал о XADD, и мне не удалось найти информацию в Google. Существует ли такая инструкция, как XADD, которая также добавляет флаг переноса? (напр. XADC) Или меня заставляют делать это двумя разными инструкциями?

Я на Ubuntu и использую NASM в 64-битном режиме.


person Luxo    schedule 29.04.2021    source источник
comment
Нет такой удачи. Используйте регистр adc, 0 перед xadd.   -  person prl    schedule 30.04.2021


Ответы (1)


Нет. xadd и adc - это две разные нишевые версии сложения, которые обычно не пересекаются, поэтому неудивительно, что для x86 нет инструкции для них.

  • xadd обычно используется с назначением памяти (и часто с префиксом lock) для atomic_fetch_add.
  • adc обычно используется для расширенной точности, для старших частей целого числа, более широкого, чем регистр.

Если бы вы сделали lock xadd / lock xadc (гипотетически), вы бы не выполняли одно атомарное fetch_add двойной ширины, вы бы выполняли два отдельных атомарных сложения для двух половин более широкого числа. Так что это не очень полезно; если вы хотите atomic_fetch_add __int128, вам нужен цикл повтора lock cmpxchg16b, а не xadd/xadc.

Если вы хотите сделать fetch_add(&mem, reg) + CF или fetch_add(&mem, reg+CF), вы можете сделать это вручную, комбинируя adc и xadd в определенном порядке. (И, возможно, некоторое ветвление для обработки случая, когда сам +CF создает перенос, если это вас беспокоит).

Это достаточная ниша, чтобы x86 не стал тратить на нее код операции. Существует лишь ограниченное количество кодов операций, и для каждого из них потребуются транзисторы в декодерах и как минимум микрокод для его реализации.

person Peter Cordes    schedule 30.04.2021