xref: /llvm-project/libc/test/UnitTest/FEnvSafeTest.cpp (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
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