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
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>;