Document need (or no need) to save & restore registers in asm_xtensa functions
I am discovering micropython for the esp8266 and am absolutely astonished at what is possible already!
One thing I am struggling with is the machine.asm_xtensa decorator which so far is undocumented.
Most things can be understood by analogy to the documented machine.asm_thumb decorator, but one thing absolutely stumps me:
Does one have to save and restore any registers one modifies in an asm_xtensa function? If so, are there any convenient solutions for doing so, or does one have to all the stack pointer algebra oneself? The asm_thumb instruction push({...}) looks great!
ARM NLR with gcc 9 should save FP registers
ARM CPUs with hardware floating point (VFP) have additional registers, s0-s31 (also labelled by d0-d15). Of these, s16-s31 are callee save and so in principle should be saved and restored by the NLR code.
Currently they are not saved. This has not been an issue so far because gcc (up to v8) only uses these s16-s31 registers when doing floating point calculations and MicroPython doesn't call into NLR-sensitive code during a floating point calculation (eg no NLR push/pop during sin(x) or during binary ops between two complex numbers). (At least this has never been observed, no problems related to this have been reported so far.)
But gcc 9 uses more aggressive optimisation and may use s16-s31 to save normal integer values instead of using the stack, and these values may be corrupted by NLR not restoring them correctly. Compiling stm32 with gcc 9.1.0 does lead to such issues (eg test suit run on PYBv1.0 fails on multiple tests).
The workaround for now would be to only use gcc 8.x or below.
Probably the only proper fix is to save registers s16-s31 (or maybe just s16-s23 since gcc 9 doesn't seem to use registers above these) in the NLR context.