1837dab96SRoland McGrath //===-- FEnvSafeTest.cpp ---------------------------------------*- C++ -*-===// 2837dab96SRoland McGrath // 3837dab96SRoland McGrath // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4837dab96SRoland McGrath // See https://llvm.org/LICENSE.txt for license information. 5837dab96SRoland McGrath // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6837dab96SRoland McGrath // 7837dab96SRoland McGrath //===---------------------------------------------------------------------===// 8837dab96SRoland McGrath 9837dab96SRoland McGrath #include "FEnvSafeTest.h" 10837dab96SRoland McGrath 11837dab96SRoland McGrath #include "src/__support/FPUtil/FEnvImpl.h" 12*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 13837dab96SRoland McGrath #include "src/__support/macros/properties/architectures.h" 14837dab96SRoland McGrath 15*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 16*5ff3ff33SPetr Hosek namespace testing { 17837dab96SRoland McGrath 18837dab96SRoland McGrath void FEnvSafeTest::PreserveFEnv::check() { 19837dab96SRoland McGrath fenv_t after; 20837dab96SRoland McGrath test.get_fenv(after); 21837dab96SRoland McGrath test.expect_fenv_eq(before, after); 22837dab96SRoland McGrath } 23837dab96SRoland McGrath 24837dab96SRoland McGrath void FEnvSafeTest::TearDown() { 25837dab96SRoland McGrath if (!should_be_unchanged) { 26837dab96SRoland McGrath restore_fenv(); 27837dab96SRoland McGrath } 28837dab96SRoland McGrath } 29837dab96SRoland McGrath 30837dab96SRoland McGrath void FEnvSafeTest::get_fenv(fenv_t &fenv) { 31837dab96SRoland McGrath ASSERT_EQ(LIBC_NAMESPACE::fputil::get_env(&fenv), 0); 32837dab96SRoland McGrath } 33837dab96SRoland McGrath 34837dab96SRoland McGrath void FEnvSafeTest::set_fenv(const fenv_t &fenv) { 35837dab96SRoland McGrath ASSERT_EQ(LIBC_NAMESPACE::fputil::set_env(&fenv), 0); 36837dab96SRoland McGrath } 37837dab96SRoland McGrath 38837dab96SRoland McGrath void FEnvSafeTest::expect_fenv_eq(const fenv_t &before_fenv, 39837dab96SRoland McGrath const fenv_t &after_fenv) { 40837dab96SRoland McGrath #if defined(LIBC_TARGET_ARCH_IS_AARCH64) 41859de945SRoland McGrath using FPState = LIBC_NAMESPACE::fputil::FEnv::FPState; 42837dab96SRoland McGrath const FPState &before_state = reinterpret_cast<const FPState &>(before_fenv); 43837dab96SRoland McGrath const FPState &after_state = reinterpret_cast<const FPState &>(after_fenv); 44837dab96SRoland McGrath 45837dab96SRoland McGrath EXPECT_EQ(before_state.ControlWord, after_state.ControlWord); 46837dab96SRoland McGrath EXPECT_EQ(before_state.StatusWord, after_state.StatusWord); 47837dab96SRoland McGrath 48837dab96SRoland McGrath #elif defined(LIBC_TARGET_ARCH_IS_X86) && !defined(__APPLE__) 49837dab96SRoland McGrath using LIBC_NAMESPACE::fputil::internal::FPState; 50837dab96SRoland McGrath const FPState &before_state = reinterpret_cast<const FPState &>(before_fenv); 51837dab96SRoland McGrath const FPState &after_state = reinterpret_cast<const FPState &>(after_fenv); 52837dab96SRoland McGrath 53837dab96SRoland McGrath #if defined(_WIN32) 54837dab96SRoland McGrath EXPECT_EQ(before_state.control_word, after_state.control_word); 55837dab96SRoland McGrath EXPECT_EQ(before_state.status_word, after_state.status_word); 56837dab96SRoland McGrath #elif defined(__APPLE__) 57837dab96SRoland McGrath EXPECT_EQ(before_state.control_word, after_state.control_word); 58837dab96SRoland McGrath EXPECT_EQ(before_state.status_word, after_state.status_word); 59837dab96SRoland McGrath EXPECT_EQ(before_state.mxcsr, after_state.mxcsr); 60837dab96SRoland McGrath #else 61837dab96SRoland McGrath EXPECT_EQ(before_state.x87_status.control_word, 62837dab96SRoland McGrath after_state.x87_status.control_word); 63837dab96SRoland McGrath EXPECT_EQ(before_state.x87_status.status_word, 64837dab96SRoland McGrath after_state.x87_status.status_word); 65837dab96SRoland McGrath EXPECT_EQ(before_state.mxcsr, after_state.mxcsr); 66837dab96SRoland McGrath #endif 67837dab96SRoland McGrath 68837dab96SRoland McGrath #elif defined(LIBC_TARGET_ARCH_IS_ARM) && defined(__ARM_FP) 69837dab96SRoland McGrath using LIBC_NAMESPACE::fputil::FEnv; 70837dab96SRoland McGrath const FEnv &before_state = reinterpret_cast<const FEnv &>(before_fenv); 71837dab96SRoland McGrath const FEnv &after_state = reinterpret_cast<const FEnv &>(after_fenv); 72837dab96SRoland McGrath 73837dab96SRoland McGrath EXPECT_EQ(before_state.fpscr, after_state.fpscr); 74837dab96SRoland McGrath 75837dab96SRoland McGrath #elif defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) 76837dab96SRoland McGrath const uint32_t &before_fcsr = reinterpret_cast<const uint32_t &>(before_fenv); 77837dab96SRoland McGrath const uint32_t &after_fcsr = reinterpret_cast<const uint32_t &>(after_fenv); 78837dab96SRoland McGrath EXPECT_EQ(before_fcsr, after_fcsr); 79837dab96SRoland McGrath 80837dab96SRoland McGrath #else 81837dab96SRoland McGrath // No arch-specific `fenv_t` support, so nothing to compare. 82837dab96SRoland McGrath 83837dab96SRoland McGrath #endif 84837dab96SRoland McGrath } 85837dab96SRoland McGrath 86*5ff3ff33SPetr Hosek } // namespace testing 87*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 88