diff mbox series

[10/12] x86: Do not raise inexact exception on floor/floorf

Message ID 20231228172026.2013007-11-adhemerval.zanella@linaro.org
State New
Headers show
Series Improve rounding to interger function for C23 | expand

Commit Message

Adhemerval Zanella Netto Dec. 28, 2023, 5:20 p.m. UTC
It is not allowed anymore on ISO C23.

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 sysdeps/i386/fpu/s_floor.S  | 34 ---------------------------------
 sysdeps/i386/fpu/s_floor.c  | 38 +++++++++++++++++++++++++++++++++++++
 sysdeps/i386/fpu/s_floorf.S | 34 ---------------------------------
 sysdeps/i386/fpu/s_floorf.c | 38 +++++++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 68 deletions(-)
 delete mode 100644 sysdeps/i386/fpu/s_floor.S
 create mode 100644 sysdeps/i386/fpu/s_floor.c
 delete mode 100644 sysdeps/i386/fpu/s_floorf.S
 create mode 100644 sysdeps/i386/fpu/s_floorf.c

Comments

H.J. Lu April 1, 2024, 2:15 p.m. UTC | #1
On Thu, Dec 28, 2023 at 9:24 AM Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
> It is not allowed anymore on ISO C23.
>
> Checked on x86_64-linux-gnu and i686-linux-gnu.
> ---
>  sysdeps/i386/fpu/s_floor.S  | 34 ---------------------------------
>  sysdeps/i386/fpu/s_floor.c  | 38 +++++++++++++++++++++++++++++++++++++
>  sysdeps/i386/fpu/s_floorf.S | 34 ---------------------------------
>  sysdeps/i386/fpu/s_floorf.c | 38 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 76 insertions(+), 68 deletions(-)
>  delete mode 100644 sysdeps/i386/fpu/s_floor.S
>  create mode 100644 sysdeps/i386/fpu/s_floor.c
>  delete mode 100644 sysdeps/i386/fpu/s_floorf.S
>  create mode 100644 sysdeps/i386/fpu/s_floorf.c
>
> diff --git a/sysdeps/i386/fpu/s_floor.S b/sysdeps/i386/fpu/s_floor.S
> deleted file mode 100644
> index 7143fdcc9a..0000000000
> --- a/sysdeps/i386/fpu/s_floor.S
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/*
> - * Public domain.
> - */
> -
> -#include <machine/asm.h>
> -#include <libm-alias-double.h>
> -
> -RCSID("$NetBSD: s_floor.S,v 1.4 1995/05/09 00:01:59 jtc Exp $")
> -
> -ENTRY(__floor)
> -       fldl    4(%esp)
> -       subl    $32,%esp
> -       cfi_adjust_cfa_offset (32)
> -
> -       fnstenv 4(%esp)                 /* store fpu environment */
> -
> -       /* We use here %edx although only the low 1 bits are defined.
> -          But none of the operations should care and they are faster
> -          than the 16 bit operations.  */
> -       movl    $0x400,%edx             /* round towards -oo */
> -       orl     4(%esp),%edx
> -       andl    $0xf7ff,%edx
> -       movl    %edx,(%esp)
> -       fldcw   (%esp)                  /* load modified control word */
> -
> -       frndint                         /* round */
> -
> -       fldenv  4(%esp)                 /* restore original environment */
> -
> -       addl    $32,%esp
> -       cfi_adjust_cfa_offset (-32)
> -       ret
> -END (__floor)
> -libm_alias_double (__floor, floor)
> diff --git a/sysdeps/i386/fpu/s_floor.c b/sysdeps/i386/fpu/s_floor.c
> new file mode 100644
> index 0000000000..90ba61da92
> --- /dev/null
> +++ b/sysdeps/i386/fpu/s_floor.c
> @@ -0,0 +1,38 @@
> +/* Return largest integral value not less than argument.  i386 version.
> +   Copyright (C) 2023 Free Software Foundation, Inc.

2024.

> +   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 NO_MATH_REDIRECT
> +#include <math.h>
> +#include <fenv_private.h>
> +#include <libm-alias-double.h>
> +
> +double
> +__floor (double x)
> +{
> +  fenv_t fenv;
> +  double r;
> +
> +  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
> +  asm volatile ("frndint" : "=t" (r) : "0" (x));
> +  /* Preserve "invalid" exceptions from sNaN input.  */
> +  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
> +  libc_fesetenv_387 (&fenv);
> +
> +  return r;
> +}
> +libm_alias_double (__floor, floor)
> diff --git a/sysdeps/i386/fpu/s_floorf.S b/sysdeps/i386/fpu/s_floorf.S
> deleted file mode 100644
> index 8fad9c0698..0000000000
> --- a/sysdeps/i386/fpu/s_floorf.S
> +++ /dev/null
> @@ -1,34 +0,0 @@
> -/*
> - * Public domain.
> - */
> -
> -#include <machine/asm.h>
> -#include <libm-alias-float.h>
> -
> -RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $")
> -
> -ENTRY(__floorf)
> -       flds    4(%esp)
> -       subl    $32,%esp
> -       cfi_adjust_cfa_offset (32)
> -
> -       fnstenv 4(%esp)                 /* store fpu environment */
> -
> -       /* We use here %edx although only the low 1 bits are defined.
> -          But none of the operations should care and they are faster
> -          than the 16 bit operations.  */
> -       movl    $0x400,%edx             /* round towards -oo */
> -       orl     4(%esp),%edx
> -       andl    $0xf7ff,%edx
> -       movl    %edx,(%esp)
> -       fldcw   (%esp)                  /* load modified control word */
> -
> -       frndint                         /* round */
> -
> -       fldenv  4(%esp)                 /* restore original environment */
> -
> -       addl    $32,%esp
> -       cfi_adjust_cfa_offset (-32)
> -       ret
> -END (__floorf)
> -libm_alias_float (__floor, floor)
> diff --git a/sysdeps/i386/fpu/s_floorf.c b/sysdeps/i386/fpu/s_floorf.c
> new file mode 100644
> index 0000000000..0e7e8223a8
> --- /dev/null
> +++ b/sysdeps/i386/fpu/s_floorf.c
> @@ -0,0 +1,38 @@
> +/* Return largest integral value not less than argument.  i386 version.
> +   Copyright (C) 2023 Free Software Foundation, Inc.

2024.

> +   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 NO_MATH_REDIRECT
> +#include <math.h>
> +#include <fenv_private.h>
> +#include <libm-alias-float.h>
> +
> +float
> +__floorf (float x)
> +{
> +  fenv_t fenv;
> +  float r;
> +
> +  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
> +  asm volatile ("frndint" : "=t" (r) : "0" (x));
> +  /* Preserve "invalid" exceptions from sNaN input.  */
> +  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
> +  libc_fesetenv_387 (&fenv);
> +
> +  return r;
> +}
> +libm_alias_float (__floor, floor)
> --
> 2.34.1
>
diff mbox series

Patch

diff --git a/sysdeps/i386/fpu/s_floor.S b/sysdeps/i386/fpu/s_floor.S
deleted file mode 100644
index 7143fdcc9a..0000000000
--- a/sysdeps/i386/fpu/s_floor.S
+++ /dev/null
@@ -1,34 +0,0 @@ 
-/*
- * Public domain.
- */
-
-#include <machine/asm.h>
-#include <libm-alias-double.h>
-
-RCSID("$NetBSD: s_floor.S,v 1.4 1995/05/09 00:01:59 jtc Exp $")
-
-ENTRY(__floor)
-	fldl	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x400,%edx		/* round towards -oo */
-	orl	4(%esp),%edx
-	andl	$0xf7ff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__floor)
-libm_alias_double (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floor.c b/sysdeps/i386/fpu/s_floor.c
new file mode 100644
index 0000000000..90ba61da92
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floor.c
@@ -0,0 +1,38 @@ 
+/* Return largest integral value not less than argument.  i386 version.
+   Copyright (C) 2023 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 NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-double.h>
+
+double
+__floor (double x)
+{
+  fenv_t fenv;
+  double r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_double (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floorf.S b/sysdeps/i386/fpu/s_floorf.S
deleted file mode 100644
index 8fad9c0698..0000000000
--- a/sysdeps/i386/fpu/s_floorf.S
+++ /dev/null
@@ -1,34 +0,0 @@ 
-/*
- * Public domain.
- */
-
-#include <machine/asm.h>
-#include <libm-alias-float.h>
-
-RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $")
-
-ENTRY(__floorf)
-	flds	4(%esp)
-	subl	$32,%esp
-	cfi_adjust_cfa_offset (32)
-
-	fnstenv	4(%esp)			/* store fpu environment */
-
-	/* We use here %edx although only the low 1 bits are defined.
-	   But none of the operations should care and they are faster
-	   than the 16 bit operations.  */
-	movl	$0x400,%edx		/* round towards -oo */
-	orl	4(%esp),%edx
-	andl	$0xf7ff,%edx
-	movl	%edx,(%esp)
-	fldcw	(%esp)			/* load modified control word */
-
-	frndint				/* round */
-
-	fldenv	4(%esp)			/* restore original environment */
-
-	addl	$32,%esp
-	cfi_adjust_cfa_offset (-32)
-	ret
-END (__floorf)
-libm_alias_float (__floor, floor)
diff --git a/sysdeps/i386/fpu/s_floorf.c b/sysdeps/i386/fpu/s_floorf.c
new file mode 100644
index 0000000000..0e7e8223a8
--- /dev/null
+++ b/sysdeps/i386/fpu/s_floorf.c
@@ -0,0 +1,38 @@ 
+/* Return largest integral value not less than argument.  i386 version.
+   Copyright (C) 2023 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 NO_MATH_REDIRECT
+#include <math.h>
+#include <fenv_private.h>
+#include <libm-alias-float.h>
+
+float
+__floorf (float x)
+{
+  fenv_t fenv;
+  float r;
+
+  libc_feholdexcept_setround_387 (&fenv, FE_DOWNWARD);
+  asm volatile ("frndint" : "=t" (r) : "0" (x));
+  /* Preserve "invalid" exceptions from sNaN input.  */
+  fenv.__status_word |= libc_fetestexcept_387 (FE_INVALID);
+  libc_fesetenv_387 (&fenv);
+
+  return r;
+}
+libm_alias_float (__floor, floor)