[-- 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; */
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
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
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
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