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 ) .
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 |
constant n = UInt(Rn); constant write_spsr = (R == '1'); if n == 15 then UNPREDICTABLE; constant SYSm = M:M1;
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) |
constant n = UInt(Rn); constant write_spsr = (R == '1'); // Armv8-A removes UNPREDICTABLE for R13 if n == 15 then UNPREDICTABLE; constant SYSm = M:M1;
For more information about the constrained unpredictable behavior of this instruction, see Architectural Constraints on UNPREDICTABLE behaviors.
<c> |
<q> |
<Rn> |
Is the general-purpose source register, encoded in the "Rn" field. |
if ConditionPassed() then EncodingSpecificOperations(); if PSTATE.EL == EL0 then UNPREDICTABLE; else constant mode = PSTATE.M; if write_spsr then SPSRaccessValid(SYSm, mode); // Check for UNPREDICTABLE cases case SYSm of when '01110' SPSR_fiq<31:0> = R[n]; when '10000' SPSR_irq<31:0> = R[n]; when '10010' SPSR_svc<31:0> = R[n]; when '10100' SPSR_abt<31:0> = R[n]; when '10110' SPSR_und<31:0> = R[n]; when '11100' if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap(); SPSR_mon<31:0> = R[n]; when '11110' SPSR_hyp<31:0> = R[n]; else BankedRegisterAccessValid(SYSm, mode); // Check for UNPREDICTABLE cases case SYSm of when '00xxx' // Access the User mode registers constant m = UInt(SYSm<2:0>) + 8; Rmode[m,M32_User] = R[n]; when '01xxx' // Access the FIQ mode registers constant m = UInt(SYSm<2:0>) + 8; Rmode[m,M32_FIQ] = R[n]; when '1000x' // Access the IRQ mode registers constant 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 constant 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 constant 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 constant 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(); constant 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];
If PSTATE.EL == EL0, then one of the following behaviors must occur:
Internal version only: isa v01_32, pseudocode v2024-12_rel ; Build timestamp: 2024-12-16T10:54
Copyright © 2010-2024 Arm Limited or its affiliates. All rights reserved. This document is Non-Confidential.