casp

Compare and Swap Pair

CASP <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]

Atomic CAS of a pair of registers (128-bit or 64-bit pair).

Details

Atomic compare and swap of a register pair (32-bit pair: 64 bits total, or 64-bit pair: 128 bits total depending on size variant). Compares the pair (Ws, W(s+1)) with memory; if equal, stores (Wt, W(t+1)) and loads old values back; otherwise loads the memory values. This AArch64-only LSE instruction requires even-numbered registers and provides full sequential consistency. Condition flags are not affected. Register numbers must be even and consecutive.

Pseudocode Operation

address ← Xn; old_value_pair ← [address]; if (Ws, W(s+1)) == old_value_pair then [address] ← (Wt, W(t+1)); (Ws, W(s+1)) ← old_value_pair; else (Ws, W(s+1)) ← old_value_pair;

Example

CASP w6, W(s+1), w3, W(t+1), [x1]

Encoding

Binary Layout
0
1
0010000
0
1
Rs
0
11111
Rn
Rt
 
Format Atomic
Opcode 0x48207C00
Extension LSE (Atomics)

Operands

  • Ws
    Cmp 1
  • Wt
    Swap 1
  • Xn
    First source / base 64-bit integer register

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x08207C00 CASP <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{, #0}] A64 0 | 0 | 0010000 | 0 | 1 | Rs | 0 | 11111 | Rn | Rt
0x48207C00 CASP <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{, #0}] A64 0 | 1 | 0010000 | 0 | 1 | Rs | 0 | 11111 | Rn | Rt

Description

Compare and Swap Pair of words or doublewords in memory reads a pair of 32-bit words or 64-bit doublewords from memory, and compares them against the values held in the first pair of registers. If the comparison is equal, the values in the second pair of registers are written to memory. If the writes are performed, the reads and writes occur atomically such that no other modification of the memory location can take place between the reads and writes. For more information about memory ordering semantics, see Load-Acquire, Store-Release. For information about memory accesses, see Load/Store addressing modes. The architecture permits that the data read clears any exclusive monitors associated with that location, even if the compare subsequently fails. If the instruction generates a synchronous Data Abort, the registers which are compared and loaded, that is <Ws> and <W(s+1)>, or <Xs> and <X(s+1)>, are restored to the values held in the registers before the instruction was executed.

Operation

bits(64) address;
bits(2*datasize) comparevalue;
bits(2*datasize) newvalue;
bits(2*datasize) data;

bits(datasize) s1 = X[s, datasize];
bits(datasize) s2 = X[s+1, datasize];
bits(datasize) t1 = X[t, datasize];
bits(datasize) t2 = X[t+1, datasize];

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

comparevalue = if BigEndian(accdesc.acctype) then s1:s2 else s2:s1;
newvalue = if BigEndian(accdesc.acctype) then t1:t2 else t2:t1;
if n == 31 then
    CheckSPAlignment();
    address = SP[];
else
    address = X[n, 64];

data = MemAtomic(address, comparevalue, newvalue, accdesc);

if BigEndian(accdesc.acctype) then
    X[s, datasize] = data<2*datasize-1:datasize>;
    X[s+1, datasize] = data<datasize-1:0>;
else
    X[s, datasize] = data<datasize-1:0>;
    X[s+1, datasize] = data<2*datasize-1:datasize>;