summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorLuke Iannini <lukexi@me.com>2014-11-19 17:23:35 -0600
committerAustin Seipp <austin@well-typed.com>2014-11-19 17:24:30 -0600
commitd87fa343cd5d298c9fea96d65d05a20929ff97d0 (patch)
treebda3913f1d047e398ba63d47253c7792f6098018 /rts
parent80f6fc1769296330687d54179a6dc149f02d6348 (diff)
downloadhaskell-d87fa343cd5d298c9fea96d65d05a20929ff97d0.tar.gz
arm64: 64bit iOS and SMP support (#7942)
Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'rts')
-rw-r--r--rts/StgCRun.c32
-rw-r--r--rts/posix/OSMem.c2
-rw-r--r--rts/sm/Storage.c4
3 files changed, 25 insertions, 13 deletions
diff --git a/rts/StgCRun.c b/rts/StgCRun.c
index f649dbe9fb..55e0a48acf 100644
--- a/rts/StgCRun.c
+++ b/rts/StgCRun.c
@@ -756,22 +756,28 @@ StgRun(StgFunPtr f, StgRegTable *basereg) {
__asm__ volatile (
/*
* save callee-saves registers on behalf of the STG code.
+ * floating point registers only need the bottom 64 bits preserved.
+ * x16 and x17 are ip0 and ip1, but we can't refer to them by that name with clang.
*/
+ "stp fp, lr, [sp, #-16]!\n\t"
+ "mov fp, sp\n\t"
+ "stp x16, x17, [sp, #-16]!\n\t"
"stp x19, x20, [sp, #-16]!\n\t"
"stp x21, x22, [sp, #-16]!\n\t"
"stp x23, x24, [sp, #-16]!\n\t"
"stp x25, x26, [sp, #-16]!\n\t"
"stp x27, x28, [sp, #-16]!\n\t"
- "stp ip0, ip1, [sp, #-16]!\n\t"
- "str lr, [sp, #-8]!\n\t"
+ "stp d8, d9, [sp, #-16]!\n\t"
+ "stp d10, d11, [sp, #-16]!\n\t"
+ "stp d12, d13, [sp, #-16]!\n\t"
+ "stp d14, d15, [sp, #-16]!\n\t"
/*
* allocate some space for Stg machine's temporary storage.
* Note: RESERVER_C_STACK_BYTES has to be a round number here or
* the assembler can't assemble it.
*/
- "str lr, [sp, %3]"
- /* "sub sp, sp, %3\n\t" */
+ "sub sp, sp, %3\n\t"
/*
* Set BaseReg
*/
@@ -779,16 +785,17 @@ StgRun(StgFunPtr f, StgRegTable *basereg) {
/*
* Jump to function argument.
*/
- "bx %1\n\t"
+ "br %1\n\t"
".globl " STG_RETURN "\n\t"
+#if !defined(ios_HOST_OS)
".type " STG_RETURN ", %%function\n"
+#endif
STG_RETURN ":\n\t"
/*
* Free the space we allocated
*/
- "ldr lr, [sp], %3\n\t"
- /* "add sp, sp, %3\n\t" */
+ "add sp, sp, %3\n\t"
/*
* Return the new register table, taking it from Stg's R1 (ARM64's R22).
*/
@@ -796,18 +803,23 @@ StgRun(StgFunPtr f, StgRegTable *basereg) {
/*
* restore callee-saves registers.
*/
- "ldr lr, [sp], #8\n\t"
- "ldp ip0, ip1, [sp], #16\n\t"
+
+ "ldp d14, d15, [sp], #16\n\t"
+ "ldp d12, d13, [sp], #16\n\t"
+ "ldp d10, d11, [sp], #16\n\t"
+ "ldp d8, d9, [sp], #16\n\t"
"ldp x27, x28, [sp], #16\n\t"
"ldp x25, x26, [sp], #16\n\t"
"ldp x23, x24, [sp], #16\n\t"
"ldp x21, x22, [sp], #16\n\t"
"ldp x19, x20, [sp], #16\n\t"
+ "ldp x16, x17, [sp], #16\n\t"
+ "ldp fp, lr, [sp], #16\n\t"
: "=r" (r)
: "r" (f), "r" (basereg), "i" (RESERVED_C_STACK_BYTES)
: "%x19", "%x20", "%x21", "%x22", "%x23", "%x24", "%x25", "%x26", "%x27", "%x28",
- "%ip0", "%ip1", "%lr"
+ "%x16", "%x17", "%lr"
);
return r;
}
diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c
index 8a6a85e3ad..359df7022b 100644
--- a/rts/posix/OSMem.c
+++ b/rts/posix/OSMem.c
@@ -32,7 +32,7 @@
#include <errno.h>
-#if darwin_HOST_OS
+#if darwin_HOST_OS || ios_HOST_OS
#include <mach/mach.h>
#include <mach/vm_map.h>
#include <sys/sysctl.h>
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index afb171b568..7174425e04 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -1168,7 +1168,7 @@ calcNeeded (rtsBool force_major, memcount *blocks_needed)
should be modified to use allocateExec instead of VirtualAlloc.
------------------------------------------------------------------------- */
-#if defined(arm_HOST_ARCH) && defined(ios_HOST_OS)
+#if (defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)) && defined(ios_HOST_OS)
void sys_icache_invalidate(void *start, size_t len);
#endif
@@ -1180,7 +1180,7 @@ void flushExec (W_ len, AdjustorExecutable exec_addr)
/* x86 doesn't need to do anything, so just suppress some warnings. */
(void)len;
(void)exec_addr;
-#elif defined(arm_HOST_ARCH) && defined(ios_HOST_OS)
+#elif (defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)) && defined(ios_HOST_OS)
/* On iOS we need to use the special 'sys_icache_invalidate' call. */
sys_icache_invalidate(exec_addr, ((unsigned char*)exec_addr)+len);
#elif defined(__GNUC__)