aarch64.c (2188B)
1 /* 2 * lib/coro/aarch64.c -- AArch64 (AAPCS) implementations of 3 * setjmp / longjmp (<setjmp.h>) 4 * __kit_coro_ctx_init / __kit_coro_switch / trampoline (<kit/coro.h>) 5 * 6 * All three primitives sit on one per-target context layout: 7 * 8 * regs[0..9] x19-x28 9 * regs[10..11] fp (x29), lr (x30) 10 * regs[12] sp 11 * fp_regs[0..7] d8-d15 (low 64 bits of v8-v15; AAPCS only mandates 12 * the lower 64 bits be preserved) 13 * 14 * sizeof = 176 (alignof-16 padded), 16-byte aligned. Fits in the 15 * 256-byte storage carved out by jmp_buf and coro_ctx. 16 * 17 * The assembly primitives live in aarch64_elf.s / aarch64_macho.s so this 18 * translation unit stays plain C and does not require file-scope asm support. 19 */ 20 21 #include <kit/coro.h> 22 #include <setjmp.h> 23 #include <stddef.h> 24 #include <stdint.h> 25 26 struct __kit_arm64_ctx { 27 uintptr_t regs[13]; 28 uint64_t fp_regs[8]; 29 } __attribute__((aligned(16))); 30 31 _Static_assert(sizeof(struct __kit_arm64_ctx) == 176, "layout"); 32 _Static_assert(_Alignof(struct __kit_arm64_ctx) == 16, "align"); 33 _Static_assert(offsetof(struct __kit_arm64_ctx, fp_regs) == 104, "fp off"); 34 _Static_assert(sizeof(struct __kit_arm64_ctx) <= sizeof(coro_ctx), 35 "fits coro_ctx"); 36 _Static_assert(sizeof(struct __kit_arm64_ctx) <= sizeof(jmp_buf), 37 "fits jmp_buf"); 38 _Static_assert(_Alignof(coro_ctx) >= _Alignof(struct __kit_arm64_ctx), 39 "align coro_ctx"); 40 41 extern void __kit_coro_trampoline(void); 42 43 void __kit_coro_ctx_init(coro_ctx* ctx, void* stack_base, size_t stack_len, 44 void (*entry)(uintptr_t)) { 45 struct __kit_arm64_ctx* c = (struct __kit_arm64_ctx*)ctx; 46 47 /* AArch64 stacks grow down; align top to 16. */ 48 uintptr_t top = (uintptr_t)stack_base + stack_len; 49 top &= ~(uintptr_t)(CORO_STACK_ALIGN - 1); 50 51 for (size_t i = 0; i < sizeof(*c) / sizeof(uintptr_t); ++i) 52 ((uintptr_t*)c)[i] = 0; 53 54 c->regs[0] = (uintptr_t)entry; /* x19 -- entry fn */ 55 c->regs[10] = 0; /* fp */ 56 c->regs[11] = (uintptr_t)__kit_coro_trampoline; /* lr */ 57 c->regs[12] = top; /* sp */ 58 }