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: