diff --git a/ChangeLog b/ChangeLog index 9b73de5cb9..ae3a10c3f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2013-09-09 Maciej W. Rozycki + + * csu/init-first.c (_init): Remove the !SHARED condition around + FPU control word initialization. + * elf/dl-support.c (_dl_fpu_control): New variable. + (_dl_aux_init) : Initialize it. + * math/test-fpucw.c [!FPU_CONTROL] (FPU_CONTROL): New macro. + (main): Replace _FPU_DEFAULT with FPU_CONTROL throughout. + * math/test-fpucw-static.c: New file. + * math/test-fpucw-ieee.c: New file. + * math/test-fpucw-ieee-static.c: New file. + * math/Makefile (tests): Add `test-fpucw-ieee' and + `$(tests-static)'. + (tests-static): New variable. + [($(build-shared),yes)] ($(addprefix $(objpfx),$(tests))): Move + dependency to... + [($(build-shared),yes)] + ($(addprefix $(objpfx),$(filter-out $(tests-static),$(tests)))): + ... this. + [($(build-shared),yes)] ($(addprefix $(objpfx),$(tests-static))): + New dependency. + 2013-09-09 Allan McRae [BZ #15939] diff --git a/csu/init-first.c b/csu/init-first.c index f0ebc94b8d..b4d22ce6aa 100644 --- a/csu/init-first.c +++ b/csu/init-first.c @@ -61,11 +61,8 @@ _init (int argc, char **argv, char **envp) if (!__libc_multiple_libcs) { /* Set the FPU control word to the proper default value if the - kernel would use a different value. (In a static program we - don't have this information.) */ -#ifdef SHARED + kernel would use a different value. */ if (__fpu_control != GLRO(dl_fpu_control)) -#endif __setfpucw (__fpu_control); } diff --git a/elf/dl-support.c b/elf/dl-support.c index 5a082feb7a..2023bd031c 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -167,6 +167,9 @@ size_t _dl_phnum; uint64_t _dl_hwcap __attribute__ ((nocommon)); uint64_t _dl_hwcap2 __attribute__ ((nocommon)); +/* The value of the FPU control word the kernel will preset in hardware. */ +fpu_control_t _dl_fpu_control = _FPU_DEFAULT; + /* This is not initialized to HWCAP_IMPORTANT, matching the definition of _dl_important_hwcaps, below, where no hwcap strings are ever used. This mask is still used to mediate the lookups in the cache @@ -253,6 +256,9 @@ _dl_aux_init (ElfW(auxv_t) *av) case AT_HWCAP2: GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; break; + case AT_FPUCW: + GLRO(dl_fpu_control) = av->a_un.a_val; + break; #ifdef NEED_DL_SYSINFO case AT_SYSINFO: GL(dl_sysinfo) = av->a_un.a_val; diff --git a/math/Makefile b/math/Makefile index 3ed78fc9c3..a9bd49baee 100644 --- a/math/Makefile +++ b/math/Makefile @@ -87,9 +87,11 @@ long-c-yes = $(calls:=l) # Rules for the test suite. tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \ - test-misc test-fpucw tst-definitions test-tgmath test-tgmath-ret \ - bug-nextafter bug-nexttoward bug-tgmath1 test-tgmath-int \ - test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan + test-misc test-fpucw test-fpucw-ieee tst-definitions test-tgmath \ + test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \ + test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \ + $(tests-static) +tests-static = test-fpucw-static test-fpucw-ieee-static # We do the `long double' tests only if this data type is available and # distinct from `double'. test-longdouble-yes = test-ldouble test-ildoubl @@ -217,7 +219,8 @@ $(objpfx)libieee.a: $(objpfx)ieee-math.o $(LN_S) $(. */ + +#define FPU_CONTROL _FPU_IEEE + +#include "test-fpucw.c" + +/* Preempt the library's definition of `__fpu_control'. */ +fpu_control_t __fpu_control = _FPU_IEEE; diff --git a/math/test-fpucw-static.c b/math/test-fpucw-static.c new file mode 100644 index 0000000000..bc1cfa8ce5 --- /dev/null +++ b/math/test-fpucw-static.c @@ -0,0 +1 @@ +#include "test-fpucw.c" diff --git a/math/test-fpucw.c b/math/test-fpucw.c index 1961a67481..ae6a2c9a71 100644 --- a/math/test-fpucw.c +++ b/math/test-fpucw.c @@ -19,6 +19,10 @@ #include #include +#ifndef FPU_CONTROL +# define FPU_CONTROL _FPU_DEFAULT +#endif + int main (void) { @@ -30,11 +34,11 @@ main (void) cw &= ~_FPU_RESERVED; - if (cw != (_FPU_DEFAULT & ~_FPU_RESERVED)) + if (cw != (FPU_CONTROL & ~_FPU_RESERVED)) printf ("control word is 0x%lx but should be 0x%lx.\n", - (long int) cw, (long int) (_FPU_DEFAULT & ~_FPU_RESERVED)); + (long int) cw, (long int) (FPU_CONTROL & ~_FPU_RESERVED)); - return cw != (_FPU_DEFAULT & ~_FPU_RESERVED); + return cw != (FPU_CONTROL & ~_FPU_RESERVED); #else return 0;