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