native 0.0.1
Vectors, masks and wide register packs for C++26
Loading...
Searching...
No Matches
x86 ADX: unsigned addition with carry

x86 instruction sets

Why use it

Multiword addition needs two results from each limb: the low sum and a carry for the next limb. addcarryx keeps that pair explicit, so an integer too wide for one register can still use the processor's carry arithmetic.

Operations

import native.x86.adx; provides native::addcarryx<Arch>(carry, a, b, out) for std::uint32_t and std::uint64_t. The module belongs to native::minimal; native.x86 and native also export it.

std::uint64_t sum;
std::uint8_t next = native::addcarryx<arch>(carry, a, b, &sum);
constexpr std::uint8_t addcarryx(std::uint8_t carry, std::uint32_t a, std::uint32_t b, std::uint32_t *result) noexcept
Add 32-bit operands with carry, writing the modular result.
Definition adx.h:55

The operands and output object have the same unsigned type. The function writes the sum modulo 2³² or 2⁶⁴ and returns a std::uint8_t containing zero or one. Any nonzero input carry contributes one. Addends are passed by value, so the output may overwrite an object from which an addend was read.

Caveats

The output pointer must identify a writable object. During constant evaluation, that object must also be modifiable under the usual constant-expression rules.

Runtime calls need target_features<native::x86>("adx"), a matching caller target and CPU admission through classify_isa. ADX needs no vector OS state. The scalar default tag is the module provider's NATIVE_BASELINE; a target attribute on the importer does not change it. An explicit tag avoids that ambiguity. Feature-bearing overloads are constexpr; tags without ADX have consteval overloads only.

Clang's intrinsics can lower to ADD/ADC in an ordinary addition chain. This API does not expose independent ADCX and ADOX flag chains.

See Clang's ADX header and Intel's Software Developer's Manual.