96 lines · cpp
1//===-- FEnvSafeTest.cpp ---------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===---------------------------------------------------------------------===//8 9#include "FEnvSafeTest.h"10 11#include "src/__support/FPUtil/FEnvImpl.h"12#include "src/__support/libc_errno.h"13#include "src/__support/macros/config.h"14#include "src/__support/macros/properties/architectures.h"15#include "test/UnitTest/ErrnoCheckingTest.h"16 17namespace LIBC_NAMESPACE_DECL {18namespace testing {19 20void FEnvSafeTest::PreserveFEnv::check() {21 fenv_t after;22 test.get_fenv(after);23 test.expect_fenv_eq(before, after);24}25 26void FEnvSafeTest::TearDown() {27 if (!should_be_unchanged) {28 restore_fenv();29 }30 // TODO (PR 135320): Remove this override once all FEnvSafeTest instances are31 // updated to validate or ignore errno.32 libc_errno = 0;33 ErrnoCheckingTest::TearDown();34}35 36void FEnvSafeTest::get_fenv(fenv_t &fenv) {37 ASSERT_EQ(LIBC_NAMESPACE::fputil::get_env(&fenv), 0);38}39 40void FEnvSafeTest::set_fenv(const fenv_t &fenv) {41 ASSERT_EQ(LIBC_NAMESPACE::fputil::set_env(&fenv), 0);42}43 44void FEnvSafeTest::expect_fenv_eq(const fenv_t &before_fenv,45 const fenv_t &after_fenv) {46#if defined(LIBC_TARGET_ARCH_IS_AARCH64) && !defined(LIBC_COMPILER_IS_MSVC) && \47 defined(__ARM_FP)48 using FPState = LIBC_NAMESPACE::fputil::FEnv::FPState;49 const FPState &before_state = reinterpret_cast<const FPState &>(before_fenv);50 const FPState &after_state = reinterpret_cast<const FPState &>(after_fenv);51 52 EXPECT_EQ(before_state.ControlWord, after_state.ControlWord);53 EXPECT_EQ(before_state.StatusWord, after_state.StatusWord);54 55#elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) && \56 !defined(LIBC_COMPILER_IS_MSVC)57 using LIBC_NAMESPACE::fputil::internal::FPState;58 const FPState &before_state = reinterpret_cast<const FPState &>(before_fenv);59 const FPState &after_state = reinterpret_cast<const FPState &>(after_fenv);60 61#if defined(_WIN32)62 EXPECT_EQ(before_state.control_word, after_state.control_word);63 EXPECT_EQ(before_state.status_word, after_state.status_word);64#elif defined(__APPLE__)65 EXPECT_EQ(before_state.control_word, after_state.control_word);66 EXPECT_EQ(before_state.status_word, after_state.status_word);67 EXPECT_EQ(before_state.mxcsr, after_state.mxcsr);68#else69 EXPECT_EQ(before_state.x87_status.control_word,70 after_state.x87_status.control_word);71 EXPECT_EQ(before_state.x87_status.status_word,72 after_state.x87_status.status_word);73 EXPECT_EQ(before_state.mxcsr, after_state.mxcsr);74#endif75 76#elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP)77 using LIBC_NAMESPACE::fputil::FEnv;78 const FEnv &before_state = reinterpret_cast<const FEnv &>(before_fenv);79 const FEnv &after_state = reinterpret_cast<const FEnv &>(after_fenv);80 81 EXPECT_EQ(before_state.fpscr, after_state.fpscr);82 83#elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)84 const uint32_t &before_fcsr = reinterpret_cast<const uint32_t &>(before_fenv);85 const uint32_t &after_fcsr = reinterpret_cast<const uint32_t &>(after_fenv);86 EXPECT_EQ(before_fcsr, after_fcsr);87 88#else89 // No arch-specific `fenv_t` support, so nothing to compare.90 91#endif92}93 94} // namespace testing95} // namespace LIBC_NAMESPACE_DECL96