[libc-commits] [libc] [libc] Fix Darwin aarch64 fenv and sigsetjmp build support (PR #192079)
Kacper Fiedorowicz via libc-commits
libc-commits at lists.llvm.org
Thu May 7 01:40:38 PDT 2026
https://github.com/fenze updated https://github.com/llvm/llvm-project/pull/192079
>From c65c1196c45778f1f5915086733f2a8a68d3c7d7 Mon Sep 17 00:00:00 2001
From: Kacper Fiedorowicz <kf at efab.pl>
Date: Tue, 14 Apr 2026 17:08:39 +0200
Subject: [PATCH 1/4] libc: fix Darwin signal and setjmp build support
---
.../llvm-libc-macros/darwin/CMakeLists.txt | 6 ++
.../llvm-libc-macros/darwin/signal-macros.h | 60 ++++++++++++++++
libc/include/llvm-libc-macros/signal-macros.h | 2 +
libc/include/llvm-libc-types/__jmp_buf.h | 2 +-
.../FPUtil/aarch64/fenv_darwin_impl.h | 38 +++++++++-
libc/src/setjmp/aarch64/sigsetjmp.cpp | 5 +-
libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp | 7 +-
libc/src/signal/darwin/CMakeLists.txt | 70 +++++++++++++++++++
libc/src/signal/darwin/sigaddset.cpp | 26 +++++++
libc/src/signal/darwin/sigdelset.cpp | 26 +++++++
libc/src/signal/darwin/sigemptyset.cpp | 26 +++++++
libc/src/signal/darwin/sigfillset.cpp | 28 ++++++++
libc/src/signal/darwin/sigprocmask.cpp | 45 ++++++++++++
13 files changed, 332 insertions(+), 9 deletions(-)
create mode 100644 libc/include/llvm-libc-macros/darwin/signal-macros.h
create mode 100644 libc/src/signal/darwin/CMakeLists.txt
create mode 100644 libc/src/signal/darwin/sigaddset.cpp
create mode 100644 libc/src/signal/darwin/sigdelset.cpp
create mode 100644 libc/src/signal/darwin/sigemptyset.cpp
create mode 100644 libc/src/signal/darwin/sigfillset.cpp
create mode 100644 libc/src/signal/darwin/sigprocmask.cpp
diff --git a/libc/include/llvm-libc-macros/darwin/CMakeLists.txt b/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
index ea08c63c00301..f3ee6af21d218 100644
--- a/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
@@ -3,3 +3,9 @@ add_header(
HDR
time-macros.h
)
+
+add_header(
+ signal_macros
+ HDR
+ signal-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/darwin/signal-macros.h b/libc/include/llvm-libc-macros/darwin/signal-macros.h
new file mode 100644
index 0000000000000..88bfcc3db627c
--- /dev/null
+++ b/libc/include/llvm-libc-macros/darwin/signal-macros.h
@@ -0,0 +1,60 @@
+//===-- Definition of Darwin signal number macros -------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_DARWIN_SIGNAL_MACROS_H
+#define LLVM_LIBC_MACROS_DARWIN_SIGNAL_MACROS_H
+
+#include "__llvm-libc-common.h"
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGEMT 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGBUS 10
+#define SIGSEGV 11
+#define SIGSYS 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGURG 16
+#define SIGSTOP 17
+#define SIGTSTP 18
+#define SIGCONT 19
+#define SIGCHLD 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGIO 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGINFO 29
+#define SIGUSR1 30
+#define SIGUSR2 31
+
+#define NSIG 32
+
+#define __NSIGSET_WORDS 1
+
+#define SIG_BLOCK 1
+#define SIG_UNBLOCK 2
+#define SIG_SETMASK 3
+
+#define SIG_ERR __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), -1)
+#define SIG_DFL __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), 0)
+#define SIG_IGN __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), 1)
+#define SIG_HOLD __LLVM_LIBC_CAST(reinterpret_cast, void (*)(int), 5)
+
+#endif // LLVM_LIBC_MACROS_DARWIN_SIGNAL_MACROS_H
diff --git a/libc/include/llvm-libc-macros/signal-macros.h b/libc/include/llvm-libc-macros/signal-macros.h
index 163c8742593b8..c28f668456f33 100644
--- a/libc/include/llvm-libc-macros/signal-macros.h
+++ b/libc/include/llvm-libc-macros/signal-macros.h
@@ -11,6 +11,8 @@
#if defined(__linux__)
#include "linux/signal-macros.h"
+#elif defined(__APPLE__)
+#include "darwin/signal-macros.h"
#elif defined(__NVPTX__) || defined(__AMDGPU__) || defined(__SPIRV__)
#include "gpu/signal-macros.h"
#endif
diff --git a/libc/include/llvm-libc-types/__jmp_buf.h b/libc/include/llvm-libc-types/__jmp_buf.h
index a80afa2e6b815..266d2ffffa8b4 100644
--- a/libc/include/llvm-libc-types/__jmp_buf.h
+++ b/libc/include/llvm-libc-types/__jmp_buf.h
@@ -11,7 +11,7 @@
// TODO: implement sigjmp_buf related functions for other architectures
// Issue: https://github.com/llvm/llvm-project/issues/136358
-#if defined(__linux__)
+#if defined(__linux__) || defined(__APPLE__)
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
defined(__arm__) || defined(__riscv)
#define __LIBC_HAS_SIGJMP_BUF
diff --git a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
index a2066d1025f63..5155c20243794 100644
--- a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
+++ b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
@@ -29,13 +29,47 @@ namespace fputil {
struct FEnv {
struct FPState {
- uint64_t StatusWord;
- uint64_t ControlWord;
+ struct Word {
+ unsigned char Bytes[sizeof(uint32_t)];
+
+ LIBC_INLINE operator uint32_t() const {
+ uint32_t value;
+ __builtin_memcpy(&value, Bytes, sizeof(value));
+ return value;
+ }
+
+ LIBC_INLINE Word &operator=(uint32_t value) {
+ __builtin_memcpy(Bytes, &value, sizeof(value));
+ return *this;
+ }
+ };
+
+ Word ControlWord;
+ Word StatusWord;
};
static_assert(
sizeof(fenv_t) == sizeof(FPState),
"Internal floating point state does not match the public fenv_t type.");
+ static_assert(
+ alignof(fenv_t) == alignof(FPState),
+ "Internal floating point state alignment does not match the public "
+ "fenv_t type.");
+
+#ifndef FE_FLUSHTOZERO
+#ifdef FE_DENORM
+ static constexpr uint32_t FE_FLUSHTOZERO = FE_DENORM;
+#else
+ static constexpr uint32_t FE_FLUSHTOZERO = 0;
+#endif
+#endif
+
+ static constexpr uint32_t __fpcr_trap_invalid = 0x100;
+ static constexpr uint32_t __fpcr_trap_overflow = 0x200;
+ static constexpr uint32_t __fpcr_trap_underflow = 0x400;
+ static constexpr uint32_t __fpcr_trap_divbyzero = 0x800;
+ static constexpr uint32_t __fpcr_trap_inexact = 0x1000;
+ static constexpr uint32_t __fpcr_flush_to_zero = 0x1000000;
static constexpr uint32_t TONEAREST = 0x0;
static constexpr uint32_t UPWARD = 0x1;
diff --git a/libc/src/setjmp/aarch64/sigsetjmp.cpp b/libc/src/setjmp/aarch64/sigsetjmp.cpp
index 734591b2aca4c..9be4f13db021c 100644
--- a/libc/src/setjmp/aarch64/sigsetjmp.cpp
+++ b/libc/src/setjmp/aarch64/sigsetjmp.cpp
@@ -17,8 +17,9 @@ namespace LIBC_NAMESPACE_DECL {
[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
asm(R"(
- cbz w1, %c[setjmp]
-
+ cbnz w1, 1f
+ b %c[setjmp]
+1:
str x30, [x0, %c[retaddr]]
str x19, [x0, %c[extra]]
mov x19, x0
diff --git a/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp b/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
index 568545a20c50c..57165cbedb12b 100644
--- a/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
+++ b/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
@@ -7,15 +7,14 @@
//===----------------------------------------------------------------------===//
#include "src/setjmp/sigsetjmp_epilogue.h"
-#include "src/__support/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/signal/sigprocmask.h"
namespace LIBC_NAMESPACE_DECL {
[[gnu::returns_twice]] int sigsetjmp_epilogue(sigjmp_buf buffer, int retval) {
- syscall_impl<long>(sigprocmask, SIG_SETMASK,
- /* set= */ retval ? &buffer->sigmask : nullptr,
- /* old_set= */ retval ? nullptr : &buffer->sigmask);
+ sigprocmask(SIG_SETMASK,
+ /* set= */ retval ? &buffer->sigmask : nullptr,
+ /* old_set= */ retval ? nullptr : &buffer->sigmask);
return retval;
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/darwin/CMakeLists.txt b/libc/src/signal/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..9d7661d60bb2e
--- /dev/null
+++ b/libc/src/signal/darwin/CMakeLists.txt
@@ -0,0 +1,70 @@
+add_entrypoint_object(
+ sigprocmask
+ SRCS
+ sigprocmask.cpp
+ HDRS
+ ../sigprocmask.h
+ DEPENDS
+ libc.hdr.types.sigset_t
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ sigemptyset
+ SRCS
+ sigemptyset.cpp
+ HDRS
+ ../sigemptyset.h
+ DEPENDS
+ libc.hdr.types.sigset_t
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ sigfillset
+ SRCS
+ sigfillset.cpp
+ HDRS
+ ../sigfillset.h
+ DEPENDS
+ libc.hdr.types.sigset_t
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ sigaddset
+ SRCS
+ sigaddset.cpp
+ HDRS
+ ../sigaddset.h
+ DEPENDS
+ libc.hdr.types.sigset_t
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ sigdelset
+ SRCS
+ sigdelset.cpp
+ HDRS
+ ../sigdelset.h
+ DEPENDS
+ libc.hdr.types.sigset_t
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.errno.errno
+)
diff --git a/libc/src/signal/darwin/sigaddset.cpp b/libc/src/signal/darwin/sigaddset.cpp
new file mode 100644
index 0000000000000..2f005adc75df3
--- /dev/null
+++ b/libc/src/signal/darwin/sigaddset.cpp
@@ -0,0 +1,26 @@
+//===-- Darwin implementation of sigaddset ---------------------------------===//
+//
+// 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/signal/sigaddset.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, sigaddset, (sigset_t * set, int signum)) {
+ if (!set || signum <= 0 || signum >= NSIG) {
+ libc_errno = EINVAL;
+ return -1;
+ }
+ set->__signals[0] |= (1U << (signum - 1));
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/darwin/sigdelset.cpp b/libc/src/signal/darwin/sigdelset.cpp
new file mode 100644
index 0000000000000..d0d4f40cb98c3
--- /dev/null
+++ b/libc/src/signal/darwin/sigdelset.cpp
@@ -0,0 +1,26 @@
+//===-- Darwin implementation of sigdelset ---------------------------------===//
+//
+// 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/signal/sigdelset.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, sigdelset, (sigset_t * set, int signum)) {
+ if (!set || signum <= 0 || signum >= NSIG) {
+ libc_errno = EINVAL;
+ return -1;
+ }
+ set->__signals[0] &= ~(1U << (signum - 1));
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/darwin/sigemptyset.cpp b/libc/src/signal/darwin/sigemptyset.cpp
new file mode 100644
index 0000000000000..bbb1a681d960c
--- /dev/null
+++ b/libc/src/signal/darwin/sigemptyset.cpp
@@ -0,0 +1,26 @@
+//===-- Darwin implementation of sigemptyset -------------------------------===//
+//
+// 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/signal/sigemptyset.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, sigemptyset, (sigset_t * set)) {
+ if (!set) {
+ libc_errno = EINVAL;
+ return -1;
+ }
+ set->__signals[0] = 0;
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/darwin/sigfillset.cpp b/libc/src/signal/darwin/sigfillset.cpp
new file mode 100644
index 0000000000000..42a6aad9b9d4a
--- /dev/null
+++ b/libc/src/signal/darwin/sigfillset.cpp
@@ -0,0 +1,28 @@
+//===-- Darwin implementation of sigfillset --------------------------------===//
+//
+// 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/signal/sigfillset.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, sigfillset, (sigset_t * set)) {
+ if (!set) {
+ libc_errno = EINVAL;
+ return -1;
+ }
+ // On Darwin, the supported signal mask here covers signals 1..31, so only
+ // the lower 32 bits of the first word are used and bit 31 remains clear.
+ set->__signals[0] = 0x7FFFFFFFU;
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/signal/darwin/sigprocmask.cpp b/libc/src/signal/darwin/sigprocmask.cpp
new file mode 100644
index 0000000000000..dc4d6ca7438de
--- /dev/null
+++ b/libc/src/signal/darwin/sigprocmask.cpp
@@ -0,0 +1,45 @@
+//===-- Darwin implementation of sigprocmask -------------------------------===//
+//
+// 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/signal/sigprocmask.h"
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/sigset_t.h"
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, sigprocmask,
+ (int how, const sigset_t *__restrict set,
+ sigset_t *__restrict oldset)) {
+ uint32_t kernel_set = 0;
+ uint32_t kernel_oldset = 0;
+
+ if (set)
+ kernel_set = static_cast<uint32_t>(set->__signals[0] & 0x7FFFFFFFU);
+
+ int ret = LIBC_NAMESPACE::syscall_impl<int>(
+ SYS_sigprocmask, how, set ? &kernel_set : nullptr,
+ oldset ? &kernel_oldset : nullptr);
+ if (ret == 0) {
+ if (oldset)
+ oldset->__signals[0] =
+ static_cast<unsigned long>(kernel_oldset & 0x7FFFFFFFU);
+ return 0;
+ }
+
+ libc_errno = ret;
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
>From 24a9a4e4eca5c779c10425f9f4a66fd503ef68ea Mon Sep 17 00:00:00 2001
From: Kacper Fiedorowicz <kf at efab.pl>
Date: Thu, 16 Apr 2026 18:30:54 +0200
Subject: [PATCH 2/4] fix header comment formatting
---
libc/src/signal/darwin/sigaddset.cpp | 2 +-
libc/src/signal/darwin/sigdelset.cpp | 2 +-
libc/src/signal/darwin/sigemptyset.cpp | 2 +-
libc/src/signal/darwin/sigfillset.cpp | 2 +-
libc/src/signal/darwin/sigprocmask.cpp | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/libc/src/signal/darwin/sigaddset.cpp b/libc/src/signal/darwin/sigaddset.cpp
index 2f005adc75df3..decd09b2da4b8 100644
--- a/libc/src/signal/darwin/sigaddset.cpp
+++ b/libc/src/signal/darwin/sigaddset.cpp
@@ -1,4 +1,4 @@
-//===-- Darwin implementation of sigaddset ---------------------------------===//
+//===-- Darwin implementation of sigaddset --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/signal/darwin/sigdelset.cpp b/libc/src/signal/darwin/sigdelset.cpp
index d0d4f40cb98c3..b6dabe92ba73c 100644
--- a/libc/src/signal/darwin/sigdelset.cpp
+++ b/libc/src/signal/darwin/sigdelset.cpp
@@ -1,4 +1,4 @@
-//===-- Darwin implementation of sigdelset ---------------------------------===//
+//===-- Darwin implementation of sigdelset --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/signal/darwin/sigemptyset.cpp b/libc/src/signal/darwin/sigemptyset.cpp
index bbb1a681d960c..f98c2bad23809 100644
--- a/libc/src/signal/darwin/sigemptyset.cpp
+++ b/libc/src/signal/darwin/sigemptyset.cpp
@@ -1,4 +1,4 @@
-//===-- Darwin implementation of sigemptyset -------------------------------===//
+//===-- Darwin implementation of sigemptyset ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/signal/darwin/sigfillset.cpp b/libc/src/signal/darwin/sigfillset.cpp
index 42a6aad9b9d4a..45e596ad24b84 100644
--- a/libc/src/signal/darwin/sigfillset.cpp
+++ b/libc/src/signal/darwin/sigfillset.cpp
@@ -1,4 +1,4 @@
-//===-- Darwin implementation of sigfillset --------------------------------===//
+//===-- Darwin implementation of sigfillset -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/libc/src/signal/darwin/sigprocmask.cpp b/libc/src/signal/darwin/sigprocmask.cpp
index dc4d6ca7438de..754c3a1166640 100644
--- a/libc/src/signal/darwin/sigprocmask.cpp
+++ b/libc/src/signal/darwin/sigprocmask.cpp
@@ -1,4 +1,4 @@
-//===-- Darwin implementation of sigprocmask -------------------------------===//
+//===-- Darwin implementation of sigprocmask ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
>From 2337255e1e876cd2d53332bde6c814f4d7c78970 Mon Sep 17 00:00:00 2001
From: Kacper Fiedorowicz <kf at efab.pl>
Date: Tue, 28 Apr 2026 18:47:26 +0200
Subject: [PATCH 3/4] libc: fix Darwin AArch64 FPCR masks
---
.../FPUtil/aarch64/fenv_darwin_impl.h | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
index 5155c20243794..88f9f73f42e64 100644
--- a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
+++ b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
@@ -64,11 +64,14 @@ struct FEnv {
#endif
#endif
+ // These FPCR masks match the controllable FPCR bit definitions exposed by
+ // Darwin's arm64 <fenv.h>: __fpcr_trap_* and __fpcr_flush_to_zero.
static constexpr uint32_t __fpcr_trap_invalid = 0x100;
- static constexpr uint32_t __fpcr_trap_overflow = 0x200;
- static constexpr uint32_t __fpcr_trap_underflow = 0x400;
- static constexpr uint32_t __fpcr_trap_divbyzero = 0x800;
+ static constexpr uint32_t __fpcr_trap_divbyzero = 0x200;
+ static constexpr uint32_t __fpcr_trap_overflow = 0x400;
+ static constexpr uint32_t __fpcr_trap_underflow = 0x800;
static constexpr uint32_t __fpcr_trap_inexact = 0x1000;
+ static constexpr uint32_t __fpcr_trap_denormal = 0x8000;
static constexpr uint32_t __fpcr_flush_to_zero = 0x1000000;
static constexpr uint32_t TONEAREST = 0x0;
@@ -93,10 +96,9 @@ struct FEnv {
static constexpr uint32_t ROUNDING_CONTROL_BIT_POSITION = 22;
// In addition to the 5 floating point exceptions, macOS on arm64 defines
- // another floating point exception: FE_FLUSHTOZERO, which is controlled by
- // __fpcr_flush_to_zero bit in the FPCR register. This control bit is
- // located in a different place from FE_FLUSHTOZERO status bit relative to
- // the other exceptions.
+ // another floating point exception: FE_FLUSHTOZERO, also called the input
+ // denormal exception. Its trap-enable bit is __fpcr_trap_denormal, while
+ // __fpcr_flush_to_zero is a separate FPCR mode control.
LIBC_INLINE static uint32_t exception_value_from_status(uint32_t status) {
return ((status & FE_INVALID) ? EX_INVALID : 0) |
((status & FE_DIVBYZERO) ? EX_DIVBYZERO : 0) |
@@ -112,7 +114,7 @@ struct FEnv {
((control & __fpcr_trap_overflow) ? EX_OVERFLOW : 0) |
((control & __fpcr_trap_underflow) ? EX_UNDERFLOW : 0) |
((control & __fpcr_trap_inexact) ? EX_INEXACT : 0) |
- ((control & __fpcr_flush_to_zero) ? EX_FLUSHTOZERO : 0);
+ ((control & __fpcr_trap_denormal) ? EX_FLUSHTOZERO : 0);
}
LIBC_INLINE static uint32_t exception_value_to_status(uint32_t excepts) {
@@ -130,7 +132,7 @@ struct FEnv {
((excepts & EX_OVERFLOW) ? __fpcr_trap_overflow : 0) |
((excepts & EX_UNDERFLOW) ? __fpcr_trap_underflow : 0) |
((excepts & EX_INEXACT) ? __fpcr_trap_inexact : 0) |
- ((excepts & EX_FLUSHTOZERO) ? __fpcr_flush_to_zero : 0);
+ ((excepts & EX_FLUSHTOZERO) ? __fpcr_trap_denormal : 0);
}
LIBC_INLINE static uint32_t get_control_word() { return __arm_rsr("fpcr"); }
>From edfeb4b440d6ae29c6c78bcf9c0820c9dcaada92 Mon Sep 17 00:00:00 2001
From: Kacper Fiedorowicz <kf at efab.pl>
Date: Thu, 7 May 2026 10:40:13 +0200
Subject: [PATCH 4/4] [libc] Rename Darwin FPCR constants
---
.../FPUtil/aarch64/fenv_darwin_impl.h | 44 +++++++++----------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
index 88f9f73f42e64..30ef0510c6b04 100644
--- a/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
+++ b/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h
@@ -65,14 +65,14 @@ struct FEnv {
#endif
// These FPCR masks match the controllable FPCR bit definitions exposed by
- // Darwin's arm64 <fenv.h>: __fpcr_trap_* and __fpcr_flush_to_zero.
- static constexpr uint32_t __fpcr_trap_invalid = 0x100;
- static constexpr uint32_t __fpcr_trap_divbyzero = 0x200;
- static constexpr uint32_t __fpcr_trap_overflow = 0x400;
- static constexpr uint32_t __fpcr_trap_underflow = 0x800;
- static constexpr uint32_t __fpcr_trap_inexact = 0x1000;
- static constexpr uint32_t __fpcr_trap_denormal = 0x8000;
- static constexpr uint32_t __fpcr_flush_to_zero = 0x1000000;
+ // Darwin's arm64 <fenv.h>.
+ static constexpr uint32_t FPCR_TRAP_INVALID = 0x100;
+ static constexpr uint32_t FPCR_TRAP_DIVBYZERO = 0x200;
+ static constexpr uint32_t FPCR_TRAP_OVERFLOW = 0x400;
+ static constexpr uint32_t FPCR_TRAP_UNDERFLOW = 0x800;
+ static constexpr uint32_t FPCR_TRAP_INEXACT = 0x1000;
+ static constexpr uint32_t FPCR_TRAP_DENORMAL = 0x8000;
+ static constexpr uint32_t FPCR_FLUSH_TO_ZERO = 0x1000000;
static constexpr uint32_t TONEAREST = 0x0;
static constexpr uint32_t UPWARD = 0x1;
@@ -97,8 +97,8 @@ struct FEnv {
// In addition to the 5 floating point exceptions, macOS on arm64 defines
// another floating point exception: FE_FLUSHTOZERO, also called the input
- // denormal exception. Its trap-enable bit is __fpcr_trap_denormal, while
- // __fpcr_flush_to_zero is a separate FPCR mode control.
+ // denormal exception. Its trap-enable bit is FPCR_TRAP_DENORMAL, while
+ // FPCR_FLUSH_TO_ZERO is a separate FPCR mode control.
LIBC_INLINE static uint32_t exception_value_from_status(uint32_t status) {
return ((status & FE_INVALID) ? EX_INVALID : 0) |
((status & FE_DIVBYZERO) ? EX_DIVBYZERO : 0) |
@@ -109,12 +109,12 @@ struct FEnv {
}
LIBC_INLINE static uint32_t exception_value_from_control(uint32_t control) {
- return ((control & __fpcr_trap_invalid) ? EX_INVALID : 0) |
- ((control & __fpcr_trap_divbyzero) ? EX_DIVBYZERO : 0) |
- ((control & __fpcr_trap_overflow) ? EX_OVERFLOW : 0) |
- ((control & __fpcr_trap_underflow) ? EX_UNDERFLOW : 0) |
- ((control & __fpcr_trap_inexact) ? EX_INEXACT : 0) |
- ((control & __fpcr_trap_denormal) ? EX_FLUSHTOZERO : 0);
+ return ((control & FPCR_TRAP_INVALID) ? EX_INVALID : 0) |
+ ((control & FPCR_TRAP_DIVBYZERO) ? EX_DIVBYZERO : 0) |
+ ((control & FPCR_TRAP_OVERFLOW) ? EX_OVERFLOW : 0) |
+ ((control & FPCR_TRAP_UNDERFLOW) ? EX_UNDERFLOW : 0) |
+ ((control & FPCR_TRAP_INEXACT) ? EX_INEXACT : 0) |
+ ((control & FPCR_TRAP_DENORMAL) ? EX_FLUSHTOZERO : 0);
}
LIBC_INLINE static uint32_t exception_value_to_status(uint32_t excepts) {
@@ -127,12 +127,12 @@ struct FEnv {
}
LIBC_INLINE static uint32_t exception_value_to_control(uint32_t excepts) {
- return ((excepts & EX_INVALID) ? __fpcr_trap_invalid : 0) |
- ((excepts & EX_DIVBYZERO) ? __fpcr_trap_divbyzero : 0) |
- ((excepts & EX_OVERFLOW) ? __fpcr_trap_overflow : 0) |
- ((excepts & EX_UNDERFLOW) ? __fpcr_trap_underflow : 0) |
- ((excepts & EX_INEXACT) ? __fpcr_trap_inexact : 0) |
- ((excepts & EX_FLUSHTOZERO) ? __fpcr_trap_denormal : 0);
+ return ((excepts & EX_INVALID) ? FPCR_TRAP_INVALID : 0) |
+ ((excepts & EX_DIVBYZERO) ? FPCR_TRAP_DIVBYZERO : 0) |
+ ((excepts & EX_OVERFLOW) ? FPCR_TRAP_OVERFLOW : 0) |
+ ((excepts & EX_UNDERFLOW) ? FPCR_TRAP_UNDERFLOW : 0) |
+ ((excepts & EX_INEXACT) ? FPCR_TRAP_INEXACT : 0) |
+ ((excepts & EX_FLUSHTOZERO) ? FPCR_TRAP_DENORMAL : 0);
}
LIBC_INLINE static uint32_t get_control_word() { return __arm_rsr("fpcr"); }
More information about the libc-commits
mailing list