mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 17:01:00 +08:00
[libc] implement sigsetjmp/siglongjmp for riscv (#137992)
See https://godbolt.org/z/jo7s6j7sq for compiled code. ```c++ #if __riscv_xlen == 64 #define STORE(A, B, C) "sd " #A ", %c[" #B "](" #C ")\n\t" #define LOAD(A, B, C) "ld " #A ", %c[" #B "](" #C ")\n\t" #elif __riscv_xlen == 32 #define STORE(A, B, C) "sw " #A ", %c[" #B "](" #C ")\n\t" #define LOAD(A, B, C) "lw " #A ", %c[" #B "](" #C ")\n\t" #else #error "Unsupported RISC-V architecture" #endif namespace LIBC_NAMESPACE_DECL { [[gnu::naked]] LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) { // clang-format off asm("beqz a1, .Lnosave\n\t" STORE(ra, retaddr, a0) STORE(s0, extra, a0) "mv s0, a0\n\t" "call %c[setjmp]\n\t" "mv a1, a0\n\t" "mv a0, s0\n\t" LOAD(s0, extra, a0) LOAD(ra, retaddr, a0) "tail %c[epilogue]\n" ".Lnosave:\n\t" "tail %c[setjmp]" // clang-format on ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)), [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp), [epilogue] "i"(sigsetjmp_epilogue) : "a0", "a1", "s0"); } ```
This commit is contained in:
committed by
GitHub
parent
c51a3aa6ce
commit
a1803ea063
@@ -877,6 +877,8 @@ if(LLVM_LIBC_FULL_BUILD)
|
||||
# setjmp.h entrypoints
|
||||
libc.src.setjmp.longjmp
|
||||
libc.src.setjmp.setjmp
|
||||
libc.src.setjmp.siglongjmp
|
||||
libc.src.setjmp.sigsetjmp
|
||||
|
||||
# stdio.h entrypoints
|
||||
libc.src.stdio.clearerr
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
// TODO: implement sigjmp_buf related functions for other architectures
|
||||
// Issue: https://github.com/llvm/llvm-project/issues/136358
|
||||
#if defined(__linux__)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
|
||||
defined(__riscv)
|
||||
#define __LIBC_HAS_SIGJMP_BUF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,22 @@ add_entrypoint_object(
|
||||
-fomit-frame-pointer
|
||||
)
|
||||
|
||||
if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
|
||||
add_entrypoint_object(
|
||||
sigsetjmp
|
||||
SRCS
|
||||
sigsetjmp.cpp
|
||||
HDRS
|
||||
../sigsetjmp.h
|
||||
DEPENDS
|
||||
libc.hdr.types.jmp_buf
|
||||
libc.hdr.types.sigset_t
|
||||
libc.hdr.offsetof_macros
|
||||
libc.src.setjmp.sigsetjmp_epilogue
|
||||
libc.src.setjmp.setjmp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_entrypoint_object(
|
||||
longjmp
|
||||
SRCS
|
||||
|
||||
49
libc/src/setjmp/riscv/sigsetjmp.cpp
Normal file
49
libc/src/setjmp/riscv/sigsetjmp.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
//===-- Implementation of sigsetjmp ---------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/setjmp/sigsetjmp.h"
|
||||
#include "hdr/offsetof_macros.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/setjmp/setjmp_impl.h"
|
||||
#include "src/setjmp/sigsetjmp_epilogue.h"
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#define STORE(A, B, C) "sd " #A ", %c[" #B "](" #C ")\n\t"
|
||||
#define LOAD(A, B, C) "ld " #A ", %c[" #B "](" #C ")\n\t"
|
||||
#elif __riscv_xlen == 32
|
||||
#define STORE(A, B, C) "sw " #A ", %c[" #B "](" #C ")\n\t"
|
||||
#define LOAD(A, B, C) "lw " #A ", %c[" #B "](" #C ")\n\t"
|
||||
#else
|
||||
#error "Unsupported RISC-V architecture"
|
||||
#endif
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
[[gnu::naked]]
|
||||
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
|
||||
// clang-format off
|
||||
asm("beqz a1, .Lnosave\n\t"
|
||||
STORE(ra, retaddr, a0)
|
||||
STORE(s0, extra, a0)
|
||||
"mv s0, a0\n\t"
|
||||
"call %c[setjmp]\n\t"
|
||||
"mv a1, a0\n\t"
|
||||
"mv a0, s0\n\t"
|
||||
LOAD(s0, extra, a0)
|
||||
LOAD(ra, retaddr, a0)
|
||||
"tail %c[epilogue]\n"
|
||||
".Lnosave:\n\t"
|
||||
"tail %c[setjmp]"
|
||||
// clang-format on
|
||||
::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
|
||||
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
|
||||
[epilogue] "i"(sigsetjmp_epilogue)
|
||||
: "a0", "a1", "s0");
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
Reference in New Issue
Block a user