68 lines · c
1/*2 * Single-precision math error handling.3 *4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5 * See https://llvm.org/LICENSE.txt for license information.6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7 */8 9#include "math_config.h"10 11#if WANT_ERRNO12#include <errno.h>13/* NOINLINE reduces code size and avoids making math functions non-leaf14 when the error handling is inlined. */15NOINLINE static float16with_errnof (float y, int e)17{18 errno = e;19 return y;20}21#else22#define with_errnof(x, e) (x)23#endif24 25/* NOINLINE reduces code size. */26NOINLINE static float27xflowf (uint32_t sign, float y)28{29 y = eval_as_float (opt_barrier_float (sign ? -y : y) * y);30 return with_errnof (y, ERANGE);31}32 33HIDDEN float34__math_uflowf (uint32_t sign)35{36 return xflowf (sign, 0x1p-95f);37}38 39#if WANT_ERRNO_UFLOW40/* Underflows to zero in some non-nearest rounding mode, setting errno41 is valid even if the result is non-zero, but in the subnormal range. */42HIDDEN float43__math_may_uflowf (uint32_t sign)44{45 return xflowf (sign, 0x1.4p-75f);46}47#endif48 49HIDDEN float50__math_oflowf (uint32_t sign)51{52 return xflowf (sign, 0x1p97f);53}54 55HIDDEN float56__math_divzerof (uint32_t sign)57{58 float y = opt_barrier_float (sign ? -1.0f : 1.0f) / 0.0f;59 return with_errnof (y, ERANGE);60}61 62HIDDEN float63__math_invalidf (float x)64{65 float y = (x - x) / (x - x);66 return isnan (x) ? y : with_errnof (y, EDOM);67}68