This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Add __abssf2 and __absdf2 to libgcc
- From: Roger Sayle <roger at www dot eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 3 Dec 2002 22:29:24 -0700 (MST)
- Subject: [PATCH] Add __abssf2 and __absdf2 to libgcc
This patch adds the functions __abssf2, __absdf2, __absxf2 and
__abstf2 to the libgcc API, and provides generic implmentations
in GCC's software floating point library. As the names suggest,
these functions calculate the absolute value of a floating point
value, much like fabs, fabsf and fabsl in the standard library.
Whilst examining the failure of 20020720-1.c on H8300, I noticed
that "fabs" was being implemented by GCC as an inlined libcall
to "__ltsf2" to compare the operand against floating point zero,
and a conditional jump around another libcall to "__negsf2".
In theory, fabs can be implemented by single bit-wise "and".
However, providing __abs?f2 in libgcc improves the current
situation, producing code that is both shorter and faster.
I was orginally waiting until after the branch to submit this
patch, as it isn't strictly a bug-fix. However, the recent
change to libgcc's API, means that GCC 3.3 now requires a
suitably versioned libgcc_s.so. I've checked with Mark and
he agrees that considering the patch below for 3.3, should
reduce the number of incompatible changes to GCC's shared
libraries. With luck, libgcc won't need to change for 3.4.
This patch only defines the new entry points. The changes to
actually make use of them can wait until after 3.3 branches.
This patch has been tested by complete bootstraps (all languages
except Ada and treelang) on i686-pc-linux-gnu [which doesn't
build software floating point by default] and on powerpc-ibm-aix5.1
and mips-sgi-irix6.5 [both which do]. There were no new testsuite
regressions on any of these platforms, nor on a powerpc-eabisim
from i686-pc-linux-gnu cross-compile using powerpc-sim. I also
checked by hand that __abssf2 and __absdf2 were actually addded
to libgcc on both IRIX and AIX.
Note the non-standard style is in keeping with the other functions
in the software floating point library, particularly the existing
implementations of __neg?f2.
Ok for mainline?
2002-12-03 Roger Sayle <roger@eyesopen.com>
* config/fp-bit.c (__absxf2, __abstf2): New stub implementations.
(clear_sign): New function to clear the sign bit of an FP number.
(absolute a.k.a. __abssf2 and __absdf2): Implement floating
point absolute, using clear_sign if L_negate_?f is defined.
* config/fp-bit.h: Define L_negate_sf and L_negate_df if
FINED_GRAINED_LIBRARIES is not defined. Define absolute
to __abssf2 if FLOAT is defined, and __absdf2 otherwise.
(absolute a.k.a. __abssf2 and __absdf2): Add prototype.
* Makefile.in (FPBIT_FUNCS): Add _absolute_sf.
(DPBIT_FUNCS): Add _absolute_df.
* libgcc-std.ver: Add __abssf2, __absdf2, __absxf2 and __abstf2
to the GCC_3.3 API.
Index: config/fp-bit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v
retrieving revision 1.36
diff -c -3 -p -r1.36 fp-bit.c
*** config/fp-bit.c 7 Oct 2002 08:47:09 -0000 1.36
--- config/fp-bit.c 4 Dec 2002 05:25:27 -0000
*************** void __subxf3 (void) { abort(); }
*** 91,96 ****
--- 91,97 ----
void __mulxf3 (void) { abort(); }
void __divxf3 (void) { abort(); }
void __negxf2 (void) { abort(); }
+ void __absxf2 (void) { abort(); }
void __eqxf2 (void) { abort(); }
void __nexf2 (void) { abort(); }
void __gtxf2 (void) { abort(); }
*************** void __subtf3 (void) { abort(); }
*** 109,114 ****
--- 110,116 ----
void __multf3 (void) { abort(); }
void __divtf3 (void) { abort(); }
void __negtf2 (void) { abort(); }
+ void __abstf2 (void) { abort(); }
void __eqtf2 (void) { abort(); }
void __netf2 (void) { abort(); }
void __gttf2 (void) { abort(); }
*************** flip_sign ( fp_number_type * x)
*** 178,183 ****
--- 180,192 ----
x->sign = !x->sign;
}
+ INLINE
+ static void
+ clear_sign ( fp_number_type * x)
+ {
+ x->sign = 0;
+ }
+
extern FLO_type pack_d ( fp_number_type * );
#if defined(L_pack_df) || defined(L_pack_sf)
*************** negate (FLO_type arg_a)
*** 1317,1322 ****
--- 1326,1346 ----
return pack_d (&a);
}
#endif /* L_negate_sf || L_negate_df */
+
+ #if defined(L_absolute_sf) || defined(L_absolute_df)
+ FLO_type
+ absolute (FLO_type arg_a)
+ {
+ fp_number_type a;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &a);
+
+ clear_sign (&a);
+ return pack_d (&a);
+ }
+ #endif /* L_absolute_sf || L_absolute_df */
#ifdef FLOAT
Index: config/fp-bit.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v
retrieving revision 1.7
diff -c -3 -p -r1.7 fp-bit.h
*** config/fp-bit.h 19 Jun 2002 23:01:59 -0000 1.7
--- config/fp-bit.h 4 Dec 2002 05:25:27 -0000
*************** Boston, MA 02111-1307, USA. */
*** 76,81 ****
--- 76,83 ----
#define L_df_to_usi
#define L_negate_sf
#define L_negate_df
+ #define L_absolute_sf
+ #define L_absolute_df
#define L_make_sf
#define L_make_df
#define L_sf_to_df
*************** typedef unsigned int UDItype __attribute
*** 169,174 ****
--- 171,177 ----
# define float_to_si fptosi
# define float_to_usi fptoui
# define negate __negsf2
+ # define absolute __abssf2
# define sf_to_df fptodp
# define dptofp dptofp
#else
*************** typedef unsigned int UDItype __attribute
*** 183,188 ****
--- 186,192 ----
# define float_to_si dptoli
# define float_to_usi dptoul
# define negate __negdf2
+ # define absolute __absdf2
# define df_to_sf dptofp
# endif /* FLOAT */
#else
*************** typedef unsigned int UDItype __attribute
*** 204,209 ****
--- 208,214 ----
# define float_to_si __fixsfsi
# define float_to_usi __fixunssfsi
# define negate __negsf2
+ # define absolute __abssf2
# define sf_to_df __extendsfdf2
#else
# define add __adddf3
*************** typedef unsigned int UDItype __attribute
*** 223,228 ****
--- 228,234 ----
# define float_to_si __fixdfsi
# define float_to_usi __fixunsdfsi
# define negate __negdf2
+ # define absolute __absdf2
# define df_to_sf __truncdfsf2
# endif /* FLOAT */
#endif /* US_SOFTWARE_GOFAST */
*************** extern FLO_type usi_to_float (USItype);
*** 394,399 ****
--- 400,409 ----
#if defined(L_negate_sf) || defined(L_negate_df)
extern FLO_type negate (FLO_type);
+ #endif
+
+ #if defined(L_absolute_sf) || defined(L_absolute_df)
+ extern FLO_type absolute (FLO_type);
#endif
#ifdef FLOAT
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.958
diff -c -3 -p -r1.958 Makefile.in
*** Makefile.in 24 Nov 2002 20:43:01 -0000 1.958
--- Makefile.in 4 Dec 2002 05:25:28 -0000
*************** LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp
*** 796,807 ****
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
_lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \
! _sf_to_df _thenan_sf _sf_to_usi _usi_to_sf
DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \
_fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \
_lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \
! _df_to_sf _thenan_df _df_to_usi _usi_to_df
# These might cause a divide overflow trap and so are compiled with
# unwinder info.
--- 796,807 ----
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
_lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \
! _sf_to_df _thenan_sf _sf_to_usi _usi_to_sf _absolute_sf
DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \
_fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \
_lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \
! _df_to_sf _thenan_df _df_to_usi _usi_to_df _absolute_df
# These might cause a divide overflow trap and so are compiled with
# unwinder info.
Index: libgcc-std.ver
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcc-std.ver,v
retrieving revision 1.16
diff -c -3 -p -r1.16 libgcc-std.ver
*** libgcc-std.ver 3 Dec 2002 22:04:22 -0000 1.16
--- libgcc-std.ver 4 Dec 2002 05:25:28 -0000
*************** GCC_3.0 {
*** 179,182 ****
--- 179,186 ----
%inherit GCC_3.3 GCC_3.0
GCC_3.3 {
_Unwind_FindEnclosingFunction
+ __abssf2
+ __absdf2
+ __absxf2
+ __abstf2
}
Roger
--
Roger Sayle, E-mail: roger@eyesopen.com
OpenEye Scientific Software, WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road, Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507. Fax: (+1) 505-473-0833