* [PATCH] x86_64: roundeven with fpu and sse4.1 support
@ 2019-12-14 16:11 Shen-Ta Hsieh
2019-12-15 5:24 ` [PATCH v2] " Shen-Ta Hsieh
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Shen-Ta Hsieh @ 2019-12-14 16:11 UTC (permalink / raw)
To: libc-alpha; +Cc: Shen-Ta Hsieh
This patch adds support for the various other hardware floating point
configurations that i386 and x86_64 supports.
---
include/math.h | 1 -
sysdeps/i386/fpu/s_roundeven.S | 38 +++++++++++++++
sysdeps/i386/fpu/s_roundevenf.S | 38 +++++++++++++++
sysdeps/i386/fpu/s_roundevenl.S | 41 ++++++++++++++++
sysdeps/ieee754/dbl-64/s_roundeven.c | 3 +-
sysdeps/x86_64/fpu/multiarch/Makefile | 5 +-
sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c | 2 +
.../x86_64/fpu/multiarch/s_roundeven-sse4_1.S | 26 ++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundeven.c | 31 ++++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c | 3 ++
.../fpu/multiarch/s_roundevenf-sse4_1.S | 26 ++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundevenf.c | 31 ++++++++++++
sysdeps/x86_64/fpu/s_roundevenl.S | 47 +++++++++++++++++++
13 files changed, 288 insertions(+), 4 deletions(-)
create mode 100644 sysdeps/i386/fpu/s_roundeven.S
create mode 100644 sysdeps/i386/fpu/s_roundevenf.S
create mode 100644 sysdeps/i386/fpu/s_roundevenl.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
create mode 100644 sysdeps/x86_64/fpu/s_roundevenl.S
diff --git a/include/math.h b/include/math.h
index a274f2bdfd..2638323a1a 100644
--- a/include/math.h
+++ b/include/math.h
@@ -38,7 +38,6 @@ libm_hidden_proto (__issignaling)
libm_hidden_proto (__issignalingf)
libm_hidden_proto (__exp)
libm_hidden_proto (__expf)
-libm_hidden_proto (__roundeven)
# ifndef __NO_LONG_DOUBLE_MATH
libm_hidden_proto (__fpclassifyl)
diff --git a/sysdeps/i386/fpu/s_roundeven.S b/sysdeps/i386/fpu/s_roundeven.S
new file mode 100644
index 0000000000..1cf78cf952
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundeven.S
@@ -0,0 +1,38 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ double version.
+ Copyright (C) 2019 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/>. */
+
+#include <machine/asm.h>
+#include <libm-alias-double.h>
+
+ENTRY(__roundeven)
+ fldl 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundeven)
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/i386/fpu/s_roundevenf.S b/sysdeps/i386/fpu/s_roundevenf.S
new file mode 100644
index 0000000000..eaf092e325
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundevenf.S
@@ -0,0 +1,38 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ float version.
+ Copyright (C) 2019 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/>. */
+
+#include <machine/asm.h>
+#include <libm-alias-float.h>
+
+ENTRY(__roundevenf)
+ flds 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundevenf)
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/i386/fpu/s_roundevenl.S b/sysdeps/i386/fpu/s_roundevenl.S
new file mode 100644
index 0000000000..b3fc10c1da
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundevenl.S
@@ -0,0 +1,41 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ long double version.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-ldouble.h>
+#include <machine/asm.h>
+
+ENTRY(__roundevenl)
+ fldt 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, 8(%esp)
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundevenl)
+libm_alias_ldouble (__roundeven, roundeven)
diff --git a/sysdeps/ieee754/dbl-64/s_roundeven.c b/sysdeps/ieee754/dbl-64/s_roundeven.c
index 3a4eccb85a..11081c4952 100644
--- a/sysdeps/ieee754/dbl-64/s_roundeven.c
+++ b/sysdeps/ieee754/dbl-64/s_roundeven.c
@@ -101,5 +101,6 @@ __roundeven (double x)
INSERT_WORDS (x, hx, lx);
return x;
}
-hidden_def (__roundeven)
+#ifndef __roundeven
libm_alias_double (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 3836574f48..7e3a3f78cb 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -1,11 +1,12 @@
ifeq ($(subdir),math)
libm-sysdep_routines += s_floor-c s_ceil-c s_floorf-c s_ceilf-c \
s_rint-c s_rintf-c s_nearbyint-c s_nearbyintf-c \
- s_trunc-c s_truncf-c
+ s_roundeven-c s_roundevenf-c s_trunc-c s_truncf-c
libm-sysdep_routines += s_ceil-sse4_1 s_ceilf-sse4_1 s_floor-sse4_1 \
s_floorf-sse4_1 s_nearbyint-sse4_1 \
- s_nearbyintf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1 \
+ s_nearbyintf-sse4_1 s_roundeven-sse4_1 \
+ s_roundevenf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1 \
s_trunc-sse4_1 s_truncf-sse4_1
libm-sysdep_routines += e_exp-fma e_log-fma e_pow-fma s_atan-fma \
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
new file mode 100644
index 0000000000..c7be43cb22
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
@@ -0,0 +1,2 @@
+#define __roundeven __roundeven_c
+#include <sysdeps/ieee754/dbl-64/s_roundeven.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
new file mode 100644
index 0000000000..6db88a1649
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
@@ -0,0 +1,26 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ double version.
+ Copyright (C) 2019 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/>. */
+
+#include <sysdep.h>
+
+ .section .text.sse4.1,"ax",@progbits
+ENTRY(__roundeven_sse41)
+ roundsd $8, %xmm0, %xmm0
+ ret
+END(__roundeven_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
new file mode 100644
index 0000000000..bd777b0ca7
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
@@ -0,0 +1,31 @@
+/* Multiple versions of __roundeven.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-double.h>
+
+#define roundeven __redirect_roundeven
+#define __roundeven __redirect___roundeven
+#include <math.h>
+#undef roundeven
+#undef __roundeven
+
+#define SYMBOL_NAME roundeven
+#include "ifunc-sse4_1.h"
+
+libc_ifunc_redirected (__redirect_roundeven, __roundeven, IFUNC_SELECTOR ());
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
new file mode 100644
index 0000000000..72a6e7d1fb
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
@@ -0,0 +1,3 @@
+#undef __roundevenf
+#define __roundevenf __roundevenf_c
+#include <sysdeps/ieee754/flt-32/s_roundevenf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
new file mode 100644
index 0000000000..74102bac0d
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
@@ -0,0 +1,26 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ float version.
+ Copyright (C) 2019 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/>. */
+
+#include <sysdep.h>
+
+ .section .text.sse4.1,"ax",@progbits
+ENTRY(__roundevenf_sse41)
+ roundss $8, %xmm0, %xmm0
+ ret
+END(__roundevenf_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
new file mode 100644
index 0000000000..8ae1944d2b
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
@@ -0,0 +1,31 @@
+/* Multiple versions of __roundevenf.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-float.h>
+
+#define roundevenf __redirect_roundevenf
+#define __roundevenf __redirect___roundevenf
+#include <math.h>
+#undef roundevenf
+#undef __roundevenf
+
+#define SYMBOL_NAME roundevenf
+#include "ifunc-sse4_1.h"
+
+libc_ifunc_redirected (__redirect_roundevenf, __roundevenf, IFUNC_SELECTOR ());
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/s_roundevenl.S b/sysdeps/x86_64/fpu/s_roundevenl.S
new file mode 100644
index 0000000000..d179b1b603
--- /dev/null
+++ b/sysdeps/x86_64/fpu/s_roundevenl.S
@@ -0,0 +1,47 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ long double version.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-ldouble.h>
+#include <machine/asm.h>
+
+ENTRY(__roundevenl)
+ fldt 8(%rsp)
+
+ fnstenv -28(%rsp) /* 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 $0xf3ff,%edx /* round to nearest (even) */
+ andl -28(%rsp),%edx
+ movl %edx,-32(%rsp)
+ fldcw -32(%rsp) /* load modified control word */
+
+ frndint /* round */
+
+ /* Preserve "invalid" exceptions from sNaN input. */
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, -24(%rsp)
+
+ fldenv -28(%rsp) /* restore original environment */
+
+ ret
+END (__roundevenl)
+libm_alias_ldouble (__roundeven, roundeven)
--
2.24.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2] x86_64: roundeven with fpu and sse4.1 support
2019-12-14 16:11 [PATCH] x86_64: roundeven with fpu and sse4.1 support Shen-Ta Hsieh
@ 2019-12-15 5:24 ` Shen-Ta Hsieh
2019-12-15 11:02 ` Florian Weimer
2019-12-16 1:27 ` [PATCH v3 2/2] " Shen-Ta Hsieh
2019-12-16 1:27 ` [PATCH v3 1/2] math: redirect roundeven function Shen-Ta Hsieh
2 siblings, 1 reply; 6+ messages in thread
From: Shen-Ta Hsieh @ 2019-12-15 5:24 UTC (permalink / raw)
To: libc-alpha; +Cc: Shen-Ta Hsieh
This patch adds support for the various other hardware floating point
configurations that i386 and x86_64 supports.
---
include/math.h | 2 +-
sysdeps/i386/fpu/s_roundeven.S | 38 +++++++++++++++
sysdeps/i386/fpu/s_roundevenf.S | 38 +++++++++++++++
sysdeps/i386/fpu/s_roundevenl.S | 41 ++++++++++++++++
sysdeps/ieee754/dbl-64/s_roundeven.c | 3 +-
.../ieee754/dbl-64/wordsize-64/s_roundeven.c | 4 +-
sysdeps/ieee754/float128/s_roundevenf128.c | 1 +
sysdeps/ieee754/flt-32/s_roundevenf.c | 3 ++
sysdeps/ieee754/ldbl-128/s_roundevenl.c | 1 +
sysdeps/x86_64/fpu/multiarch/Makefile | 5 +-
sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c | 2 +
.../x86_64/fpu/multiarch/s_roundeven-sse4_1.S | 26 ++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundeven.c | 31 ++++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c | 3 ++
.../fpu/multiarch/s_roundevenf-sse4_1.S | 26 ++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundevenf.c | 31 ++++++++++++
sysdeps/x86_64/fpu/s_roundevenl.S | 47 +++++++++++++++++++
17 files changed, 297 insertions(+), 5 deletions(-)
create mode 100644 sysdeps/i386/fpu/s_roundeven.S
create mode 100644 sysdeps/i386/fpu/s_roundevenf.S
create mode 100644 sysdeps/i386/fpu/s_roundevenl.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
create mode 100644 sysdeps/x86_64/fpu/s_roundevenl.S
diff --git a/include/math.h b/include/math.h
index a274f2bdfd..3639422b76 100644
--- a/include/math.h
+++ b/include/math.h
@@ -38,7 +38,6 @@ libm_hidden_proto (__issignaling)
libm_hidden_proto (__issignalingf)
libm_hidden_proto (__exp)
libm_hidden_proto (__expf)
-libm_hidden_proto (__roundeven)
# ifndef __NO_LONG_DOUBLE_MATH
libm_hidden_proto (__fpclassifyl)
@@ -157,6 +156,7 @@ fabsf128 (_Float128 x)
MATH_REDIRECT (sqrt, "__ieee754_", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (ceil, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (floor, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (roundeven, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (rint, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (round, "__", MATH_REDIRECT_UNARY_ARGS)
diff --git a/sysdeps/i386/fpu/s_roundeven.S b/sysdeps/i386/fpu/s_roundeven.S
new file mode 100644
index 0000000000..1cf78cf952
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundeven.S
@@ -0,0 +1,38 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ double version.
+ Copyright (C) 2019 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/>. */
+
+#include <machine/asm.h>
+#include <libm-alias-double.h>
+
+ENTRY(__roundeven)
+ fldl 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundeven)
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/i386/fpu/s_roundevenf.S b/sysdeps/i386/fpu/s_roundevenf.S
new file mode 100644
index 0000000000..eaf092e325
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundevenf.S
@@ -0,0 +1,38 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ float version.
+ Copyright (C) 2019 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/>. */
+
+#include <machine/asm.h>
+#include <libm-alias-float.h>
+
+ENTRY(__roundevenf)
+ flds 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundevenf)
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/i386/fpu/s_roundevenl.S b/sysdeps/i386/fpu/s_roundevenl.S
new file mode 100644
index 0000000000..b3fc10c1da
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundevenl.S
@@ -0,0 +1,41 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ long double version.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-ldouble.h>
+#include <machine/asm.h>
+
+ENTRY(__roundevenl)
+ fldt 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, 8(%esp)
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundevenl)
+libm_alias_ldouble (__roundeven, roundeven)
diff --git a/sysdeps/ieee754/dbl-64/s_roundeven.c b/sysdeps/ieee754/dbl-64/s_roundeven.c
index 3a4eccb85a..11081c4952 100644
--- a/sysdeps/ieee754/dbl-64/s_roundeven.c
+++ b/sysdeps/ieee754/dbl-64/s_roundeven.c
@@ -101,5 +101,6 @@ __roundeven (double x)
INSERT_WORDS (x, hx, lx);
return x;
}
-hidden_def (__roundeven)
+#ifndef __roundeven
libm_alias_double (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c
index c1738c47d6..90197f8ba9 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-double.h>
@@ -67,5 +68,6 @@ __roundeven (double x)
INSERT_WORDS64 (x, ix);
return x;
}
-hidden_def (__roundeven)
+#ifndef __roundeven
libm_alias_double (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/ieee754/float128/s_roundevenf128.c b/sysdeps/ieee754/float128/s_roundevenf128.c
index 5a9b3f395f..e0faf727f6 100644
--- a/sysdeps/ieee754/float128/s_roundevenf128.c
+++ b/sysdeps/ieee754/float128/s_roundevenf128.c
@@ -1,2 +1,3 @@
+#define NO_MATH_REDIRECT
#include <float128_private.h>
#include "../ldbl-128/s_roundevenl.c"
diff --git a/sysdeps/ieee754/flt-32/s_roundevenf.c b/sysdeps/ieee754/flt-32/s_roundevenf.c
index 6cb1a3435f..7e5b6c4c84 100644
--- a/sysdeps/ieee754/flt-32/s_roundevenf.c
+++ b/sysdeps/ieee754/flt-32/s_roundevenf.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-float.h>
@@ -67,4 +68,6 @@ __roundevenf (float x)
SET_FLOAT_WORD (x, ix);
return x;
}
+#ifndef __roundevenf
libm_alias_float (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/ieee754/ldbl-128/s_roundevenl.c b/sysdeps/ieee754/ldbl-128/s_roundevenl.c
index ad3c121023..08be08bde1 100644
--- a/sysdeps/ieee754/ldbl-128/s_roundevenl.c
+++ b/sysdeps/ieee754/ldbl-128/s_roundevenl.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-ldouble.h>
diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 3836574f48..7e3a3f78cb 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -1,11 +1,12 @@
ifeq ($(subdir),math)
libm-sysdep_routines += s_floor-c s_ceil-c s_floorf-c s_ceilf-c \
s_rint-c s_rintf-c s_nearbyint-c s_nearbyintf-c \
- s_trunc-c s_truncf-c
+ s_roundeven-c s_roundevenf-c s_trunc-c s_truncf-c
libm-sysdep_routines += s_ceil-sse4_1 s_ceilf-sse4_1 s_floor-sse4_1 \
s_floorf-sse4_1 s_nearbyint-sse4_1 \
- s_nearbyintf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1 \
+ s_nearbyintf-sse4_1 s_roundeven-sse4_1 \
+ s_roundevenf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1 \
s_trunc-sse4_1 s_truncf-sse4_1
libm-sysdep_routines += e_exp-fma e_log-fma e_pow-fma s_atan-fma \
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
new file mode 100644
index 0000000000..c7be43cb22
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
@@ -0,0 +1,2 @@
+#define __roundeven __roundeven_c
+#include <sysdeps/ieee754/dbl-64/s_roundeven.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
new file mode 100644
index 0000000000..6db88a1649
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
@@ -0,0 +1,26 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ double version.
+ Copyright (C) 2019 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/>. */
+
+#include <sysdep.h>
+
+ .section .text.sse4.1,"ax",@progbits
+ENTRY(__roundeven_sse41)
+ roundsd $8, %xmm0, %xmm0
+ ret
+END(__roundeven_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
new file mode 100644
index 0000000000..bd777b0ca7
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
@@ -0,0 +1,31 @@
+/* Multiple versions of __roundeven.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-double.h>
+
+#define roundeven __redirect_roundeven
+#define __roundeven __redirect___roundeven
+#include <math.h>
+#undef roundeven
+#undef __roundeven
+
+#define SYMBOL_NAME roundeven
+#include "ifunc-sse4_1.h"
+
+libc_ifunc_redirected (__redirect_roundeven, __roundeven, IFUNC_SELECTOR ());
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
new file mode 100644
index 0000000000..72a6e7d1fb
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
@@ -0,0 +1,3 @@
+#undef __roundevenf
+#define __roundevenf __roundevenf_c
+#include <sysdeps/ieee754/flt-32/s_roundevenf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
new file mode 100644
index 0000000000..74102bac0d
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
@@ -0,0 +1,26 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ float version.
+ Copyright (C) 2019 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/>. */
+
+#include <sysdep.h>
+
+ .section .text.sse4.1,"ax",@progbits
+ENTRY(__roundevenf_sse41)
+ roundss $8, %xmm0, %xmm0
+ ret
+END(__roundevenf_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
new file mode 100644
index 0000000000..8ae1944d2b
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
@@ -0,0 +1,31 @@
+/* Multiple versions of __roundevenf.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-float.h>
+
+#define roundevenf __redirect_roundevenf
+#define __roundevenf __redirect___roundevenf
+#include <math.h>
+#undef roundevenf
+#undef __roundevenf
+
+#define SYMBOL_NAME roundevenf
+#include "ifunc-sse4_1.h"
+
+libc_ifunc_redirected (__redirect_roundevenf, __roundevenf, IFUNC_SELECTOR ());
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/s_roundevenl.S b/sysdeps/x86_64/fpu/s_roundevenl.S
new file mode 100644
index 0000000000..d179b1b603
--- /dev/null
+++ b/sysdeps/x86_64/fpu/s_roundevenl.S
@@ -0,0 +1,47 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ long double version.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-ldouble.h>
+#include <machine/asm.h>
+
+ENTRY(__roundevenl)
+ fldt 8(%rsp)
+
+ fnstenv -28(%rsp) /* 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 $0xf3ff,%edx /* round to nearest (even) */
+ andl -28(%rsp),%edx
+ movl %edx,-32(%rsp)
+ fldcw -32(%rsp) /* load modified control word */
+
+ frndint /* round */
+
+ /* Preserve "invalid" exceptions from sNaN input. */
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, -24(%rsp)
+
+ fldenv -28(%rsp) /* restore original environment */
+
+ ret
+END (__roundevenl)
+libm_alias_ldouble (__roundeven, roundeven)
--
2.24.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] x86_64: roundeven with fpu and sse4.1 support
2019-12-15 5:24 ` [PATCH v2] " Shen-Ta Hsieh
@ 2019-12-15 11:02 ` Florian Weimer
0 siblings, 0 replies; 6+ messages in thread
From: Florian Weimer @ 2019-12-15 11:02 UTC (permalink / raw)
To: Shen-Ta Hsieh; +Cc: libc-alpha
* Shen-Ta Hsieh:
> diff --git a/include/math.h b/include/math.h
> index a274f2bdfd..3639422b76 100644
> --- a/include/math.h
> +++ b/include/math.h
> @@ -38,7 +38,6 @@ libm_hidden_proto (__issignaling)
> libm_hidden_proto (__issignalingf)
> libm_hidden_proto (__exp)
> libm_hidden_proto (__expf)
> -libm_hidden_proto (__roundeven)
I think this causes build failures on targets which uses the generic
roundeven in sysdeps/ieee754/dbl-64/s_roundeven.c (such as
powerp64le-linux-gnu).
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] math: redirect roundeven function
2019-12-14 16:11 [PATCH] x86_64: roundeven with fpu and sse4.1 support Shen-Ta Hsieh
2019-12-15 5:24 ` [PATCH v2] " Shen-Ta Hsieh
2019-12-16 1:27 ` [PATCH v3 2/2] " Shen-Ta Hsieh
@ 2019-12-16 1:27 ` Shen-Ta Hsieh
2 siblings, 0 replies; 6+ messages in thread
From: Shen-Ta Hsieh @ 2019-12-16 1:27 UTC (permalink / raw)
To: libc-alpha; +Cc: Shen-Ta Hsieh
This patch redirect roundeven function for futhermore changes.
---
include/math.h | 2 +-
sysdeps/ieee754/dbl-64/s_roundeven.c | 3 ++-
sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c | 4 +++-
sysdeps/ieee754/float128/s_roundevenf128.c | 1 +
sysdeps/ieee754/flt-32/s_roundevenf.c | 3 +++
sysdeps/ieee754/ldbl-128/s_roundevenl.c | 1 +
sysdeps/ieee754/ldbl-96/s_roundevenl.c | 1 +
7 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/include/math.h b/include/math.h
index a274f2bdfd..3639422b76 100644
--- a/include/math.h
+++ b/include/math.h
@@ -38,7 +38,6 @@ libm_hidden_proto (__issignaling)
libm_hidden_proto (__issignalingf)
libm_hidden_proto (__exp)
libm_hidden_proto (__expf)
-libm_hidden_proto (__roundeven)
# ifndef __NO_LONG_DOUBLE_MATH
libm_hidden_proto (__fpclassifyl)
@@ -157,6 +156,7 @@ fabsf128 (_Float128 x)
MATH_REDIRECT (sqrt, "__ieee754_", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (ceil, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (floor, "__", MATH_REDIRECT_UNARY_ARGS)
+MATH_REDIRECT (roundeven, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (rint, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS)
MATH_REDIRECT (round, "__", MATH_REDIRECT_UNARY_ARGS)
diff --git a/sysdeps/ieee754/dbl-64/s_roundeven.c b/sysdeps/ieee754/dbl-64/s_roundeven.c
index 3a4eccb85a..11081c4952 100644
--- a/sysdeps/ieee754/dbl-64/s_roundeven.c
+++ b/sysdeps/ieee754/dbl-64/s_roundeven.c
@@ -101,5 +101,6 @@ __roundeven (double x)
INSERT_WORDS (x, hx, lx);
return x;
}
-hidden_def (__roundeven)
+#ifndef __roundeven
libm_alias_double (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c
index c1738c47d6..90197f8ba9 100644
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-double.h>
@@ -67,5 +68,6 @@ __roundeven (double x)
INSERT_WORDS64 (x, ix);
return x;
}
-hidden_def (__roundeven)
+#ifndef __roundeven
libm_alias_double (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/ieee754/float128/s_roundevenf128.c b/sysdeps/ieee754/float128/s_roundevenf128.c
index 5a9b3f395f..e0faf727f6 100644
--- a/sysdeps/ieee754/float128/s_roundevenf128.c
+++ b/sysdeps/ieee754/float128/s_roundevenf128.c
@@ -1,2 +1,3 @@
+#define NO_MATH_REDIRECT
#include <float128_private.h>
#include "../ldbl-128/s_roundevenl.c"
diff --git a/sysdeps/ieee754/flt-32/s_roundevenf.c b/sysdeps/ieee754/flt-32/s_roundevenf.c
index 6cb1a3435f..7e5b6c4c84 100644
--- a/sysdeps/ieee754/flt-32/s_roundevenf.c
+++ b/sysdeps/ieee754/flt-32/s_roundevenf.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-float.h>
@@ -67,4 +68,6 @@ __roundevenf (float x)
SET_FLOAT_WORD (x, ix);
return x;
}
+#ifndef __roundevenf
libm_alias_float (__roundeven, roundeven)
+#endif
diff --git a/sysdeps/ieee754/ldbl-128/s_roundevenl.c b/sysdeps/ieee754/ldbl-128/s_roundevenl.c
index ad3c121023..08be08bde1 100644
--- a/sysdeps/ieee754/ldbl-128/s_roundevenl.c
+++ b/sysdeps/ieee754/ldbl-128/s_roundevenl.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-ldouble.h>
diff --git a/sysdeps/ieee754/ldbl-96/s_roundevenl.c b/sysdeps/ieee754/ldbl-96/s_roundevenl.c
index 6544bf20f8..8f4ab4c7ed 100644
--- a/sysdeps/ieee754/ldbl-96/s_roundevenl.c
+++ b/sysdeps/ieee754/ldbl-96/s_roundevenl.c
@@ -17,6 +17,7 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
+#define NO_MATH_REDIRECT
#include <math.h>
#include <math_private.h>
#include <libm-alias-ldouble.h>
--
2.24.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] x86_64: roundeven with fpu and sse4.1 support
2019-12-14 16:11 [PATCH] x86_64: roundeven with fpu and sse4.1 support Shen-Ta Hsieh
2019-12-15 5:24 ` [PATCH v2] " Shen-Ta Hsieh
@ 2019-12-16 1:27 ` Shen-Ta Hsieh
2020-03-05 1:20 ` Joseph Myers
2019-12-16 1:27 ` [PATCH v3 1/2] math: redirect roundeven function Shen-Ta Hsieh
2 siblings, 1 reply; 6+ messages in thread
From: Shen-Ta Hsieh @ 2019-12-16 1:27 UTC (permalink / raw)
To: libc-alpha; +Cc: Shen-Ta Hsieh
This patch adds support for the various other hardware floating point
configurations that i386 and x86_64 supports.
---
sysdeps/i386/fpu/s_roundeven.S | 38 +++++++++++++++
sysdeps/i386/fpu/s_roundevenf.S | 38 +++++++++++++++
sysdeps/i386/fpu/s_roundevenl.S | 41 ++++++++++++++++
sysdeps/x86_64/fpu/multiarch/Makefile | 5 +-
sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c | 2 +
.../x86_64/fpu/multiarch/s_roundeven-sse4_1.S | 26 ++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundeven.c | 31 ++++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c | 3 ++
.../fpu/multiarch/s_roundevenf-sse4_1.S | 26 ++++++++++
sysdeps/x86_64/fpu/multiarch/s_roundevenf.c | 31 ++++++++++++
sysdeps/x86_64/fpu/s_roundevenl.S | 47 +++++++++++++++++++
11 files changed, 286 insertions(+), 2 deletions(-)
create mode 100644 sysdeps/i386/fpu/s_roundeven.S
create mode 100644 sysdeps/i386/fpu/s_roundevenf.S
create mode 100644 sysdeps/i386/fpu/s_roundevenl.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundeven.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
create mode 100644 sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
create mode 100644 sysdeps/x86_64/fpu/s_roundevenl.S
diff --git a/sysdeps/i386/fpu/s_roundeven.S b/sysdeps/i386/fpu/s_roundeven.S
new file mode 100644
index 0000000000..1cf78cf952
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundeven.S
@@ -0,0 +1,38 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ double version.
+ Copyright (C) 2019 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/>. */
+
+#include <machine/asm.h>
+#include <libm-alias-double.h>
+
+ENTRY(__roundeven)
+ fldl 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundeven)
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/i386/fpu/s_roundevenf.S b/sysdeps/i386/fpu/s_roundevenf.S
new file mode 100644
index 0000000000..eaf092e325
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundevenf.S
@@ -0,0 +1,38 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ float version.
+ Copyright (C) 2019 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/>. */
+
+#include <machine/asm.h>
+#include <libm-alias-float.h>
+
+ENTRY(__roundevenf)
+ flds 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundevenf)
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/i386/fpu/s_roundevenl.S b/sysdeps/i386/fpu/s_roundevenl.S
new file mode 100644
index 0000000000..b3fc10c1da
--- /dev/null
+++ b/sysdeps/i386/fpu/s_roundevenl.S
@@ -0,0 +1,41 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ long double version.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-ldouble.h>
+#include <machine/asm.h>
+
+ENTRY(__roundevenl)
+ fldt 4(%esp)
+ subl $32, %esp
+ cfi_adjust_cfa_offset (32)
+ fnstenv 4(%esp)
+ movl $0xf3ff, %edx
+ andl 4(%esp), %edx
+ movl %edx, (%esp)
+ fldcw (%esp)
+ frndint
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, 8(%esp)
+ fldenv 4(%esp)
+ addl $32, %esp
+ cfi_adjust_cfa_offset (-32)
+ ret
+END(__roundevenl)
+libm_alias_ldouble (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
index 3836574f48..7e3a3f78cb 100644
--- a/sysdeps/x86_64/fpu/multiarch/Makefile
+++ b/sysdeps/x86_64/fpu/multiarch/Makefile
@@ -1,11 +1,12 @@
ifeq ($(subdir),math)
libm-sysdep_routines += s_floor-c s_ceil-c s_floorf-c s_ceilf-c \
s_rint-c s_rintf-c s_nearbyint-c s_nearbyintf-c \
- s_trunc-c s_truncf-c
+ s_roundeven-c s_roundevenf-c s_trunc-c s_truncf-c
libm-sysdep_routines += s_ceil-sse4_1 s_ceilf-sse4_1 s_floor-sse4_1 \
s_floorf-sse4_1 s_nearbyint-sse4_1 \
- s_nearbyintf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1 \
+ s_nearbyintf-sse4_1 s_roundeven-sse4_1 \
+ s_roundevenf-sse4_1 s_rint-sse4_1 s_rintf-sse4_1 \
s_trunc-sse4_1 s_truncf-sse4_1
libm-sysdep_routines += e_exp-fma e_log-fma e_pow-fma s_atan-fma \
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
new file mode 100644
index 0000000000..c7be43cb22
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-c.c
@@ -0,0 +1,2 @@
+#define __roundeven __roundeven_c
+#include <sysdeps/ieee754/dbl-64/s_roundeven.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
new file mode 100644
index 0000000000..6db88a1649
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven-sse4_1.S
@@ -0,0 +1,26 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ double version.
+ Copyright (C) 2019 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/>. */
+
+#include <sysdep.h>
+
+ .section .text.sse4.1,"ax",@progbits
+ENTRY(__roundeven_sse41)
+ roundsd $8, %xmm0, %xmm0
+ ret
+END(__roundeven_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundeven.c b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
new file mode 100644
index 0000000000..bd777b0ca7
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundeven.c
@@ -0,0 +1,31 @@
+/* Multiple versions of __roundeven.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-double.h>
+
+#define roundeven __redirect_roundeven
+#define __roundeven __redirect___roundeven
+#include <math.h>
+#undef roundeven
+#undef __roundeven
+
+#define SYMBOL_NAME roundeven
+#include "ifunc-sse4_1.h"
+
+libc_ifunc_redirected (__redirect_roundeven, __roundeven, IFUNC_SELECTOR ());
+libm_alias_double (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
new file mode 100644
index 0000000000..72a6e7d1fb
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-c.c
@@ -0,0 +1,3 @@
+#undef __roundevenf
+#define __roundevenf __roundevenf_c
+#include <sysdeps/ieee754/flt-32/s_roundevenf.c>
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
new file mode 100644
index 0000000000..74102bac0d
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf-sse4_1.S
@@ -0,0 +1,26 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ float version.
+ Copyright (C) 2019 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/>. */
+
+#include <sysdep.h>
+
+ .section .text.sse4.1,"ax",@progbits
+ENTRY(__roundevenf_sse41)
+ roundss $8, %xmm0, %xmm0
+ ret
+END(__roundevenf_sse41)
diff --git a/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
new file mode 100644
index 0000000000..8ae1944d2b
--- /dev/null
+++ b/sysdeps/x86_64/fpu/multiarch/s_roundevenf.c
@@ -0,0 +1,31 @@
+/* Multiple versions of __roundevenf.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-float.h>
+
+#define roundevenf __redirect_roundevenf
+#define __roundevenf __redirect___roundevenf
+#include <math.h>
+#undef roundevenf
+#undef __roundevenf
+
+#define SYMBOL_NAME roundevenf
+#include "ifunc-sse4_1.h"
+
+libc_ifunc_redirected (__redirect_roundevenf, __roundevenf, IFUNC_SELECTOR ());
+libm_alias_float (__roundeven, roundeven)
diff --git a/sysdeps/x86_64/fpu/s_roundevenl.S b/sysdeps/x86_64/fpu/s_roundevenl.S
new file mode 100644
index 0000000000..d179b1b603
--- /dev/null
+++ b/sysdeps/x86_64/fpu/s_roundevenl.S
@@ -0,0 +1,47 @@
+/* Round to nearest integer value, rounding halfway cases to even.
+ long double version.
+ Copyright (C) 2019 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/>. */
+
+#include <libm-alias-ldouble.h>
+#include <machine/asm.h>
+
+ENTRY(__roundevenl)
+ fldt 8(%rsp)
+
+ fnstenv -28(%rsp) /* 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 $0xf3ff,%edx /* round to nearest (even) */
+ andl -28(%rsp),%edx
+ movl %edx,-32(%rsp)
+ fldcw -32(%rsp) /* load modified control word */
+
+ frndint /* round */
+
+ /* Preserve "invalid" exceptions from sNaN input. */
+ fnstsw
+ andl $0x1, %eax
+ orl %eax, -24(%rsp)
+
+ fldenv -28(%rsp) /* restore original environment */
+
+ ret
+END (__roundevenl)
+libm_alias_ldouble (__roundeven, roundeven)
--
2.24.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] x86_64: roundeven with fpu and sse4.1 support
2019-12-16 1:27 ` [PATCH v3 2/2] " Shen-Ta Hsieh
@ 2020-03-05 1:20 ` Joseph Myers
0 siblings, 0 replies; 6+ messages in thread
From: Joseph Myers @ 2020-03-05 1:20 UTC (permalink / raw)
To: Shen-Ta Hsieh; +Cc: libc-alpha
Generally such architecture-specific function versions should be justified
with benchmark results showing a performance improvement.
That is, first you should add benchmark inputs for the roundeven functions
in benchtests/. Then patches adding architecture-specific roundeven
implementations should include before-and-after benchmark results in the
commit message to demonstrate that the architecture-specific
implementation does indeed result in a performance improvement.
Note also the need for an FSF copyright assignment for significant
contributions:
https://sourceware.org/glibc/wiki/Contribution%20checklist#FSF_copyright_Assignment
--
Joseph S. Myers
joseph@codesourcery.com
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-03-05 1:20 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-14 16:11 [PATCH] x86_64: roundeven with fpu and sse4.1 support Shen-Ta Hsieh
2019-12-15 5:24 ` [PATCH v2] " Shen-Ta Hsieh
2019-12-15 11:02 ` Florian Weimer
2019-12-16 1:27 ` [PATCH v3 2/2] " Shen-Ta Hsieh
2020-03-05 1:20 ` Joseph Myers
2019-12-16 1:27 ` [PATCH v3 1/2] math: redirect roundeven function Shen-Ta Hsieh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).