Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Mar 2021 19:07:31 GMT
From:      Brandon Bergren <bdragon@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: d905133e26d0 - stable/12 - [PowerPC] Fix SPE floating point environment manipulation
Message-ID:  <202103081907.128J7VCK063085@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by bdragon:

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

commit d905133e26d0c8852c9977a76a1091f25a031284
Author:     Brandon Bergren <bdragon@FreeBSD.org>
AuthorDate: 2019-12-12 17:12:18 +0000
Commit:     Brandon Bergren <bdragon@FreeBSD.org>
CommitDate: 2021-03-08 18:51:31 +0000

    [PowerPC] Fix SPE floating point environment manipulation
    
    Fix multiple problems in the powerpcspe floating point code.
    
    * Endianness handling of the SPEFSCR in fenv.h was completely broken.
    * Ensure SPEFSCR synchronization requirements are being met.
    
    The __r.__d -> __r transformations were written by jhibbits.
    
    Reviewed by:    jhibbits
    Differential Revision:  https://reviews.freebsd.org/D22526
    
    (cherry picked from commit 4f9ed3156c3aff08629d37c8a89ed5ba525b01c9)
---
 lib/libc/powerpcspe/gen/fpsetmask.c  |  2 +-
 lib/libc/powerpcspe/gen/fpsetround.c |  2 +-
 lib/msun/powerpc/fenv.h              | 57 ++++++++++++++++++++----------------
 sys/powerpc/booke/spe.c              |  2 +-
 4 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/lib/libc/powerpcspe/gen/fpsetmask.c b/lib/libc/powerpcspe/gen/fpsetmask.c
index 9763b78a0919..e71b822d6e0b 100644
--- a/lib/libc/powerpcspe/gen/fpsetmask.c
+++ b/lib/libc/powerpcspe/gen/fpsetmask.c
@@ -47,7 +47,7 @@ fpsetmask(fp_except_t mask)
 	__asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR));
 	old = (fp_rnd_t)((fpscr >> 2) & 0x1f);
 	fpscr = (fpscr & 0xffffff83) | (mask << 2);
-	__asm__ __volatile("mtspr %1,%0" :: "r"(fpscr), "K"(SPR_SPEFSCR));
+	__asm__ __volatile("mtspr %1,%0;isync" :: "r"(fpscr), "K"(SPR_SPEFSCR));
 	return (old);
 }
 #endif
diff --git a/lib/libc/powerpcspe/gen/fpsetround.c b/lib/libc/powerpcspe/gen/fpsetround.c
index b5340a6d9ea2..2e2469cdae5e 100644
--- a/lib/libc/powerpcspe/gen/fpsetround.c
+++ b/lib/libc/powerpcspe/gen/fpsetround.c
@@ -47,7 +47,7 @@ fpsetround(fp_rnd_t rnd_dir)
 	__asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR) );
 	old = (fp_rnd_t)(fpscr & 0x3);
 	fpscr = (fpscr & 0xfffffffc) | rnd_dir;
-	__asm__ __volatile("mtspr %1, %0" :: "r"(fpscr), "K"(SPR_SPEFSCR));
+	__asm__ __volatile("mtspr %1, %0;isync" :: "r"(fpscr), "K"(SPR_SPEFSCR));
 	return (old);
 }
 #endif
diff --git a/lib/msun/powerpc/fenv.h b/lib/msun/powerpc/fenv.h
index af9eee999b70..3e2a11c48c50 100644
--- a/lib/msun/powerpc/fenv.h
+++ b/lib/msun/powerpc/fenv.h
@@ -32,6 +32,7 @@
 #define	_FENV_H_
 
 #include <sys/_types.h>
+#include <machine/endian.h>
 
 #ifndef	__fenv_static
 #define	__fenv_static	static
@@ -90,11 +91,15 @@ extern const fenv_t	__fe_dfl_env;
 
 #ifndef _SOFT_FLOAT
 #ifdef __SPE__
-#define	__mffs(__env)	__asm __volatile("mfspr %0, 512" : "=r" (*(__env)))
-#define	__mtfsf(__env)	__asm __volatile("mtspr 512,%0" : : "r" (__env))
+#define	__mffs(__env) \
+	__asm __volatile("mfspr %0, 512" : "=r" ((__env)->__bits.__reg))
+#define	__mtfsf(__env) \
+	__asm __volatile("mtspr 512,%0;isync" :: "r" ((__env).__bits.__reg))
 #else
-#define	__mffs(__env)	__asm __volatile("mffs %0" : "=f" (*(__env)))
-#define	__mtfsf(__env)	__asm __volatile("mtfsf 255,%0" : : "f" (__env))
+#define	__mffs(__env) \
+	__asm __volatile("mffs %0" : "=f" ((__env)->__d))
+#define	__mtfsf(__env) \
+	__asm __volatile("mtfsf 255,%0" :: "f" ((__env).__d))
 #endif
 #else
 #define	__mffs(__env)
@@ -121,9 +126,9 @@ feclearexcept(int __excepts)
 
 	if (__excepts & FE_INVALID)
 		__excepts |= FE_ALL_INVALID;
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__r.__bits.__reg &= ~__excepts;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -132,7 +137,7 @@ fegetexceptflag(fexcept_t *__flagp, int __excepts)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	*__flagp = __r.__bits.__reg & __excepts;
 	return (0);
 }
@@ -144,10 +149,10 @@ fesetexceptflag(const fexcept_t *__flagp, int __excepts)
 
 	if (__excepts & FE_INVALID)
 		__excepts |= FE_ALL_EXCEPT;
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__r.__bits.__reg &= ~__excepts;
 	__r.__bits.__reg |= *__flagp & __excepts;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -158,9 +163,9 @@ feraiseexcept(int __excepts)
 
 	if (__excepts & FE_INVALID)
 		__excepts |= FE_VXSOFT;
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__r.__bits.__reg |= __excepts;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -169,7 +174,7 @@ fetestexcept(int __excepts)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	return (__r.__bits.__reg & __excepts);
 }
 
@@ -178,7 +183,7 @@ fegetround(void)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	return (__r.__bits.__reg & _ROUND_MASK);
 }
 
@@ -189,10 +194,10 @@ fesetround(int __round)
 
 	if (__round & ~_ROUND_MASK)
 		return (-1);
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__r.__bits.__reg &= ~_ROUND_MASK;
 	__r.__bits.__reg |= __round;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -201,7 +206,7 @@ fegetenv(fenv_t *__envp)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	*__envp = __r.__bits.__reg;
 	return (0);
 }
@@ -211,10 +216,10 @@ feholdexcept(fenv_t *__envp)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	*__envp = __r.__d;
 	__r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -224,7 +229,7 @@ fesetenv(const fenv_t *__envp)
 	union __fpscr __r;
 
 	__r.__bits.__reg = *__envp;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -233,10 +238,10 @@ feupdateenv(const fenv_t *__envp)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__r.__bits.__reg &= FE_ALL_EXCEPT;
 	__r.__bits.__reg |= *__envp;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return (0);
 }
 
@@ -250,10 +255,10 @@ feenableexcept(int __mask)
 	union __fpscr __r;
 	fenv_t __oldmask;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__oldmask = __r.__bits.__reg;
 	__r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
 }
 
@@ -263,10 +268,10 @@ fedisableexcept(int __mask)
 	union __fpscr __r;
 	fenv_t __oldmask;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	__oldmask = __r.__bits.__reg;
 	__r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
-	__mtfsf(__r.__d);
+	__mtfsf(__r);
 	return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
 }
 
@@ -275,7 +280,7 @@ fegetexcept(void)
 {
 	union __fpscr __r;
 
-	__mffs(&__r.__d);
+	__mffs(&__r);
 	return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
 }
 
diff --git a/sys/powerpc/booke/spe.c b/sys/powerpc/booke/spe.c
index 7b24f3b7a759..0305145d5107 100644
--- a/sys/powerpc/booke/spe.c
+++ b/sys/powerpc/booke/spe.c
@@ -134,7 +134,7 @@ enable_vec(struct thread *td)
 
 	/* Restore SPEFSCR and ACC.  Use %r0 as the scratch for ACC. */
 	mtspr(SPR_SPEFSCR, pcb->pcb_vec.vscr);
-	__asm __volatile("evldd 0, 0(%0); evmra 0,0\n"
+	__asm __volatile("isync;evldd 0, 0(%0); evmra 0,0\n"
 	    :: "b"(&pcb->pcb_vec.spare[0]));
 
 	/* 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103081907.128J7VCK063085>