MSR (Banked register)
Move to Banked or Special register from general-purpose register moves the value of a general-purpose register to the Banked general-purpose register or Saved Program Status Registers (SPSRs) of the specified mode, or to ELR_hyp.
MSR (Banked register) is unpredictable if executed in User mode.
When EL3 is using AArch64, if an MSR (Banked register) instruction that is executed in a Secure EL1 mode would access SPSR_mon, SP_mon, or LR_mon, it is trapped to EL3.
The effect of using an MSR (Banked register) instruction with a register argument that is not valid for the current mode is unpredictable. For more information see Usage restrictions on the Banked register transfer instructions.
It has encodings from the following instruction sets: A32 ( A1 ) and T32 ( T1 ) .
A1
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
!= 1111 | 0 | 0 | 0 | 1 | 0 | R | 1 | 0 | M1 | (1) | (1) | (1) | (1) | (0) | (0) | 1 | M | 0 | 0 | 0 | 0 | Rn | |||||||||
cond |
A1
MSR{<c>}{<q>} <banked_reg>, <Rn>
n = UInt(Rn); write_spsr = (R == '1'); if n == 15 then UNPREDICTABLE; SYSm = M:M1;
T1
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | R | Rn | 1 | 0 | (0) | 0 | M1 | (0) | (0) | 1 | M | (0) | (0) | (0) | (0) |
T1
MSR{<c>}{<q>} <banked_reg>, <Rn>
n = UInt(Rn); write_spsr = (R == '1'); if n == 15 then UNPREDICTABLE; // Armv8-A removes UNPREDICTABLE for R13 SYSm = M:M1;
For more information about the constrained unpredictable behavior of this instruction, see Architectural Constraints on UNPREDICTABLE behaviors.
Assembler Symbols
<c> |
<q> |
<Rn> |
Is the general-purpose source register, encoded in the "Rn" field. |
Operation
if ConditionPassed() then EncodingSpecificOperations(); if PSTATE.EL == EL0 then UNPREDICTABLE; else mode = PSTATE.M; if write_spsr then SPSRaccessValid(SYSm, mode); // Check for UNPREDICTABLE cases case SYSm of when '01110' SPSR_fiq = R[n]; when '10000' SPSR_irq = R[n]; when '10010' SPSR_svc = R[n]; when '10100' SPSR_abt = R[n]; when '10110' SPSR_und = R[n]; when '11100' if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); SPSR_mon = R[n]; when '11110' SPSR_hyp = R[n]; else BankedRegisterAccessValid(SYSm, mode); // Check for UNPREDICTABLE cases case SYSm of when '00xxx' // Access the User mode registers m = UInt(SYSm<2:0>) + 8; Rmode[m,M32_User] = R[n]; when '01xxx' // Access the FIQ mode registers m = UInt(SYSm<2:0>) + 8; Rmode[m,M32_FIQ] = R[n]; when '1000x' // Access the IRQ mode registers m = 14 - UInt(SYSm<0>); // LR when SYSm<0> == 0, otherwise SP Rmode[m,M32_IRQ] = R[n]; when '1001x' // Access the Supervisor mode registers m = 14 - UInt(SYSm<0>); // LR when SYSm<0> == 0, otherwise SP Rmode[m,M32_Svc] = R[n]; when '1010x' // Access the Abort mode registers m = 14 - UInt(SYSm<0>); // LR when SYSm<0> == 0, otherwise SP Rmode[m,M32_Abort] = R[n]; when '1011x' // Access the Undefined mode registers m = 14 - UInt(SYSm<0>); // LR when SYSm<0> == 0, otherwise SP Rmode[m,M32_Undef] = R[n]; when '1110x' // Access Monitor registers if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); m = 14 - UInt(SYSm<0>); // LR when SYSm<0> == 0, otherwise SP Rmode[m,M32_Monitor] = R[n]; when '11110' // Access ELR_hyp register ELR_hyp = R[n]; when '11111' // Access SP_hyp register Rmode[13,M32_Hyp] = R[n];
CONSTRAINED UNPREDICTABLE behavior
If PSTATE.EL == EL0, then one of the following behaviors must occur:
- The instruction is undefined.
- The instruction executes as NOP.