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!
Add push/pop asm_xtensa convenience functions
It would be nice if asm_xtensa were to provide push/pop convenience functions for saving/restoring registers.
In asm_thumb one can write very clean code (ignoring the wrong register names for illustration purposes):
@micropyhton.asm_thumb():
def foo():
push({a5, a6, a7, a8, a9, a10, a11})
# do your stuff
push({a5, a6, a7, a8, a9, a10, a11})
The same with asm_xtensa is a nightmare to write and easy to mess up:
@micropyhton.asm_thumb():
def foo():
# calculate stack pointer to make space for registers
# but: must be in multiples of 16!
addi(a1, a1, -32)
# store registers
s32i(a5, a1, 0)
s32i(a6, a1, 4)
s32i(a7, a1, 8)
s32i(a8, a1, 12)
s32i(a9, a1, 16)
s32i(a10, a1, 20)
s32i(a11, a1, 24)
# do your stuff
# restore registers
l32i(a5, a1, 0)
l32i(a6, a1, 4)
l32i(a7, a1, 8)
l32i(a8, a1, 12)
l32i(a9, a1, 16)
l32i(a10, a1, 20)
l32i(a11, a1, 24)
# move stack pointer back
addi(a1, a1, 32)
And here I am not even checking for stack underflow/overflow!