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]

[PATCH v2] Fix static-binary lazy FPU context allocation


On Tue, 3 Sep 2013, Carlos O'Donell wrote:

> >  No regressions in mips-linux-gnu testing, o32, n64 and n32 ABIs.  OK to 
> > apply?
> 
> What existing test case checks for this?

 We've got math/test-fpucw that gives partial coverage; this won't check 
static semantics though unless $(build-shared) is (unusually) set to `no'.

> Could you please add a static test that verifies this is set correctly?

 The update below adds static coverage in all cases and extends dynamic 
coverage to non-default __fpu_control initialisation; the only portable 
way of doing that is I believe with the use of the _FPU_IEEE macro, so 
I've chosen that (it is worth noting however that the use of anything but 
_FPU_DEFAULT breaks ISO C compliance).

 Note that the test cases rely on the presence of the _FPU_GETCW macro so 
some ports are not covered (Alpha).  Also the only Linux port that 
currently actually produces the AT_FPUCW tag is Renesas SuperH.

> > Index: glibc-fsf-trunk-quilt/elf/dl-support.c
> > ===================================================================
> > --- glibc-fsf-trunk-quilt.orig/elf/dl-support.c	2013-08-20 15:18:10.000000000 +0100
> > +++ glibc-fsf-trunk-quilt/elf/dl-support.c	2013-08-21 20:07:55.169669153 +0100
> > @@ -167,6 +167,8 @@ size_t _dl_phnum;
> >  uint64_t _dl_hwcap __attribute__ ((nocommon));
> >  uint64_t _dl_hwcap2 __attribute__ ((nocommon));
> >  
> 
> This needs a detailed comment here explaining the behaviour of this
> internal variable. I would also welcome an expounding of the semantics
> of __fpu_control and the behaviour for static and dynamic applications.

 I've added a note on _dl_fpu_control now; NB most of these variables are 
undocumented here.

 I'm not sure what you'd like to see on `__fpu_control' and where (an 
expansion of the note in math/fpu_control.c perhaps?), I'll appreciate 
guidance.  The semantics of this variable is supposed to be the same 
whether a static or a dynamic app.

> In summary:
> - Test case.
> - Comment for _dl_fpu_control.

 Thanks for your review, here's an updated patch.  No failures with the 
test-fpucw* cases on MIPS/Linux; regrettably I have no way to test 
SuperH/Linux.  OK for this version (barring any `__fpu_control' doc 
update)?

 BTW, I have realised I am supposed to add myself to wiki/MAINTAINERS -- 
can you please grant me a write privilege to do so (ID: macro)?

2013-09-05  Maciej W. Rozycki  <macro@codesourcery.com>

	* 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) <AT_FPUCW>: 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.

  Maciej

glibc-static-fpucw.diff
Index: glibc-fsf-trunk-quilt/csu/init-first.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/csu/init-first.c	2013-05-07 22:59:41.000000000 +0100
+++ glibc-fsf-trunk-quilt/csu/init-first.c	2013-08-22 19:46:48.168109470 +0100
@@ -61,11 +61,8 @@ _init (int argc, char **argv, char **env
   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);
     }
 
Index: glibc-fsf-trunk-quilt/elf/dl-support.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/elf/dl-support.c	2013-08-20 15:18:10.000000000 +0100
+++ glibc-fsf-trunk-quilt/elf/dl-support.c	2013-09-05 17:06:45.407939629 +0100
@@ -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;
Index: glibc-fsf-trunk-quilt/math/Makefile
===================================================================
--- glibc-fsf-trunk-quilt.orig/math/Makefile	2013-06-14 01:57:07.000000000 +0100
+++ glibc-fsf-trunk-quilt/math/Makefile	2013-09-04 22:35:10.468404476 +0100
@@ -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) $(<F) $(@F)
 
 ifeq ($(build-shared),yes)
-$(addprefix $(objpfx),$(tests)): $(objpfx)libm.so$(libm.so-version)
+$(addprefix $(objpfx),$(filter-out $(tests-static),$(tests))): $(objpfx)libm.so$(libm.so-version)
+$(addprefix $(objpfx),$(tests-static)): $(objpfx)libm.a
 else
 $(addprefix $(objpfx),$(tests)): $(objpfx)libm.a
 endif
Index: glibc-fsf-trunk-quilt/math/test-fpucw-ieee-static.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ glibc-fsf-trunk-quilt/math/test-fpucw-ieee-static.c	2013-09-04 18:47:08.638421823 +0100
@@ -0,0 +1 @@
+#include "test-fpucw-ieee.c"
Index: glibc-fsf-trunk-quilt/math/test-fpucw-ieee.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ glibc-fsf-trunk-quilt/math/test-fpucw-ieee.c	2013-09-04 18:46:37.148423857 +0100
@@ -0,0 +1,24 @@
+/* FPU control word overridden initialization test.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define FPU_CONTROL _FPU_IEEE
+
+#include "test-fpucw.c"
+
+/* Preempt the library's definition of `__fpu_control'.  */
+fpu_control_t __fpu_control = _FPU_IEEE;
Index: glibc-fsf-trunk-quilt/math/test-fpucw-static.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ glibc-fsf-trunk-quilt/math/test-fpucw-static.c	2013-09-04 18:43:54.677640608 +0100
@@ -0,0 +1 @@
+#include "test-fpucw.c"
Index: glibc-fsf-trunk-quilt/math/test-fpucw.c
===================================================================
--- glibc-fsf-trunk-quilt.orig/math/test-fpucw.c	2013-01-16 00:04:04.000000000 +0000
+++ glibc-fsf-trunk-quilt/math/test-fpucw.c	2013-09-04 18:45:29.657640413 +0100
@@ -19,6 +19,10 @@
 #include <fpu_control.h>
 #include <stdio.h>
 
+#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;


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