From e31b1509ebb518548780aa2544459337854af48e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 16 Aug 2017 21:17:26 -0700 Subject: Port to aarch64 (ARM 8). Continuations don't work yet. * gc.c (STACK_TOP_EXTRA_WORDS): New macro. (mark): On aarch64, we must include four words above the stack top. Some live root pointers sometimes hide there which are not in any of the callee-saved register that end up in the machine context via jmp_save. * jmp.S (jmp_save, jmp_restore): Implement for aarch64. --- gc.c | 8 +++++++- jmp.S | 36 +++++++++++++++++++++++++++++++++++- signal.h | 30 ++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/gc.c b/gc.c index d8f8b1ff..3ec20d76 100644 --- a/gc.c +++ b/gc.c @@ -52,6 +52,12 @@ #define FRESHOBJ_VEC_SIZE (8 * HEAP_SIZE) #define DFL_MALLOC_DELTA_THRESH (64L * 1024 * 1024) +#if __aarch64__ +#define STACK_TOP_EXTRA_WORDS 4 +#else +#define STACK_TOP_EXTRA_WORDS 0 +#endif + typedef struct heap { struct heap *next; obj_t block[HEAP_SIZE]; @@ -499,7 +505,7 @@ static void mark(mach_context_t *pmc, val *gc_stack_top) /* * Finally, the stack. */ - mark_mem_region(gc_stack_top, gc_stack_bottom); + mark_mem_region(gc_stack_top - STACK_TOP_EXTRA_WORDS, gc_stack_bottom); } static int sweep_one(obj_t *block) diff --git a/jmp.S b/jmp.S index 045f1a89..51563636 100644 --- a/jmp.S +++ b/jmp.S @@ -33,7 +33,7 @@ _ ## NAME: ; #define DEFUN(NAME) \ .globl _ ## NAME ; \ _ ## NAME: ; -#elif __arm__ && !__thumb__ +#elif (__arm__ && !__thumb__) || __aarch64__ #define DEFUN(NAME) \ .text ; \ .align 4 ; \ @@ -295,6 +295,40 @@ DEFUN(jmp_restore) mr %r3, %r4 blr +#elif __aarch64__ + +DEFUN(jmp_save) + stp x19, x20, [x0, 0] + stp x21, x22, [x0, 16] + stp x23, x24, [x0, 32] + stp x25, x26, [x0, 48] + stp x27, x28, [x0, 64] + stp x29, x30, [x0, 80] + stp d8, d9, [x0, 96] + stp d10, d11, [x0, 112] + stp d12, d13, [x0, 128] + stp d14, d15, [x0, 144] + mov x16, sp + str x16, [x0, 160] + mov w0, #0 + ret + +DEFUN(jmp_restore) + ldp x19, x20, [x0, 0] + ldp x21, x22, [x0, 16] + ldp x23, x24, [x0, 32] + ldp x25, x26, [x0, 48] + ldp x27, x28, [x0, 64] + ldp x29, x30, [x0, 80] + ldp d8, d9, [x0, 96] + ldp d10, d11, [x0, 112] + ldp d12, d13, [x0, 128] + ldp d14, d15, [x0, 144] + ldr x16, [x0, 160] + mov sp, x16 + mov w0, w1 + br x30 + #else #error port me! #endif diff --git a/signal.h b/signal.h index 435ce6f6..ec56b9e7 100644 --- a/signal.h +++ b/signal.h @@ -127,6 +127,36 @@ struct jmp { unsigned long r31; }; +#elif __aarch64__ + +struct jmp { + unsigned long x19; + unsigned long x20; + unsigned long x21; + unsigned long x22; + unsigned long x23; + unsigned long x24; + unsigned long x25; + unsigned long x26; + unsigned long x27; + unsigned long x28; + unsigned long x29; + unsigned long x30; + unsigned long d8; + unsigned long d9; + unsigned long d10; + unsigned long d11; + unsigned long d12; + unsigned long d13; + unsigned long d14; + unsigned long d15; + unsigned long x16; +}; + +/* Jump buffer contains: + x19-x28, x29(fp), x30(lr), (x31)sp, d8-d15. Other registers are not + saved. */ + #else #error port me! #endif -- cgit v1.2.3