assemblyarmarm64osdevstack-pointer

Does a write to SP on ARMv8 also write to SP_ELx?


I have been attempting to read through the ARM manual to gain an understanding of how ARM works architecturally. I know that there is a system register for SP at each EL, like SP_EL0, SP_EL1, etc. I also know that there is an SPSel bit in PSTATE that selects if on an EL change, it takes the stack pointer from SP_EL0 or SP_ELx. My question is, however, is SP architecturally mapped to the appropriate SP_ELx register or is SP_ELx copied into SP on an EL change? In other words, if say I write to SP, do I also write to SP_ELx?

I attempted to read the manual on this, but it seemed fairly ambiguous and could have been interpreted either way.


Solution

  • Using version K.a of the manual:

    On page B1-182, under B1.2.3:

    The SP[] accessors have no parameters and are used to read or write the currently selected 64-bit stack pointer at the current Exception level.

    And clicking on SP[] gets us to page J1-13867 where we can see the pseudocode for aarch64/functions/registers/SP:

    // SP[] - assignment form
    // ======================
    // Write to stack pointer from a 64-bit value.
    
    SP[] = bits(64) value
        if PSTATE.SP == '0' then
            SP_EL0 = value;
        else
            case PSTATE.EL of
                when EL0 SP_EL0 = value;
                when EL1 SP_EL1 = value;
                when EL2 SP_EL2 = value;
                when EL3 SP_EL3 = value;
        return;
    
    // SP[] - non-assignment form
    // ==========================
    // Read stack pointer with slice of 64 bits.
    
    bits(64) SP[]
        if PSTATE.SP == '0' then
            return SP_EL0;
        else
            case PSTATE.EL of
                when EL0 return SP_EL0;
                when EL1 return SP_EL1;
                when EL2 return SP_EL2;
                when EL3 return SP_EL3;
    

    So yes, SP is always mapped to one of the SP_ELn registers.