Date: Thu, 12 Dec 2019 17:12:18 +0000 (UTC) From: Brandon Bergren <bdragon@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355656 - in head: lib/libc/powerpcspe/gen lib/msun/powerpc sys/powerpc/booke Message-ID: <201912121712.xBCHCIxM019653@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bdragon Date: Thu Dec 12 17:12:18 2019 New Revision: 355656 URL: https://svnweb.freebsd.org/changeset/base/355656 Log: [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 Modified: head/lib/libc/powerpcspe/gen/fpsetmask.c head/lib/libc/powerpcspe/gen/fpsetround.c head/lib/msun/powerpc/fenv.h head/sys/powerpc/booke/spe.c Modified: head/lib/libc/powerpcspe/gen/fpsetmask.c ============================================================================== --- head/lib/libc/powerpcspe/gen/fpsetmask.c Thu Dec 12 16:49:55 2019 (r355655) +++ head/lib/libc/powerpcspe/gen/fpsetmask.c Thu Dec 12 17:12:18 2019 (r355656) @@ -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 Modified: head/lib/libc/powerpcspe/gen/fpsetround.c ============================================================================== --- head/lib/libc/powerpcspe/gen/fpsetround.c Thu Dec 12 16:49:55 2019 (r355655) +++ head/lib/libc/powerpcspe/gen/fpsetround.c Thu Dec 12 17:12:18 2019 (r355656) @@ -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 Modified: head/lib/msun/powerpc/fenv.h ============================================================================== --- head/lib/msun/powerpc/fenv.h Thu Dec 12 16:49:55 2019 (r355655) +++ head/lib/msun/powerpc/fenv.h Thu Dec 12 17:12:18 2019 (r355656) @@ -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 __except 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); } Modified: head/sys/powerpc/booke/spe.c ============================================================================== --- head/sys/powerpc/booke/spe.c Thu Dec 12 16:49:55 2019 (r355655) +++ head/sys/powerpc/booke/spe.c Thu Dec 12 17:12:18 2019 (r355656) @@ -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?201912121712.xBCHCIxM019653>