This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc 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] Implement __abs?f2 functions in soft-fp


This is the third instalment in my series of patches to soft-fp.
This patch provides the functions __absdf2, __abssf2 and
__abstf2, which implement the libm fabs, fabsf and fabsl
functions, directly in the emulator.  These are currently
implemented by GCC by calling __ge?f2 to compare against
zero, and then a conditional branch around a call to __neg?f2.
It is both shorter and faster to implement __abs?f2 directly,
which can just clear the sign bit.

Once this has been in glibc for a while, I'll submit a patch
to GCC to make use of this new API.

Is this patch OK?


2002-10-31  Roger Sayle  <roger@eyesopen.com>

	* soft-fp/absdf2.c: New file.
	* soft-fp/abssf2.c: New file.
	* soft-fp/abstf2.c: New file.
	* soft-fp/Makefile: Build these new files.
	* soft-fp/op-common.h (_FP_ABS): New macro to implement abs?f2.
	* soft-fp/single.h (FP_ABS_S): New macro that uses _FP_ABS.
	* soft-fp/double.h (FP_ABS_D): New macro that uses _FP_ABS.
	* soft-fp/extended.h (FP_ABS_E): New macro that uses _FP_ABS.
	* soft-fp/quad.h (FP_ABS_Q): New macro that uses _FP_ABS.
	* soft-fp/testit.c: Update to test __absdf2 and __abssf2 using
	the two new 'B' and 'b' command line options respectively.


*** /dev/null	Thu Aug 30 14:30:55 2001
--- absdf2.c	Wed Oct 30 16:52:26 2002
***************
*** 0 ****
--- 1,38 ----
+ /* Software floating-point emulation.
+    Return fabs(a)
+    Copyright (C) 2002 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Roger Sayle <roger@eyesopen.com>.
+
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The GNU C Library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+
+ #include "soft-fp.h"
+ #include "double.h"
+
+ double __absdf2(double a)
+ {
+   FP_DECL_EX;
+   FP_DECL_D(A); FP_DECL_D(R);
+   double r;
+
+   FP_UNPACK_D(A, a);
+   FP_ABS_D(R, A);
+   FP_PACK_D(r, R);
+   FP_CLEAR_EXCEPTIONS;
+   FP_HANDLE_EXCEPTIONS;
+
+   return r;
+ }
*** /dev/null	Thu Aug 30 14:30:55 2001
--- abssf2.c	Wed Oct 30 16:54:53 2002
***************
*** 0 ****
--- 1,38 ----
+ /* Software floating-point emulation.
+    Return fabsf(a)
+    Copyright (C) 2002 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Roger Sayle <roger@eyesopen.com>.
+
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The GNU C Library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+
+ #include "soft-fp.h"
+ #include "single.h"
+
+ float __abssf2(float a)
+ {
+   FP_DECL_EX;
+   FP_DECL_S(A); FP_DECL_S(R);
+   float r;
+
+   FP_UNPACK_S(A, a);
+   FP_ABS_S(R, A);
+   FP_PACK_S(r, R);
+   FP_CLEAR_EXCEPTIONS;
+   FP_HANDLE_EXCEPTIONS;
+
+   return r;
+ }
*** /dev/null	Thu Aug 30 14:30:55 2001
--- abstf2.c	Wed Oct 30 16:55:01 2002
***************
*** 0 ****
--- 1,38 ----
+ /* Software floating-point emulation.
+    Return fabsl(a)
+    Copyright (C) 2002 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Roger Sayle <roger@eyesopen.com>.
+
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The GNU C Library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+
+ #include "soft-fp.h"
+ #include "quad.h"
+
+ long double __abstf2(long double a)
+ {
+   FP_DECL_EX;
+   FP_DECL_Q(A); FP_DECL_Q(R);
+   long double r;
+
+   FP_UNPACK_Q(A, a);
+   FP_ABS_Q(R, A);
+   FP_PACK_Q(r, R);
+   FP_CLEAR_EXCEPTIONS;
+   FP_HANDLE_EXCEPTIONS;
+
+   return r;
+ }
Index: Makefile
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/Makefile,v
retrieving revision 1.7
diff -c -3 -p -r1.7 Makefile
*** Makefile	6 Jul 2001 04:55:40 -0000	1.7
--- Makefile	31 Oct 2002 00:31:00 -0000
***************
*** 1,4 ****
! # Copyright (C) 1997, 1999, 2000  Free Software Foundation, Inc.
  # This file is part of the GNU C Library.
  #

--- 1,4 ----
! # Copyright (C) 1997, 1999, 2000, 2002  Free Software Foundation, Inc.
  # This file is part of the GNU C Library.
  #

*************** subdir	:= soft-fp
*** 24,39 ****

  gcc-single-routines := negsf2 addsf3 subsf3 mulsf3 divsf3 eqsf2 \
  	lesf2 gesf2 fixsfsi fixunssfsi floatsisf fixsfdi        \
! 	fixunssfdi floatdisf sqrtsf2

  gcc-double-routines := negdf2 adddf3 subdf3 muldf3 divdf3 eqdf2 \
  	ledf2 gedf2 fixdfsi fixunsdfsi floatsidf fixdfdi        \
! 	fixunsdfdi floatdidf extendsfdf2 truncdfsf2 sqrtdf2

  gcc-quad-routines := negtf2 addtf3 subtf3 multf3 divtf3 eqtf2 \
  	letf2 getf2 fixtfsi fixunstfsi floatsitf fixtfdi      \
  	fixunstfdi floatditf extendsftf2 trunctfsf2 extenddftf2 \
! 	trunctfdf2 sqrttf2

  distribute := double.h op-1.h op-2.h op-4.h op-common.h quad.h \
  	single.h soft-fp.h extended.h Banner op-8.h testit.c \
--- 24,40 ----

  gcc-single-routines := negsf2 addsf3 subsf3 mulsf3 divsf3 eqsf2 \
  	lesf2 gesf2 fixsfsi fixunssfsi floatsisf fixsfdi        \
! 	fixunssfdi floatdisf sqrtsf2 abssf2

  gcc-double-routines := negdf2 adddf3 subdf3 muldf3 divdf3 eqdf2 \
  	ledf2 gedf2 fixdfsi fixunsdfsi floatsidf fixdfdi        \
! 	fixunsdfdi floatdidf extendsfdf2 truncdfsf2 sqrtdf2     \
! 	absdf2

  gcc-quad-routines := negtf2 addtf3 subtf3 multf3 divtf3 eqtf2 \
  	letf2 getf2 fixtfsi fixunstfsi floatsitf fixtfdi      \
  	fixunstfdi floatditf extendsftf2 trunctfsf2 extenddftf2 \
! 	trunctfdf2 sqrttf2 abstf2

  distribute := double.h op-1.h op-2.h op-4.h op-common.h quad.h \
  	single.h soft-fp.h extended.h Banner op-8.h testit.c \
Index: op-common.h
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/op-common.h,v
retrieving revision 1.4
diff -c -3 -p -r1.4 op-common.h
*** op-common.h	17 Oct 2002 23:16:13 -0000	1.4
--- op-common.h	31 Oct 2002 00:31:01 -0000
***************
*** 1,5 ****
  /* Software floating-point emulation. Common operations.
!    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
--- 1,5 ----
  /* Software floating-point emulation. Common operations.
!    Copyright (C) 1997,1998,1999,2002 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
*************** do {									     \
*** 363,368 ****
--- 363,381 ----
      R##_c = X##_c;			\
      R##_e = X##_e;			\
      R##_s = 1 ^ X##_s;			\
+   } while (0)
+
+
+ /*
+  * Main absolute value routine.
+  */
+
+ #define _FP_ABS(fs, wc, R, X)		\
+   do {					\
+     _FP_FRAC_COPY_##wc(R, X);		\
+     R##_c = X##_c;			\
+     R##_e = X##_e;			\
+     R##_s = 0;				\
    } while (0)


Index: single.h
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/single.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 single.h
*** single.h	6 Jul 2001 04:55:40 -0000	1.2
--- single.h	31 Oct 2002 00:31:01 -0000
***************
*** 1,6 ****
  /* Software floating-point emulation.
     Definitions for IEEE Single Precision.
!    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
--- 1,6 ----
  /* Software floating-point emulation.
     Definitions for IEEE Single Precision.
!    Copyright (C) 1997,1998,1999,2002 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
*************** union _FP_UNION_S
*** 93,98 ****
--- 93,99 ----

  #define FP_ISSIGNAN_S(X)		_FP_ISSIGNAN(S,1,X)
  #define FP_NEG_S(R,X)			_FP_NEG(S,1,R,X)
+ #define FP_ABS_S(R,X)			_FP_ABS(S,1,R,X)
  #define FP_ADD_S(R,X,Y)			_FP_ADD(S,1,R,X,Y)
  #define FP_SUB_S(R,X,Y)			_FP_SUB(S,1,R,X,Y)
  #define FP_MUL_S(R,X,Y)			_FP_MUL(S,1,R,X,Y)
Index: double.h
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/double.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 double.h
*** double.h	6 Jul 2001 04:55:40 -0000	1.2
--- double.h	31 Oct 2002 00:31:01 -0000
***************
*** 1,6 ****
  /* Software floating-point emulation.
     Definitions for IEEE Double Precision
!    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
--- 1,6 ----
  /* Software floating-point emulation.
     Definitions for IEEE Double Precision
!    Copyright (C) 1997,1998,1999,2002 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
*************** union _FP_UNION_D
*** 104,109 ****
--- 104,110 ----

  #define FP_ISSIGNAN_D(X)		_FP_ISSIGNAN(D,2,X)
  #define FP_NEG_D(R,X)			_FP_NEG(D,2,R,X)
+ #define FP_ABS_D(R,X)			_FP_ABS(D,2,R,X)
  #define FP_ADD_D(R,X,Y)			_FP_ADD(D,2,R,X,Y)
  #define FP_SUB_D(R,X,Y)			_FP_SUB(D,2,R,X,Y)
  #define FP_MUL_D(R,X,Y)			_FP_MUL(D,2,R,X,Y)
*************** union _FP_UNION_D
*** 175,180 ****
--- 176,182 ----

  #define FP_ISSIGNAN_D(X)		_FP_ISSIGNAN(D,1,X)
  #define FP_NEG_D(R,X)			_FP_NEG(D,1,R,X)
+ #define FP_ABS_D(R,X)			_FP_ABS(D,1,R,X)
  #define FP_ADD_D(R,X,Y)			_FP_ADD(D,1,R,X,Y)
  #define FP_SUB_D(R,X,Y)			_FP_SUB(D,1,R,X,Y)
  #define FP_MUL_D(R,X,Y)			_FP_MUL(D,1,R,X,Y)
Index: extended.h
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/extended.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 extended.h
*** extended.h	6 Jul 2001 04:55:40 -0000	1.2
--- extended.h	31 Oct 2002 00:31:01 -0000
***************
*** 1,6 ****
  /* Software floating-point emulation.
     Definitions for IEEE Extended Precision.
!    Copyright (C) 1999 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Jakub Jelinek (jj@ultra.linux.cz).

--- 1,6 ----
  /* Software floating-point emulation.
     Definitions for IEEE Extended Precision.
!    Copyright (C) 1999,2002 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Jakub Jelinek (jj@ultra.linux.cz).

*************** union _FP_UNION_E
*** 161,166 ****
--- 161,167 ----

  #define FP_ISSIGNAN_E(X)	_FP_ISSIGNAN(E,4,X)
  #define FP_NEG_E(R,X)		_FP_NEG(E,4,R,X)
+ #define FP_ABS_E(R,X)		_FP_ABS(E,4,R,X)
  #define FP_ADD_E(R,X,Y)		_FP_ADD(E,4,R,X,Y)
  #define FP_SUB_E(R,X,Y)		_FP_SUB(E,4,R,X,Y)
  #define FP_MUL_E(R,X,Y)		_FP_MUL(E,4,R,X,Y)
*************** union _FP_UNION_E
*** 337,342 ****
--- 338,344 ----

  #define FP_ISSIGNAN_E(X)	_FP_ISSIGNAN(E,2,X)
  #define FP_NEG_E(R,X)		_FP_NEG(E,2,R,X)
+ #define FP_ABS_E(R,X)		_FP_ABS(E,2,R,X)
  #define FP_ADD_E(R,X,Y)		_FP_ADD(E,2,R,X,Y)
  #define FP_SUB_E(R,X,Y)		_FP_SUB(E,2,R,X,Y)
  #define FP_MUL_E(R,X,Y)		_FP_MUL(E,2,R,X,Y)
Index: quad.h
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/quad.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 quad.h
*** quad.h	6 Jul 2001 04:55:40 -0000	1.2
--- quad.h	31 Oct 2002 00:31:01 -0000
***************
*** 1,6 ****
  /* Software floating-point emulation.
     Definitions for IEEE Quad Precision.
!    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
--- 1,6 ----
  /* Software floating-point emulation.
     Definitions for IEEE Quad Precision.
!    Copyright (C) 1997,1998,1999,2002 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
     Contributed by Richard Henderson (rth@cygnus.com),
  		  Jakub Jelinek (jj@ultra.linux.cz),
*************** union _FP_UNION_Q
*** 110,115 ****
--- 110,116 ----

  #define FP_ISSIGNAN_Q(X)		_FP_ISSIGNAN(Q,4,X)
  #define FP_NEG_Q(R,X)			_FP_NEG(Q,4,R,X)
+ #define FP_ABS_Q(R,X)			_FP_ABS(Q,4,R,X)
  #define FP_ADD_Q(R,X,Y)			_FP_ADD(Q,4,R,X,Y)
  #define FP_SUB_Q(R,X,Y)			_FP_SUB(Q,4,R,X,Y)
  #define FP_MUL_Q(R,X,Y)			_FP_MUL(Q,4,R,X,Y)
*************** union _FP_UNION_Q
*** 182,187 ****
--- 183,189 ----

  #define FP_ISSIGNAN_Q(X)		_FP_ISSIGNAN(Q,2,X)
  #define FP_NEG_Q(R,X)			_FP_NEG(Q,2,R,X)
+ #define FP_ABS_Q(R,X)			_FP_ABS(Q,2,R,X)
  #define FP_ADD_Q(R,X,Y)			_FP_ADD(Q,2,R,X,Y)
  #define FP_SUB_Q(R,X,Y)			_FP_SUB(Q,2,R,X,Y)
  #define FP_MUL_Q(R,X,Y)			_FP_MUL(Q,2,R,X,Y)
Index: testit.c
===================================================================
RCS file: /cvs/glibc/libc/soft-fp/testit.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 testit.c
*** testit.c	29 Dec 1999 18:08:14 -0000	1.1
--- testit.c	31 Oct 2002 00:31:01 -0000
*************** double __muldf3(double, double);
*** 17,24 ****
--- 17,26 ----
  double __divdf3(double, double);
  double __negdf2(double);
  double __sqrtdf2(double);
+ double __absdf2(double);
  double __negdf3(double a, double dummy) { return __negdf2(a); }
  double __sqrtdf3(double a, double dummy) { return __sqrtdf2(a); }
+ double __absdf3(double a, double dummy) { return __absdf(a); }

  float __addsf3(float, float);
  float __subsf3(float, float);
*************** float __mulsf3(float, float);
*** 26,33 ****
--- 28,37 ----
  float __divsf3(float, float);
  float __negsf2(float);
  float __sqrtsf2(float);
+ float __abssf2(float);
  float __negsf3(float a, float dummy) { return __negsf2(a); }
  float __sqrtsf3(float a, float dummy) { return __sqrtsf2(a); }
+ float __abssf3(float a, float dummy) { return __abssf2(a); }

  int __fixdfsi(double);
  int __fixsfsi(float);
*************** double r_divdf3(double a, double b) { re
*** 60,65 ****
--- 64,71 ----
  double r_negdf3(double a, double b) { return -a; }
  double sqrt(double x);
  double r_sqrtdf3(double a, double b) { return sqrt(a); }
+ double fabs(double x);
+ double r_absdf3(double a, double b) { return fabs(a); }

  float r_addsf3(float a, float b) { return a + b; }
  float r_subsf3(float a, float b) { return a - b; }
*************** float r_divsf3(float a, float b) { retur
*** 68,73 ****
--- 74,81 ----
  float r_negsf3(float a, float b) { return -a; }
  float sqrtf(float x);
  float r_sqrtsf3(float a, float b) { return sqrtf(a); }
+ float fabsf(float x);
+ float r_abssf3(float a, float b) { return fabsf(a); }

  int r_fixdfsi(double a) { return (int)a; }
  int r_fixsfsi(float a) { return (int)a; }
*************** int main(int ac, char **av)
*** 461,466 ****
--- 469,475 ----
  	      case 'd': r = r_divsf3; t = __divsf3; break;
  	      case 'r': r = r_sqrtsf3; t = __sqrtsf3; break;
  	      case 'j': r = r_negsf3; t = __negsf3; break;
+ 	      case 'b': r = r_abssf3; t = __abssf3; break;
  	    } while (0);

  	    switch (*(*av)++)
*************** int main(int ac, char **av)
*** 503,508 ****
--- 512,518 ----
  	      case 'D': r = r_divdf3; t = __divdf3; break;
  	      case 'R': r = r_sqrtdf3; t = __sqrtdf3; break;
  	      case 'J': r = r_negdf3; t = __negdf3; break;
+ 	      case 'B': r = r_absdf3; t = __absdf3; break;
  	    } while (0);

  	    switch (*(*av)++)

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]