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