This is the mail archive of the libc-alpha@sourceware.org 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]

soft-fp: split FP_INIT_EXCEPTIONS from FP_INIT_ROUNDMODE


The soft-fp macro FP_INIT_ROUNDMODE initializes state used both for
rounding and also, on some architectures, for exception handling
(typically a local variable with a copy of the floating-point control
register, which may be used for both purposes).

Some soft-fp functions only need exception handling and not rounding,
because their results are always exact (but signaling NaNs, if nothing
else, may still result in exceptions) or do not depend on the rounding
mode (e.g. comparisons and conversions to integers).  For these, it's
misleading to use FP_INIT_ROUNDMODE; on architectures where the state
in question is only used for rounding and not for exceptions, it's
also suboptimal.  Thus, this patch defines a separate macro
FP_INIT_EXCEPTIONS, defaulting to FP_INIT_ROUNDMODE, and uses it in
the floating-point extensions that are the existing uses of
FP_INIT_ROUNDMODE that can change.

I didn't change any existing sfp-machine.h files; powerpc-nofpu, the
only current case building soft-fp in glibc, doesn't define
FP_INIT_ROUNDMODE anyway, and there is no benefit for those
architectures using soft-fp for no more than sqrtl and possibly fma.
I haven't checked whether the sparc and alpha code using soft-fp in
glibc could benefit at all from such optimizations.  When soft-fp is
next updated in libgcc, sfp-machine.h files there can be made to
define the new macro where beenficial.

The immediate motivation is that e500 builds show warnings from files
that do in fact need such initialization but are missing it.  This
patch is preliminary to properly making all files needing such
initialization have it, to avoid adding potentially confusing and
suboptimal FP_INIT_ROUNDMODE to files that obviously don't depend on
the rounding mode.  (There will be another such preliminary patch, to
add a way to stub out rounding/exceptions code in cases where
generically it might be needed but not for the particular types
involved.  Thus, float*.c generally need FP_INIT_ROUNDMODE but
e.g. floatsidf.c is a case where the conversions are always exact and
so it's best to stub out the rounding/exceptions macros used by
FP_FROM_INT_D as no rounding can actually occur.)

One corner case to note is that floating-point extensions can have
exact underflow cases, so needing FP_TRAPPING_EXCEPTIONS tests (which
may need more initialized state than FP_HANDLE_EXCEPTIONS does), if
the wider type has more precision but no larger exponent range.  The
only case of this in practice is __extendxftf2 in libgcc (converting
long double to __float128 on x86 / x86_64 / ia64).  FP_EXTEND does
nothing to detect such cases at present; the way to make it do so
would involve providing a way for the other cases of extensions to
stub out FP_TRAPPING_EXCEPTIONS so they can continue to use
FP_INIT_EXCEPTIONS.  (But this is a pretty obscure bug in the
__float128 code in libgcc; I'd consider the lack of handling of x86
being an after-rounding tininess detection architecture as more
significant, although more complicated to fix, while ia64 doesn't have
a definition of FP_TRAPPING_EXCEPTIONS at all in libgcc.)

Tested for powerpc-nofpu.

Presume that once this is in I'll update the e500 port (whether or not
it's been reviewed by then) to define FP_INIT_EXCEPTIONS appropriately
(as in the e500 case the state used for rounding isn't used for
exception raising in soft-fp).

2013-10-09  Joseph Myers  <joseph@codesourcery.com>

	* soft-fp/soft-fp.h (FP_INIT_EXCEPTIONS): New macro.
	* soft-fp/extenddftf2.c (__extenddftf2): Use FP_INIT_EXCEPTIONS
	instead of FP_INIT_ROUNDMODE.
	* soft-fp/extendsfdf2.c (__extendsfdf2): Likewise.
	* soft-fp/extendsftf2.c (__extendsftf2): Likewise.

diff --git a/soft-fp/extenddftf2.c b/soft-fp/extenddftf2.c
index ff76a8c..fd4f9dd 100644
--- a/soft-fp/extenddftf2.c
+++ b/soft-fp/extenddftf2.c
@@ -39,7 +39,7 @@ TFtype __extenddftf2(DFtype a)
   FP_DECL_Q(R);
   TFtype r;
 
-  FP_INIT_ROUNDMODE;
+  FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_D(A, a);
 #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
   FP_EXTEND(Q,D,4,2,R,A);
diff --git a/soft-fp/extendsfdf2.c b/soft-fp/extendsfdf2.c
index 7fc4046..614da79 100644
--- a/soft-fp/extendsfdf2.c
+++ b/soft-fp/extendsfdf2.c
@@ -39,7 +39,7 @@ DFtype __extendsfdf2(SFtype a)
   FP_DECL_D(R);
   DFtype r;
 
-  FP_INIT_ROUNDMODE;
+  FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_S(A, a);
 #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
   FP_EXTEND(D,S,2,1,R,A);
diff --git a/soft-fp/extendsftf2.c b/soft-fp/extendsftf2.c
index 8271a88..b1ab593 100644
--- a/soft-fp/extendsftf2.c
+++ b/soft-fp/extendsftf2.c
@@ -39,7 +39,7 @@ TFtype __extendsftf2(SFtype a)
   FP_DECL_Q(R);
   TFtype r;
 
-  FP_INIT_ROUNDMODE;
+  FP_INIT_EXCEPTIONS;
   FP_UNPACK_RAW_S(A, a);
 #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
   FP_EXTEND(Q,S,4,1,R,A);
diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
index b1c6e61..8a22a11 100644
--- a/soft-fp/soft-fp.h
+++ b/soft-fp/soft-fp.h
@@ -101,10 +101,18 @@
 #define FP_DECL_EX int _fex = 0
 #endif
 
+/* Initialize any machine-specific state used in FP_ROUNDMODE,
+   FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS.  */
 #ifndef FP_INIT_ROUNDMODE
 #define FP_INIT_ROUNDMODE do {} while (0)
 #endif
 
+/* Initialize any machine-specific state used in
+   FP_HANDLE_EXCEPTIONS.  */
+#ifndef FP_INIT_EXCEPTIONS
+#define FP_INIT_EXCEPTIONS FP_INIT_ROUNDMODE
+#endif
+
 #ifndef FP_HANDLE_EXCEPTIONS
 #define FP_HANDLE_EXCEPTIONS do {} while (0)
 #endif

-- 
Joseph S. Myers
joseph@codesourcery.com


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