This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 2/2] soft-fp: Add new KF routines


From: Michael Meissner <meissner@linux.vnet.ibm.com>

Add cmpukf2, extendkftf2 and trunctfk2 to soft-fp.
This is the minimal set of routines required to be imported in GCC for
IEEE 128-bit floating point support.

2015-10-26  Michael Meissner  <meissner@linux.vnet.ibm.com>
            Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>

	* soft-fp/.gitignore: Negate cmpukf2.c, extendkftf2.c and trunctfk2.c.
	* soft-fp/Makefile (gcc-kf-routines): New variable with all KF
        routines.
	* soft-fp/cmpukf2.c: New file
	* soft-fp/extendkftf2.c: Likewise
	* soft-fp/trunctfk2.c: Likewise
---
 soft-fp/.gitignore    |  3 ++
 soft-fp/Makefile      |  2 ++
 soft-fp/cmpukf2.c     | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
 soft-fp/extendkftf2.c | 59 ++++++++++++++++++++++++++++++++++
 soft-fp/trunctfk2.c   | 65 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 216 insertions(+)
 create mode 100644 soft-fp/cmpukf2.c
 create mode 100644 soft-fp/extendkftf2.c
 create mode 100644 soft-fp/trunctfk2.c

diff --git a/soft-fp/.gitignore b/soft-fp/.gitignore
index 833e136..f68a4fa 100644
--- a/soft-fp/.gitignore
+++ b/soft-fp/.gitignore
@@ -1 +1,4 @@
 *kf*.c
+!cmpukf2.c
+!extendkftf2.c
+!trunctfk2.c
\ No newline at end of file
diff --git a/soft-fp/Makefile b/soft-fp/Makefile
index e392b9d..b398615 100644
--- a/soft-fp/Makefile
+++ b/soft-fp/Makefile
@@ -41,6 +41,8 @@ gcc-quad-routines := negtf2 addtf3 subtf3 multf3 divtf3 eqtf2 \
 gcc-kf-routines-auto := $(subst tf,kf,\
                           $(filter-out sqrttf2,$(gcc-quad-routines)))
 
+gcc-kf-routines := cmpukf2 extendtfkf2 trunctfk2 $(gcc-kf-routines-auto)
+
 generate-routines: $(addsuffix .c,$(gcc-kf-routines-auto))
 
 clean:
diff --git a/soft-fp/cmpukf2.c b/soft-fp/cmpukf2.c
new file mode 100644
index 0000000..d27c544
--- /dev/null
+++ b/soft-fp/cmpukf2.c
@@ -0,0 +1,87 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+   Code is based on the main soft-fp library written by:
+	Richard Henderson (rth@cygnus.com) and
+	Jakub Jelinek (jj@ultra.linux.cz).
+
+   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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Force the use of the VSX instruction set.  */
+#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+#pragma GCC target ("vsx,float128")
+#endif
+
+#include "soft-fp.h"
+#include "double.h"
+#include "single.h"
+#include "quad-float128.h"
+
+/* PowerPC condition register bits.  */
+#define PPC_UNORDERED		0x1		/* isnan (a) || isnan (b).  */
+#define PPC_EQUAL		0x2		/* a == b.  */
+#define PPC_GREATER_THEN	0x4		/* a > b.  */
+#define PPC_LESS_THEN		0x8		/* a < b.  */
+
+/* Map FP_CMP_Q output to PowerPC condition register bits.  */
+#define CMP_UNORDERED		(-2)		/* isnan (a) || isnan (b).  */
+#define CMP_LESS_THEN		(-1)		/* a < b.  */
+#define CMP_EQUAL		0		/* a == b.  */
+#define CMP_GREATER_THEN	1		/* a < b.  */
+#define CMP_INVALID		2		/* raise invalid exception.  */
+
+#define CMP_LOW			CMP_UNORDERED	/* comparison low value.  */
+#define CMP_HIGH		CMP_INVALID	/* comparison high value.  */
+
+static const unsigned char ppc_cr_map[] = {
+  PPC_UNORDERED,				/* -2: unordered.  */
+  PPC_LESS_THEN,				/* -1: a < b.  */
+  PPC_EQUAL,					/*  0: a == b.  */
+  PPC_GREATER_THEN,				/*  1: a > b.  */
+  PPC_UNORDERED,				/*  2: invalid.  */
+};
+
+/* Compare two IEEE 128-bit floating point values and return the status.  We
+   return the status as a 4-bit value that can be copied into an appropriate
+   PowerPC conditon code register.  */
+
+CMPtype
+__cmpukf2 (TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (A);
+  FP_DECL_Q (B);
+  CMPtype r;
+
+  FP_INIT_EXCEPTIONS;
+  FP_UNPACK_RAW_Q (A, a);
+  FP_UNPACK_RAW_Q (B, b);
+  FP_CMP_Q (r, A, B, 2, 2);
+  if (r == CMP_INVALID)
+    FP_SET_EXCEPTION (FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return (r < CMP_LOW || r > CMP_HIGH) ? PPC_UNORDERED : ppc_cr_map[r-CMP_LOW];
+}
diff --git a/soft-fp/extendkftf2.c b/soft-fp/extendkftf2.c
new file mode 100644
index 0000000..4b78b86
--- /dev/null
+++ b/soft-fp/extendkftf2.c
@@ -0,0 +1,59 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+   Code is based on the main soft-fp library written by:
+	Richard Henderson (rth@cygnus.com) and
+	Jakub Jelinek (jj@ultra.linux.cz).
+
+   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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Convert IEEE 128-bit floating point to IBM long double.  */
+
+/* Force the use of the VSX instruction set.  */
+#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+#pragma GCC target ("vsx,float128")
+#endif
+
+extern __ibm128 __extendkftf2 (__float128);
+
+__ibm128
+__extendkftf2 (__float128 value)
+{
+  double high, low;
+
+  high = (double) value;
+  if (__builtin_isnan (high) || __builtin_isinf (high))
+    low = high;
+
+  else
+    {
+      low = (double) (value - (__float128)high);
+
+      /* Use copysign to propigate the sign bit so that -0.0Q becomes -0.0L.  */
+      low = __builtin_copysign (low, high);
+    }
+
+  return __builtin_pack_longdouble (high, low);
+}
diff --git a/soft-fp/trunctfk2.c b/soft-fp/trunctfk2.c
new file mode 100644
index 0000000..0d38c5a
--- /dev/null
+++ b/soft-fp/trunctfk2.c
@@ -0,0 +1,65 @@
+/* Software IEEE 128-bit floating-point emulation for PowerPC.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Michael Meissner (meissner@linux.vnet.ibm.com)
+   Code is based on the main soft-fp library written by:
+	Richard Henderson (rth@cygnus.com) and
+	Jakub Jelinek (jj@ultra.linux.cz).
+
+   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.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Convert IBM long double to IEEE 128-bit floating point.  */
+
+/* Force the use of the VSX instruction set.  */
+#if defined(_ARCH_PPC) && (!defined(__VSX__) || !defined(__FLOAT128__))
+#pragma GCC target ("vsx,float128")
+#endif
+
+extern __float128 __trunctfkf2 (__ibm128);
+
+#ifdef __LITTLE_ENDIAN__
+#define HIGH_WORD	1
+#define LOW_WORD	0
+#else
+#define HIGH_WORD	0
+#define LOW_WORD	1
+#endif
+
+__float128
+__trunctfkf2 (__ibm128 value)
+{
+  double high = __builtin_unpack_longdouble (value, HIGH_WORD);
+  double low = __builtin_unpack_longdouble (value, LOW_WORD);
+
+  /* Handle the special cases of NAN and inifinity.  */
+  if (__builtin_isnan (high) || __builtin_isinf (high))
+    return (__float128) high;
+
+  /* If low is 0.0, there no need to do the add.  In addition, avoiding the add
+     produces the correct sign if high is -0.0.  */
+  if (low == 0.0)
+    return (__float128) high;
+
+  return ((__float128)high) + ((__float128)low);
+}
-- 
2.1.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]