From 01f0aad7c0fa2d816f9171d21b0168a9c1770a6b Mon Sep 17 00:00:00 2001 From: alexfanqi Date: Tue, 25 Jan 2022 13:47:06 +1100 Subject: [PATCH] Add riscv64 support for libcontext modified to match function arguments different from upstream Author: Andreas Schwab --- thirdparty/libcontext/libcontext.cpp | 108 +++++++++++++++++++++++++++ thirdparty/libcontext/libcontext.h | 5 ++ 2 files changed, 113 insertions(+) diff --git a/thirdparty/libcontext/libcontext.cpp b/thirdparty/libcontext/libcontext.cpp index 44a969d380..a56ff44407 100644 --- a/thirdparty/libcontext/libcontext.cpp +++ b/thirdparty/libcontext/libcontext.cpp @@ -1444,6 +1444,114 @@ __asm ( #endif +#if defined(LIBCONTEXT_PLATFORM_linux_riscv64) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".text\n" +".align 1\n" +".global jump_fcontext\n" +".type jump_fcontext, %function\n" +"jump_fcontext:\n" +" # prepare stack for GP + FPU\n" +" addi sp, sp, -0xd0\n" +" # save fs0 - fs11\n" +" fsd fs0, 0x00(sp)\n" +" fsd fs1, 0x08(sp)\n" +" fsd fs2, 0x10(sp)\n" +" fsd fs3, 0x18(sp)\n" +" fsd fs4, 0x20(sp)\n" +" fsd fs5, 0x28(sp)\n" +" fsd fs6, 0x30(sp)\n" +" fsd fs7, 0x38(sp)\n" +" fsd fs8, 0x40(sp)\n" +" fsd fs9, 0x48(sp)\n" +" fsd fs10, 0x50(sp)\n" +" fsd fs11, 0x58(sp)\n" +" # save s0-s11, ra\n" +" sd s0, 0x60(sp)\n" +" sd s1, 0x68(sp)\n" +" sd s2, 0x70(sp)\n" +" sd s3, 0x78(sp)\n" +" sd s4, 0x80(sp)\n" +" sd s5, 0x88(sp)\n" +" sd s6, 0x90(sp)\n" +" sd s7, 0x98(sp)\n" +" sd s8, 0xa0(sp)\n" +" sd s9, 0xa8(sp)\n" +" sd s10, 0xb0(sp)\n" +" sd s11, 0xb8(sp)\n" +" sd ra, 0xc0(sp)\n" +" # save RA as PC\n" +" sd ra, 0xc8(sp)\n" +" # store SP in the first arg(pointer to fcontext_t)\n" +" sd sp, 0x00(a0)\n" +" # restore SP from the second arg(fcontext_t)\n" +" mv sp, a1\n" +" # load fs0 - fs11\n" +" fld fs0, 0x00(sp)\n" +" fld fs1, 0x08(sp)\n" +" fld fs2, 0x10(sp)\n" +" fld fs3, 0x18(sp)\n" +" fld fs4, 0x20(sp)\n" +" fld fs5, 0x28(sp)\n" +" fld fs6, 0x30(sp)\n" +" fld fs7, 0x38(sp)\n" +" fld fs8, 0x40(sp)\n" +" fld fs9, 0x48(sp)\n" +" fld fs10, 0x50(sp)\n" +" fld fs11, 0x58(sp)\n" +" # load s0-s11,ra\n" +" ld s0, 0x60(sp)\n" +" ld s1, 0x68(sp)\n" +" ld s2, 0x70(sp)\n" +" ld s3, 0x78(sp)\n" +" ld s4, 0x80(sp)\n" +" ld s5, 0x88(sp)\n" +" ld s6, 0x90(sp)\n" +" ld s7, 0x98(sp)\n" +" ld s8, 0xa0(sp)\n" +" ld s9, 0xa8(sp)\n" +" ld s10, 0xb0(sp)\n" +" ld s11, 0xb8(sp)\n" +" ld ra, 0xc0(sp)\n" +" # use the third arg as return value\n" +" mv a0, a2\n" +" # load pc from new context\n" +" ld a4, 0xc8(sp)\n" +" # restore stack from GP + FPU\n" +" addi sp, sp, 0xd0\n" +" jr a4\n" +".size jump_fcontext,.-jump_fcontext\n" +); +#endif + +#if defined(LIBCONTEXT_PLATFORM_linux_riscv64) && defined(LIBCONTEXT_COMPILER_gcc) +__asm ( +".text\n" +".align 1\n" +".global make_fcontext\n" +".type make_fcontext, %function\n" +"make_fcontext:\n" +" # shift address in a0 (allocated stack) to lower 16 byte boundary\n" +" andi a0, a0, ~0xF\n" +" # reserve space for context-data on context-stack\n" +" addi a0, a0, -0xd0\n" +" # third arg of make_fcontext() == address of context-function\n" +" # store address as a PC to jump in\n" +" sd a2, 0xc8(a0)\n" +" # save address of finish as return-address for context-function\n" +" # will be entered after context-function returns (RA register)\n" +" lla a4, finish\n" +" sd a4, 0xc0(a0)\n" +" ret # return pointer to context-data (a0)\n" +"finish:\n" +" # exit code is zero\n" +" li a0, 0\n" +" # exit application\n" +" tail _exit@plt\n" +".size make_fcontext,.-make_fcontext\n" +); +#endif + #if defined(LIBCONTEXT_USE_WINFIBER) && (defined(LIBCONTEXT_PLATFORM_msvc_x86_64) || defined(LIBCONTEXT_PLATFORM_msvc_i386)) #include diff --git a/thirdparty/libcontext/libcontext.h b/thirdparty/libcontext/libcontext.h index 82141424ab..289e145954 100644 --- a/thirdparty/libcontext/libcontext.h +++ b/thirdparty/libcontext/libcontext.h @@ -55,6 +55,11 @@ #define LIBCONTEXT_PLATFORM_linux_ppc32 #define LIBCONTEXT_CALL_CONVENTION #endif + #elif defined(__riscv) + #if __riscv_xlen == 64 + #define LIBCONTEXT_PLATFORM_linux_riscv64 + #define LIBCONTEXT_CALL_CONVENTION + #endif #endif #elif defined(__MINGW32__) || defined(__MINGW64__)