Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for aarch64 #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions aco.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
void aco_runtime_test(void){
#ifdef __i386__
_Static_assert(sizeof(void*) == 4, "require 'sizeof(void*) == 4'");
#elif __x86_64__
#elif defined(__x86_64__) || defined(__aarch64__)
_Static_assert(sizeof(void*) == 8, "require 'sizeof(void*) == 8'");
_Static_assert(sizeof(__uint128_t) == 16, "require 'sizeof(__uint128_t) == 16'");
#else
Expand Down Expand Up @@ -171,7 +171,7 @@ static __thread aco_cofuncp_t aco_gtls_last_word_fp = aco_default_protector_last

#ifdef __i386__
static __thread void* aco_gtls_fpucw_mxcsr[2];
#elif __x86_64__
#elif defined(__x86_64__) || defined(__aarch64__)
static __thread void* aco_gtls_fpucw_mxcsr[1];
#else
#error "platform no support yet"
Expand Down Expand Up @@ -273,11 +273,16 @@ aco_share_stack_t* aco_share_stack_new2(size_t sz, char guard_page_enabled){
p->ptr, (void*)((uintptr_t)p->ptr + p->sz)
);
#endif
#if defined(__i386__) || defined(__x86_64__)
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
uintptr_t u_p = (uintptr_t)(p->sz - (sizeof(void*) << 1) + (uintptr_t)p->ptr);
u_p = (u_p >> 4) << 4;
p->align_highptr = (void*)u_p;
#ifdef __aarch64__
// aarch64 hardware-enforces 16 byte stack alignment
p->align_retptr = (void*)(u_p - 16);
#else
p->align_retptr = (void*)(u_p - sizeof(void*));
#endif
*((void**)(p->align_retptr)) = (void*)(aco_funcp_protector_asm);
assert(p->sz > (16 + (sizeof(void*) << 1) + sizeof(void*)));
p->align_limit = p->sz - 16 - (sizeof(void*) << 1);
Expand Down Expand Up @@ -331,6 +336,12 @@ aco_t* aco_create(
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
p->reg[ACO_REG_IDX_FPU] = aco_gtls_fpucw_mxcsr[0];
#endif
#elif __aarch64__
p->reg[ACO_REG_IDX_RETADDR] = (void*)fp;
p->reg[ACO_REG_IDX_SP] = p->share_stack->align_retptr;
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
p->reg[ACO_REG_IDX_FPU] = aco_gtls_fpucw_mxcsr[0];
#endif
#else
#error "platform no support yet"
#endif
Expand All @@ -343,7 +354,7 @@ aco_t* aco_create(
p->save_stack.ptr = malloc(save_stack_sz);
assertalloc_ptr(p->save_stack.ptr);
p->save_stack.sz = save_stack_sz;
#if defined(__i386__) || defined(__x86_64__)
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
p->save_stack.valid_sz = 0;
#else
#error "platform no support yet"
Expand All @@ -369,7 +380,7 @@ void aco_resume(aco_t* resume_co){
if(resume_co->share_stack->owner != NULL){
aco_t* owner_co = resume_co->share_stack->owner;
assert(owner_co->share_stack == resume_co->share_stack);
#if defined(__i386__) || defined(__x86_64__)
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
assert(
(
(uintptr_t)(owner_co->share_stack->align_retptr)
Expand Down Expand Up @@ -430,7 +441,7 @@ void aco_resume(aco_t* resume_co){
#endif
}
assert(resume_co->share_stack->owner == NULL);
#if defined(__i386__) || defined(__x86_64__)
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
assert(
resume_co->save_stack.valid_sz
<=
Expand Down
11 changes: 11 additions & 0 deletions aco.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ extern "C" {
#define ACO_REG_IDX_SP 5
#define ACO_REG_IDX_BP 7
#define ACO_REG_IDX_FPU 8
#elif __aarch64__
#define ACO_REG_IDX_RETADDR 13
#define ACO_REG_IDX_SP 14
#define ACO_REG_IDX_BP 12
#define ACO_REG_IDX_FPU 15
#else
#error "platform no support yet"
#endif
Expand Down Expand Up @@ -99,6 +104,12 @@ struct aco_s{
#else
void* reg[9];
#endif
#elif __aarch64__
#ifdef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
void* reg[15];
#else
void* reg[16];
#endif
#else
#error "platform no support yet"
#endif
Expand Down
54 changes: 54 additions & 0 deletions acosw.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#else
.type acosw, @function
#endif
#ifndef __aarch64__
.intel_syntax noprefix
#endif
acosw:
/*
extern void acosw(aco_t* from_co, aco_t* to_co);
Expand Down Expand Up @@ -118,6 +120,43 @@ acosw:
#endif
mov rsp,rcx
jmp rax
#elif __aarch64__
/*
0x00 --> 0xff
x16 x17 x19 ... x29 lr sp fpcr
0 8 10 ... 60 68 70 78
*/
// r0 - from_co | r1 - to_co
mov x2, lr
stp x16, x17, [x0, 0x00]
stp x19, x20, [x0, 0x10]
stp x21, x22, [x0, 0x20]
stp x23, x24, [x0, 0x30]
stp x25, x26, [x0, 0x40]
stp x27, x28, [x0, 0x50]
stp x29, lr, [x0, 0x60]
mov x5, sp
str x5, [x0, 0x70]
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
mrs x5, fpcr
str x5, [x1, 0x78]
#endif

ldp x16, x17, [x1, 0x00]
ldp x19, x20, [x1, 0x10]
ldp x21, x22, [x1, 0x20]
ldp x23, x24, [x1, 0x30]
ldp x25, x26, [x1, 0x40]
ldp x27, x28, [x1, 0x50]
ldp x29, x30, [x1, 0x60]
ldr x3, [x1, 0x70]
mov sp, x3
#ifndef ACO_CONFIG_SHARE_FPU_MXCSR_ENV
ldr x3, [x1, 0x78]
msr fpcr,x3
#endif

br x30
#else
#error "platform not support"
#endif
Expand All @@ -127,7 +166,9 @@ acosw:
#else
.type aco_save_fpucw_mxcsr, @function
#endif
#ifndef __aarch64__
.intel_syntax noprefix
#endif
aco_save_fpucw_mxcsr:
#ifdef __i386__
mov eax,DWORD PTR [esp+0x4] // ptr
Expand All @@ -138,6 +179,10 @@ aco_save_fpucw_mxcsr:
fnstcw WORD PTR [rdi]
stmxcsr DWORD PTR [rdi+0x4]
ret
#elif __aarch64__
mrs x1, fpcr
str x1, [x0]
ret
#else
#error "platform not support"
#endif
Expand All @@ -155,7 +200,9 @@ aco_save_fpucw_mxcsr:
#else
.type aco_funcp_protector_asm, @function
#endif
#ifndef __aarch64__
.intel_syntax noprefix
#endif
aco_funcp_protector_asm:
#ifdef __i386__
and esp,0xfffffff0
Expand Down Expand Up @@ -187,6 +234,13 @@ aco_funcp_protector_asm:
#endif
#endif
ret
#elif __aarch64__
mov x9, sp
and x9, x9, #0xfffffffffffffff0
mov sp, x9
bl aco_funcp_protector
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#if defined(APPLE)
bl _aco_funcp_protector
bl _abort
#else
bl aco_funcp_protector
bl abort
#endif

bl abort
ret
#else
#error "platform not support"
#endif