casp
Compare and Swap Pair
Atomic CAS of a pair of registers (128-bit or 64-bit pair).
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
Encoding
Operands
-
Ws
Cmp 1 -
Wt
Swap 1 -
Xn
First source / base 64-bit integer register
Related
More in LSE (Atomics)
Reference
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>;