17.5.1 Context Save on Interrupt
The standard calling convention for C/C++ functions will already preserve
zero
, s0-s7
, gp
,
sp
, and fp
. k0
and
k1
are used by the compiler to access and preserve non-GPR context,
but are always accessed atomically (that is, in sequences with global interrupts
disabled), so they need not be preserved actively. A handler function will actively
preserve the a0-a3
, t0-t9
, v0
,
v1
and ra
registers in addition to the standard
registers.
An interrupt handler function will also actively save processor status registers that are
utilized by the handler function. Specifically, the EPC
,
SR
, hi
and lo
registers are
preserved as context. All available DSP accumulators are preserved as necessary.
In addition, if a DSP accumulator register is preserved, the DSP Control register is also preserved.
Handler functions may use a shadow register set to preserve the General Purpose
Registers, enabling lower latency entry into the application code of the handler
function. On some devices, the shadow register set is assigned to an interrupt priority
level (IPL) using the device Configuration bit settings (for example, #pragma
config FSRSSEL=PRIORITY_6
). While on other devices, the shadow register set
may be hard wired to IPL7. Consult the target device’s data sheet for more information
on the shadow register set.
By default, the compiler saves the Floating-point Unit (FPU) general registers and the
FCSR register on the stack as required for interrupt()
attributed
functions. This includes functions that use the __ISR(vector,priority)
macro. As always, to minimize the required context saving for an ISR, avoid making
calling functions from within the ISR so that the compiler generates code for only the
registers used within the ISR.
no_fpu
function attribute can be used to suppress context saving of
the FPU register. For
example:void __attribute__((interrupt(IPL7SRS),vector(_CORE_TIMER_VECTOR),no_fpu)) ct_isr(void)
{
foo();
}
It also causes the compiler to disable the FPU in the ISR prologue, such
that any use of the FPU from within the ISR context would result in a general exception.
This means that any higher-priority ISR interrupting an ISR using the
no_fpu
attribute must re-enable the FPU if floating-point
operations are required.