This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG0f6fd1b704c0: [libc] Add support for setjmp and longjmp in
riscv (authored by Mikhail R. Gadelha <[email protected]>).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D145584/new/
https://reviews.llvm.org/D145584
Files:
clang/docs/tools/clang-formatted-files.txt
libc/config/linux/riscv64/entrypoints.txt
libc/config/linux/riscv64/headers.txt
libc/include/llvm-libc-types/jmp_buf.h
libc/src/setjmp/CMakeLists.txt
libc/src/setjmp/longjmp.cpp
libc/src/setjmp/riscv64/CMakeLists.txt
libc/src/setjmp/riscv64/longjmp.cpp
libc/src/setjmp/riscv64/setjmp.cpp
libc/src/setjmp/setjmp.cpp
libc/src/setjmp/x86_64/CMakeLists.txt
libc/src/setjmp/x86_64/longjmp.cpp
libc/src/setjmp/x86_64/setjmp.cpp
Index: libc/src/setjmp/x86_64/setjmp.cpp
===================================================================
--- libc/src/setjmp/x86_64/setjmp.cpp
+++ libc/src/setjmp/x86_64/setjmp.cpp
@@ -7,15 +7,15 @@
//===----------------------------------------------------------------------===//
#include "src/__support/common.h"
-#include "src/__support/macros/properties/architectures.h"
#include "src/setjmp/setjmp_impl.h"
-#include <setjmp.h>
+#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
+#error "Invalid file include"
+#endif
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, setjmp, (__jmp_buf * buf)) {
-#ifdef LIBC_TARGET_ARCH_IS_X86_64
register __UINT64_TYPE__ rbx __asm__("rbx");
register __UINT64_TYPE__ r12 __asm__("r12");
register __UINT64_TYPE__ r13 __asm__("r13");
@@ -50,10 +50,6 @@
buf->rsp = reinterpret_cast<__UINTPTR_TYPE__>(__builtin_frame_address(0)) +
sizeof(__UINTPTR_TYPE__) * 2;
buf->rip = reinterpret_cast<__UINTPTR_TYPE__>(__builtin_return_address(0));
-#else // LIBC_TARGET_ARCH_IS_X86_64
-#error "setjmp implementation not available for the target architecture."
-#endif
-
return 0;
}
Index: libc/src/setjmp/x86_64/longjmp.cpp
===================================================================
--- libc/src/setjmp/x86_64/longjmp.cpp
+++ libc/src/setjmp/x86_64/longjmp.cpp
@@ -8,14 +8,14 @@
#include "src/setjmp/longjmp.h"
#include "src/__support/common.h"
-#include "src/__support/macros/properties/architectures.h"
-#include <setjmp.h>
+#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
+#error "Invalid file include"
+#endif
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(void, longjmp, (__jmp_buf * buf, int val)) {
-#ifdef LIBC_TARGET_ARCH_IS_X86_64
register __UINT64_TYPE__ rbx __asm__("rbx");
register __UINT64_TYPE__ rbp __asm__("rbp");
register __UINT64_TYPE__ r12 __asm__("r12");
@@ -38,9 +38,6 @@
LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(r15) : "m"(buf->r15) :);
LIBC_INLINE_ASM("mov %1, %0\n\t" : "=r"(rsp) : "m"(buf->rsp) :);
LIBC_INLINE_ASM("jmp *%0\n\t" : : "m"(buf->rip));
-#else // LIBC_TARGET_ARCH_IS_X86_64
-#error "longjmp implementation not available for the target architecture."
-#endif
}
} // namespace __llvm_libc
Index: libc/src/setjmp/x86_64/CMakeLists.txt
===================================================================
--- libc/src/setjmp/x86_64/CMakeLists.txt
+++ libc/src/setjmp/x86_64/CMakeLists.txt
@@ -3,12 +3,12 @@
SRCS
setjmp.cpp
HDRS
- setjmp_impl.h
- COMPILE_OPTIONS
- -O3 # We do not want any local variables in setjmp
- -fno-omit-frame-pointer # The implementation assumes frame pointer on to the stack
+ ../setjmp_impl.h
DEPENDS
libc.include.setjmp
+ COMPILE_OPTIONS
+ -O3
+ -fno-omit-frame-pointer
)
add_entrypoint_object(
@@ -16,9 +16,10 @@
SRCS
longjmp.cpp
HDRS
- longjmp.h
- COMPILE_OPTIONS
- -O3 # We do not want any local variables in longjmp
+ ../longjmp.h
DEPENDS
libc.include.setjmp
+ COMPILE_OPTIONS
+ -O3
+ -fno-omit-frame-pointer
)
Index: libc/src/setjmp/riscv64/setjmp.cpp
===================================================================
--- /dev/null
+++ libc/src/setjmp/riscv64/setjmp.cpp
@@ -0,0 +1,56 @@
+//===-- Implementation of setjmp ------------------------------------------===//
+//
+// 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/__support/common.h"
+#include "src/setjmp/setjmp_impl.h"
+
+#include <setjmp.h>
+
+#if !defined(LIBC_TARGET_ARCH_IS_RISCV64)
+#error "Invalid file include"
+#endif
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, setjmp, (__jmp_buf * buf)) {
+ LIBC_INLINE_ASM("sd ra, %0\n\t" : : "m"(buf->__pc) :);
+ LIBC_INLINE_ASM("sd s0, %0\n\t" : : "m"(buf->__regs[0]) :);
+ LIBC_INLINE_ASM("sd s1, %0\n\t" : : "m"(buf->__regs[1]) :);
+ LIBC_INLINE_ASM("sd s2, %0\n\t" : : "m"(buf->__regs[2]) :);
+ LIBC_INLINE_ASM("sd s3, %0\n\t" : : "m"(buf->__regs[3]) :);
+ LIBC_INLINE_ASM("sd s4, %0\n\t" : : "m"(buf->__regs[4]) :);
+ LIBC_INLINE_ASM("sd s5, %0\n\t" : : "m"(buf->__regs[5]) :);
+ LIBC_INLINE_ASM("sd s6, %0\n\t" : : "m"(buf->__regs[6]) :);
+ LIBC_INLINE_ASM("sd s7, %0\n\t" : : "m"(buf->__regs[7]) :);
+ LIBC_INLINE_ASM("sd s8, %0\n\t" : : "m"(buf->__regs[8]) :);
+ LIBC_INLINE_ASM("sd s9, %0\n\t" : : "m"(buf->__regs[9]) :);
+ LIBC_INLINE_ASM("sd s10, %0\n\t" : : "m"(buf->__regs[10]) :);
+ LIBC_INLINE_ASM("sd s11, %0\n\t" : : "m"(buf->__regs[11]) :);
+ LIBC_INLINE_ASM("sd sp, %0\n\t" : : "m"(buf->__sp) :);
+
+#if __riscv_float_abi_double
+ LIBC_INLINE_ASM("fsd fs0, %0\n\t" : : "m"(buf->__fpregs[0]) :);
+ LIBC_INLINE_ASM("fsd fs1, %0\n\t" : : "m"(buf->__fpregs[1]) :);
+ LIBC_INLINE_ASM("fsd fs2, %0\n\t" : : "m"(buf->__fpregs[2]) :);
+ LIBC_INLINE_ASM("fsd fs3, %0\n\t" : : "m"(buf->__fpregs[3]) :);
+ LIBC_INLINE_ASM("fsd fs4, %0\n\t" : : "m"(buf->__fpregs[4]) :);
+ LIBC_INLINE_ASM("fsd fs5, %0\n\t" : : "m"(buf->__fpregs[5]) :);
+ LIBC_INLINE_ASM("fsd fs6, %0\n\t" : : "m"(buf->__fpregs[6]) :);
+ LIBC_INLINE_ASM("fsd fs7, %0\n\t" : : "m"(buf->__fpregs[7]) :);
+ LIBC_INLINE_ASM("fsd fs8, %0\n\t" : : "m"(buf->__fpregs[8]) :);
+ LIBC_INLINE_ASM("fsd fs9, %0\n\t" : : "m"(buf->__fpregs[9]) :);
+ LIBC_INLINE_ASM("fsd fs10, %0\n\t" : : "m"(buf->__fpregs[10]) :);
+ LIBC_INLINE_ASM("fsd fs11, %0\n\t" : : "m"(buf->__fpregs[11]) :);
+#elif defined(__riscv_float_abi_single)
+#error "setjmp implementation not available for the target architecture."
+#endif
+
+ return 0;
+}
+
+} // namespace __llvm_libc
Index: libc/src/setjmp/riscv64/longjmp.cpp
===================================================================
--- /dev/null
+++ libc/src/setjmp/riscv64/longjmp.cpp
@@ -0,0 +1,58 @@
+//===-- Implementation of longjmp -----------------------------------------===//
+//
+// 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/longjmp.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
+
+#include <setjmp.h>
+
+#if !defined(LIBC_TARGET_ARCH_IS_RISCV64)
+#error "Invalid file include"
+#endif
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(void, longjmp, (__jmp_buf * buf, int val)) {
+ LIBC_INLINE_ASM("ld ra, %0\n\t" : : "m"(buf->__pc) :);
+ LIBC_INLINE_ASM("ld s0, %0\n\t" : : "m"(buf->__regs[0]) :);
+ LIBC_INLINE_ASM("ld s1, %0\n\t" : : "m"(buf->__regs[1]) :);
+ LIBC_INLINE_ASM("ld s2, %0\n\t" : : "m"(buf->__regs[2]) :);
+ LIBC_INLINE_ASM("ld s3, %0\n\t" : : "m"(buf->__regs[3]) :);
+ LIBC_INLINE_ASM("ld s4, %0\n\t" : : "m"(buf->__regs[4]) :);
+ LIBC_INLINE_ASM("ld s5, %0\n\t" : : "m"(buf->__regs[5]) :);
+ LIBC_INLINE_ASM("ld s6, %0\n\t" : : "m"(buf->__regs[6]) :);
+ LIBC_INLINE_ASM("ld s7, %0\n\t" : : "m"(buf->__regs[7]) :);
+ LIBC_INLINE_ASM("ld s8, %0\n\t" : : "m"(buf->__regs[8]) :);
+ LIBC_INLINE_ASM("ld s9, %0\n\t" : : "m"(buf->__regs[9]) :);
+ LIBC_INLINE_ASM("ld s10, %0\n\t" : : "m"(buf->__regs[10]) :);
+ LIBC_INLINE_ASM("ld s11, %0\n\t" : : "m"(buf->__regs[11]) :);
+ LIBC_INLINE_ASM("ld sp, %0\n\t" : : "m"(buf->__sp) :);
+
+#if __riscv_float_abi_double
+ LIBC_INLINE_ASM("fld fs0, %0\n\t" : : "m"(buf->__fpregs[0]) :);
+ LIBC_INLINE_ASM("fld fs1, %0\n\t" : : "m"(buf->__fpregs[1]) :);
+ LIBC_INLINE_ASM("fld fs2, %0\n\t" : : "m"(buf->__fpregs[2]) :);
+ LIBC_INLINE_ASM("fld fs3, %0\n\t" : : "m"(buf->__fpregs[3]) :);
+ LIBC_INLINE_ASM("fld fs4, %0\n\t" : : "m"(buf->__fpregs[4]) :);
+ LIBC_INLINE_ASM("fld fs5, %0\n\t" : : "m"(buf->__fpregs[5]) :);
+ LIBC_INLINE_ASM("fld fs6, %0\n\t" : : "m"(buf->__fpregs[6]) :);
+ LIBC_INLINE_ASM("fld fs7, %0\n\t" : : "m"(buf->__fpregs[7]) :);
+ LIBC_INLINE_ASM("fld fs8, %0\n\t" : : "m"(buf->__fpregs[8]) :);
+ LIBC_INLINE_ASM("fld fs9, %0\n\t" : : "m"(buf->__fpregs[9]) :);
+ LIBC_INLINE_ASM("fld fs10, %0\n\t" : : "m"(buf->__fpregs[10]) :);
+ LIBC_INLINE_ASM("fld fs11, %0\n\t" : : "m"(buf->__fpregs[11]) :);
+#elif defined(__riscv_float_abi_single)
+#error "longjmp implementation not available for the target architecture."
+#endif
+
+ val = val == 0 ? 1 : val;
+ LIBC_INLINE_ASM("add a0, %0, zero\n\t" : : "r"(val) :);
+}
+
+} // namespace __llvm_libc
Index: libc/src/setjmp/riscv64/CMakeLists.txt
===================================================================
--- libc/src/setjmp/riscv64/CMakeLists.txt
+++ libc/src/setjmp/riscv64/CMakeLists.txt
@@ -3,12 +3,12 @@
SRCS
setjmp.cpp
HDRS
- setjmp_impl.h
- COMPILE_OPTIONS
- -O3 # We do not want any local variables in setjmp
- -fno-omit-frame-pointer # The implementation assumes frame pointer on to the stack
+ ../setjmp_impl.h
DEPENDS
libc.include.setjmp
+ COMPILE_OPTIONS
+ -O3
+ -fomit-frame-pointer
)
add_entrypoint_object(
@@ -16,9 +16,10 @@
SRCS
longjmp.cpp
HDRS
- longjmp.h
- COMPILE_OPTIONS
- -O3 # We do not want any local variables in longjmp
+ ../longjmp.h
DEPENDS
libc.include.setjmp
+ COMPILE_OPTIONS
+ -O3
+ -fomit-frame-pointer
)
Index: libc/src/setjmp/CMakeLists.txt
===================================================================
--- libc/src/setjmp/CMakeLists.txt
+++ libc/src/setjmp/CMakeLists.txt
@@ -1,24 +1,17 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+endif()
+
add_entrypoint_object(
setjmp
- SRCS
- setjmp.cpp
- HDRS
- setjmp_impl.h
- COMPILE_OPTIONS
- -O3 # We do not want any local variables in setjmp
- -fno-omit-frame-pointer # The implementation assumes frame pointer on to the stack
+ ALIAS
DEPENDS
- libc.include.setjmp
+ .${LIBC_TARGET_ARCHITECTURE}.setjmp
)
add_entrypoint_object(
longjmp
- SRCS
- longjmp.cpp
- HDRS
- longjmp.h
- COMPILE_OPTIONS
- -O3 # We do not want any local variables in longjmp
+ ALIAS
DEPENDS
- libc.include.setjmp
+ .${LIBC_TARGET_ARCHITECTURE}.longjmp
)
Index: libc/include/llvm-libc-types/jmp_buf.h
===================================================================
--- libc/include/llvm-libc-types/jmp_buf.h
+++ libc/include/llvm-libc-types/jmp_buf.h
@@ -19,6 +19,19 @@
__UINT64_TYPE__ r15;
__UINTPTR_TYPE__ rsp;
__UINTPTR_TYPE__ rip;
+#elif defined(__riscv)
+ /* Program counter. */
+ long int __pc;
+ /* Callee-saved registers. */
+ long int __regs[12];
+ /* Stack pointer. */
+ long int __sp;
+ /* Callee-saved floating point registers. */
+#if __riscv_float_abi_double
+ double __fpregs[12];
+#elif defined(__riscv_float_abi_single)
+#error "__jmp_buf not available for your target architecture."
+#endif
#else
#error "__jmp_buf not available for your target architecture."
#endif
Index: libc/config/linux/riscv64/headers.txt
===================================================================
--- libc/config/linux/riscv64/headers.txt
+++ libc/config/linux/riscv64/headers.txt
@@ -10,6 +10,7 @@
libc.include.sched
libc.include.signal
libc.include.spawn
+ libc.include.setjmp
libc.include.stdio
libc.include.stdlib
libc.include.string
Index: libc/config/linux/riscv64/entrypoints.txt
===================================================================
--- libc/config/linux/riscv64/entrypoints.txt
+++ libc/config/linux/riscv64/entrypoints.txt
@@ -371,6 +371,10 @@
# sched.h entrypoints
libc.src.sched.__sched_getcpucount
+ # setjmp.h entrypoints
+ libc.src.setjmp.longjmp
+ libc.src.setjmp.setjmp
+
# stdio.h entrypoints
libc.src.stdio.clearerr
libc.src.stdio.clearerr_unlocked
Index: clang/docs/tools/clang-formatted-files.txt
===================================================================
--- clang/docs/tools/clang-formatted-files.txt
+++ clang/docs/tools/clang-formatted-files.txt
@@ -2594,6 +2594,7 @@
libc/include/llvm-libc-types/FILE.h
libc/include/llvm-libc-types/float_t.h
libc/include/llvm-libc-types/imaxdiv_t.h
+libc/include/llvm-libc-types/jmp_buf.h
libc/include/llvm-libc-types/ldiv_t.h
libc/include/llvm-libc-types/lldiv_t.h
libc/include/llvm-libc-types/mode_t.h
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits