aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libspl/include/sys/simd.h40
-rw-r--r--lib/libzpool/Makefile.am6
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