The ARM Program Status Registers (PSRs) are special purpose 32-bit registers that control and reflect the state of the processor. The PSRs allow the operating system to quickly determine the current state of the processor, and allow low-level code to efficiently modify the execution environment. There are five PSRs – Current Program Status Register (CPSR), Saved Program Status Registers (SPSRs), Exception Link Registers (ELRs), Special Purpose Registers (SPRs) and Extended Program Status Registers (EPSRs). Each PSR has a specific role in controlling and monitoring program execution.
CPSR – Current Program Status Register
The 32-bit Current Program Status Register (CPSR) contains condition code flags, interrupt disable bits, execution state bits, and other status and control information. The control bits change frequently to reflect the state of the processor during program execution. The CPSR can be read with the MRS instruction and written using the MSR instruction. The CPSR is used for:
- Storing results of arithmetic operations (condition code flags)
- Masking interrupts
- Determining processor mode
- Determining instruction set state – ARM or Thumb
- Enabling/disabling fast interrupt requests
The CPSR register contains the following major bit fields:
- 31 – Conditional execution flags (N, Z, C, V)
- 30 – Overflow flag (Q)
- 29-28 – Carry/zero/overflow/saturation flags (GE)
- 27 – Java mode bit (J)
- 26-25 – Software interrupt bits (IT)
- 24 – Undefined instruction bit (T)
- 23-20 – Conditional execution bits (M)
- 19 – Data Endianness bit (E)
- 18 – Register Bank Select (R)
- 17 – Exception State (A)
- 16-10 – Exception return offset (I)
- 9 – Interrupt disable bit (F)
- 8-7 – Fast Interrupt bits (FIQ)
- 6 – Thumb state bit (T)
- 5-0 – Processor mode bits (M)
The conditional execution flags (N, Z, C, V) are updated based on the result of arithmetic and logical instructions. They can be tested to conditionally execute instructions without branching. For example, an ADD instruction might set the Z bit if the result is zero. A later BEQ instruction would branch if Z=1.
The overflow (Q), carry/zero/overflow/saturation (GE) and undefined instruction (T) bits are also used to indicate arithmetic status. The software interrupt (IT) bits indicate the number of IT (if-then) instructions pending. The endianness (E) bit controls byte ordering for data accesses. The register bank (R) bit selects between register banks for FIQ mode. The exception state (A) bit shows the level of current access – user (A=0) or privileged (A=1).
The interrupt disable (F) bit masks IRQ interrupts when set. The fast interrupt bits (FIQ) disable/enable FIQ interrupts. The Thumb state bit (T) indicates execution in Thumb (T=1) or ARM (T=0) instruction set state. The processor mode bits (M) determine the current operating processor mode – user, FIQ, supervisor, etc.
By reading the CPSR, the operating system can quickly determine the current processor state, interrupt levels, arithmetic status, execution mode, etc. This allows efficient handling of exceptions and interrupts. By modifying the CPSR, privileged code can mask interrupts, switch processor modes, change stack pointers, and modify the execution environment.
SPSRs – Saved Program Status Registers
The Saved Program Status Registers (SPSRs) save the CPSR contents on an exception entry. There are separate SPSR registers for each exception mode – SPSR_fiq, SPSR_irq, SPSR_und, SPSR_abt, SPSR_svc. When an exception occurs, the CPSR is copied to the SPSR for that exception mode before the exception handler is executed. The SPSR can then be copied back to the CPSR to efficiently return to the pre-exception state. The SPSRs provide:
- Saving processor state on exceptions
- Restoring pre-exception state on exception return
- Accessing pre-exception status in exception handlers
When an exception occurs:
- CPSR -> SPSR[CurrentMode]
- Change to HandlerMode, set LR to return address
- Execute handler code using HandlerMode CPSR
- SPSR[CurrentMode] -> CPSR to return to pre-exception state
This avoids corrupting the CPSR during exception processing. The SPSRs allow the handler to examine the CPSR contents at exception entry, while keeping the handlers independent of the pre-exception processor state.
ELRs – Exception Link Registers
The Exception Link Registers (ELRs) save the return address when an exception occurs. There is one ELR for each exception mode. When an exception is taken the ELR is set to the address of the next instruction that would have executed (the return address). The ELRs allow the exception handler to return to the correct instruction after handling the exception. The ELR provides:
- Saving return address on exception entry
- Restarting the interrupted instruction stream after handling exception
On exception entry:
- Save return address to ELR[CurrentMode]
- Change to HandlerMode and jump to handler
- To return, branch to ELR[CurrentMode]
This allows correct return to the interrupted program flow after the handler runs. The ELRs are banked per exception mode to keep each handler independent. The LR register is used to hold the ELR value within the handler code.
SPRs – Special Purpose Registers
The Special Purpose Registers (SPRs) provide extra control, status and ID registers for specific purposes. These include registers for:
- System control
- Memory protection and access control
- Cache control
- TLB control
- Processor configuration and status information
- Implementation and revision details
- Processor ID number
- Cache prefetch/branch prediction control
- Tightly-coupled memory control
The SPRs allow system code to efficiently control and interrogate the processor capabilities. By modifying SPRs, the operating system can enable/disable caching, protect memory regions, configure power-down modes, etc. By reading SPRs, code can determine cache sizes, processor variants, coherency support, etc. SPRs are accessed using the MRC and MCR instructions.
Common SPRs include:
- CP15 – system control registers
- CP14 – trace registers
- CP13 – context ID registers
- CP12 – vectored interrupt controller
- CP11 – DSP extensions
- CP10 – memory protections, cache ops, TLB control
- CP9 – cache lockdown, TCM control
- CP8 – TLB lockdown
- CP7 – cache and TLB ops, memory bypass
- CP6 – not used
- CP5 – memory protection unit
- CP4 – not used
- CP3 – not used
- CP2 – not used
- CP1 – floating point (VFP)
- CP0 – ID registers, cache type, TCM status, etc
The CP15 registers are the main system control registers. CP0 contains key ID and implementation details. Specific SPRs are designated using an OPCode and CRn/CRm/Op2 encoding.
EPSRs – Extended Program Status Registers
The Extended Program Status Registers (EPSRs) provide additional architectural status bits introduced in the ARMv6 architecture and above. This includes new state bits for Java, saturation handling, conditional execution etc. The new EPSR state is split across:
- Extended CPSR (CPSR.EXT) – accessed using MRS/MSR instructions
- Extended SPSRs (SPSR.EXT) – banked per mode
The EPSR registers provide:
- Expanded conditional execution modes
- Java/Jazelle state control
- Saturation arithmetic overflow handling
- Enabling the ThumbEE subset instructions
The new conditional execution modes (M bits) in the CPSR.EXT allow if-then (IT) blocks up to four instructions. The IT bits (J and T) indicate the number of IT instructions pending. The Java mode bit (J) enables Jazelle Java bytecode execution. The saturation handling (Q/GE) bits manage saturated arithmetic overflow.
The EPSRs allow compatible expansion of the PSR state bits in newer architectures while keeping backward compatibility with previous processor modes. Extending the PSRs while maintaining their original form and function allows inheriting existing operating systems and software.
PSR Access Instructions
The PSRs are accessed using the MRS and MSR instructions:
- MRS – Copy PSR to general purpose register
- MSR – Copy general purpose register to PSR
For example: MRS R0, CPSR ;R0 = Current CPSR state MSR CPSR_c, R0 ;CPSR = R0 (only change control bits)
The MRS/MSR instructions can access the CPSR, SPSRs and EPSRs. Access to SPSRs is banked by processor mode. Access to some CPSR/EPSR fields may be privileged or read-only. Conditional execution bits are always read-only.
Common PSR operations:
- Read CPSR – MRS R0, CPSR
- Write CPSR – MSR CPSR_fx, R0
- Disable interrupts – MSR CPSR_c, #0xC0
- Change to SVC mode – MSR CPSR_c, #0x13
- Return from exception – MSR SPSR_xx, CPSR
Care must be taken when writing the PSRs to avoid accidentally changing privileged bits or enabling unintended behavior. Bitmasking is often used to only modify certain fields.
PSR Roles in ARM Architecture
The PSRs play key roles in the ARM architecture and processors:
- Processor state control – The PSRs contain mode bits, interrupt enables, execution environment details etc. necessary for managing processor state.
- Conditional execution – Flag bits like N, Z, C, V allow conditional execution without branches.
- Exception handling – The SPSR and ELR registers are banked per mode to save context and return addresses.
- System configuration – SPRs control caches, MMUs, write buffers, power modes etc.
- Identification – ID registers provide architecture version, feature configuration etc.
- Operating system management – PSR access allows managing exceptions and interrupts in the OS kernel.
- Context switching – The PSRs maintain process/task state across context switches.
PSR operations are essential for low-level OS coding, exception handlers, context switching, multithreading, embedded control, and any privileged system code. PSR access allows efficient control of the CPU state and execution environment.
Typical PSR Uses
Common uses of the ARM PSRs include:
- Exception handling – SPSR and ELR save state on exceptions for the handler.
- Interrupt control – CPSR bits mask interrupts, CPSR saved/restored around handlers.
- Mode switching – Changing CPSR switches CPU into new mode with separate stack pointer.
- Flags testing – N, Z, C, V status flags support conditional code execution.
- Processor configuration – CP15/CP0 SPRs configure caches, MMUs, write buffering, etc.
- Debug/trace support – Various SPRs used for debug, trace, profiling.
- Operating system – PSR handling required in OS kernel for syscalls, preemption.
- Context switching – CPSR/SPSR saved/restored on context switches for new thread.
By utilizing the PSR mechanisms, ARM-based operating systems can efficiently manage interrupts, memory protection, processor modes, execution privilege and thread context switches required for effective multitasking.
PSR Handling Guidelines
Guidelines for working with ARM Program Status Registers:
- Use MRS/MSR instructions to safely read/write PSR contents.
- Modify only intended fields – use masks or clear bits when writing PSRs.
- Store CPSR to SPSR on exception entry, restore on exception return.
- Load ELR with return address and branch to handler on exception.
- Load LR from ELR within handler, return via LR to restart program flow.
- Use banked SPSR/ELR registers for nested exceptions.
- Resume pre-exception CPSR state by copying SPSR back to CPSR.
- Use CPSR mode bits and interrupt flags for OS context switches.
- Employ SPRs to configure caches, MMUs, write buffering, etc.
- Utilize CP15 to control caches, TLBs, memory regions and access permissions.
- Set N, Z, C, V bits on arithmetic operations, test conditionally.
- Consider security – limit PSR access, don’t leak data in registers.
Proper PSR usage is key to exception handling, multitasking OS design, and low-level system programming on ARM processors. Mastering the PSRs allows leverage of the ARM architecture’s performance and efficiency benefits.
The ARM Program Status Registers provide indispensable control, status and configuration functions necessary for exception processing, operating system management, and low-level system coding on ARM processors. The PSR mechanisms permeate ARM architecture and underpin effective system-level software.
The CPSR holds master processor state. The SPSRs and ELRs save context for exception handlers. SPRs enable system configuration and monitoring. EPSRs expand the PSR capabilities in newer architecture versions. Together, the PSR facilities allow robust interrupt handling, multitasking, privilege management, task switching, and control of the processor execution environment critical for exploiting ARM’s capabilities.
Mastering ARM’s PSR architecture is key for OS, driver and embedded developers. Proper handling of the CPSR, SPSR, ELR, SPR and EPSR registers enables crafting high performance exception handlers, kernels, device drivers and low-level code leveraging the ARM processor’s features and strengths. With a grasp of the PSR mechanisms, developers can fully utilize the speed, power efficiency and versatility of the ARM