Search code examples
assemblyx86-64instruction-setcarryflag

Is there an x86 assembly instruction that does both 'xadd' and 'adc reg,0'?


I've recently learnt about XADD and I had no luck at looking up on google. Does an instruction like XADD that also adds the carry flag exist? (ex. XADC) Or am I forced to do it with two different instructions?

I'm on Ubuntu and I'm using NASM in 64 bits mode.


Solution

  • No. xadd and adc are two different niche versions of addition that don't normally overlap, so it's not surprising that x86 doesn't have an instruction for it.

    • xadd is usually used with a memory destination (and often a lock prefix) for atomic_fetch_add
    • adc is usually used for extended-precision stuff, for the high parts of an integer wider than a register

    If you did lock xadd / lock xadc (hypothetical), you wouldn't be doing a single double-width atomic fetch_add, you'd be doing two separate atomic additions on the two halves of a wider number. So it's not really useful; if you want to atomic_fetch_add an __int128, you need a lock cmpxchg16b retry loop, not xadd / "xadc".

    If you want to do fetch_add(&mem, reg) + CF or fetch_add(&mem, reg+CF), you can do that manually with a combination of adc and xadd in some order. (And maybe some branching to handle the case where the +CF itself produces a carry if that's a concern).

    That's a niche enough need that x86 didn't choose to spend an opcode on it. There are only a limited number of opcodes, and each one would require transistors in the decoders, and at least microcode to implement it.