git: 34cc08e33698 - main - Save all fpcr/fpsr bits in the AArch64 fenv_t

Alex Richardson arichardson at FreeBSD.org
Fri Mar 12 17:36:21 UTC 2021


The branch main has been updated by arichardson:

URL: https://cgit.FreeBSD.org/src/commit/?id=34cc08e336987a8ebc316595e3f552a4c09f1fd4

commit 34cc08e336987a8ebc316595e3f552a4c09f1fd4
Author:     Alex Richardson <arichardson at FreeBSD.org>
AuthorDate: 2021-03-12 17:01:37 +0000
Commit:     Alex Richardson <arichardson at FreeBSD.org>
CommitDate: 2021-03-12 17:01:41 +0000

    Save all fpcr/fpsr bits in the AArch64 fenv_t
    
    The existing code masked off all bits that it didn't know about. To be
    future-proof, we should save and restore the entire fpcr/fpsr registers.
    Additionally, the existing fesetenv() was incorrectly setting the rounding
    mode in fpsr instead of fpcr.
    
    This patch stores fpcr in the high 32 bits of fenv_t and fpsr in the low
    bits instead of trying to interleave them in a single 32-bit field.
    
    Technically, this is an ABI break if you re-compile parts of your code or
    pass a fenv_t between DSOs that were compiled with different versions
    of fenv.h. However, I believe we should fix this since the existing code
    was broken and passing fenv_t across DSOs should rarely happen.
    
    Reviewed By:    andrew
    Differential Revision: https://reviews.freebsd.org/D29160
---
 lib/msun/aarch64/fenv.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/msun/aarch64/fenv.h b/lib/msun/aarch64/fenv.h
index 2bd29877e5dc..2a55db3a9545 100644
--- a/lib/msun/aarch64/fenv.h
+++ b/lib/msun/aarch64/fenv.h
@@ -35,6 +35,7 @@
 #define	__fenv_static	static
 #endif
 
+/* The high 32 bits contain fpcr, low 32 contain fpsr. */
 typedef	__uint64_t	fenv_t;
 typedef	__uint64_t	fexcept_t;
 
@@ -156,13 +157,12 @@ fesetround(int __round)
 __fenv_static inline int
 fegetenv(fenv_t *__envp)
 {
-	fenv_t __r;
-
-	__mrs_fpcr(__r);
-	*__envp = __r & _ENABLE_MASK;
+	__uint64_t fpcr;
+	__uint64_t fpsr;
 
-	__mrs_fpsr(__r);
-	*__envp |= __r & (FE_ALL_EXCEPT | (_ROUND_MASK << _ROUND_SHIFT));
+	__mrs_fpcr(fpcr);
+	__mrs_fpsr(fpsr);
+	*__envp = fpsr | (fpcr << 32);
 
 	return (0);
 }
@@ -173,12 +173,12 @@ feholdexcept(fenv_t *__envp)
 	fenv_t __r;
 
 	__mrs_fpcr(__r);
-	*__envp = __r & _ENABLE_MASK;
+	*__envp = __r << 32;
 	__r &= ~(_ENABLE_MASK);
 	__msr_fpcr(__r);
 
 	__mrs_fpsr(__r);
-	*__envp |= __r & (FE_ALL_EXCEPT | (_ROUND_MASK << _ROUND_SHIFT));
+	*__envp |= (__uint32_t)__r;
 	__r &= ~(_ENABLE_MASK);
 	__msr_fpsr(__r);
 	return (0);
@@ -188,8 +188,8 @@ __fenv_static inline int
 fesetenv(const fenv_t *__envp)
 {
 
-	__msr_fpcr((*__envp) & _ENABLE_MASK);
-	__msr_fpsr((*__envp) & (FE_ALL_EXCEPT | (_ROUND_MASK << _ROUND_SHIFT)));
+	__msr_fpcr((*__envp) >> 32);
+	__msr_fpsr((fenv_t)(__uint32_t)*__envp);
 	return (0);
 }
 


More information about the dev-commits-src-all mailing list