From ce8039c327b820fd665a6cbe76dc964a53b9b7a9 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Mon, 4 Jan 2021 19:17:17 +0800 Subject: [PATCH] libcontext: Initial support for Apple Silicon The assembly for apple_arm64 is adapted from linux_arm64 target with small modifications: 1. Re-enable FPU conditional save/restore as apple_x86_64 does 2. Workaround limitation in relocation in assembly for clang --- thirdparty/libcontext/libcontext.cpp | 91 ++++++++++++++++++++++++++++ thirdparty/libcontext/libcontext.h | 3 + 2 files changed, 94 insertions(+) diff --git a/thirdparty/libcontext/libcontext.cpp b/thirdparty/libcontext/libcontext.cpp index 30479fea2a..85a9a47253 100644 --- a/thirdparty/libcontext/libcontext.cpp +++ b/thirdparty/libcontext/libcontext.cpp @@ -531,6 +531,97 @@ __asm ( #endif +#if defined(LIBCONTEXT_PLATFORM_apple_arm64) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".cpu generic+fp+simd\n" +".text\n" +".align 2\n" +".global _jump_fcontext\n" +"_jump_fcontext:\n" +" # prepare stack for GP + FPU\n" +" sub sp, sp, #0xb0\n" +" # test if fpu env should be preserved\n" +" cmp w3, #0\n" +" b.eq 1f\n" +" # save d8 - d15\n" +" stp d8, d9, [sp, #0x00]\n" +" stp d10, d11, [sp, #0x10]\n" +" stp d12, d13, [sp, #0x20]\n" +" stp d14, d15, [sp, #0x30]\n" +"1:\n" +" # save x19-x30\n" +" stp x19, x20, [sp, #0x40]\n" +" stp x21, x22, [sp, #0x50]\n" +" stp x23, x24, [sp, #0x60]\n" +" stp x25, x26, [sp, #0x70]\n" +" stp x27, x28, [sp, #0x80]\n" +" stp x29, x30, [sp, #0x90]\n" +" # save LR as PC\n" +" str x30, [sp, #0xa0]\n" +" # store RSP (pointing to context-data) in first argument (x0).\n" +" # STR cannot have sp as a target register\n" +" mov x4, sp\n" +" str x4, [x0]\n" +" # restore RSP (pointing to context-data) from A2 (x1)\n" +" mov sp, x1\n" +" # test if fpu env should be preserved\n" +" cmp w3, #0\n" +" b.eq 2f\n" +" # load d8 - d15\n" +" ldp d8, d9, [sp, #0x00]\n" +" ldp d10, d11, [sp, #0x10]\n" +" ldp d12, d13, [sp, #0x20]\n" +" ldp d14, d15, [sp, #0x30]\n" +"2:\n" +" # load x19-x30\n" +" ldp x19, x20, [sp, #0x40]\n" +" ldp x21, x22, [sp, #0x50]\n" +" ldp x23, x24, [sp, #0x60]\n" +" ldp x25, x26, [sp, #0x70]\n" +" ldp x27, x28, [sp, #0x80]\n" +" ldp x29, x30, [sp, #0x90]\n" +" # use third arg as return value after jump\n" +" # and as first arg in context function\n" +" mov x0, x2\n" +" # load pc\n" +" ldr x4, [sp, #0xa0]\n" +" # restore stack from GP + FPU\n" +" add sp, sp, #0xb0\n" +" ret x4\n" +); + +#endif + +#if defined(LIBCONTEXT_PLATFORM_apple_arm64) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".cpu generic+fp+simd\n" +".text\n" +".align 2\n" +".global _make_fcontext\n" +"_make_fcontext:\n" +" # shift address in x0 (allocated stack) to lower 16 byte boundary\n" +" and x0, x0, ~0xF\n" +" # reserve space for context-data on context-stack\n" +" sub x0, x0, #0xb0\n" +" # third arg of make_fcontext() == address of context-function\n" +" # store address as a PC to jump in\n" +" str x2, [x0, #0xa0]\n" +" # save address of finish as return-address for context-function\n" +" # will be entered after context-function returns (LR register)\n" +" # need to relocate manually because of Clang limitation\n" +" adrp x1, finish@PAGE\n" +" add x1, x1, finish@PAGEOFF\n" +" str x1, [x0, #0x98]\n" +" ret x30 \n" +"finish:\n" +" # exit code is zero\n" +" mov x0, #0\n" +" # exit application\n" +" bl _exit\n" +); + +#endif + #if defined(LIBCONTEXT_PLATFORM_linux_arm32) && defined(LIBCONTEXT_COMPILER_gcc) __asm ( ".text\n" diff --git a/thirdparty/libcontext/libcontext.h b/thirdparty/libcontext/libcontext.h index e2a903ce18..ce7a2d8da1 100644 --- a/thirdparty/libcontext/libcontext.h +++ b/thirdparty/libcontext/libcontext.h @@ -73,6 +73,9 @@ #elif defined(__x86_64__) #define LIBCONTEXT_PLATFORM_apple_x86_64 #define LIBCONTEXT_CALL_CONVENTION + #elif __aarch64__ + #define LIBCONTEXT_PLATFORM_apple_arm64 + #define LIBCONTEXT_CALL_CONVENTION #endif #endif #elif defined (_MSC_VER)