diff options
author | Romain Dolbeau <[email protected]> | 2020-01-23 20:01:24 +0100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2020-01-23 11:01:24 -0800 |
commit | 35b07497c60701465a87aab48fc890a0bc502561 (patch) | |
tree | ded14fd0cfd7c3dd985617ae1d576d4e26c165a2 /lib | |
parent | 1a69856034304e74b32fb372e89967e91989cafd (diff) |
Add AltiVec RAID-Z
Implements the RAID-Z function using AltiVec SIMD.
This is basically the NEON code translated to AltiVec.
Note that the 'fletcher' algorithm requires 64-bits
operations, and the initial implementations of AltiVec
(PPC74xx a.k.a. G4, PPC970 a.k.a. G5) only has up to
32-bits operations, so no 'fletcher'.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Romain Dolbeau <[email protected]>
Closes #9539
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 |