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/
    [EMAIL PROTECTED] (personal mail)
    [EMAIL PROTECTED] (CodeSourcery mail)
    [EMAIL PROTECTED] (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:

Reply via email to