//===-- Common header for helpers to set exceptional values -----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_EXCEPT_VALUE_UTILS_H #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_EXCEPT_VALUE_UTILS_H #include "FEnvImpl.h" #include "FPBits.h" namespace __llvm_libc { namespace fputil { template struct ExceptionalValues { using UIntType = typename FPBits::UIntType; static constexpr int SIZE = N; // Input bits. UIntType inputs[SIZE]; // Output bits contains 4 values: // output[i][0]: output bits corresponding to FE_TOWARDZERO // output[i][1]: offset for FE_UPWARD // output[i][2]: offset for FE_DOWNWARD // output[i][3]: offset for FE_TONEAREST UIntType outputs[SIZE][4]; }; template struct ExceptionChecker { using UIntType = typename FPBits::UIntType; using FPBits = FPBits; using ExceptionalValues = ExceptionalValues; static bool check_odd_func(const ExceptionalValues &ExceptVals, UIntType x_abs, bool sign, T &result) { for (int i = 0; i < N; ++i) { if (unlikely(x_abs == ExceptVals.inputs[i])) { UIntType out_bits = ExceptVals.outputs[i][0]; // FE_TOWARDZERO switch (fputil::get_round()) { case FE_UPWARD: out_bits += sign ? ExceptVals.outputs[i][2] : ExceptVals.outputs[i][1]; break; case FE_DOWNWARD: out_bits += sign ? ExceptVals.outputs[i][1] : ExceptVals.outputs[i][2]; break; case FE_TONEAREST: out_bits += ExceptVals.outputs[i][3]; break; } result = FPBits(out_bits).get_val(); if (sign) result = -result; return true; } } return false; } }; } // namespace fputil } // namespace __llvm_libc #endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_EXCEPT_VALUE_UTILS_H