summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-16 21:17:26 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-16 21:17:26 -0700
commite31b1509ebb518548780aa2544459337854af48e (patch)
treeb30ef7d8bb1db97ba8ad7bad4299b349c87f2756
parentc77cd7d90f4a1549dacbf4b5e34827df2d6e4f03 (diff)
downloadtxr-e31b1509ebb518548780aa2544459337854af48e.tar.gz
txr-e31b1509ebb518548780aa2544459337854af48e.tar.bz2
txr-e31b1509ebb518548780aa2544459337854af48e.zip
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.
-rw-r--r--gc.c8
-rw-r--r--jmp.S36
-rw-r--r--signal.h30
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