1218885Sdim//===- llvm/Support/FEnv.h - Host floating-point exceptions ------*- C++ -*-===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim//
10218885Sdim// This file provides an operating system independent interface to
11218885Sdim// floating-point exception interfaces.
12218885Sdim//
13218885Sdim//===----------------------------------------------------------------------===//
14218885Sdim
15249423Sdim#ifndef LLVM_SUPPORT_FENV_H
16249423Sdim#define LLVM_SUPPORT_FENV_H
17218885Sdim
18218885Sdim#include "llvm/Config/config.h"
19218885Sdim#include <cerrno>
20218885Sdim#ifdef HAVE_FENV_H
21218885Sdim#include <fenv.h>
22218885Sdim#endif
23218885Sdim
24218885Sdim// FIXME: Clang's #include handling apparently doesn't work for libstdc++'s
25218885Sdim// fenv.h; see PR6907 for details.
26218885Sdim#if defined(__clang__) && defined(_GLIBCXX_FENV_H)
27218885Sdim#undef HAVE_FENV_H
28218885Sdim#endif
29218885Sdim
30218885Sdimnamespace llvm {
31218885Sdimnamespace sys {
32218885Sdim
33218885Sdim/// llvm_fenv_clearexcept - Clear the floating-point exception state.
34218885Sdimstatic inline void llvm_fenv_clearexcept() {
35249423Sdim#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
36218885Sdim  feclearexcept(FE_ALL_EXCEPT);
37218885Sdim#endif
38218885Sdim  errno = 0;
39218885Sdim}
40218885Sdim
41218885Sdim/// llvm_fenv_testexcept - Test if a floating-point exception was raised.
42218885Sdimstatic inline bool llvm_fenv_testexcept() {
43218885Sdim  int errno_val = errno;
44218885Sdim  if (errno_val == ERANGE || errno_val == EDOM)
45218885Sdim    return true;
46249423Sdim#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
47218885Sdim  if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
48218885Sdim    return true;
49218885Sdim#endif
50218885Sdim  return false;
51218885Sdim}
52218885Sdim
53218885Sdim} // End sys namespace
54218885Sdim} // End llvm namespace
55218885Sdim
56218885Sdim#endif
57