2 * Double-precision math error handling.
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-exception
9 #include "math_config.h"
13 /* NOINLINE reduces code size and avoids making math functions non-leaf
14 when the error handling is inlined. */
15 NOINLINE
static double
16 with_errno (double y
, int e
)
22 #define with_errno(x, e) (x)
25 /* NOINLINE reduces code size. */
26 NOINLINE
static double
27 xflow (uint32_t sign
, double y
)
29 y
= eval_as_double (opt_barrier_double (sign
? -y
: y
) * y
);
30 return with_errno (y
, ERANGE
);
34 __math_uflow (uint32_t sign
)
36 return xflow (sign
, 0x1p
-767);
40 /* Underflows to zero in some non-nearest rounding mode, setting errno
41 is valid even if the result is non-zero, but in the subnormal range. */
43 __math_may_uflow (uint32_t sign
)
45 return xflow (sign
, 0x1.8p
-538);
50 __math_oflow (uint32_t sign
)
52 return xflow (sign
, 0x1p
769);
56 __math_divzero (uint32_t sign
)
58 double y
= opt_barrier_double (sign
? -1.0 : 1.0) / 0.0;
59 return with_errno (y
, ERANGE
);
63 __math_invalid (double x
)
65 double y
= (x
- x
) / (x
- x
);
66 return isnan (x
) ? y
: with_errno (y
, EDOM
);
69 /* Check result and set errno if necessary. */
72 __math_check_uflow (double y
)
74 return y
== 0.0 ? with_errno (y
, ERANGE
) : y
;
78 __math_check_oflow (double y
)
80 return isinf (y
) ? with_errno (y
, ERANGE
) : y
;