[libc-commits] [libc] [libc] fix woa64 fenv implementation (PR #119155)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Sun Dec 8 17:20:51 PST 2024


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/119155

>From 7c53723fb46e197459fb7f81c87ad2994675f08d Mon Sep 17 00:00:00 2001
From: schrodingerzhu <i at zhuyi.fan>
Date: Sun, 8 Dec 2024 19:44:35 -0500
Subject: [PATCH 1/2] [libc] fix woa64 fenv implementation

---
 libc/src/__support/FPUtil/aarch64/FEnvImpl.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
index 3cea9772154fc6..ff3485de4a007d 100644
--- a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
@@ -26,7 +26,10 @@
 
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
-
+#pragma push_macro("OVERFLOW")
+#undef OVERFLOW
+#pragma push_macro("UNDERFLOW")
+#undef UNDERFLOW
 struct FEnv {
   struct FPState {
     uint32_t ControlWord;
@@ -279,6 +282,8 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
   return 0;
 }
 
+#pragma pop_macro("UNDERFLOW")
+#pragma pop_macro("OVERFLOW")
 } // namespace fputil
 } // namespace LIBC_NAMESPACE_DECL
 

>From 8c77a4f55a26b6640e0d01c3f52125f3a82562d7 Mon Sep 17 00:00:00 2001
From: schrodingerzhu <i at zhuyi.fan>
Date: Sun, 8 Dec 2024 20:20:39 -0500
Subject: [PATCH 2/2] [libc] fix woa64 fenv implementation

---
 libc/src/__support/FPUtil/aarch64/FEnvImpl.h | 57 +++++++++-----------
 1 file changed, 25 insertions(+), 32 deletions(-)

diff --git a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
index ff3485de4a007d..18b0631324f8fb 100644
--- a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
+++ b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h
@@ -26,10 +26,6 @@
 
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
-#pragma push_macro("OVERFLOW")
-#undef OVERFLOW
-#pragma push_macro("UNDERFLOW")
-#undef UNDERFLOW
 struct FEnv {
   struct FPState {
     uint32_t ControlWord;
@@ -45,11 +41,11 @@ struct FEnv {
   static constexpr uint32_t DOWNWARD = 0x2;
   static constexpr uint32_t TOWARDZERO = 0x3;
 
-  static constexpr uint32_t INVALID = 0x1;
-  static constexpr uint32_t DIVBYZERO = 0x2;
-  static constexpr uint32_t OVERFLOW = 0x4;
-  static constexpr uint32_t UNDERFLOW = 0x8;
-  static constexpr uint32_t INEXACT = 0x10;
+  static constexpr uint32_t INVALID_F = 0x1;
+  static constexpr uint32_t DIVBYZERO_F = 0x2;
+  static constexpr uint32_t OVERFLOW_F = 0x4;
+  static constexpr uint32_t UNDERFLOW_F = 0x8;
+  static constexpr uint32_t INEXACT_F = 0x10;
 
   // Zero-th bit is the first bit.
   static constexpr uint32_t RoundingControlBitPosition = 22;
@@ -57,19 +53,19 @@ struct FEnv {
   static constexpr uint32_t ExceptionControlFlagsBitPosition = 8;
 
   LIBC_INLINE static uint32_t getStatusValueForExcept(int excepts) {
-    return ((excepts & FE_INVALID) ? INVALID : 0) |
-           ((excepts & FE_DIVBYZERO) ? DIVBYZERO : 0) |
-           ((excepts & FE_OVERFLOW) ? OVERFLOW : 0) |
-           ((excepts & FE_UNDERFLOW) ? UNDERFLOW : 0) |
-           ((excepts & FE_INEXACT) ? INEXACT : 0);
+    return ((excepts & FE_INVALID) ? INVALID_F : 0) |
+           ((excepts & FE_DIVBYZERO) ? DIVBYZERO_F : 0) |
+           ((excepts & FE_OVERFLOW) ? OVERFLOW_F : 0) |
+           ((excepts & FE_UNDERFLOW) ? UNDERFLOW_F : 0) |
+           ((excepts & FE_INEXACT) ? INEXACT_F : 0);
   }
 
   LIBC_INLINE static int exceptionStatusToMacro(uint32_t status) {
-    return ((status & INVALID) ? FE_INVALID : 0) |
-           ((status & DIVBYZERO) ? FE_DIVBYZERO : 0) |
-           ((status & OVERFLOW) ? FE_OVERFLOW : 0) |
-           ((status & UNDERFLOW) ? FE_UNDERFLOW : 0) |
-           ((status & INEXACT) ? FE_INEXACT : 0);
+    return ((status & INVALID_F) ? FE_INVALID : 0) |
+           ((status & DIVBYZERO_F) ? FE_DIVBYZERO : 0) |
+           ((status & OVERFLOW_F) ? FE_OVERFLOW : 0) |
+           ((status & UNDERFLOW_F) ? FE_UNDERFLOW : 0) |
+           ((status & INEXACT_F) ? FE_INEXACT : 0);
   }
 
   static uint32_t getControlWord() {
@@ -174,36 +170,36 @@ LIBC_INLINE int raise_except(int excepts) {
   uint32_t toRaise = FEnv::getStatusValueForExcept(excepts);
   int result = 0;
 
-  if (toRaise & FEnv::INVALID) {
+  if (toRaise & FEnv::INVALID_F) {
     divfunc(zero, zero);
     uint32_t statusWord = FEnv::getStatusWord();
     if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
-          FEnv::INVALID))
+          FEnv::INVALID_F))
       result = -1;
   }
 
-  if (toRaise & FEnv::DIVBYZERO) {
+  if (toRaise & FEnv::DIVBYZERO_F) {
     divfunc(one, zero);
     uint32_t statusWord = FEnv::getStatusWord();
     if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
-          FEnv::DIVBYZERO))
+          FEnv::DIVBYZERO_F))
       result = -1;
   }
-  if (toRaise & FEnv::OVERFLOW) {
+  if (toRaise & FEnv::OVERFLOW_F) {
     divfunc(largeValue, smallValue);
     uint32_t statusWord = FEnv::getStatusWord();
     if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
-          FEnv::OVERFLOW))
+          FEnv::OVERFLOW_F))
       result = -1;
   }
-  if (toRaise & FEnv::UNDERFLOW) {
+  if (toRaise & FEnv::UNDERFLOW_F) {
     divfunc(smallValue, largeValue);
     uint32_t statusWord = FEnv::getStatusWord();
     if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
-          FEnv::UNDERFLOW))
+          FEnv::UNDERFLOW_F))
       result = -1;
   }
-  if (toRaise & FEnv::INEXACT) {
+  if (toRaise & FEnv::INEXACT_F) {
     float two = 2.0f;
     float three = 3.0f;
     // 2.0 / 3.0 cannot be represented exactly in any radix 2 floating point
@@ -211,7 +207,7 @@ LIBC_INLINE int raise_except(int excepts) {
     divfunc(two, three);
     uint32_t statusWord = FEnv::getStatusWord();
     if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) &
-          FEnv::INEXACT))
+          FEnv::INEXACT_F))
       result = -1;
   }
   return result;
@@ -281,9 +277,6 @@ LIBC_INLINE int set_env(const fenv_t *envp) {
   FEnv::writeStatusWord(state->StatusWord);
   return 0;
 }
-
-#pragma pop_macro("UNDERFLOW")
-#pragma pop_macro("OVERFLOW")
 } // namespace fputil
 } // namespace LIBC_NAMESPACE_DECL
 



More information about the libc-commits mailing list