1*04c681d1SAlex Brachet //===-- RoundingModeUtils.cpp ---------------------------------------------===//
2*04c681d1SAlex Brachet //
3*04c681d1SAlex Brachet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*04c681d1SAlex Brachet // See https://llvm.org/LICENSE.txt for license information.
5*04c681d1SAlex Brachet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*04c681d1SAlex Brachet //
7*04c681d1SAlex Brachet //===----------------------------------------------------------------------===//
8*04c681d1SAlex Brachet 
9*04c681d1SAlex Brachet #include "RoundingModeUtils.h"
10*04c681d1SAlex Brachet 
11*04c681d1SAlex Brachet #include <fenv.h>
12*04c681d1SAlex Brachet 
13*04c681d1SAlex Brachet namespace __llvm_libc {
14*04c681d1SAlex Brachet namespace testutils {
15*04c681d1SAlex Brachet 
get_fe_rounding(RoundingMode mode)16*04c681d1SAlex Brachet int get_fe_rounding(RoundingMode mode) {
17*04c681d1SAlex Brachet   switch (mode) {
18*04c681d1SAlex Brachet   case RoundingMode::Upward:
19*04c681d1SAlex Brachet     return FE_UPWARD;
20*04c681d1SAlex Brachet     break;
21*04c681d1SAlex Brachet   case RoundingMode::Downward:
22*04c681d1SAlex Brachet     return FE_DOWNWARD;
23*04c681d1SAlex Brachet     break;
24*04c681d1SAlex Brachet   case RoundingMode::TowardZero:
25*04c681d1SAlex Brachet     return FE_TOWARDZERO;
26*04c681d1SAlex Brachet     break;
27*04c681d1SAlex Brachet   case RoundingMode::Nearest:
28*04c681d1SAlex Brachet     return FE_TONEAREST;
29*04c681d1SAlex Brachet     break;
30*04c681d1SAlex Brachet   }
31*04c681d1SAlex Brachet }
32*04c681d1SAlex Brachet 
ForceRoundingMode(RoundingMode mode)33*04c681d1SAlex Brachet ForceRoundingMode::ForceRoundingMode(RoundingMode mode) {
34*04c681d1SAlex Brachet   old_rounding_mode = fegetround();
35*04c681d1SAlex Brachet   rounding_mode = get_fe_rounding(mode);
36*04c681d1SAlex Brachet   if (old_rounding_mode != rounding_mode)
37*04c681d1SAlex Brachet     fesetround(rounding_mode);
38*04c681d1SAlex Brachet }
39*04c681d1SAlex Brachet 
~ForceRoundingMode()40*04c681d1SAlex Brachet ForceRoundingMode::~ForceRoundingMode() {
41*04c681d1SAlex Brachet   if (old_rounding_mode != rounding_mode)
42*04c681d1SAlex Brachet     fesetround(old_rounding_mode);
43*04c681d1SAlex Brachet }
44*04c681d1SAlex Brachet 
45*04c681d1SAlex Brachet } // namespace testutils
46*04c681d1SAlex Brachet } // namespace __llvm_libc
47