SWPT, SWPTA, SWPTAL, SWPTL

Swap unprivileged

This instruction atomically loads a 32-bit word or 64-bit doubleword from a memory location, and stores the value held in a register back to the same memory location. The value initially loaded from memory is returned in the destination register.

  • If the destination register is not one of WZR or XZR, SWPTA and SWPTAL load from memory with acquire semantics.
  • SWPTL and SWPTAL store to memory with release semantics.
  • SWPT has neither acquire nor release semantics.
  • For more information about memory ordering semantics, see Load-Acquire, Store-Release.

    For information about addressing modes, see Load/Store addressing modes.

    Explicit Memory effects produced by the instruction behave as if the instruction was executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:

  • The instruction is executed at EL1.
  • The instruction is executed at EL2 when the Effective value of HCR_EL2.{E2H, TGE} is {1, 1}.
  • Otherwise, the Explicit Memory effects operate with the restrictions determined by the Exception level at which the instruction is executed.

    Encoding: Integer

    Variants: FEAT_LSUI (ARMv9.6)

    313029282726252423222120191817161514131211109876543210
    00110011100001
    szARRso3opcRnRt

    32-bit SWPT (sz == 0 && A == 0 && R == 0)

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

    32-bit SWPTA (sz == 0 && A == 1 && R == 0)

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

    32-bit SWPTAL (sz == 0 && A == 1 && R == 1)

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

    32-bit SWPTL (sz == 0 && A == 0 && R == 1)

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

    64-bit SWPT (sz == 1 && A == 0 && R == 0)

    SWPT <Xs>, <Xt>, [<Xn|SP>]

    64-bit SWPTA (sz == 1 && A == 1 && R == 0)

    SWPTA <Xs>, <Xt>, [<Xn|SP>]

    64-bit SWPTAL (sz == 1 && A == 1 && R == 1)

    SWPTAL <Xs>, <Xt>, [<Xn|SP>]

    64-bit SWPTL (sz == 1 && A == 0 && R == 1)

    SWPTL <Xs>, <Xt>, [<Xn|SP>]

    Decoding algorithm

    if !IsFeatureImplemented(FEAT_LSUI) then EndOfDecode(Decode_UNDEF);
    
    constant integer s = UInt(Rs);
    constant integer t = UInt(Rt);
    constant integer n = UInt(Rn);
    
    constant integer datasize = 32 << UInt(sz);
    constant integer regsize = if datasize == 64 then 64 else 32;
    constant boolean acquire = A == '1' && Rt != '11111';
    constant boolean release = R == '1';
    constant boolean tagchecked = n != 31;

    Operation

    bits(64) address;
    bits(datasize) data;
    bits(datasize) store_value;
    
    constant boolean privileged = AArch64.IsUnprivAccessPriv();
    constant AccessDescriptor accdesc = CreateAccDescAtomicOp(MemAtomicOp_SWP, acquire, release,
                                                              tagchecked, privileged);
    
    if n == 31 then
        CheckSPAlignment();
        address = SP[64];
    else
        address = X[n, 64];
    
    store_value = X[s, datasize];
    
    constant bits(datasize) comparevalue = bits(datasize) UNKNOWN; // Irrelevant when not executing CAS
    data = MemAtomic(address, comparevalue, store_value, accdesc);
    
    X[t, regsize] = ZeroExtend(data, regsize);

    Explanations

    <Ws>: Is the 32-bit name of the general-purpose register to be stored, encoded in the "Rs" field.
    <Wt>: Is the 32-bit name of the general-purpose register to be loaded, encoded in the "Rt" field.
    <Xn|SP>: Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.
    <Xs>: Is the 64-bit name of the general-purpose register to be stored, encoded in the "Rs" field.
    <Xt>: Is the 64-bit name of the general-purpose register to be loaded, encoded in the "Rt" field.