1 //===-- Common header for helpers to set exceptional values -----*- 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_EXCEPT_VALUE_UTILS_H 10 #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_EXCEPT_VALUE_UTILS_H 11 12 #include "FEnvImpl.h" 13 #include "FPBits.h" 14 15 namespace __llvm_libc { 16 17 namespace fputil { 18 19 template <typename T, int N> struct ExceptionalValues { 20 using UIntType = typename FPBits<T>::UIntType; 21 static constexpr int SIZE = N; 22 // Input bits. 23 UIntType inputs[SIZE]; 24 // Output bits contains 4 values: 25 // output[i][0]: output bits corresponding to FE_TOWARDZERO 26 // output[i][1]: offset for FE_UPWARD 27 // output[i][2]: offset for FE_DOWNWARD 28 // output[i][3]: offset for FE_TONEAREST 29 UIntType outputs[SIZE][4]; 30 }; 31 32 template <typename T, int N> struct ExceptionChecker { 33 using UIntType = typename FPBits<T>::UIntType; 34 using FPBits = FPBits<T>; 35 using ExceptionalValues = ExceptionalValues<T, N>; 36 check_odd_funcExceptionChecker37 static bool check_odd_func(const ExceptionalValues &ExceptVals, 38 UIntType x_abs, bool sign, T &result) { 39 for (int i = 0; i < N; ++i) { 40 if (unlikely(x_abs == ExceptVals.inputs[i])) { 41 UIntType out_bits = ExceptVals.outputs[i][0]; // FE_TOWARDZERO 42 switch (fputil::get_round()) { 43 case FE_UPWARD: 44 out_bits += 45 sign ? ExceptVals.outputs[i][2] : ExceptVals.outputs[i][1]; 46 break; 47 case FE_DOWNWARD: 48 out_bits += 49 sign ? ExceptVals.outputs[i][1] : ExceptVals.outputs[i][2]; 50 break; 51 case FE_TONEAREST: 52 out_bits += ExceptVals.outputs[i][3]; 53 break; 54 } 55 result = FPBits(out_bits).get_val(); 56 if (sign) 57 result = -result; 58 59 return true; 60 } 61 } 62 return false; 63 } 64 }; 65 66 } // namespace fputil 67 68 } // namespace __llvm_libc 69 70 #endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_EXCEPT_VALUE_UTILS_H 71