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-main
mailing list