#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 <typename T, int N> struct ExceptionalValues {
using UIntType = typename FPBits<T>::UIntType;
static constexpr int SIZE = N;
UIntType inputs[SIZE];
UIntType outputs[SIZE][4];
};
template <typename T, int N> struct ExceptionChecker {
using UIntType = typename FPBits<T>::UIntType;
using FPBits = FPBits<T>;
using ExceptionalValues = ExceptionalValues<T, N>;
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];
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;
}
};
}
}
#endif