Changeset View
Changeset View
Standalone View
Standalone View
flang/lib/Evaluate/host.cpp
//===-- lib/Evaluate/host.cpp ---------------------------------------------===// | //===-- lib/Evaluate/host.cpp ---------------------------------------------===// | ||||
Lint: Lint: clang-format not found in user's PATH; not linting file. | |||||
// | // | ||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||||
// See https://llvm.org/LICENSE.txt for license information. | // See https://llvm.org/LICENSE.txt for license information. | ||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||||
// | // | ||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "host.h" | #include "host.h" | ||||
#include "flang/Common/idioms.h" | #include "flang/Common/idioms.h" | ||||
#include "llvm/Support/Errno.h" | #include "llvm/Support/Errno.h" | ||||
#include <cfenv> | #include <cfenv> | ||||
#if __x86_64__ && defined(_MSC_VER) | |||||
#include <xmmintrin.h> | |||||
#endif | |||||
namespace Fortran::evaluate::host { | namespace Fortran::evaluate::host { | ||||
using namespace Fortran::parser::literals; | using namespace Fortran::parser::literals; | ||||
void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment( | void HostFloatingPointEnvironment::SetUpHostFloatingPointEnvironment( | ||||
FoldingContext &context) { | FoldingContext &context) { | ||||
errno = 0; | errno = 0; | ||||
if (feholdexcept(&originalFenv_) != 0) { | if (feholdexcept(&originalFenv_) != 0) { | ||||
common::die("Folding with host runtime: feholdexcept() failed: %s", | common::die("Folding with host runtime: feholdexcept() failed: %s", | ||||
llvm::sys::StrError(errno).c_str()); | llvm::sys::StrError(errno).c_str()); | ||||
return; | return; | ||||
} | } | ||||
if (fegetenv(¤tFenv_) != 0) { | if (fegetenv(¤tFenv_) != 0) { | ||||
common::die("Folding with host runtime: fegetenv() failed: %s", | common::die("Folding with host runtime: fegetenv() failed: %s", | ||||
llvm::sys::StrError(errno).c_str()); | llvm::sys::StrError(errno).c_str()); | ||||
return; | return; | ||||
} | } | ||||
#if __x86_64__ | #if __x86_64__ | ||||
hasSubnormalFlushingHardwareControl_ = true; | hasSubnormalFlushingHardwareControl_ = true; | ||||
#ifdef _MSC_VER | |||||
unsigned int new_mxcsr{_mm_getcsr()}; | |||||
if (context.flushSubnormalsToZero()) { | |||||
new_mxcsr |= 0x8000; | |||||
new_mxcsr |= 0x0040; | |||||
} else { | |||||
new_mxcsr &= ~0x8000; | |||||
new_mxcsr &= ~0x0040; | |||||
} | |||||
#else | |||||
if (context.flushSubnormalsToZero()) { | if (context.flushSubnormalsToZero()) { | ||||
currentFenv_.__mxcsr |= 0x8000; // result | currentFenv_.__mxcsr |= 0x8000; // result | ||||
currentFenv_.__mxcsr |= 0x0040; // operands | currentFenv_.__mxcsr |= 0x0040; // operands | ||||
} else { | } else { | ||||
currentFenv_.__mxcsr &= ~0x8000; // result | currentFenv_.__mxcsr &= ~0x8000; // result | ||||
currentFenv_.__mxcsr &= ~0x0040; // operands | currentFenv_.__mxcsr &= ~0x0040; // operands | ||||
} | } | ||||
#endif | |||||
#elif defined(__aarch64__) | #elif defined(__aarch64__) | ||||
#if defined(__GNU_LIBRARY__) | #if defined(__GNU_LIBRARY__) | ||||
hasSubnormalFlushingHardwareControl_ = true; | hasSubnormalFlushingHardwareControl_ = true; | ||||
if (context.flushSubnormalsToZero()) { | if (context.flushSubnormalsToZero()) { | ||||
currentFenv_.__fpcr |= (1U << 24); // control register | currentFenv_.__fpcr |= (1U << 24); // control register | ||||
} else { | } else { | ||||
currentFenv_.__fpcr &= ~(1U << 24); // control register | currentFenv_.__fpcr &= ~(1U << 24); // control register | ||||
} | } | ||||
Show All 22 Lines | #ifdef __clang__ | ||||
hardwareFlagsAreReliable_ = false; | hardwareFlagsAreReliable_ = false; | ||||
#endif | #endif | ||||
errno = 0; | errno = 0; | ||||
if (fesetenv(¤tFenv_) != 0) { | if (fesetenv(¤tFenv_) != 0) { | ||||
common::die("Folding with host runtime: fesetenv() failed: %s", | common::die("Folding with host runtime: fesetenv() failed: %s", | ||||
llvm::sys::StrError(errno).c_str()); | llvm::sys::StrError(errno).c_str()); | ||||
return; | return; | ||||
} | } | ||||
#if __x86_64__ && defined(_MSC_VER) | |||||
_mm_setcsr(new_mxcsr); | |||||
#endif | |||||
switch (context.rounding().mode) { | switch (context.rounding().mode) { | ||||
case common::RoundingMode::TiesToEven: | case common::RoundingMode::TiesToEven: | ||||
fesetround(FE_TONEAREST); | fesetround(FE_TONEAREST); | ||||
break; | break; | ||||
case common::RoundingMode::ToZero: | case common::RoundingMode::ToZero: | ||||
fesetround(FE_TOWARDZERO); | fesetround(FE_TOWARDZERO); | ||||
break; | break; | ||||
case common::RoundingMode::Up: | case common::RoundingMode::Up: | ||||
▲ Show 20 Lines • Show All 61 Lines • Show Last 20 Lines |
clang-format not found in user's PATH; not linting file.