alpha: Fix missing inexact-flag raising for lround/lrint

The l*[rint|round]f implements uses alpha 'cvtst/s', 'addt/suc',
adn 'cvttq/svd' which are not not fully IEEE compliant w.r.t
inexact-flag raising..  Use the software fallback implementation
instead.

Checked on alpha-linux-gnu.

Tested-by: Michael Cree <mcree@orcon.net.nz>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Adhemerval Zanella 2025-09-06 19:23:22 -03:00
parent cde86de627
commit dbebe0c418
9 changed files with 17 additions and 140 deletions

View File

@ -38,9 +38,13 @@ CFLAGS-rtld.c = -mbuild-constants
endif
ifeq ($(subdir),math)
# The fma routines rely on inexact being raised for correct results.
# The following routines rely on inexact being raised for correct results.
CFLAGS-s_fma.c = -mieee-with-inexact
CFLAGS-s_fmaf.c = -mieee-with-inexact
CFLAGS-s_llrintf.c += -mieee-with-inexact
CFLAGS-s_llrint.c += -mieee-with-inexact
CFLAGS-s_lrintf.c += -mieee-with-inexact
CFLAGS-s_lrint.c += -mieee-with-inexact
# This test tries to check for inexact being raised by arithmetic.
CFLAGS-test-misc.c += -mieee-with-inexact
# Avoid "conflicting types for built-in function" warnings

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2007-2025 Free Software Foundation, Inc.
/* Fix for conversion of floating point to integer overflow. Alpha version.
Copyright (C) 2025 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
@ -12,27 +13,18 @@
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
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define __llrint not___llrint
#define llrint not_llrint
#include <math.h>
#include <math_ldbl_opt.h>
#include <libm-alias-double.h>
#undef __llrint
#undef llrint
#ifndef FIX_FP_INT_CONVERT_OVERFLOW_H
#define FIX_FP_INT_CONVERT_OVERFLOW_H 1
long int
__lrint (double x)
{
long ret;
#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1
#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1
#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 1
__asm ("cvttq/svd %1,%0" : "=&f"(ret) : "f"(x));
#define FIX_FLT_LONG_CONVERT_OVERFLOW 1
#define FIX_DBL_LONG_CONVERT_OVERFLOW 1
#define FIX_LDBL_LONG_CONVERT_OVERFLOW 1
return ret;
}
strong_alias (__lrint, __llrint)
libm_alias_double (__lrint, lrint)
libm_alias_double (__llrint, llrint)
#endif /* fix-fp-int-convert-overflow.h */

View File

@ -1 +0,0 @@
/* In s_lrint.c */

View File

@ -1 +0,0 @@
/* In s_lrintf.c */

View File

@ -1 +0,0 @@
/* In s_lround.c. */

View File

@ -1 +0,0 @@
/* In s_lroundf.c. */

View File

@ -1,39 +0,0 @@
/* Copyright (C) 2007-2025 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
<https://www.gnu.org/licenses/>. */
#define __llrintf not___llrintf
#define llrintf not_llrintf
#include <math.h>
#include <libm-alias-float.h>
#undef __llrintf
#undef llrintf
long int
__lrintf (float x)
{
double tmp;
long ret;
__asm ("cvtst/s %2,%1\n\tcvttq/svd %1,%0"
: "=&f"(ret), "=&f"(tmp) : "f"(x));
return ret;
}
strong_alias (__lrintf, __llrintf)
libm_alias_float (__lrint, lrint)
libm_alias_float (__llrint, llrint)

View File

@ -1,38 +0,0 @@
/* Copyright (C) 2007-2025 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
<https://www.gnu.org/licenses/>. */
#define __llround not___llround
#define llround not_llround
#include <math.h>
#include <math_ldbl_opt.h>
#include <libm-alias-double.h>
#undef __llround
#undef llround
long int
__lround (double x)
{
double adj, y;
adj = copysign (0.5, x);
asm("addt/suc %1,%2,%0" : "=&f"(y) : "f"(x), "f"(adj));
return y;
}
strong_alias (__lround, __llround)
libm_alias_double (__lround, lround)
libm_alias_double (__llround, llround)

View File

@ -1,38 +0,0 @@
/* Copyright (C) 2007-2025 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
<https://www.gnu.org/licenses/>. */
#define __llroundf not___llroundf
#define llroundf not_llroundf
#include <math.h>
#include <libm-alias-float.h>
#undef __llroundf
#undef llroundf
long int
__lroundf (float x)
{
float adj, y;
adj = copysignf (0.5f, x);
asm("adds/suc %1,%2,%0" : "=&f"(y) : "f"(x), "f"(adj));
return y;
}
strong_alias (__lroundf, __llroundf)
libm_alias_float (__lround, lround)
libm_alias_float (__llround, llround)