brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.6 KiB · 77d8a94 Raw
82 lines · c
1/*2 * Double-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 double16with_errno (double y, int e)17{18  errno = e;19  return y;20}21#else22#define with_errno(x, e) (x)23#endif24 25/* NOINLINE reduces code size.  */26NOINLINE static double27xflow (uint32_t sign, double y)28{29  y = eval_as_double (opt_barrier_double (sign ? -y : y) * y);30  return with_errno (y, ERANGE);31}32 33HIDDEN double34__math_uflow (uint32_t sign)35{36  return xflow (sign, 0x1p-767);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 double43__math_may_uflow (uint32_t sign)44{45  return xflow (sign, 0x1.8p-538);46}47#endif48 49HIDDEN double50__math_oflow (uint32_t sign)51{52  return xflow (sign, 0x1p769);53}54 55HIDDEN double56__math_divzero (uint32_t sign)57{58  double y = opt_barrier_double (sign ? -1.0 : 1.0) / 0.0;59  return with_errno (y, ERANGE);60}61 62HIDDEN double63__math_invalid (double x)64{65  double y = (x - x) / (x - x);66  return isnan (x) ? y : with_errno (y, EDOM);67}68 69/* Check result and set errno if necessary.  */70 71HIDDEN double72__math_check_uflow (double y)73{74  return y == 0.0 ? with_errno (y, ERANGE) : y;75}76 77HIDDEN double78__math_check_oflow (double y)79{80  return isinf (y) ? with_errno (y, ERANGE) : y;81}82