This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Torbjorn's ieeelib.c
On Tue, 29 Nov 2005, Hans-Peter Nilsson wrote:
> On Mon, 28 Nov 2005, Mark Mitchell wrote:
> > So, we're considering doing what it takes to get ieeelib.c into GCC, or,
> > perhaps, borrowing some of its ideas for fp-bit.c.
>
> Very nice! Don't forget the few posts with bug-fixes over the
> years from someone or other. (Yes, actually posted here on a
> gcc-list, not to Tege.)
The only one I've found is
<http://gcc.gnu.org/ml/gcc/2003-06/msg02495.html>. The current patch I'm
using for testing (relative to a version with the 2003 patch applied) is
appended, obviously this isn't suited to going in GCC as-is but it allows
it to build and provide the set of functions soft-float code is currently
expected to provide.
(Incidentally, why does libgcc-std.ver not include __unordxf2 and
__unordtf2 although it has __unordsf2 and __unorddf2?)
--
Joseph S. Myers http://www.srcf.ucam.org/~jsm28/gcc/
jsm@polyomino.org.uk (personal mail)
joseph@codesourcery.com (CodeSourcery mail)
jsm28@gcc.gnu.org (Bugzilla assignments and CCs)
diff -rupN orig2003/ieeecvt.c patched/ieeecvt.c
--- orig2003/ieeecvt.c 1998-11-24 19:11:21.000000000 +0000
+++ patched/ieeecvt.c 2005-11-28 23:10:20.000000000 +0000
@@ -1,22 +1,22 @@
/* IEEE 754 format floating-point routines. */
/* Copyright (C) 1991, 1995, 1998 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+GCC 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 General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
diff -rupN orig2003/ieeelib.c patched/ieeelib.c
--- orig2003/ieeelib.c 2005-11-28 22:57:37.000000000 +0000
+++ patched/ieeelib.c 2005-11-29 18:08:07.000000000 +0000
@@ -1,22 +1,22 @@
/* IEEE 754 format floating-point routines. */
-/* Copyright (C) 1991, 1995, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1998, 2005 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+GCC 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 General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
@@ -183,10 +183,11 @@ typedef float DFtype __attribute__ ((mod
#define ge_1 __gesf2
#define lt_1 __ltsf2
#define le_1 __lesf2
+#define unord_1 __unordsf2
#define floatsifp_1 __floatsisf
-#define floatunssifp_1 __floatunssisf
+#define floatunssifp_1 __floatunsisf
#define fixfpsi_1 __fixsfsi
-#define fixunsfpsi_1 __fixunssfsi
+/*#define fixunsfpsi_1 __fixunssfsi*/
#define truncdfsf_1 __extendsfdf2
#endif
@@ -204,10 +205,11 @@ typedef float DFtype __attribute__ ((mod
#define ge_2 __gedf2
#define lt_2 __ltdf2
#define le_2 __ledf2
+#define unord_2 __unorddf2
#define floatsifp_2 __floatsidf
-#define floatunssifp_2 __floatunssidf
+#define floatunssifp_2 __floatunsidf
#define fixfpsi_2 __fixdfsi
-#define fixunsfpsi_2 __fixunsdfsi
+/*#define fixunsfpsi_2 __fixunsdfsi*/
#define truncdfsf_2 __truncdfsf2
#else
#define add_1 __adddf3
@@ -222,10 +224,11 @@ typedef float DFtype __attribute__ ((mod
#define ge_1 __gedf2
#define lt_1 __ltdf2
#define le_1 __ledf2
+#define unord_1 __unorddf2
#define floatsifp_1 __floatsidf
-#define floatunssifp_1 __floatunssidf
+#define floatunssifp_1 __floatunsidf
#define fixfpsi_1 __fixdfsi
-#define fixunsfpsi_1 __fixunsdfsi
+/*#define fixunsfpsi_1 __fixunsdfsi*/
#define truncdfsf_1 __truncdfsf2
#endif
#endif
@@ -243,26 +246,45 @@ typedef float DFtype __attribute__ ((mod
#define ge_2 __getf2
#define lt_2 __lttf2
#define le_2 __letf2
+#define unord_2 __unordtf2
#define floatsifp_2 __floatsitf
-#define floatunssifp_2 __floatunssitf
+#define floatunssifp_2 __floatunsitf
#define fixfpsi_2 __fixtfsi
#define fixunsfpsi_2 __fixunstfsi
#define trunctfsf_2 __trunctfsf2
#endif
-#if defined (COUNT_LEADING_ZEROS_NEED_CLZ_TAB)
-const unsigned char __clz_tab[] =
-{
- 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-};
-#endif
+/* Count leading zeroes in N. */
+static inline int
+clzusi (USItype n)
+{
+ extern int __clzsi2 (USItype);
+ if (sizeof (USItype) == sizeof (unsigned int))
+ return __builtin_clz (n);
+ else if (sizeof (USItype) == sizeof (unsigned long))
+ return __builtin_clzl (n);
+ else if (sizeof (USItype) == sizeof (unsigned long long))
+ return __builtin_clzll (n);
+ else
+ return __clzsi2 (n);
+}
+#define CLZ_SI_OFFSET (COMPUTE_TYPE_BITS - sizeof (USItype) * __CHAR_BIT__)
+
+/* Count leading zeroes in N. */
+static inline int
+clzcomptype (COMPUTE_TYPE n)
+{
+ extern void abort (void);
+ if (sizeof (COMPUTE_TYPE) == sizeof (unsigned int))
+ return __builtin_clz (n);
+ else if (sizeof (COMPUTE_TYPE) == sizeof (unsigned long))
+ return __builtin_clzl (n);
+ else if (sizeof (COMPUTE_TYPE) == sizeof (unsigned long long))
+ return __builtin_clzll (n);
+ else
+ abort ();
+}
+
#ifdef add_1
FLOATING_TYPE
@@ -582,7 +604,7 @@ add_1 (FLOATING_TYPE u, FLOATING_TYPE v)
if (rm != 0)
{
int cnt;
- count_leading_zeros (cnt, rm);
+ cnt = clzcomptype (rm);
rm = rm << cnt;
if ((re & EXP_MASK) <= cnt)
@@ -984,7 +1006,7 @@ add_2 (FLOATING_TYPE u, FLOATING_TYPE v)
if (rh != 0)
{
int cnt;
- count_leading_zeros (cnt, rh);
+ cnt = clzcomptype (rh);
rh = (rh << cnt) | (rl >> (COMPUTE_TYPE_BITS - cnt));
rl = rl << cnt;
@@ -1005,7 +1027,7 @@ add_2 (FLOATING_TYPE u, FLOATING_TYPE v)
else if (rl != 0)
{
int cnt;
- count_leading_zeros (cnt, rl);
+ cnt = clzcomptype (rl);
rh = rl << cnt;
rl = 0;
@@ -1433,7 +1455,7 @@ mul_2 (FLOATING_TYPE u, FLOATING_TYPE v)
/*-----------------------------------------------------------------------------------------*/
#ifdef div_1
-static int internal_divide_1 ();
+static int internal_divide_1 (COMPUTE_TYPE, COMPUTE_TYPE, COMPUTE_TYPE *);
FLOATING_TYPE
div_1 (FLOATING_TYPE u, FLOATING_TYPE v)
{
@@ -1591,7 +1613,9 @@ div_1 (FLOATING_TYPE u, FLOATING_TYPE v)
#endif
#ifdef div_2
-static int internal_divide_2 ();
+static int internal_divide_2 (COMPUTE_TYPE, COMPUTE_TYPE,
+ COMPUTE_TYPE, COMPUTE_TYPE,
+ COMPUTE_TYPE *);
FLOATING_TYPE
div_2 (FLOATING_TYPE u, FLOATING_TYPE v)
{
@@ -1783,7 +1807,7 @@ floatsifp_1 (SItype si)
if (six > 0)
{
- count_leading_zeros (cnt, six);
+ cnt = clzusi (six) + CLZ_SI_OFFSET;
rh = (six << cnt) & UP_MANT_MASK;
/* ??? No need to round here when MANTISSA_BITS > bits of SImode ??? */
@@ -1792,8 +1816,8 @@ floatsifp_1 (SItype si)
}
else if (si < 0)
{
- six = -six;
- count_leading_zeros (cnt, six);
+ six = -(COMPUTE_TYPE) six;
+ cnt = clzusi (six) + CLZ_SI_OFFSET;
rh = (six << cnt) & UP_MANT_MASK;
/* ??? No need to round here when MANTISSA_BITS > bits of SImode ??? */
@@ -1816,7 +1840,7 @@ floatsifp_2 (SItype si)
if (six > 0)
{
- count_leading_zeros (cnt, six);
+ cnt = clzusi (six) + CLZ_SI_OFFSET;
rh = (six << cnt) & UP_MANT_MASK;
/* ??? No need to round here when MANTISSA_BITS > bits of SImode ??? */
@@ -1826,7 +1850,7 @@ floatsifp_2 (SItype si)
else if (si < 0)
{
six = -six;
- count_leading_zeros (cnt, six);
+ cnt = clzusi (six) + CLZ_SI_OFFSET;
rh = (six << cnt) & UP_MANT_MASK;
/* ??? No need to round here when MANTISSA_BITS > bits of SImode ??? */
@@ -1849,7 +1873,7 @@ floatunssifp_1 (USItype ui)
if (uix > 0)
{
- count_leading_zeros (cnt, uix);
+ cnt = clzusi (uix) + CLZ_SI_OFFSET;
rh = (uix << cnt) & UP_MANT_MASK;
/* ??? No need to round here when MANTISSA_BITS > bits of SImode ??? */
@@ -1872,7 +1896,7 @@ floatunssifp_2 (USItype ui)
if (uix > 0)
{
- count_leading_zeros (cnt, uix);
+ cnt = clzusi (uix) + CLZ_SI_OFFSET;
rh = (uix << cnt) & UP_MANT_MASK;
/* ??? No need to round here when MANTISSA_BITS > bits of SImode ??? */
@@ -2092,7 +2116,7 @@ internal_divide_2 (COMPUTE_TYPE uh, COMP
/* Compare two operands. Assumes NaN has already been taken care of.
I.e., we can have the operand types: -Inf, -R, -0, +0, +R, +Inf. */
int
-cmp_1 (double u, double v, int nan_retval)
+cmp_1 (FLOATING_TYPE u, FLOATING_TYPE v, int nan_retval)
{
COMPUTE_TYPE um, vm;
int ue, ve;
@@ -2132,7 +2156,7 @@ cmp_1 (double u, double v, int nan_retva
/* Compare two operands. Assumes NaN has already been taken care of.
I.e., we can have the operand types: -Inf, -R, -0, +0, +R, +Inf. */
int
-cmp_2 (double u, double v, int nan_retval)
+cmp_2 (FLOATING_TYPE u, FLOATING_TYPE v, int nan_retval)
{
COMPUTE_TYPE uh, ul, vh, vl;
int ue, ve;
@@ -2243,6 +2267,46 @@ int
le_2 (FLOATING_TYPE u, FLOATING_TYPE v)
{ return cmp_2 (u, v, 1); }
#endif
+
+#ifdef unord_1
+int
+unord_1 (FLOATING_TYPE u, FLOATING_TYPE v)
+{
+ COMPUTE_TYPE um, vm;
+ int ue, ve;
+
+ unpack_for_compare_1 (um, ue, u);
+ unpack_for_compare_1 (vm, ve, v);
+
+ /* Check for NaN. ue/ve will be either 0x7ff or 0xfffff800. */
+ if ((COMPUTE_TYPE) ((ue ^ 0x7ff) + 1) <= 1 && um != 0)
+ return 1;
+ if ((COMPUTE_TYPE) ((ve ^ 0x7ff) + 1) <= 1 && vm != 0)
+ return 1;
+
+ return 0;
+}
+#endif
+
+#ifdef unord_2
+int
+unord_2 (FLOATING_TYPE u, FLOATING_TYPE v)
+{
+ COMPUTE_TYPE uh, ul, vh, vl;
+ int ue, ve;
+
+ unpack_for_compare_2 (uh, ul, ue, u);
+ unpack_for_compare_2 (vh, vl, ve, v);
+
+ /* Check for NaN. ue/ve will be either 0x7ff or 0xfffff800. */
+ if ((COMPUTE_TYPE) ((ue ^ 0x7ff) + 1) <= 1 && (uh | ul) != 0)
+ return 1;
+ if ((COMPUTE_TYPE) ((ve ^ 0x7ff) + 1) <= 1 && (vh | vl) != 0)
+ return 1;
+
+ return 0;
+}
+#endif
/* Things to work on: