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).

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
31
1
30
0010000
29:23
0
22
1
21
Rs
20:16
0
15
11111
14:10
Rn
9:5
Rt
4:0
 
Format Atomic
Opcode 0x48207C00
Extension LSE (Atomics)

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