-static void GNUC3_ATTRIBUTE(used)
-StgRunIsImplementedInAssembler(void)
-{
- __asm__ volatile(
- ".global StgRun\n"
- "StgRun:\n"
- "\talloc loc29 = ar.pfs, 0, %1, 8, 0\n" /* setup register frame */
- "\tld8 r18 = [r32],8\n" /* get procedure address */
- "\tadds sp = -%0, sp ;;\n" /* setup stack */
- "\tld8 gp = [r32]\n" /* get procedure GP */
- "\tadds r16 = %0-(6*16), sp\n"
- "\tadds r17 = %0-(5*16), sp ;;\n"
- "\tstf.spill [r16] = f16,32\n" /* spill callee-saved fp regs */
- "\tstf.spill [r17] = f17,32\n"
- "\tmov b6 = r18 ;;\n" /* set target address */
- "\tstf.spill [r16] = f18,32\n"
- "\tstf.spill [r17] = f19,32\n"
- "\tmov loc30 = b0 ;;\n" /* save return address */
- "\tstf.spill [r16] = f20,32\n"
- "\tstf.spill [r17] = f21,32\n"
- "\tbr.few b6 ;;\n" /* branch to function */
- ".global StgReturn\n"
- "StgReturn:\n"
- "\tmov r8 = loc16\n" /* return value in r8 */
- "\tadds r16 = %0-(6*16), sp\n"
- "\tadds r17 = %0-(5*16), sp ;;\n"
- "\tldf.fill f16 = [r16],32\n" /* start restoring fp regs */
- "\tldf.fill f17 = [r17],32\n"
- "\tmov ar.pfs = loc29 ;;\n" /* restore register frame */
- "\tldf.fill f18 = [r16],32\n"
- "\tldf.fill f19 = [r17],32\n"
- "\tmov b0 = loc30 ;;\n" /* restore return address */
- "\tldf.fill f20 = [r16],32\n"
- "\tldf.fill f21 = [r17],32\n"
- "\tadds sp = %0, sp\n" /* restore stack */
- "\tbr.ret.sptk.many b0 ;;\n" /* return */
- : : "i"(RESERVED_C_STACK_BYTES + 6*16), "i"(LOCALS));
+#if defined(aarch64_HOST_ARCH)
+
+StgRegTable *
+StgRun(StgFunPtr f, StgRegTable *basereg) {
+ StgRegTable * r;
+ __asm__ volatile (
+ /*
+ * Save callee-saves registers on behalf of the STG code.
+ * Floating point registers only need the bottom 64 bits preserved.
+ * We need to use the the names x16, x17, x29 and x30 instead of ip0
+ * ip1, fp and lp because one of either clang or gcc doesn't understand
+ * the later names.
+ */
+ "stp x29, x30, [sp, #-16]!\n\t"
+ "mov x29, 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 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: RESERVED_C_STACK_BYTES has to be a round number here or
+ * the assembler can't assemble it.
+ */
+ "sub sp, sp, %3\n\t"
+ /*
+ * Set BaseReg
+ */
+ "mov x19, %2\n\t"
+ /*
+ * Jump to function argument.
+ */
+ "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
+ */
+ "add sp, sp, %3\n\t"
+ /*
+ * Return the new register table, taking it from Stg's R1 (ARM64's R22).
+ */
+ "mov %0, x22\n\t"
+ /*
+ * restore callee-saves registers.
+ */
+
+ "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 x29, x30, [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",
+ "%x16", "%x17", "%x30"
+ );
+ return r;