I compile the attached file with "bin/sdcc --std-sdcc99 -mpic16 -p18f4550 --fommit-frame-pointer --obanksel=1 --optimize-cmp --optimize-df test.c -I device/include/pic16" (version SDCC : pic16 2.9.7 #5703 (Feb 21 2010) (UNIX)), built from the source snapshot 5703, which was compiled but not installed (hence the "bin/" and "-I").
The problem is that, according to the listing file, the __shadowregs keyword is completely ignored. According to the documentation, this is because it must be placed before the __interrupt keyword, but there's no way to do that when using the SIGHANDLER macro.
Since the dispatch table macros make the interrupt handler itself contain a list of conditional GOTOs, only one interrupt can be handled per invocation of the ISR. The ISR itself does not do any saving and restoring of registers; instead, registers are saved and restored separately in each individual handler. The individual handler ends with RETFIE, which completely bypasses the ISR on the return path. Since the ISR itself never modifies any regs, using RETFIE versus RETFIE FAST in the ISR itself is irrelevant; there's nothing to restore. However, __shadowregs could omit the save-and-restore code for BSR/WREG/STATUS in the individual handlers and end them with RETFIE FAST instead of RETFIE; this would work perfectly, since the shadows would most recently have been saved by the hardware on entry to the ISR.
Not having read the source code, it seems the easiest way to solve this ought to be to allow __shadowregs to apply properly to a function whether it comes before or after __interrupt. I can't see any use for the current limitation, anyway!
Log in to post a comment.