RISCOS Ltd RISCOS Ltd ------------------------------ TECHNICAL NOTE: USE OF MRS/MSR ------------------------------ Document: 20000110-003 Version: 1.00 (05 Oct 1999) MIB: Minor changes from ARM's FAQ Author(s): Matthew Bullock (matthew@riscos.com) The ARM 6/7 technical specs from ARM incorrectly describe the use of both the MSR and MRS instructions (used for reading and writing to the PSR). The following is an extract from the ARM FAQ available at MRS transfers the CPSR or the SPSR of the current mode to a general-purpose register. MSR transfers the value of a general-purpose register or immediate constant to the CPSR or the SPSR of the current mode. The status registers are split into four 8-bit fields that can be individually written: Control (c) bits 0-7 5 processor mode bits, I & F interrupt disable bits, and the T bit on ARMv4T. Extension (x) bits 8-15 Reserved for future use (unused in Arch 3, 4 & 4T) Status (s) bits 16-23 Reserved for future use (unused in Arch 3, 4 & 4T) Flags (f) bits 24-31 NZCV flags (28-31) and 4 bits (24-27) reserved for future use Bits that are reserved for future use should not be modified by current software. Typically, a read-modify-write strategy should be used to update the value of a status register to ensure future compatibility. However, in cases where the processor state is known in advance (e.g. on reset, following an interrupt, or some other exception), an immediate value may be written directly into the status registers, to change only specific bits (e.g. to change mode). Instruction Formats and Usage The ARM assembler (objasm) and the BASIC assembler both supports the full range of MRS and MSR instructions, in the form: MRS(cond) Rd, CPSR MRS(cond) Rd, SPSR MSR(cond) CPSR_fields, Rm MSR(cond) SPSR_fields, Rm MSR(cond) CPSR_fields, #immediate MSR(cond) SPSR_fields, #immediate where 'fields' can be any combination of "cxsf". Note that MSR CPSR_c, #immediate is a legitimate instruction (despite what is written in the ARM ARM), so a sequence of two instructions like: MOV r0, #0x1F MSR CPSR_c, r0 as commonly found in boot code, can be combined into one instruction, like: MSR CPSR_c, #0x1F ; go to System mode, IRQ & FIQ enabled This immediate form of MSR can actually be used with any of the field masks, but care must be taken that a read-modify-write strategy is followed so that currently unallocated bits are not affected. Otherwise the code could have distinctly different effect on future cores where such bits are allocated. When used with the flag bits, the immediate form is shielded from this as bits 27-24 can be considered to be read only. For MSR operations, we recommend that only the minimum number of fields are written, because some ARM implementations may need to take extra cycles to write specific fields; by not writing to fields which don't need changing reduces any such extra cycles to a minimum. For example, ARM9 needs more cycles than an ARM7 to execute an MSR when the CPSR control field is modified, to allow the changes to propagate through the pipeline correctly, so that register reads for the following instruction come from the correct banked registers. For example, an MRS/BIC/ORR/MSR sequence to change processor mode is best written with the last instruction being MSR CPSR_c, Rm, though any other set of fields that includes 'c' will also work. As another example, to restore a saved PSR value (where all fields need to be restored), you should use MSR SPSR_cxsf, Rm. ObjAsm allows other forms of the MSR instruction to modify the control field and flags field: cpsr or cpsr_all Control and flags field. cpsr_flg Flags field only. cpsr_ctl Control field only and similarly for SPSR. These forms are now deprecated, so should not be used. In most cases, you should simply modify your code to use '_c', '_f', '_cf' or '_cxsf' instead. -- Comment: MRS and MSR technote Part: 20000117-001