ldadd

Atomic Load-Add Word

LDADD <Ws>, <Wt>, [<Xn|SP>]

Atomic add to memory, return old value.

Details

Atomic load-add of a 32-bit word. Atomically adds Ws to the memory location at address Xn and loads the original memory value into Wt. The sum is stored to memory; the original value (before the addition) is returned. This AArch64-only LSE instruction provides full sequential consistency without explicit acquire/release semantics. Condition flags are not affected.

Pseudocode Operation

address ← Xn; old_value ← [address]; [address] ← old_value + Ws; Wt ← old_value;

Example

LDADD w6, w3, [x1]

Encoding

Binary Layout
10
111
0
00
0
0
1
Rs
0
000
00
Rn
Rt
 
Format Atomic
Opcode 0xB8200000
Extension LSE (Atomics)

Operands

  • Ws
    Value
  • Wt
    Transfer 32-bit integer register (load/store)
  • Xn
    First source / base 64-bit integer register

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0xB8200000 LDADD <Ws>, <Wt>, [<Xn|SP>] A64 10 | 111 | 0 | 00 | 0 | 0 | 1 | Rs | 0 | 000 | 00 | Rn | Rt
0xF8200000 LDADD <Xs>, <Xt>, [<Xn|SP>] A64 11 | 111 | 0 | 00 | 0 | 0 | 1 | Rs | 0 | 000 | 00 | Rn | Rt

Description

Atomic add on word or doubleword in memory atomically loads a 32-bit word or 64-bit doubleword from memory, adds the value held in a register to it, and stores the result back to memory. The value initially loaded from memory is returned in the destination register. For more information about memory ordering semantics, see Load-Acquire, Store-Release. For information about memory accesses, see Load/Store addressing modes.

Operation

bits(64) address;
bits(datasize) value;
bits(datasize) data;

AccessDescriptor accdesc = CreateAccDescAtomicOp(MemAtomicOp_ADD, acquire, release, tagchecked);

value = X[s, datasize];
if n == 31 then
    CheckSPAlignment();
    address = SP[];
else
    address = X[n, 64];

bits(datasize) comparevalue = bits(datasize) UNKNOWN;    // Irrelevant when not executing CAS
data = MemAtomic(address, comparevalue, value, accdesc);

if t != 31 then
    X[t, regsize] = ZeroExtend(data, regsize);