I was thumbing through the FPU Primer (spraan9.pdf) and found the section 'Interrupt Context Save and Restore'. I then realized that I am performing context switches but not preserving the FPU registers during the context save and restore.
We have an in-house written task switcher that uses Timer 2 to switch between tasks. Several of these threads are using floating point calculations so I am very concerned.
In the spraam9.dpf document, there is a comment that says that the SAVE and RESTORE instructions should only be used within 'High Priority Interrupts'.
'RB must be saved if it is used in the interrupt and the FPU registers are copied to their shadow registers using the SAVE instruction. SAVE and RESTORE should only be used in high-priority interrupts.'
How do I know which interrupts are considered to be 'high' and 'low' priorities? I do not recall any documentation or chart that classifies interrupts sources as being catagorized as 'high' or 'low'. Can someone help clarify this?
Also, in the same document, it mentions a couple of pragmas that are used to identify your interrupts as 'high' and 'low' priority.
// Specify a High-Priority Interrupt:
#pragma INTERRUPT (function_name, HPI)
// Specify a Low-Priority Interrupt:
#pragma INTERRUPT (function_name, LPI)
Do I need to use these pragmas on all of my C interrupt routines so that the FPU state is properly saved and restored?
Here are the macros that I used to preserve and restore registers during a context save (does not include the FPU registers):
I$$SAVE .macro
;ASP
PUSH AR1H:AR0H ; Save remaining registers.
PUSH XAR2
PUSH XAR3
PUSH XAR4
PUSH XAR5
PUSH XAR6
PUSH XAR7
PUSH XT
PUSH RPC
.endm
I$$REST .macro
POP RPC
POP XT
POP XAR7
POP XAR6
POP XAR5
POP XAR4
POP XAR3
POP XAR2
POP AR1H:AR0H
;NASP
IRET
.endm
Here is the recommended context save and restore instructions:
High Priority Context save:
ASP ; Align stack
PUSH RB ; Save RB if used <-- New for FPU
PUSH AR1H:AR0H ; Save if used
PUSH XAR2
PUSH XAR3
PUSH XAR4
PUSH XAR5
PUSH XAR6
PUSH XAR7
PUSH XT
SPM 0 ; Set C28 modes
CLRC AMODE
CLRC PAGE0,OVM
SAVE RNDF32=1 ; FPU registers <--
High Priority Context restore:
RESTORE ; FPU registers ; <-- new for FPU
POP XT ; Restore registers
POP XAR7
POP XAR6
POP XAR5
POP XAR4
POP XAR3
POP XAR2
POP AR1H:AR0H
POP RB ; Restore RB ; <-- new for FPU
NASP ; Un-align stack
IRET ; Return