1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00
2014-11-20 17:25:27 +03:00

133 lines
3.2 KiB
ArmAsm

/////////////////////////////////////////////////////////////////////////////
//
// cont.S: continuations support for Xtensa call0 ABI
// Copyright (c) Ivan Grokhotkov 2014
//
// This file is licensed under MIT license
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
/////////////////////////////////////////////////////////////////////////////
.text
.align 4
.literal_position
.global cont_yield
.type cont_yield, @function
cont_yield:
/* a1: sp */
/* a2: void* cont_ctx */
/* adjust stack and save registers */
addi a1, a1, -24
s32i a12, a1, 0
s32i a13, a1, 4
s32i a14, a1, 8
s32i a15, a1, 12
s32i a0, a1, 16
s32i a2, a1, 20
/* &cont_continue -> cont_ctx.pc_yield */
movi a3, cont_continue
s32i a3, a2, 8
/* sp -> cont_ctx.sp_yield */
s32i a1, a2, 12
/* a0 <- cont_ctx.pc_ret */
l32i a0, a2, 0
/* sp <- cont_ctx.sp_ret */
l32i a1, a2, 4
jx a0
cont_continue:
l32i a12, a1, 0
l32i a13, a1, 4
l32i a14, a1, 8
l32i a15, a1, 12
l32i a0, a1, 16
l32i a2, a1, 20
addi a1, a1, 24
ret
.size cont_yield, . - cont_yield
////////////////////////////////////////////////////
.text
.align 4
.literal_position
.global cont_run
.type cont_run, @function
cont_run:
/* a1: sp */
/* a2: void* cont_ctx */
/* a3: void (*pfn) */
/* adjust stack and save registers */
addi a1, a1, -20
s32i a12, a1, 0
s32i a13, a1, 4
s32i a14, a1, 8
s32i a15, a1, 12
s32i a0, a1, 16
/* cont_ret -> a4 -> cont_ctx.pc_ret*/
movi a4, cont_ret
s32i a4, a2, 0
/* sp -> cont_ctx.sp_ret */
s32i a1, a2, 4
/* if cont_ctx.pc_yield != 0, goto cont_resume */
l32i a4, a2, 8
bnez a4, cont_resume
/* else */
/* set new stack*/
l32i a1, a2, 16;
/* goto pfn */
movi a0, cont_norm
jx a3
cont_resume:
/* a1 <- cont_ctx.sp_yield */
l32i a1, a2, 12
/* reset yield flag, 0 -> cont_ctx.pc_yield */
movi a3, 0
s32i a3, a2, 8
/* jump to saved cont_ctx.pc_yield */
movi a0, cont_ret
jx a4
cont_norm:
/* calculate pointer to cont_ctx.struct_start from sp */
l32i a2, a1, 8
/* sp <- cont_ctx.sp_ret */
l32i a1, a2, 4
cont_ret:
/* restore registers */
l32i a12, a1, 0
l32i a13, a1, 4
l32i a14, a1, 8
l32i a15, a1, 12
l32i a0, a1, 16
/* adjust stack and return */
addi a1, a1, 20
ret
.size cont_run, . - cont_run