SWPH, SWPAH, SWPALH, SWPLH

Swap halfword in memory

This instruction atomically loads a 16-bit halfword 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 WZR, SWPAH and SWPALH load from memory with acquire semantics.
  • SWPLH and SWPALH store to memory with release semantics.
  • SWPH 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.

    Encoding: Integer

    Variants: FEAT_LSE (ARMv8.1)

    313029282726252423222120191817161514131211109876543210
    011110001100000
    sizeVRARRso3opcRnRt

    SWPH (A == 0 && R == 0)

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

    SWPAH (A == 1 && R == 0)

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

    SWPALH (A == 1 && R == 1)

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

    SWPLH (A == 0 && R == 1)

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

    Decoding algorithm

    if !IsFeatureImplemented(FEAT_LSE) then EndOfDecode(Decode_UNDEF);
    
    constant integer s = UInt(Rs);
    constant integer t = UInt(Rt);
    constant integer n = UInt(Rn);
    
    constant boolean acquire = A == '1' && Rt != '11111';
    constant boolean release = R == '1';
    constant boolean tagchecked = n != 31;

    Operation

    bits(64) address;
    bits(16) data;
    bits(16) store_value;
    
    constant boolean privileged = PSTATE.EL != EL0;
    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, 16];
    
    constant bits(16) comparevalue = bits(16) UNKNOWN; // Irrelevant when not executing CAS
    data = MemAtomic(address, comparevalue, store_value, accdesc);
    
    X[t, 32] = ZeroExtend(data, 32);

    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.