diff --git a/co_routine.cpp b/co_routine.cpp index 352ae7e..5236097 100644 --- a/co_routine.cpp +++ b/co_routine.cpp @@ -914,6 +914,12 @@ stCoRoutine_t *GetCurrThreadCo( ) typedef int (*poll_pfn_t)(struct pollfd fds[], nfds_t nfds, int timeout); + +#if defined(__aarch64__) +#pragma GCC push_options +#pragma GCC optimize ("O0") +#endif + int co_poll_inner( stCoEpoll_t *ctx,struct pollfd fds[], nfds_t nfds, int timeout, poll_pfn_t pollfunc) { if (timeout == 0) @@ -1027,6 +1033,10 @@ int co_poll_inner( stCoEpoll_t *ctx,struct pollfd fds[], nfds_t nfds, int timeou return iRaiseCnt; } +#if defined(__aarch64__) +#pragma GCC pop_options +#endif + int co_poll( stCoEpoll_t *ctx,struct pollfd fds[], nfds_t nfds, int timeout_ms ) { return co_poll_inner(ctx, fds, nfds, timeout_ms, NULL); diff --git a/coctx.cpp b/coctx.cpp index d5eeed1..e5e4f57 100644 --- a/coctx.cpp +++ b/coctx.cpp @@ -81,15 +81,38 @@ enum { kRSP = 13, }; -// 64 bit -extern "C" { -extern void coctx_swap(coctx_t*, coctx_t*) asm("coctx_swap"); +//------------- +// 64 bit arm +//low | regs[0]: x19 | +// | regs[1]: x20 | +// | regs[2]: x21 | +// | regs[3]: x22 | +// | regs[4]: x23 | +// | regs[5]: x24 | +// | regs[6]: x25 | +// | regs[7]: x26 | +// | regs[8]: x27 | +// | regs[9]: x28 | +// | regs[10]: x29| +// | regs[11]: x30|//ret func addr +// | regs[12]: sp | +//hig | regs[13]: x0 | + +enum { + kARG1 = 13, + kRETAddr_ARM64 = 11, + kSP_ARM64 = 12, }; -#if defined(__i386__) + int coctx_init(coctx_t* ctx) { memset(ctx, 0, sizeof(*ctx)); return 0; } +// 64 bit +extern "C" { +extern void coctx_swap(coctx_t*, coctx_t*) asm("coctx_swap"); +}; +#if defined(__i386__) int coctx_make(coctx_t* ctx, coctx_pfn_t pfn, const void* s, const void* s1) { // make room for coctx_param char* sp = ctx->ss_sp + ctx->ss_size - sizeof(coctx_param_t); @@ -124,9 +147,17 @@ int coctx_make(coctx_t* ctx, coctx_pfn_t pfn, const void* s, const void* s1) { return 0; } -int coctx_init(coctx_t* ctx) { - memset(ctx, 0, sizeof(*ctx)); - return 0; -} +#elif defined(__aarch64__) +int coctx_make(coctx_t* ctx, coctx_pfn_t pfn, const void* s, const void* s1) { + char* sp = ctx->ss_sp + ctx->ss_size - sizeof(void*); + sp = (char*)((unsigned long)sp & -16LL); + memset(ctx->regs, 0, sizeof(ctx->regs)); + + ctx->regs[kSP_ARM64] = sp; + ctx->regs[kRETAddr_ARM64] = (char*)pfn; + + ctx->regs[kARG1] = (char*)s; + return 0; +} #endif diff --git a/coctx_swap.S b/coctx_swap.S index 0e4ce1c..37282b2 100644 --- a/coctx_swap.S +++ b/coctx_swap.S @@ -80,4 +80,30 @@ coctx_swap: movq 64(%rsi), %rsi ret + +#elif defined(__aarch64__) + mov x3, sp + + stp x19, x20, [x0] + stp x21, x22, [x0, #0x10] + stp x23, x24, [x0, #0x20] + stp x25, x26, [x0, #0x30] + stp x27, x28, [x0, #0x40] + stp x29, x30, [x0, #0x50] + stp x3, x0, [x0, #0x60] + + ldp x19, x20, [x1] + ldp x21, x22, [x1,#0x10] + ldp x23, x24, [x1,#0x20] + ldp x25, x26, [x1,#0x30] + ldp x27, x28, [x1,#0x40] + ldp x29, x30, [x1,#0x50] + ldp x3, x0, [x1,#0x60] + + mov sp, x3 + ret +coctx_get_sp: + mov x0 ,sp + ret + #endif