[PATCH 01/17] S390: Use load-fp-integer instruction for nearbyint functions.

classic Classic list List threaded Threaded
40 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PATCH 01/17] S390: Use load-fp-integer instruction for nearbyint functions.

Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement nearbyint, nearbyintf, nearbyintl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_nearbyint.c  | 38 ++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_nearbyintf.c | 38 ++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_nearbyintl.c | 39 +++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_nearbyint.c
 create mode 100644 sysdeps/s390/fpu/s_nearbyintf.c
 create mode 100644 sysdeps/s390/fpu/s_nearbyintl.c

diff --git a/sysdeps/s390/fpu/s_nearbyint.c b/sysdeps/s390/fpu/s_nearbyint.c
new file mode 100644
index 0000000000..7af92ace0c
--- /dev/null
+++ b/sysdeps/s390/fpu/s_nearbyint.c
@@ -0,0 +1,38 @@
+/* nearbyint() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__nearbyint (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer according to current rounding mode (M3-field: 0)
+     where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fidbra %0,0,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_double (__nearbyint, nearbyint)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_nearbyint.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_nearbyintf.c b/sysdeps/s390/fpu/s_nearbyintf.c
new file mode 100644
index 0000000000..66473e3b2e
--- /dev/null
+++ b/sysdeps/s390/fpu/s_nearbyintf.c
@@ -0,0 +1,38 @@
+/* nearbyintf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__nearbyintf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer according to current rounding mode (M3-field: 0)
+     where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fiebra %0,0,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__nearbyint, nearbyint)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_nearbyintf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_nearbyintl.c b/sysdeps/s390/fpu/s_nearbyintl.c
new file mode 100644
index 0000000000..f154cf41c7
--- /dev/null
+++ b/sysdeps/s390/fpu/s_nearbyintl.c
@@ -0,0 +1,39 @@
+/* nearbyintl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__nearbyintl (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer according to current rounding mode (M3-field: 0)
+     where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fixbra %0,0,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__nearbyint, nearbyint)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_nearbyintl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 02/17] S390: Use load-fp-integer instruction for rint functions.

Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement rint, rintf, rintl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_rint.c  | 39 +++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_rintf.c | 39 +++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_rintl.c | 40 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_rint.c
 create mode 100644 sysdeps/s390/fpu/s_rintf.c
 create mode 100644 sysdeps/s390/fpu/s_rintl.c

diff --git a/sysdeps/s390/fpu/s_rint.c b/sysdeps/s390/fpu/s_rint.c
new file mode 100644
index 0000000000..17442cab21
--- /dev/null
+++ b/sysdeps/s390/fpu/s_rint.c
@@ -0,0 +1,39 @@
+/* rint() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__rint (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer according to current rounding mode (M3-field: 0)
+     where inexact exceptions are not suppressed (M4-field: 0).  */
+  __asm__ ("fidbra %0,0,%1,0" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_double (__rint, rint)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_rint.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_rintf.c b/sysdeps/s390/fpu/s_rintf.c
new file mode 100644
index 0000000000..3c20edcf38
--- /dev/null
+++ b/sysdeps/s390/fpu/s_rintf.c
@@ -0,0 +1,39 @@
+/* rintf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__rintf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer according to current rounding mode (M3-field: 0)
+     where inexact exceptions are not suppressed (M4-field: 0).  */
+  __asm__ ("fiebra %0,0,%1,0" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__rint, rint)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_rintf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_rintl.c b/sysdeps/s390/fpu/s_rintl.c
new file mode 100644
index 0000000000..8ceaceded0
--- /dev/null
+++ b/sysdeps/s390/fpu/s_rintl.c
@@ -0,0 +1,40 @@
+/* rintl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__rintl (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer according to current rounding mode (M3-field: 0)
+     where inexact exceptions are not suppressed (M4-field: 0).  */
+  __asm__ ("fixbra %0,0,%1,0" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__rint, rint)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_rintl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 03/17] S390: Use load-fp-integer instruction for floor functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement floor, floorf, floorl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_floor.c  | 40 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_floorf.c | 40 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_floorl.c | 41 +++++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_floor.c
 create mode 100644 sysdeps/s390/fpu/s_floorf.c
 create mode 100644 sysdeps/s390/fpu/s_floorl.c

diff --git a/sysdeps/s390/fpu/s_floor.c b/sysdeps/s390/fpu/s_floor.c
new file mode 100644
index 0000000000..dd21fff428
--- /dev/null
+++ b/sysdeps/s390/fpu/s_floor.c
@@ -0,0 +1,40 @@
+/* floor() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__floor (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer with "round towards minus infinity"
+     rounding mode (M3-field: 7) where inexact exceptions are suppressed
+     (M4-field: 4).  */
+  __asm__ ("fidbra %0,7,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_double (__floor, floor)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_floor.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_floorf.c b/sysdeps/s390/fpu/s_floorf.c
new file mode 100644
index 0000000000..c128c63750
--- /dev/null
+++ b/sysdeps/s390/fpu/s_floorf.c
@@ -0,0 +1,40 @@
+/* floorf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__floorf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer with "round towards minus infinity"
+     rounding mode (M3-field: 7) where inexact exceptions are suppressed
+     (M4-field: 4).  */
+  __asm__ ("fiebra %0,7,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__floor, floor)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_floorf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_floorl.c b/sysdeps/s390/fpu/s_floorl.c
new file mode 100644
index 0000000000..737cb94913
--- /dev/null
+++ b/sysdeps/s390/fpu/s_floorl.c
@@ -0,0 +1,41 @@
+/* floorl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__floorl (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer with "round towards minus infinity"
+     rounding mode (M3-field: 7) where inexact exceptions are suppressed
+     (M4-field: 4).  */
+  __asm__ ("fixbra %0,7,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__floor, floor)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_floorl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 04/17] S390: Use load-fp-integer instruction for ceil functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement ceil, ceilf, ceill.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_ceil.c  | 40 +++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_ceilf.c | 40 +++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_ceill.c | 41 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_ceil.c
 create mode 100644 sysdeps/s390/fpu/s_ceilf.c
 create mode 100644 sysdeps/s390/fpu/s_ceill.c

diff --git a/sysdeps/s390/fpu/s_ceil.c b/sysdeps/s390/fpu/s_ceil.c
new file mode 100644
index 0000000000..8613890d67
--- /dev/null
+++ b/sysdeps/s390/fpu/s_ceil.c
@@ -0,0 +1,40 @@
+/* ceil() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__ceil (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer with "round towards plus infinity"
+     rounding mode (M3-field: 6) where inexact exceptions are suppressed
+     (M4-field: 4).  */
+  __asm__ ("fidbra %0,6,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_double (__ceil, ceil)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_ceil.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_ceilf.c b/sysdeps/s390/fpu/s_ceilf.c
new file mode 100644
index 0000000000..692b57826f
--- /dev/null
+++ b/sysdeps/s390/fpu/s_ceilf.c
@@ -0,0 +1,40 @@
+/* ceilf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__ceilf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer with "round towards plus infinity"
+     rounding mode (M3-field: 6) where inexact exceptions are suppressed
+     (M4-field: 4).  */
+  __asm__ ("fiebra %0,6,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__ceil, ceil)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_ceilf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_ceill.c b/sysdeps/s390/fpu/s_ceill.c
new file mode 100644
index 0000000000..5448444fe5
--- /dev/null
+++ b/sysdeps/s390/fpu/s_ceill.c
@@ -0,0 +1,41 @@
+/* ceill() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__ceill (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer with "round towards plus infinity"
+     rounding mode (M3-field: 6) where inexact exceptions are suppressed
+     (M4-field: 4).  */
+  __asm__ ("fixbra %0,6,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__ceil, ceil)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_ceill.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 05/17] S390: Use load-fp-integer instruction for trunc functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement trunc, truncf, truncl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_trunc.c  | 39 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_truncf.c | 39 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_truncl.c | 40 +++++++++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_trunc.c
 create mode 100644 sysdeps/s390/fpu/s_truncf.c
 create mode 100644 sysdeps/s390/fpu/s_truncl.c

diff --git a/sysdeps/s390/fpu/s_trunc.c b/sysdeps/s390/fpu/s_trunc.c
new file mode 100644
index 0000000000..7744843a91
--- /dev/null
+++ b/sysdeps/s390/fpu/s_trunc.c
@@ -0,0 +1,39 @@
+/* trunc() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__trunc (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer with "round towards zero" rounding mode
+     (M3-field: 5) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fidbra %0,5,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_double (__trunc, trunc)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_trunc.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_truncf.c b/sysdeps/s390/fpu/s_truncf.c
new file mode 100644
index 0000000000..40c126eef2
--- /dev/null
+++ b/sysdeps/s390/fpu/s_truncf.c
@@ -0,0 +1,39 @@
+/* truncf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__truncf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer with "round towards zero" rounding mode
+     (M3-field: 5) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fiebra %0,5,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__trunc, trunc)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_truncf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_truncl.c b/sysdeps/s390/fpu/s_truncl.c
new file mode 100644
index 0000000000..68de3ea6bc
--- /dev/null
+++ b/sysdeps/s390/fpu/s_truncl.c
@@ -0,0 +1,40 @@
+/* truncl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__truncl (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer with "round towards zero" rounding mode
+     (M3-field: 5) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fixbra %0,5,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__trunc, trunc)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_truncl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 06/17] S390: Use load-fp-integer instruction for round functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement round, roundf, roundl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_round.c  | 39 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_roundf.c | 39 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_roundl.c | 40 +++++++++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_round.c
 create mode 100644 sysdeps/s390/fpu/s_roundf.c
 create mode 100644 sysdeps/s390/fpu/s_roundl.c

diff --git a/sysdeps/s390/fpu/s_round.c b/sysdeps/s390/fpu/s_round.c
new file mode 100644
index 0000000000..48e2863046
--- /dev/null
+++ b/sysdeps/s390/fpu/s_round.c
@@ -0,0 +1,39 @@
+/* round() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__round (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fidbra %0,1,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_double (__round, round)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_round.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_roundf.c b/sysdeps/s390/fpu/s_roundf.c
new file mode 100644
index 0000000000..c3aff70aed
--- /dev/null
+++ b/sysdeps/s390/fpu/s_roundf.c
@@ -0,0 +1,39 @@
+/* roundf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__roundf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fiebra %0,1,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__round, round)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_roundf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_roundl.c b/sysdeps/s390/fpu/s_roundl.c
new file mode 100644
index 0000000000..698fc6c6f4
--- /dev/null
+++ b/sysdeps/s390/fpu/s_roundl.c
@@ -0,0 +1,40 @@
+/* roundl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__roundl (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fixbra %0,1,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__round, round)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_roundl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 07/17] S390: Use load-fp-integer instruction for roundeven functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the load-fp-integer instruction
is used to implement roundeven, roundevenf, roundevenl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_roundeven.c  | 39 +++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_roundevenf.c | 38 ++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_roundevenl.c | 39 +++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_roundeven.c
 create mode 100644 sysdeps/s390/fpu/s_roundevenf.c
 create mode 100644 sysdeps/s390/fpu/s_roundevenl.c

diff --git a/sysdeps/s390/fpu/s_roundeven.c b/sysdeps/s390/fpu/s_roundeven.c
new file mode 100644
index 0000000000..95a83a70e8
--- /dev/null
+++ b/sysdeps/s390/fpu/s_roundeven.c
@@ -0,0 +1,39 @@
+/* roundeven() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-double.h>
+
+double
+__roundeven (double x)
+{
+  double y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer with "ties to even" rounding mode
+     (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fidbra %0,4,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+hidden_def (__roundeven)
+libm_alias_double (__roundeven, roundeven)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_roundeven.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_roundevenf.c b/sysdeps/s390/fpu/s_roundevenf.c
new file mode 100644
index 0000000000..c620a0189c
--- /dev/null
+++ b/sysdeps/s390/fpu/s_roundevenf.c
@@ -0,0 +1,38 @@
+/* roundevenf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__roundevenf (float x)
+{
+  float y;
+  /* The z196 zarch "load fp integer" (fiebra) instruction is rounding
+     x to the nearest integer with "ties to even" rounding mode
+     (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fiebra %0,4,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_float (__roundeven, roundeven)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_roundevenf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_roundevenl.c b/sysdeps/s390/fpu/s_roundevenl.c
new file mode 100644
index 0000000000..3481af2665
--- /dev/null
+++ b/sysdeps/s390/fpu/s_roundevenl.c
@@ -0,0 +1,39 @@
+/* roundevenl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__roundevenl (_Float128 x)
+{
+  _Float128 y;
+  /* The z196 zarch "load fp integer" (fixbra) instruction is rounding
+     x to the nearest integer with "ties to even" rounding mode
+     (M3-field: 4) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fixbra %0,4,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+libm_alias_ldouble (__roundeven, roundeven)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_roundevenl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 08/17] S390: Use convert-to-fixed instruction for lrint functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the convert-to-fixed instruction
is used to implement lrint, lrintf, lrintl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_lrint.c  | 55 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_lrintf.c | 55 ++++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_lrintl.c | 56 +++++++++++++++++++++++++++++++++++++
 3 files changed, 166 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_lrint.c
 create mode 100644 sysdeps/s390/fpu/s_lrintf.c
 create mode 100644 sysdeps/s390/fpu/s_lrintl.c

diff --git a/sysdeps/s390/fpu/s_lrint.c b/sysdeps/s390/fpu/s_lrint.c
new file mode 100644
index 0000000000..7be60665b5
--- /dev/null
+++ b/sysdeps/s390/fpu/s_lrint.c
@@ -0,0 +1,55 @@
+/* lrint() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-double.h>
+
+/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
+   Thus we need different instructions as the target size is encoded there.
+   Note: On s390 this instruction is only used if build with -mzarch.  */
+# ifdef __s390x__
+#  define INSN "cgdbra"
+# else
+#  define INSN "cfdbra"
+# endif
+
+long int
+__lrint (double x)
+{
+  long int y;
+  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
+     according to current rounding mode (M3-field: 0).
+     First convert x with suppressed inexact exception and check if the
+     resulting value is beyond the target limits (indicated by cc=3;
+     Note: a nan is also indicated by cc=3).
+     If the resulting value is within the target limits, redo
+     without suppressing the inexact exception.  */
+  __asm__ (INSN " %0,0,%1,4 \n\t"
+   "jo 1f \n\t"
+   INSN " %0,0,%1,0 \n\t"
+   "1:"
+   : "=&d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_double (__lrint, lrint)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_lrint.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_lrintf.c b/sysdeps/s390/fpu/s_lrintf.c
new file mode 100644
index 0000000000..d6a2a4081a
--- /dev/null
+++ b/sysdeps/s390/fpu/s_lrintf.c
@@ -0,0 +1,55 @@
+/* lrintf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-float.h>
+
+/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
+   Thus we need different instructions as the target size is encoded there.
+   Note: On s390 this instruction is only used if build with -mzarch.  */
+# ifdef __s390x__
+#  define INSN "cgebra"
+# else
+#  define INSN "cfebra"
+# endif
+
+long int
+__lrintf (float x)
+{
+  long int y;
+  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
+     according to current rounding mode (M3-field: 0).
+     First convert x with suppressed inexact exception and check if the
+     resulting value is beyond the target limits (indicated by cc=3;
+     Note: a nan is also indicated by cc=3).
+     If the resulting value is within the target limits, redo
+     without suppressing the inexact exception.  */
+  __asm__ (INSN " %0,0,%1,4 \n\t"
+   "jo 1f \n\t"
+   INSN " %0,0,%1,0 \n\t"
+   "1:"
+   : "=&d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_float (__lrint, lrint)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_lrintf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_lrintl.c b/sysdeps/s390/fpu/s_lrintl.c
new file mode 100644
index 0000000000..2d386ecff9
--- /dev/null
+++ b/sysdeps/s390/fpu/s_lrintl.c
@@ -0,0 +1,56 @@
+/* lrintl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
+   Thus we need different instructions as the target size is encoded there.
+   Note: On s390 this instruction is only used if build with -mzarch.  */
+# ifdef __s390x__
+#  define INSN "cgxbra"
+# else
+#  define INSN "cfxbra"
+# endif
+
+long int
+__lrintl (_Float128 x)
+{
+  long int y;
+  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
+     according to current rounding mode (M3-field: 0).
+     First convert x with suppressed inexact exception and check if the
+     resulting value is beyond the target limits (indicated by cc=3;
+     Note: a nan is also indicated by cc=3).
+     If the resulting value is within the target limits, redo
+     without suppressing the inexact exception.  */
+  __asm__ (INSN " %0,0,%1,4 \n\t"
+   "jo 1f \n\t"
+   INSN " %0,0,%1,0 \n\t"
+   "1:"
+   : "=&d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_ldouble (__lrint, lrint)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_lrintl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 09/17] S390: Use convert-to-fixed instruction for llrint functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the convert-to-fixed instruction
is used to implement llrint, llrintf, llrintl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_llrint.c  | 50 +++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_llrintf.c | 50 +++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_llrintl.c | 51 ++++++++++++++++++++++++++++++++++++
 3 files changed, 151 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_llrint.c
 create mode 100644 sysdeps/s390/fpu/s_llrintf.c
 create mode 100644 sysdeps/s390/fpu/s_llrintl.c

diff --git a/sysdeps/s390/fpu/s_llrint.c b/sysdeps/s390/fpu/s_llrint.c
new file mode 100644
index 0000000000..edd796ae8c
--- /dev/null
+++ b/sysdeps/s390/fpu/s_llrint.c
@@ -0,0 +1,50 @@
+/* llrint() - S390 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/>.  */
+
+#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+/* We only support s390x as on s390 a long long int refers to a register pair
+   of two 4byte registers instead of a 8byte register which is produced by the
+   instruction.
+   Note: On s390 this instruction would only be used if build with -mzarch.  */
+# include <math.h>
+# include <libm-alias-double.h>
+
+long long int
+__llrint (double x)
+{
+  long long int y;
+  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
+     according to current rounding mode (M3-field: 0).
+     First convert x with suppressed inexact exception and check if the
+     resulting value is beyond the target limits (indicated by cc=3;
+     Note: a nan is also indicated by cc=3).
+     If the resulting value is within the target limits, redo
+     without suppressing the inexact exception.  */
+  __asm__ ("cgdbra %0,0,%1,4 \n\t"
+   "jo 1f \n\t"
+   "cgdbra %0,0,%1,0 \n\t"
+   "1:"
+   : "=&d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_double (__llrint, llrint)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_llrint.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_llrintf.c b/sysdeps/s390/fpu/s_llrintf.c
new file mode 100644
index 0000000000..3cbe7c581a
--- /dev/null
+++ b/sysdeps/s390/fpu/s_llrintf.c
@@ -0,0 +1,50 @@
+/* llrintf() - S390 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/>.  */
+
+#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+/* We only support s390x as on s390 a long long int refers to a register pair
+   of two 4byte registers instead of a 8byte register which is produced by the
+   instruction.
+   Note: On s390 this instruction would only be used if build with -mzarch.  */
+# include <math.h>
+# include <libm-alias-float.h>
+
+long long int
+__llrintf (float x)
+{
+  long long int y;
+  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
+     according to current rounding mode (M3-field: 0).
+     First convert x with suppressed inexact exception and check if the
+     resulting value is beyond the target limits (indicated by cc=3;
+     Note: a nan is also indicated by cc=3).
+     If the resulting value is within the target limits, redo
+     without suppressing the inexact exception.  */
+  __asm__ ("cgebra %0,0,%1,4 \n\t"
+   "jo 1f \n\t"
+   "cgebra %0,0,%1,0 \n\t"
+   "1:"
+   : "=&d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_float (__llrint, llrint)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_llrintf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_llrintl.c b/sysdeps/s390/fpu/s_llrintl.c
new file mode 100644
index 0000000000..37eea5914f
--- /dev/null
+++ b/sysdeps/s390/fpu/s_llrintl.c
@@ -0,0 +1,51 @@
+/* llrintl() - S390 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/>.  */
+
+#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+/* We only support s390x as on s390 a long long int refers to a register pair
+   of two 4byte registers instead of a 8byte register which is produced by the
+   instruction.
+   Note: On s390 this instruction would only be used if build with -mzarch.  */
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+long long int
+__llrintl (_Float128 x)
+{
+  long long int y;
+  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
+     according to current rounding mode (M3-field: 0).
+     First convert x with suppressed inexact exception and check if the
+     resulting value is beyond the target limits (indicated by cc=3;
+     Note: a nan is also indicated by cc=3).
+     If the resulting value is within the target limits, redo
+     without suppressing the inexact exception.  */
+  __asm__ ("cgxbra %0,0,%1,4 \n\t"
+   "jo 1f \n\t"
+   "cgxbra %0,0,%1,0 \n\t"
+   "1:"
+   : "=&d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_ldouble (__llrint, llrint)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_llrintl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 10/17] S390: Use convert-to-fixed instruction for lround functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the convert-to-fixed instruction
is used to implement lround, lroundf, lroundl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_lround.c  | 47 +++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_lroundf.c | 47 +++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_lroundl.c | 48 ++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_lround.c
 create mode 100644 sysdeps/s390/fpu/s_lroundf.c
 create mode 100644 sysdeps/s390/fpu/s_lroundl.c

diff --git a/sysdeps/s390/fpu/s_lround.c b/sysdeps/s390/fpu/s_lround.c
new file mode 100644
index 0000000000..9290ec32cd
--- /dev/null
+++ b/sysdeps/s390/fpu/s_lround.c
@@ -0,0 +1,47 @@
+/* lround() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-double.h>
+
+/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
+   Thus we need different instructions as the target size is encoded there.
+   Note: On s390 this instruction is only used if build with -mzarch.  */
+# ifdef __s390x__
+#  define INSN "cgdbra"
+# else
+#  define INSN "cfdbra"
+# endif
+
+long int
+__lround (double x)
+{
+  long int y;
+  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_double (__lround, lround)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_lround.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_lroundf.c b/sysdeps/s390/fpu/s_lroundf.c
new file mode 100644
index 0000000000..097b924c91
--- /dev/null
+++ b/sysdeps/s390/fpu/s_lroundf.c
@@ -0,0 +1,47 @@
+/* lroundf() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <libm-alias-float.h>
+
+/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
+   Thus we need different instructions as the target size is encoded there.
+   Note: On s390 this instruction is only used if build with -mzarch.  */
+# ifdef __s390x__
+#  define INSN "cgebra"
+# else
+#  define INSN "cfebra"
+# endif
+
+long int
+__lroundf (float x)
+{
+  long int y;
+  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_float (__lround, lround)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_lroundf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_lroundl.c b/sysdeps/s390/fpu/s_lroundl.c
new file mode 100644
index 0000000000..0ef77dc667
--- /dev/null
+++ b/sysdeps/s390/fpu/s_lroundl.c
@@ -0,0 +1,48 @@
+/* lroundl() - S390 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/>.  */
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+/* The sizeof (long int) differs between s390x (8byte) and s390 (4byte).
+   Thus we need different instructions as the target size is encoded there.
+   Note: On s390 this instruction is only used if build with -mzarch.  */
+# ifdef __s390x__
+#  define INSN "cgxbra"
+# else
+#  define INSN "cfxbra"
+# endif
+
+long int
+__lroundl (_Float128 x)
+{
+  long int y;
+  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ (INSN " %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_ldouble (__lround, lround)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_lroundl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 11/17] S390: Use convert-to-fixed instruction for llround functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z196 zarch support, the convert-to-fixed instruction
is used to implement llround, llroundf, llroundl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_llround.c  | 42 ++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_llroundf.c | 42 ++++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_llroundl.c | 43 +++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_llround.c
 create mode 100644 sysdeps/s390/fpu/s_llroundf.c
 create mode 100644 sysdeps/s390/fpu/s_llroundl.c

diff --git a/sysdeps/s390/fpu/s_llround.c b/sysdeps/s390/fpu/s_llround.c
new file mode 100644
index 0000000000..f4a1b21637
--- /dev/null
+++ b/sysdeps/s390/fpu/s_llround.c
@@ -0,0 +1,42 @@
+/* llround() - S390 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/>.  */
+
+#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+/* We only support s390x as on s390 a long long int refers to a register pair
+   of two 4byte registers instead of a 8byte register which is produced by the
+   instruction.
+   Note: On s390 this instruction would only be used if build with -mzarch.  */
+# include <math.h>
+# include <libm-alias-double.h>
+
+long long int
+__llround (double x)
+{
+  long long int y;
+  /* The z196 zarch "convert to fixed" (cgdbra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("cgdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_double (__llround, llround)
+
+#else
+# include <sysdeps/ieee754/dbl-64/s_llround.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_llroundf.c b/sysdeps/s390/fpu/s_llroundf.c
new file mode 100644
index 0000000000..d202f4be8c
--- /dev/null
+++ b/sysdeps/s390/fpu/s_llroundf.c
@@ -0,0 +1,42 @@
+/* llroundf() - S390 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/>.  */
+
+#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+/* We only support s390x as on s390 a long long int refers to a register pair
+   of two 4byte registers instead of a 8byte register which is produced by the
+   instruction.
+   Note: On s390 this instruction would only be used if build with -mzarch.  */
+# include <math.h>
+# include <libm-alias-float.h>
+
+long long int
+__llroundf (float x)
+{
+  long long int y;
+  /* The z196 zarch "convert to fixed" (cgebra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("cgebra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_float (__llround, llround)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_llroundf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_llroundl.c b/sysdeps/s390/fpu/s_llroundl.c
new file mode 100644
index 0000000000..58976cd5c5
--- /dev/null
+++ b/sysdeps/s390/fpu/s_llroundl.c
@@ -0,0 +1,43 @@
+/* llroundl() - S390 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/>.  */
+
+#if defined __s390x__ && defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+/* We only support s390x as on s390 a long long int refers to a register pair
+   of two 4byte registers instead of a 8byte register which is produced by the
+   instruction.
+   Note: On s390 this instruction would only be used if build with -mzarch.  */
+# include <math.h>
+# include <math_private.h>
+# include <libm-alias-ldouble.h>
+
+long long int
+__llroundl (_Float128 x)
+{
+  long long int y;
+  /* The z196 zarch "convert to fixed" (cgxbra) instruction is rounding
+     x to the nearest integer with "ties away from 0" rounding mode
+     (M3-field: 1) where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("cgxbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+libm_alias_ldouble (__llround, llround)
+
+#else
+# include <sysdeps/ieee754/ldbl-128/s_llroundl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 12/17] S390: Use copy-sign instruction for copysign functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
If compiled with z10 zarch support, the copy-sign instruction
is used to implement copysign, copysignf, copysignl.
Otherwise the common-code implementation is used.
---
 sysdeps/s390/fpu/s_copysign.c  | 39 ++++++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_copysignf.c | 35 +++++++++++++++++++++++++++++
 sysdeps/s390/fpu/s_copysignl.c | 41 ++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+)
 create mode 100644 sysdeps/s390/fpu/s_copysign.c
 create mode 100644 sysdeps/s390/fpu/s_copysignf.c
 create mode 100644 sysdeps/s390/fpu/s_copysignl.c

diff --git a/sysdeps/s390/fpu/s_copysign.c b/sysdeps/s390/fpu/s_copysign.c
new file mode 100644
index 0000000000..f62d86b925
--- /dev/null
+++ b/sysdeps/s390/fpu/s_copysign.c
@@ -0,0 +1,39 @@
+/* copysign() - S390 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/>.  */
+
+#if defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-double.h>
+# include <math_ldbl_opt.h>
+
+double
+__copysign (double x, double y)
+{
+  __asm__ ("cpsdr %0,%1,%0" : "+f" (x) : "f" (y));
+  return x;
+}
+libm_alias_double (__copysign, copysign)
+# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0)
+compat_symbol (libc, __copysign, copysignl, GLIBC_2_0);
+# endif
+
+#else
+# include <sysdeps/ieee754/ldbl-opt/s_copysign.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_copysignf.c b/sysdeps/s390/fpu/s_copysignf.c
new file mode 100644
index 0000000000..017f558486
--- /dev/null
+++ b/sysdeps/s390/fpu/s_copysignf.c
@@ -0,0 +1,35 @@
+/* copysignf() - S390 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/>.  */
+
+#if defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <libm-alias-float.h>
+
+float
+__copysignf (float x, float y)
+{
+  __asm__ ("cpsdr %0,%1,%0" : "+f" (x) : "f" (y));
+  return x;
+}
+libm_alias_float (__copysign, copysign)
+
+#else
+# include <sysdeps/ieee754/flt-32/s_copysignf.c>
+#endif
diff --git a/sysdeps/s390/fpu/s_copysignl.c b/sysdeps/s390/fpu/s_copysignl.c
new file mode 100644
index 0000000000..b7aec86d90
--- /dev/null
+++ b/sysdeps/s390/fpu/s_copysignl.c
@@ -0,0 +1,41 @@
+/* copysignl() - S390 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/>.  */
+
+#if defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
+# define NO_MATH_REDIRECT
+# include <math.h>
+# include <math_private.h>
+# include <math_ldbl_opt.h>
+# include <libm-alias-ldouble.h>
+
+_Float128
+__copysignl (_Float128 x, _Float128 y)
+{
+  __asm__ ("cpsdr %0,%1,%0" : "+f" (x) : "f" (y));
+  return x;
+}
+# if IS_IN (libc)
+long_double_symbol (libc, __copysignl, copysignl);
+# else
+libm_alias_ldouble (__copysign, copysign)
+# endif
+
+#else
+# include <sysdeps/ieee754/ldbl-64-128/s_copysignl.c>
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 13/17] S390: Implement libc_fe* macros.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
This patch provides the s390 specific implementation for
libc_feholdexcept, libc_fesetround, libc_feholdexcept_setround,
libc_fetestexcept, libc_fesetenv, libc_feupdateenv_test,
libc_feupdateenv, libc_feholdsetround_ctx, libc_feresetround_ctx,
libc_feholdsetround_noex_ctx and libc_feresetround_noex_ctx.
---
 sysdeps/s390/fpu/fenv_private.h | 250 ++++++++++++++++++++++++++++++++
 1 file changed, 250 insertions(+)
 create mode 100644 sysdeps/s390/fpu/fenv_private.h

diff --git a/sysdeps/s390/fpu/fenv_private.h b/sysdeps/s390/fpu/fenv_private.h
new file mode 100644
index 0000000000..babb9e3123
--- /dev/null
+++ b/sysdeps/s390/fpu/fenv_private.h
@@ -0,0 +1,250 @@
+/* Private floating point rounding and exceptions handling.  390/s390x 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/>.  */
+
+#ifndef S390_FENV_PRIVATE_H
+#define S390_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+static __always_inline void
+libc_feholdexcept_s390 (fenv_t *envp)
+{
+  fpu_control_t fpc, fpc_new;
+
+  /* Store the environment.  */
+  _FPU_GETCW (fpc);
+  envp->__fpc = fpc;
+
+  /* Clear the current exception flags and dxc field.
+     Hold from generating fpu exceptions temporarily.  */
+  fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK);
+
+  /* Only set new environment if it has changed.  */
+  if (fpc_new != fpc)
+    _FPU_SETCW (fpc_new);
+}
+
+#define libc_feholdexcept  libc_feholdexcept_s390
+#define libc_feholdexceptf libc_feholdexcept_s390
+#define libc_feholdexceptl libc_feholdexcept_s390
+
+static __always_inline void
+libc_fesetround_s390 (int round)
+{
+  __asm__ __volatile__ ("srnm 0(%0)" : : "a" (round));
+}
+
+#define libc_fesetround  libc_fesetround_s390
+#define libc_fesetroundf libc_fesetround_s390
+#define libc_fesetroundl libc_fesetround_s390
+
+static __always_inline void
+libc_feholdexcept_setround_s390 (fenv_t *envp, int r)
+{
+  fpu_control_t fpc, fpc_new;
+
+  _FPU_GETCW (fpc);
+  envp->__fpc = fpc;
+
+  /* Clear the current exception flags and dxc field.
+     Hold from generating fpu exceptions temporarily.
+     Reset rounding mode bits.  */
+  fpc_new = fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK | FPC_EXCEPTION_MASK
+    | FPC_RM_MASK);
+
+  /* Set new rounding mode.  */
+  fpc_new |= (r & FPC_RM_MASK);
+
+  /* Only set new environment if it has changed.  */
+  if (fpc_new != fpc)
+    _FPU_SETCW (fpc_new);
+}
+
+#define libc_feholdexcept_setround  libc_feholdexcept_setround_s390
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_s390
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_s390
+
+static __always_inline int
+libc_fetestexcept_s390 (int excepts)
+{
+  int res;
+  fexcept_t fpc;
+
+  _FPU_GETCW (fpc);
+
+  /* Get current exceptions.  */
+  res = (fpc >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT;
+  if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0)
+    /* Bits 6, 7 of dxc-byte are zero,
+       thus bits 0-5 of dxc-byte correspond to the flag-bits.
+       Evaluate flags and last dxc-exception-code.  */
+    res |= (fpc >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT;
+
+  return res & excepts;
+}
+
+#define libc_fetestexcept  libc_fetestexcept_s390
+#define libc_fetestexceptf libc_fetestexcept_s390
+#define libc_fetestexceptl libc_fetestexcept_s390
+
+static __always_inline void
+libc_fesetenv_s390 (const fenv_t *envp)
+{
+  _FPU_SETCW (envp->__fpc);
+}
+
+#define libc_fesetenv  libc_fesetenv_s390
+#define libc_fesetenvf libc_fesetenv_s390
+#define libc_fesetenvl libc_fesetenv_s390
+
+static __always_inline int
+libc_feupdateenv_test_s390 (const fenv_t *envp, int ex)
+{
+  /* Get the currently raised exceptions.  */
+  int excepts;
+  fexcept_t fpc_old;
+
+  _FPU_GETCW (fpc_old);
+
+  /* Get current exceptions.  */
+  excepts = (fpc_old >> FPC_FLAGS_SHIFT) & FE_ALL_EXCEPT;
+  if ((fpc_old & FPC_NOT_FPU_EXCEPTION) == 0)
+    /* Bits 6, 7 of dxc-byte are zero,
+       thus bits 0-5 of dxc-byte correspond to the flag-bits.
+       Evaluate flags and last dxc-exception-code.  */
+    excepts |= (fpc_old >> FPC_DXC_SHIFT) & FE_ALL_EXCEPT;
+
+  /* Merge the currently raised exceptions with those in envp.  */
+  fpu_control_t fpc_new = envp->__fpc;
+  fpc_new |= excepts << FPC_FLAGS_SHIFT;
+
+  /* Install the new fpc from envp.  */
+  if (fpc_new != fpc_old)
+    _FPU_SETCW (fpc_new);
+
+  /* Raise the exceptions if enabled in new fpc.  */
+  if (__glibc_unlikely ((fpc_new >> FPC_EXCEPTION_MASK_SHIFT) & excepts))
+    __feraiseexcept (excepts);
+
+  return excepts & ex;
+}
+
+#define libc_feupdateenv_test  libc_feupdateenv_test_s390
+#define libc_feupdateenv_testf libc_feupdateenv_test_s390
+#define libc_feupdateenv_testl libc_feupdateenv_test_s390
+
+static __always_inline void
+libc_feupdateenv_s390 (const fenv_t *envp)
+{
+  libc_feupdateenv_test_s390 (envp, 0);
+}
+
+#define libc_feupdateenv  libc_feupdateenv_s390
+#define libc_feupdateenvf libc_feupdateenv_s390
+#define libc_feupdateenvl libc_feupdateenv_s390
+
+static __always_inline fenv_t
+libc_handle_user_fenv_s390 (const fenv_t *envp)
+{
+  fenv_t env;
+  if (envp == FE_DFL_ENV)
+    {
+      env.__fpc = _FPU_DEFAULT;
+    }
+  else if (envp == FE_NOMASK_ENV)
+    {
+      env.__fpc = FPC_EXCEPTION_MASK;
+    }
+  else
+    env = (*envp);
+
+  return env;
+}
+
+/* We have support for rounding mode context.  */
+#define HAVE_RM_CTX 1
+
+static __always_inline void
+libc_feholdsetround_s390_ctx (struct rm_ctx *ctx, int r)
+{
+  fpu_control_t fpc;
+  int round;
+
+  _FPU_GETCW (fpc);
+  ctx->env.__fpc = fpc;
+
+  /* Check whether rounding modes are different.  */
+  round = fpc & FPC_RM_MASK;
+
+  /* Set the rounding mode if changed.  */
+  if (__glibc_unlikely (round != r))
+    {
+      ctx->updated_status = true;
+      libc_fesetround_s390 (r);
+    }
+  else
+    ctx->updated_status = false;
+}
+
+#define libc_feholdsetround_ctx libc_feholdsetround_s390_ctx
+#define libc_feholdsetroundf_ctx libc_feholdsetround_s390_ctx
+#define libc_feholdsetroundl_ctx libc_feholdsetround_s390_ctx
+
+static __always_inline void
+libc_feresetround_s390_ctx (struct rm_ctx *ctx)
+{
+  /* Restore the rounding mode if updated.  */
+  if (__glibc_unlikely (ctx->updated_status))
+    {
+      fpu_control_t fpc;
+      _FPU_GETCW (fpc);
+      fpc = ctx->env.__fpc | (fpc & FPC_FLAGS_MASK);
+      _FPU_SETCW (fpc);
+    }
+}
+
+#define libc_feresetround_ctx libc_feresetround_s390_ctx
+#define libc_feresetroundf_ctx libc_feresetround_s390_ctx
+#define libc_feresetroundl_ctx libc_feresetround_s390_ctx
+
+static __always_inline void
+libc_feholdsetround_noex_s390_ctx (struct rm_ctx *ctx, int r)
+{
+  libc_feholdexcept_setround_s390 (&ctx->env, r);
+}
+
+#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_s390_ctx
+#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_s390_ctx
+#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_s390_ctx
+
+static __always_inline void
+libc_feresetround_noex_s390_ctx (struct rm_ctx *ctx)
+{
+  /* Restore exception flags and rounding mode.  */
+  libc_fesetenv_s390 (&ctx->env);
+}
+
+#define libc_feresetround_noex_ctx libc_feresetround_noex_s390_ctx
+#define libc_feresetround_noexf_ctx libc_feresetround_noex_s390_ctx
+#define libc_feresetround_noexl_ctx libc_feresetround_noex_s390_ctx
+
+#include_next <fenv_private.h>
+
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 14/17] S390: Use libc_fe* macros in fe* functions.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
This patch updates the s390 specific functions fegetround,
fesetround, feholdexcept, fesetenv, feupdateenv, fegetexceptflag,
fetestexcept, fesetexceptflag, fetestexceptflag.
Now those functions are using the libc_fe* macros if possible.

Furthermore fegetexceptflag is now returning the exception from
dxc field shifted to the usual exception-flags.
Thus a special fetestexceptflag implementation is not needed anymore.
---
 sysdeps/s390/fpu/fegetround.c       |  9 ++-------
 sysdeps/s390/fpu/feholdexcpt.c      | 12 ++---------
 sysdeps/s390/fpu/fesetenv.c         | 21 +++----------------
 sysdeps/s390/fpu/fesetround.c       |  9 +++------
 sysdeps/s390/fpu/fetestexceptflag.c | 31 -----------------------------
 sysdeps/s390/fpu/feupdateenv.c      | 14 +++----------
 sysdeps/s390/fpu/fgetexcptflg.c     | 16 ++-------------
 sysdeps/s390/fpu/fsetexcptflg.c     | 23 ++++++++++-----------
 sysdeps/s390/fpu/ftestexcept.c      | 16 ++-------------
 9 files changed, 27 insertions(+), 124 deletions(-)
 delete mode 100644 sysdeps/s390/fpu/fetestexceptflag.c

diff --git a/sysdeps/s390/fpu/fegetround.c b/sysdeps/s390/fpu/fegetround.c
index 8e61605bad..847b5d2de5 100644
--- a/sysdeps/s390/fpu/fegetround.c
+++ b/sysdeps/s390/fpu/fegetround.c
@@ -17,17 +17,12 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
+#include <get-rounding-mode.h>
 
 int
 __fegetround (void)
 {
-  fexcept_t cw;
-
-  _FPU_GETCW (cw);
-
-  return cw & FPC_RM_MASK;
+  return get_rounding_mode ();
 }
 libm_hidden_def (__fegetround)
 weak_alias (__fegetround, fegetround)
diff --git a/sysdeps/s390/fpu/feholdexcpt.c b/sysdeps/s390/fpu/feholdexcpt.c
index 8ad7d530bd..e2eb5d2a77 100644
--- a/sysdeps/s390/fpu/feholdexcpt.c
+++ b/sysdeps/s390/fpu/feholdexcpt.c
@@ -17,19 +17,11 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
+#include <fenv_private.h>
 
 int __feholdexcept (fenv_t *envp)
 {
-  fexcept_t fpc;
-  /* Store the environment.  */
-  __fegetenv (envp);
-  /* Clear the current sticky bits as more than one exception
-     may be generated.  */
-  fpc = envp->__fpc & ~(FPC_FLAGS_MASK | FPC_DXC_MASK);
-  /* Hold from generating fpu exceptions temporarily.  */
-  _FPU_SETCW ((fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT)));
+  libc_feholdexcept_s390 (envp);
   return 0;
 }
 libm_hidden_def (__feholdexcept)
diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c
index ede3d89b3b..dca26033a7 100644
--- a/sysdeps/s390/fpu/fesetenv.c
+++ b/sysdeps/s390/fpu/fesetenv.c
@@ -17,28 +17,13 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
-#include <stddef.h>
-#include <unistd.h>
+#include <fenv_private.h>
 
 int
 __fesetenv (const fenv_t *envp)
 {
-  fenv_t env;
-
-  if (envp == FE_DFL_ENV)
-    {
-      env.__fpc = _FPU_DEFAULT;
-    }
-  else if (envp == FE_NOMASK_ENV)
-    {
-      env.__fpc = FPC_EXCEPTION_MASK;
-    }
-  else
-    env = (*envp);
-
-  _FPU_SETCW (env.__fpc);
+  fenv_t env = libc_handle_user_fenv_s390 (envp);
+  libc_fesetenv_s390 (&env);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/s390/fpu/fesetround.c b/sysdeps/s390/fpu/fesetround.c
index 38ec4284d3..752b41a171 100644
--- a/sysdeps/s390/fpu/fesetround.c
+++ b/sysdeps/s390/fpu/fesetround.c
@@ -17,21 +17,18 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
+#include <fenv_private.h>
 
 int
 __fesetround (int round)
 {
-  if ((round|FPC_RM_MASK) != FPC_RM_MASK)
+  if ((round | FPC_RM_MASK) != FPC_RM_MASK)
     {
       /* ROUND is not a valid rounding mode.  */
       return 1;
     }
-  __asm__ __volatile__ ("srnm 0(%0)"
- :
- : "a" (round));
 
+  libc_fesetround_s390 (round);
   return 0;
 }
 libm_hidden_def (__fesetround)
diff --git a/sysdeps/s390/fpu/fetestexceptflag.c b/sysdeps/s390/fpu/fetestexceptflag.c
deleted file mode 100644
index e8badeb13e..0000000000
--- a/sysdeps/s390/fpu/fetestexceptflag.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Test exception in saved exception state.  S/390 version.
-   Copyright (C) 2016-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 <fenv.h>
-#include <fenv_libc.h>
-
-int
-fetestexceptflag (const fexcept_t *flagp, int excepts)
-{
-  /* As *flagp is obtained by an earlier call of fegetexceptflag the
-     bits 0-5 of dxc-byte are either zero or correspond to the
-     flag-bits.  Evaluate flags and last dxc-exception-code.  */
-  return (((*flagp >> FPC_FLAGS_SHIFT) | (*flagp >> FPC_DXC_SHIFT))
-  & excepts
-  & FE_ALL_EXCEPT);
-}
diff --git a/sysdeps/s390/fpu/feupdateenv.c b/sysdeps/s390/fpu/feupdateenv.c
index e6b1ff8ff1..9ddff724e6 100644
--- a/sysdeps/s390/fpu/feupdateenv.c
+++ b/sysdeps/s390/fpu/feupdateenv.c
@@ -18,21 +18,13 @@
    <https://www.gnu.org/licenses/>.  */
 
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
+#include <fenv_private.h>
 
 int
 __feupdateenv (const fenv_t *envp)
 {
-  fexcept_t temp;
-
-  _FPU_GETCW (temp);
-  temp = (temp & FPC_FLAGS_MASK) >> FPC_FLAGS_SHIFT;
-
-  /* Raise the exceptions since the last call to feholdenv  */
-  /* re install saved environment.  */
-  __fesetenv (envp);
-  __feraiseexcept ((int) temp);
+  fenv_t env = libc_handle_user_fenv_s390 (envp);
+  libc_feupdateenv_s390 (&env);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c
index 779eec83bc..7231752029 100644
--- a/sysdeps/s390/fpu/fgetexcptflg.c
+++ b/sysdeps/s390/fpu/fgetexcptflg.c
@@ -17,24 +17,12 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
+#include <fenv_private.h>
 
 int
 fegetexceptflag (fexcept_t *flagp, int excepts)
 {
-  fexcept_t temp, newexcepts;
-
-  /* Get the current exceptions.  */
-  _FPU_GETCW (temp);
-  newexcepts = excepts << FPC_FLAGS_SHIFT;
-  if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
-    /* Bits 6, 7 of dxc-byte are zero,
-       thus bits 0-5 of dxc-byte correspond to the flag-bits.
-       Evaluate flags and last dxc-exception-code.  */
-    newexcepts |= excepts << FPC_DXC_SHIFT;
-
-  *flagp = temp & newexcepts;
+  *flagp = libc_fetestexcept_s390 (excepts);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c
index b3e4bbf878..0b9517ef59 100644
--- a/sysdeps/s390/fpu/fsetexcptflg.c
+++ b/sysdeps/s390/fpu/fsetexcptflg.c
@@ -24,29 +24,26 @@
 int
 fesetexceptflag (const fexcept_t *flagp, int excepts)
 {
-  fexcept_t temp, newexcepts;
+  fexcept_t fpc, fpc_new;
 
   /* Get the current environment.  We have to do this since we cannot
      separately set the status word.  */
-  _FPU_GETCW (temp);
-  /* Install the new exception bits in the Accrued Exception Byte.  */
-  excepts = excepts & FE_ALL_EXCEPT;
-  newexcepts = excepts << FPC_FLAGS_SHIFT;
-  temp &= ~newexcepts;
-  if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
+  _FPU_GETCW (fpc);
+
+  /* Clear the current exception bits.  */
+  fpc_new = fpc & ~((excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT);
+  if ((fpc & FPC_NOT_FPU_EXCEPTION) == 0)
     /* Bits 6, 7 of dxc-byte are zero,
        thus bits 0-5 of dxc-byte correspond to the flag-bits.
        Clear given exceptions in dxc-field.  */
-    temp &= ~(excepts << FPC_DXC_SHIFT);
+    fpc_new &= ~((excepts & FE_ALL_EXCEPT) << FPC_DXC_SHIFT);
 
-  /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains
-     either an ieee-exception or 0 (see fegetexceptflag).  */
-  temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT))
-    & newexcepts;
+  /* Set exceptions from flagp in flags-field.  */
+  fpc_new |= (*flagp & excepts & FE_ALL_EXCEPT) << FPC_FLAGS_SHIFT;
 
   /* Store the new status word (along with the rest of the environment.
      Possibly new exceptions are set but they won't get executed.  */
-  _FPU_SETCW (temp);
+  _FPU_SETCW (fpc_new);
 
   /* Success.  */
   return 0;
diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c
index eabc1b65b9..ed7df8b02b 100644
--- a/sysdeps/s390/fpu/ftestexcept.c
+++ b/sysdeps/s390/fpu/ftestexcept.c
@@ -17,23 +17,11 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <fenv_libc.h>
-#include <fpu_control.h>
+#include <fenv_private.h>
 
 int
 fetestexcept (int excepts)
 {
-  fexcept_t temp, res;
-
-  /* Get current exceptions.  */
-  _FPU_GETCW (temp);
-  res = temp >> FPC_FLAGS_SHIFT;
-  if ((temp & FPC_NOT_FPU_EXCEPTION) == 0)
-    /* Bits 6, 7 of dxc-byte are zero,
-       thus bits 0-5 of dxc-byte correspond to the flag-bits.
-       Evaluate flags and last dxc-exception-code.  */
-    res |= temp >> FPC_DXC_SHIFT;
-
-  return res & excepts & FE_ALL_EXCEPT;
+  return libc_fetestexcept_s390 (excepts);
 }
 libm_hidden_def (fetestexcept)
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 15/17] S390: Implement math-barriers math_opt_barrier and math_force_eval.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
This patch implements the s390 specific math barriers in order
to omit the store and load from stack if possible.
---
 sysdeps/s390/fpu/math-barriers.h | 46 ++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 sysdeps/s390/fpu/math-barriers.h

diff --git a/sysdeps/s390/fpu/math-barriers.h b/sysdeps/s390/fpu/math-barriers.h
new file mode 100644
index 0000000000..7c3e6b15e0
--- /dev/null
+++ b/sysdeps/s390/fpu/math-barriers.h
@@ -0,0 +1,46 @@
+/* Control when floating-point expressions are evaluated.  s390 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/>.  */
+
+#ifndef S390_MATH_BARRIERS_H
+#define S390_MATH_BARRIERS_H 1
+
+#ifdef HAVE_S390_VX_GCC_SUPPORT
+# define ASM_CONSTRAINT_VR "v"
+#else
+# define ASM_CONSTRAINT_VR
+#endif
+
+#define math_opt_barrier(x) \
+  ({ __typeof (x) __x = (x); \
+    if (__builtin_types_compatible_p (__typeof (x), _Float128)) \
+      __asm__ ("# math_opt_barrier_f128 %0" : "+fm" (__x)); \
+    else \
+      __asm__ ("# math_opt_barrier %0" \
+       : "+f" ASM_CONSTRAINT_VR "m" (__x)); \
+    __x; })
+#define math_force_eval(x) \
+  ({ __typeof (x) __x = (x); \
+    if (__builtin_types_compatible_p (__typeof (x), _Float128)) \
+      __asm__ __volatile__ ("# math_force_eval_f128 %0" \
+    : : "fm" (__x)); \
+    else \
+      __asm__ __volatile__ ("# math_force_eval %0" \
+    : : "f" ASM_CONSTRAINT_VR "m" (__x)); \
+  })
+
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 16/17] S390: Implement roundtoint and converttoint and define TOINT_INTRINSICS.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
This patch implements roundtoint and convertoint for s390
by using the load-fp-integer and convert-to-fixed instructions.
Both functions are using "round to nearest with ties away from zero"
rounding mode and do not raise inexact exceptions.
---
 sysdeps/s390/fpu/math_private.h | 53 +++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 sysdeps/s390/fpu/math_private.h

diff --git a/sysdeps/s390/fpu/math_private.h b/sysdeps/s390/fpu/math_private.h
new file mode 100644
index 0000000000..a1ae91a87c
--- /dev/null
+++ b/sysdeps/s390/fpu/math_private.h
@@ -0,0 +1,53 @@
+/* Configure optimized libm functions.  S390 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/>.  */
+
+#ifndef S390_MATH_PRIVATE_H
+#define S390_MATH_PRIVATE_H 1
+
+#include <stdint.h>
+#include <math.h>
+
+#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
+# define TOINT_INTRINSICS 1
+
+static inline double_t
+roundtoint (double_t x)
+{
+  double_t y;
+  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
+     x to the nearest integer with ties away from zero (M3-field: 1)
+     where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("fidbra %0,1,%1,4" : "=f" (y) : "f" (x));
+  return y;
+}
+
+static inline int32_t
+converttoint (double_t x)
+{
+  int32_t y;
+  /* The z196 zarch "convert to fixed" (cfdbra) instruction is rounding
+     x to the nearest integer with ties away from zero (M3-field: 1)
+     where inexact exceptions are suppressed (M4-field: 4).  */
+  __asm__ ("cfdbra %0,1,%1,4" : "=d" (y) : "f" (x) : "cc");
+  return y;
+}
+#endif
+
+#include_next <math_private.h>
+
+#endif
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 17/17] S390: Use sysdeps/ieee754/dbl-64/wordsize-64 on s390x.

Stefan Liebler-2
In reply to this post by Stefan Liebler-2
This patch enables the usage of implementations in
sysdeps/ieee754/dbl-64/wordsize-64 on 64bit s390x.
---
 sysdeps/s390/s390-64/Implies | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sysdeps/s390/s390-64/Implies b/sysdeps/s390/s390-64/Implies
index a8cae95f9d..7603c9859c 100644
--- a/sysdeps/s390/s390-64/Implies
+++ b/sysdeps/s390/s390-64/Implies
@@ -1 +1,2 @@
 wordsize-64
+ieee754/dbl-64/wordsize-64
--
2.19.1

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 01/17] S390: Use load-fp-integer instruction for nearbyint functions.

Adhemerval Zanella-2
In reply to this post by Stefan Liebler-2


On 04/11/2019 12:27, Stefan Liebler wrote:
> If compiled with z196 zarch support, the load-fp-integer instruction
> is used to implement nearbyint, nearbyintf, nearbyintl.
> Otherwise the common-code implementation is used.

> +
> +double
> +__nearbyint (double x)
> +{
> +  double y;
> +  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
> +     x to the nearest integer according to current rounding mode (M3-field: 0)
> +     where inexact exceptions are suppressed (M4-field: 4).  */
> +  __asm__ ("fidbra %0,0,%1,4" : "=f" (y) : "f" (x));
> +  return y;
> +}
> +libm_alias_double (__nearbyint, nearbyint)

At least with recent gcc __builtin_nearbyint generates the expected fidbra
instruction for -march=z196.  I wonder if we could start to simplify some
math symbols implementation where new architectures/extensions provide
direct implementation by a direct mapping implemented by compiler builtins.

I would expect to:

  1. Move all sysdeps/ieee754/dbl-64/wordsize-64 to sysdeps/ieee754/dbl-64/
     since I hardly doubt these micro-optimizations really pay off with
     recent architectures and compiler version.

  2. Add internal macros __USE_<SYMBOL>_BUILTIN and use as:

     * sysdeps/ieee754/dbl-64/s_nearbyint.c
     
     [...]
     double
     __nearbyint (double x)
     {
     #if __USE_NEARBYINT_BUILTIN
       return __builtin_nearbyint (x);
     #else
       /* Use generic implementation.  */
     #endif
     }

  3. Define the __USE_<SYMBOL>_BUILTIN for each architecture.    

It would allow to simplify some architectures, aarch64 for instance.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 01/17] S390: Use load-fp-integer instruction for nearbyint functions.

Stefan Liebler-2
On 11/4/19 7:22 PM, Adhemerval Zanella wrote:

>
>
> On 04/11/2019 12:27, Stefan Liebler wrote:
>> If compiled with z196 zarch support, the load-fp-integer instruction
>> is used to implement nearbyint, nearbyintf, nearbyintl.
>> Otherwise the common-code implementation is used.
>
>> +
>> +double
>> +__nearbyint (double x)
>> +{
>> +  double y;
>> +  /* The z196 zarch "load fp integer" (fidbra) instruction is rounding
>> +     x to the nearest integer according to current rounding mode (M3-field: 0)
>> +     where inexact exceptions are suppressed (M4-field: 4).  */
>> +  __asm__ ("fidbra %0,0,%1,4" : "=f" (y) : "f" (x));
>> +  return y;
>> +}
>> +libm_alias_double (__nearbyint, nearbyint)
>
> At least with recent gcc __builtin_nearbyint generates the expected fidbra
> instruction for -march=z196.  I wonder if we could start to simplify some
> math symbols implementation where new architectures/extensions provide
> direct implementation by a direct mapping implemented by compiler builtins.
>
> I would expect to:
>
>    1. Move all sysdeps/ieee754/dbl-64/wordsize-64 to sysdeps/ieee754/dbl-64/
>       since I hardly doubt these micro-optimizations really pay off with
>       recent architectures and compiler version.
>
>    2. Add internal macros __USE_<SYMBOL>_BUILTIN and use as:
>
>       * sysdeps/ieee754/dbl-64/s_nearbyint.c
>      
>       [...]
>       double
>       __nearbyint (double x)
>       {
>       #if __USE_NEARBYINT_BUILTIN
>         return __builtin_nearbyint (x);
>       #else
>         /* Use generic implementation.  */
>       #endif
>       }
>
>    3. Define the __USE_<SYMBOL>_BUILTIN for each architecture.
>
> It would allow to simplify some architectures, aarch64 for instance.
>

Currently the long double builtins are generating an extra not needed
stack frame compared to the inline assembly. But this needs to be fixed
in gcc.

E.g. if build for s390 (31bit), where the fidbra & co instructions are
not available, the builtins generate a call to libc which would end in
an infinite loop.  I will make some tests on s390 starting with the
current minimum gcc 6.2 to be sure that the instructions are used.  I
have never build glibc with other compilers like clang.  Is there a
special need to check this behavior?

In general I can start with those functions where the builtins can be
used on s390, but I won't move all wordsize-64 functions and adjust them
to use the builtins with this patch series.
This means for now, I start with using builtins for nearbyint, rint,
floor, ceil, trunc, round and copysign.

Afterwards the same can be done for the remaining functions.

I will create an own header file, e.g.
sysdeps/generic/math-use-builtins.h in the same way as
fix-fp-int-compare-invalid.h.
The generic version contains all USE_XYZ_BUILTIN macros defined to 0
and each architecture can provide its own file with other settings.
For each functions XYZ there will be three macros, e.g.
USE_NEARBYINT_BUILTIN, USE_NEARBYINTF_BUILTIN, USE_NEARBYINTL_BUILTIN.
How about this?

Thanks,
Stefan

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 01/17] S390: Use load-fp-integer instruction for nearbyint functions.

Joseph Myers
On Tue, 5 Nov 2019, Stefan Liebler wrote:

> I will create an own header file, e.g. sysdeps/generic/math-use-builtins.h in
> the same way as fix-fp-int-compare-invalid.h.
> The generic version contains all USE_XYZ_BUILTIN macros defined to 0
> and each architecture can provide its own file with other settings.
> For each functions XYZ there will be three macros, e.g. USE_NEARBYINT_BUILTIN,
> USE_NEARBYINTF_BUILTIN, USE_NEARBYINTL_BUILTIN.

You'll need macro variants for _Float128 as well, with corresponding
#undef / #define of the long double variants and of the built-in names in
float128_private.h (see what it does for FIX_LDBL_LONG_CONVERT_OVERFLOW
and FIX_LDBL_LLONG_CONVERT_OVERFLOW) - POWER9 supports doing various such
_Float128 operations as built-in functions.

--
Joseph S. Myers
[hidden email]
12