[libc-commits] [PATCH] D95637: [libc] set the ES bit when raising FP exceptions on x86

Michael Jones via Phabricator via libc-commits libc-commits at lists.llvm.org
Thu Jan 28 11:51:18 PST 2021


michaelrj created this revision.
michaelrj added a reviewer: sivachandra.
Herald added subscribers: libc-commits, ecnelises, tschuett.
Herald added a project: libc-project.
michaelrj requested review of this revision.

This change brings our fenv implementation up to spec with the
"Intel 64 and IA-32 Architectures Software Developer's Manual, Vol 1"
section 8.7.1. The reason behind this is that it should fix a breaking
one of our tests under Fuchsia.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D95637

Files:
  libc/utils/FPUtil/x86_64/FEnv.h


Index: libc/utils/FPUtil/x86_64/FEnv.h
===================================================================
--- libc/utils/FPUtil/x86_64/FEnv.h
+++ libc/utils/FPUtil/x86_64/FEnv.h
@@ -48,6 +48,8 @@
   static constexpr uint16_t Inexact = 0x20;
 };
 
+static constexpr uint16_t ExceptionSummaryStatusBit = 0x80;
+
 // The exception control bits occupy six bits, one bit for each exception.
 // In the x87 control word, they occupy the first 6 bits. In the MXCSR
 // register, they occupy bits 7 to 12.
@@ -194,6 +196,13 @@
       (statusValue & internal::getMXCSR()));
 }
 
+static inline int isEnabled(int excepts) {
+  uint16_t x87CW = internal::getX87ControlWord();
+  return excepts & (~x87CW);
+  // since we want each bit where excepts is 1 and x87CW is 0
+  // (since 0 means enabled) I just and excepts and the inverse of the CW state.
+}
+
 static inline int raiseExcept(int excepts) {
   uint16_t statusValue = internal::getStatusValueForExcept(excepts);
 
@@ -214,6 +223,9 @@
     internal::X87State state;
     internal::getX87State(state);
     state.StatusWord |= internal::ExceptionFlags::Invalid;
+    if (isEnabled(internal::ExceptionFlags::Invalid)) {
+      state.StatusWord |= internal::ExceptionSummaryStatusBit;
+    }
     internal::writeX87State(state);
     internal::fwait();
   }
@@ -221,6 +233,9 @@
     internal::X87State state;
     internal::getX87State(state);
     state.StatusWord |= internal::ExceptionFlags::DivByZero;
+    if (isEnabled(internal::ExceptionFlags::DivByZero)) {
+      state.StatusWord |= internal::ExceptionSummaryStatusBit;
+    }
     internal::writeX87State(state);
     internal::fwait();
   }
@@ -228,6 +243,9 @@
     internal::X87State state;
     internal::getX87State(state);
     state.StatusWord |= internal::ExceptionFlags::Overflow;
+    if (isEnabled(internal::ExceptionFlags::Overflow)) {
+      state.StatusWord |= internal::ExceptionSummaryStatusBit;
+    }
     internal::writeX87State(state);
     internal::fwait();
   }
@@ -235,6 +253,9 @@
     internal::X87State state;
     internal::getX87State(state);
     state.StatusWord |= internal::ExceptionFlags::Underflow;
+    if (isEnabled(internal::ExceptionFlags::Underflow)) {
+      state.StatusWord |= internal::ExceptionSummaryStatusBit;
+    }
     internal::writeX87State(state);
     internal::fwait();
   }
@@ -242,6 +263,9 @@
     internal::X87State state;
     internal::getX87State(state);
     state.StatusWord |= internal::ExceptionFlags::Inexact;
+    if (isEnabled(internal::ExceptionFlags::Inexact)) {
+      state.StatusWord |= internal::ExceptionSummaryStatusBit;
+    }
     internal::writeX87State(state);
     internal::fwait();
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95637.319934.patch
Type: text/x-patch
Size: 2674 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20210128/6c677ed7/attachment.bin>


More information about the libc-commits mailing list