This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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] 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


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