mrs

Move from Special Register (Banked)

MRS <Rd>, <banked_reg>

Reads a banked register into a general-purpose register.

Details

Reads the value of a banked system register into a general-purpose register. This instruction is available only in privileged modes (not User mode) and performs a mode-aware read from the specified banked register. No condition flags are affected by this instruction.

Pseudocode Operation

Rd ← BankedReg[sysm]

Example

MRS r0, banked_reg

Encoding

Binary Layout
cond
00010
R
0
0
M1
Rd
0
0
1
M
0000
0000
 
Format System
Opcode 0x01000200
Extension A32 (System)

Operands

  • Rd
    Destination general-purpose register
  • banked_reg
    Banked

Reference (Arm AArch32 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x010F0000 MRS{<c>}{<q>} <Rd>, <spec_reg> A32 cond | 00010 | R | 0 | 0 | 1111 | Rd | 0 | 0 | 0 | 0 | 0000 | 0000
0xF3EF8000 MRS{<c>}{<q>} <Rd>, <spec_reg> T32 11110011111 | R | 1 | 1 | 1 | 1 | 10 | 0 | 0 | Rd | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
0x01000200 MRS{<c>}{<q>} <Rd>, <banked_reg> A32 cond | 00010 | R | 0 | 0 | M1 | Rd | 0 | 0 | 1 | M | 0000 | 0000
0xF3E08020 MRS{<c>}{<q>} <Rd>, <banked_reg> T32 11110011111 | R | M1 | 10 | 0 | 0 | Rd | 0 | 0 | 1 | M | 0 | 0 | 0 | 0

Description

Move to Register from Banked or Special register moves the value from the Banked general-purpose register or Saved Program Status Registers (SPSRs) of the specified mode, or the value of ELR_hyp, to a general-purpose register. MRS (Banked register) is unpredictable if executed in User mode. When EL3 is using AArch64, if an MRS (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 MRS (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.

Operation

if ConditionPassed() then
    EncodingSpecificOperations();
    if PSTATE.EL == EL0 then
        UNPREDICTABLE;
    else
        mode = PSTATE.M;
        if read_spsr then
            SPSRaccessValid(SYSm, mode);           // Check for UNPREDICTABLE cases
            case SYSm of
                when '01110'  R[d] = SPSR_fiq<31:0>;
                when '10000'  R[d] = SPSR_irq<31:0>;
                when '10010'  R[d] = SPSR_svc<31:0>;
                when '10100'  R[d] = SPSR_abt<31:0>;
                when '10110'  R[d] = SPSR_und<31:0>;
                when '11100'
                    if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap();
                    R[d] = SPSR_mon;
                when '11110'  R[d] = SPSR_hyp<31:0>;
        else
            integer m;
            BankedRegisterAccessValid(SYSm, mode); // Check for UNPREDICTABLE cases
            case SYSm of
                when '00xxx'                       // Access the User mode registers
                    m = UInt(SYSm<2:0>) + 8;
                    R[d] = Rmode[m,M32_User];
                when '01xxx'                       // Access the FIQ mode registers
                    m = UInt(SYSm<2:0>) + 8;
                    R[d] = Rmode[m,M32_FIQ];
                when '1000x'                       // Access the IRQ mode registers
                    m = 14 - UInt(SYSm<0>);        // LR when SYSm<0> == 0, otherwise SP
                    R[d] = Rmode[m,M32_IRQ];
                when '1001x'                       // Access the Supervisor mode registers
                    m = 14 - UInt(SYSm<0>);        // LR when SYSm<0> == 0, otherwise SP
                    R[d] = Rmode[m,M32_Svc];
                when '1010x'                       // Access the Abort mode registers
                    m = 14 - UInt(SYSm<0>);        // LR when SYSm<0> == 0, otherwise SP
                    R[d] = Rmode[m,M32_Abort];
                when '1011x'                       // Access the Undefined mode registers
                    m = 14 - UInt(SYSm<0>);        // LR when SYSm<0> == 0, otherwise SP
                    R[d] = Rmode[m,M32_Undef];
                when '1110x'                       // Access Monitor registers
                    if !ELUsingAArch32(EL3) then AArch64.MonitorModeTrap();
                    m = 14 - UInt(SYSm<0>);        // LR when SYSm<0> == 0, otherwise SP
                    R[d] = Rmode[m,M32_Monitor];
                when '11110'                       // Access ELR_hyp register
                    R[d] = ELR_hyp;
                when '11111'                       // Access SP_hyp register
                    R[d] = Rmode[13,M32_Hyp];