diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libspl/include/sys/simd.h | 40 | ||||
-rw-r--r-- | lib/libzpool/Makefile.am | 6 |
2 files changed, 46 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 diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 7b1ae098d..f1f56b704 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -130,6 +130,7 @@ KERNEL_C = \ vdev_raidz_math_scalar.c \ vdev_raidz_math_sse2.c \ vdev_raidz_math_ssse3.c \ + vdev_raidz_math_powerpc_altivec.c \ vdev_removal.c \ vdev_root.c \ vdev_trim.c \ @@ -201,3 +202,8 @@ libzpool_la_LIBADD += $(ZLIB) -ldl libzpool_la_LDFLAGS = -pthread -version-info 2:0:0 EXTRA_DIST = $(USER_C) + +if TARGET_CPU_POWERPC +vdev_raidz_math_powerpc_altivec.$(OBJEXT): CFLAGS += -maltivec +vdev_raidz_math_powerpc_altivec.l$(OBJEXT): CFLAGS += -maltivec +endif |