diff options
Diffstat (limited to 'lib/libspl')
-rw-r--r-- | lib/libspl/include/sys/simd.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/libspl/include/sys/simd.h b/lib/libspl/include/sys/simd.h index b25e476a3..32864e153 100644 --- a/lib/libspl/include/sys/simd.h +++ b/lib/libspl/include/sys/simd.h @@ -437,6 +437,46 @@ zfs_avx512vbmi_available(void) #define kfpu_begin() do {} while (0) #define kfpu_end() do {} while (0) +#elif defined(__powerpc__) + +#define kfpu_allowed() 1 +#define kfpu_initialize(tsk) do {} while (0) +#define kfpu_begin() do {} while (0) +#define kfpu_end() do {} while (0) + +/* + * Check if AltiVec instruction set is available + * No easy way beyond 'altivec works' :-( + */ +#include <signal.h> +#include <setjmp.h> + +#ifdef __ALTIVEC__ +static jmp_buf env; +static void sigillhandler(int x) +{ + longjmp(env, 1); +} +#endif + +static inline boolean_t +zfs_altivec_available(void) +{ + boolean_t has_altivec = B_FALSE; +#ifdef __ALTIVEC__ + sighandler_t savesig; + savesig = signal(SIGILL, sigillhandler); + if (setjmp(env)) { + signal(SIGILL, savesig); + has_altivec = B_FALSE; + } else { + __asm__ __volatile__("vor 0,0,0\n" : : : "v0"); + signal(SIGILL, savesig); + has_altivec = B_TRUE; + } +#endif + return (has_altivec); +} #else #define kfpu_allowed() 0 |