This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] Implement __abs?f2 functions in soft-fp
- From: Roger Sayle <roger at eyesopen dot com>
- To: <libc-alpha at sources dot redhat dot com>
- Date: Thu, 31 Oct 2002 19:23:28 -0700 (MST)
- Subject: [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