public inbox for libc-ports@sourceware.org
 help / color / mirror / Atom feed
* [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp
@ 2013-11-26 11:34 Matheus Almeida
  2013-11-26 16:25 ` Joseph S. Myers
  0 siblings, 1 reply; 5+ messages in thread
From: Matheus Almeida @ 2013-11-26 11:34 UTC (permalink / raw)
  To: libc-ports; +Cc: Doug Gilmore

[-- Attachment #1: Type: text/plain, Size: 858 bytes --]

Mips allow the width of FPU registers to be controlled by specifying the FR configuration bit:
FR=0 -> 32-bit FPU registers
FR=1 -> 64-bit FPU registers
This can be controlled by -mfp32/-mfp64 command line options.

This patch updates the definition of setjmp, longjmp and jmp_buf so that on a call to setjmp/longjmp, all the required floating-point callee-saved registers are properly saved/restored. 

We are aware that updating the size of jmp_buf can potentially break existing applications but we expect the number of applications built with FR=1 mode to be very small, possibly zero. Nevertheless this should be clearly stated in the release notes that existing applications built with FR=1 (-mfp64) need to be recompiled in order to use new versions of the library.

Regards,
Matheus

Matheus Almeida
MIPS processor IP
www.imgtec.com


[-- Attachment #2: glibc_fp64.patch --]
[-- Type: application/octet-stream, Size: 3967 bytes --]

diff --git a/ports/sysdeps/mips/__longjmp.c b/ports/sysdeps/mips/__longjmp.c
index d1d7d64..ea60b1d 100644
--- a/ports/sysdeps/mips/__longjmp.c
+++ b/ports/sysdeps/mips/__longjmp.c
@@ -41,12 +41,29 @@ ____longjmp (env_arg, val_arg)
 
 #ifdef __mips_hard_float
   /* Pull back the floating point callee-saved registers.  */
+#if __mips_fpr == 32
   asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
   asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[1]));
   asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[2]));
   asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[3]));
   asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
   asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
+#elif __mips_fpr == 64
+  asm volatile ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
+  asm volatile ("l.d $f21, %0" : : "m" (env[0].__fpregs[1]));
+  asm volatile ("l.d $f22, %0" : : "m" (env[0].__fpregs[2]));
+  asm volatile ("l.d $f23, %0" : : "m" (env[0].__fpregs[3]));
+  asm volatile ("l.d $f24, %0" : : "m" (env[0].__fpregs[4]));
+  asm volatile ("l.d $f25, %0" : : "m" (env[0].__fpregs[5]));
+  asm volatile ("l.d $f26, %0" : : "m" (env[0].__fpregs[6]));
+  asm volatile ("l.d $f27, %0" : : "m" (env[0].__fpregs[7]));
+  asm volatile ("l.d $f28, %0" : : "m" (env[0].__fpregs[8]));
+  asm volatile ("l.d $f29, %0" : : "m" (env[0].__fpregs[9]));
+  asm volatile ("l.d $f30, %0" : : "m" (env[0].__fpregs[10]));
+  asm volatile ("l.d $f31, %0" : : "m" (env[0].__fpregs[11]));
+#else
+#error "Unsupported FPU configuration."
+#endif
 #endif
 
   /* Get the GP. */
diff --git a/ports/sysdeps/mips/bits/setjmp.h b/ports/sysdeps/mips/bits/setjmp.h
index 437848f..0714d5a 100644
--- a/ports/sysdeps/mips/bits/setjmp.h
+++ b/ports/sysdeps/mips/bits/setjmp.h
@@ -66,7 +66,14 @@ typedef struct __jmp_buf_internal_tag
 #if _MIPS_SIM == _ABI64
     double __fpregs[8];
 #else
+    /* Assuming the ABI is _ABIO32. */
+# if __mips_fpr == 32
     double __fpregs[6];
+# elif __mips_fpr == 64
+    double __fpregs[12];
+# else
+#  error "Unsupported FPU configuration."
+# endif
 #endif
   } __jmp_buf[1];
 
diff --git a/ports/sysdeps/mips/setjmp_aux.c b/ports/sysdeps/mips/setjmp_aux.c
index 26715b7..2374cfc 100644
--- a/ports/sysdeps/mips/setjmp_aux.c
+++ b/ports/sysdeps/mips/setjmp_aux.c
@@ -28,12 +28,29 @@ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
 {
 #ifdef __mips_hard_float
   /* Store the floating point callee-saved registers...  */
+#if __mips_fpr == 32
   asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
   asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
   asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
   asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
   asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
   asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#elif __mips_fpr == 64
+  asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
+  asm volatile ("s.d $f21, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
+  asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
+  asm volatile ("s.d $f23, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
+  asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
+  asm volatile ("s.d $f25, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+  asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[6]));
+  asm volatile ("s.d $f27, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[7]));
+  asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[8]));
+  asm volatile ("s.d $f29, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[9]));
+  asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[10]));
+  asm volatile ("s.d $f31, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[11]));
+#else
+#error "Unsupported FPU configuration."
+#endif
 #endif
 
   /* .. and the PC;  */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp
  2013-11-26 11:34 [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp Matheus Almeida
@ 2013-11-26 16:25 ` Joseph S. Myers
  2013-11-30  8:03   ` Joseph S. Myers
  2013-12-04  2:45   ` Doug Gilmore
  0 siblings, 2 replies; 5+ messages in thread
From: Joseph S. Myers @ 2013-11-26 16:25 UTC (permalink / raw)
  To: Matheus Almeida; +Cc: libc-ports, Doug Gilmore

On Tue, 26 Nov 2013, Matheus Almeida wrote:

> This patch updates the definition of setjmp, longjmp and jmp_buf so that 
> on a call to setjmp/longjmp, all the required floating-point 
> callee-saved registers are properly saved/restored.
> 
> We are aware that updating the size of jmp_buf can potentially break 
> existing applications but we expect the number of applications built 
> with FR=1 mode to be very small, possibly zero. Nevertheless this should 
> be clearly stated in the release notes that existing applications built 
> with FR=1 (-mfp64) need to be recompiled in order to use new versions of 
> the library.

I don't recall a response to 
<https://sourceware.org/ml/binutils/2013-09/msg00045.html>, and don't see 
one in the binutils list archives.  I believe that just like the NaN 
changes, this needs to be considered as an incompatible ABI variant, with 
ELF header checks in the dynamic linker to ensure that all loaded objects 
are compatible (whether or not you also define new dynamic linker names 
for one or both of o32/-mfp64/legacy-NaN and o32/-mfp64/NaN-2008) - 
incompatibilities should be detected by the dynamic linker, not "need to 
be recompiled".  I suggest looking at Maciej's NaN changes as a model.  
Also as suggested in that message to the binutils list, I think *context 
functions need updating as well as setjmp/longjmp, and there should be an 
ABI supplement document explaining o32 function call and return for 
-mfp64.

What's the kernel.org kernel version with support for this feature (that 
is, the kernel that checks the ELF header flag and ensures the FPU is 
correctly set up for the process)?  As with NaN-2008, arch_minimum_kernel 
should be set to the appropriate kernel version, or 10.0.0 until the 
relevant support is in the kernel.org tree.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp
  2013-11-26 16:25 ` Joseph S. Myers
@ 2013-11-30  8:03   ` Joseph S. Myers
  2013-12-04  2:45   ` Doug Gilmore
  1 sibling, 0 replies; 5+ messages in thread
From: Joseph S. Myers @ 2013-11-30  8:03 UTC (permalink / raw)
  To: Matheus Almeida; +Cc: libc-ports, Doug Gilmore

On Tue, 26 Nov 2013, Joseph S. Myers wrote:

> incompatibilities should be detected by the dynamic linker, not "need to 
> be recompiled".  I suggest looking at Maciej's NaN changes as a model.  

Sorry, I see your "need to be recompiled" was about old -mfp64 binaries, 
which indeed we don't need to care about.  But we *do* need to ensure 
incompatibilities between o32-fp32 and o32-fp64 binaries / shared 
libraries are detected, which means doing similar things to Maciej's patch 
to check ELF flags, distinguish libraries in ldconfig and arguably use a 
different dynamic linker name (or two such names, if o32-fp64 is supported 
with both NaN variants).  (New dynamic linker names mean changes to specs 
in GCC, but those changes should be small and so fine even in development 
stage 3.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp
  2013-11-26 16:25 ` Joseph S. Myers
  2013-11-30  8:03   ` Joseph S. Myers
@ 2013-12-04  2:45   ` Doug Gilmore
  2013-12-04 14:56     ` Joseph S. Myers
  1 sibling, 1 reply; 5+ messages in thread
From: Doug Gilmore @ 2013-12-04  2:45 UTC (permalink / raw)
  To: Joseph S.Myers, libc-ports

On 11/26/2013 08:21 AM, Joseph S.Myers wrote:
Hi Joseph,

Sorry for the delay in responding, there were issues with the
*context routines I wanted to understand more fully, thus the delay.
> On Tue, 26 Nov 2013, Matheus Almeida wrote:
> 
>> This patch updates the definition of setjmp, longjmp and jmp_buf so that 
>> on a call to setjmp/longjmp, all the required floating-point 
>> callee-saved registers are properly saved/restored.
>>
>> We are aware that updating the size of jmp_buf can potentially break 
>> existing applications but we expect the number of applications built 
>> with FR=1 mode to be very small, possibly zero. Nevertheless this should 
>> be clearly stated in the release notes that existing applications built 
>> with FR=1 (-mfp64) need to be recompiled in order to use new versions of 
>> the library.
Good point, we will attend to that.

> 
> I don't recall a response to 
> <https://sourceware.org/ml/binutils/2013-09/msg00045.html>, and don't see
> one in the binutils list archives.  I believe that just like the NaN 
> changes, this needs to be considered as an incompatible ABI variant, with 
> ELF header checks in the dynamic linker to ensure that all loaded objects 
> are compatible (whether or not you also define new dynamic linker names 
> for one or both of o32/-mfp64/legacy-NaN and o32/-mfp64/NaN-2008) - 
> incompatibilities should be detected by the dynamic linker, not "need to 
> be recompiled".  I suggest looking at Maciej's NaN changes as a model.
Yes, this is definitely something we need to attend to.

> Also as suggested in that message to the binutils list, I think *context 
> functions need updating
An important motivation for adding -mfp64 support is to efficiently
support the new MSA ISA, which requires the register file to operate
in -mfp64 mode when MSA instructions are executed.  Since the
definition of ucontext_t is basically the kernel's struct sigcontext,
with possibly with some massaging some of the types used in the
definition, our preference is to wait in adding this functionality
once MSA context switching support is added to the Linux kernel.

If worse comes to worse we may have to live with the *context routines
not being supported properly, just as they are on X86_64 in AVX mode.
> as well as setjmp/longjmp, and there should be an 
> ABI supplement document explaining o32 function call and return for 
> -mfp64.
Will do.

>
> What's the kernel.org kernel version with support for this feature (that 
> is, the kernel that checks the ELF header flag and ensures the FPU is 
> correctly set up for the process)?  As with NaN-2008, arch_minimum_kernel 
> should be set to the appropriate kernel version, or 10.0.0 until the 
> relevant support is in the kernel.org tree.

In your follow-up message you wrote:
> Sorry, I see your "need to be recompiled" was about old -mfp64 binaries, 
> which indeed we don't need to care about.
Is the kernel version check still a concern given that currently there
is no ToT kernel support for -mfp64?  We just need to add the checks to
ensure the dynamic linker will only map compatible shared objects.  Right?

Thanks,

Doug


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp
  2013-12-04  2:45   ` Doug Gilmore
@ 2013-12-04 14:56     ` Joseph S. Myers
  0 siblings, 0 replies; 5+ messages in thread
From: Joseph S. Myers @ 2013-12-04 14:56 UTC (permalink / raw)
  To: Doug Gilmore; +Cc: libc-ports

On Tue, 3 Dec 2013, Doug Gilmore wrote:

> > Also as suggested in that message to the binutils list, I think *context 
> > functions need updating
> An important motivation for adding -mfp64 support is to efficiently
> support the new MSA ISA, which requires the register file to operate
> in -mfp64 mode when MSA instructions are executed.  Since the
> definition of ucontext_t is basically the kernel's struct sigcontext,
> with possibly with some massaging some of the types used in the
> definition, our preference is to wait in adding this functionality
> once MSA context switching support is added to the Linux kernel.

If the functions don't work then it's better for them to be stubs setting 
errno to ENOSYS and with associated stub_warnings, rather than a broken 
function that may return a success status.

Note that the general rule for all such functions - setjmp / longjmp and 
*context - is that you only need to deal with call-preserved registers, 
not call-clobbered ones.  A corollary of this is that it's generally a bad 
idea for new registers in instruction set extensions to be call-preserved 
because that means running code with old libc and using new instruction 
set features can quietly break.  You can choose register preservation 
rules in your ABI supplement (as long as you make GCC match, of course), 
but then any future registers not mentioned in the ABI should be 
call-clobbered.

It is also the case that once a glibc release has been made with a 
particular size for a type such as ucontext_t, any change to that type 
requires symbol versioning unless you can demonstrate there are no issues 
with interoperation of applications built for one type size with 
libraries built for another.

> Is the kernel version check still a concern given that currently there
> is no ToT kernel support for -mfp64?  We just need to add the checks to
> ensure the dynamic linker will only map compatible shared objects.  Right?

There should still be the arch_minimum_kernel setting, to 10.0.0 until the 
support is upstream and then to the actual version where the support goes 
upstream.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-12-04 14:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-26 11:34 [Patch, mips]: Add support for FR=1/o32. Update implemention of setjmp/longjmp Matheus Almeida
2013-11-26 16:25 ` Joseph S. Myers
2013-11-30  8:03   ` Joseph S. Myers
2013-12-04  2:45   ` Doug Gilmore
2013-12-04 14:56     ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).