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
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];