From 90f0ac10a74b2d43b5a65aab4be40565e359be43 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Tue, 28 Sep 2021 23:31:35 +0000 Subject: Add fmaximum, fminimum functions C2X adds new functions for floating-point maximum and minimum, corresponding to the new operations that were added in IEEE 754-2019 because of concerns about the old operations not being associative in the presence of signaling NaNs. fmaximum and fminimum handle NaNs like most functions (any NaN argument means the result is a quiet NaN). fmaximum_num and fminimum_num handle both quiet and signaling NaNs the way fmax and fmin handle quiet NaNs (if one argument is a number and the other is a NaN, return the number), but still raise "invalid" for a signaling NaN argument, making them exceptions to the normal rule that a function with a floating-point result raising "invalid" also returns a quiet NaN. fmaximum_mag, fminimum_mag, fmaximum_mag_num and fminimum_mag_num are corresponding functions returning the argument with greatest or least absolute value. All these functions also treat +0 as greater than -0. There are also corresponding type-generic macros. Add these functions to glibc. The implementations use type-generic templates based on those for fmax, fmin, fmaxmag and fminmag, and test inputs are based on those for those functions with appropriate adjustments to the expected results. The RISC-V maintainers might wish to add optimized versions of fmaximum_num and fminimum_num (for float and double), since RISC-V (F extension version 2.2 and later) provides instructions corresponding to those functions - though it might be at least as useful to add architecture-independent built-in functions to GCC and teach the RISC-V back end to expand those functions inline, which is what you generally want for functions that can be implemented with a single instruction. Tested for x86_64 and x86, and with build-many-glibcs.py. --- math/s_fmaximum_mag_num_template.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 math/s_fmaximum_mag_num_template.c (limited to 'math/s_fmaximum_mag_num_template.c') diff --git a/math/s_fmaximum_mag_num_template.c b/math/s_fmaximum_mag_num_template.c new file mode 100644 index 0000000000..5c9cef21fd --- /dev/null +++ b/math/s_fmaximum_mag_num_template.c @@ -0,0 +1,35 @@ +/* Return number with maximum magnitude. + Copyright (C) 2016-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +FLOAT +M_DECL_FUNC (__fmaximum_mag_num) (FLOAT x, FLOAT y) +{ + FLOAT ax = M_FABS (x); + FLOAT ay = M_FABS (y); + if (isgreater (ax, ay)) + return x; + else if (isless (ax, ay)) + return y; + else if (ax == ay) + return (M_COPYSIGN (1, x) >= M_COPYSIGN (1, y) ? x : y); + else + return isnan (y) ? (isnan (x) ? x + y : x) : y; +} +declare_mgen_alias (__fmaximum_mag_num, fmaximum_mag_num); -- cgit 1.4.1