1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
--- mesa-18.3.2/src/util/u_cpu_detect.c.old 2019-01-17 11:26:23.000000000 +0000
+++ mesa-18.3.2/src/util/u_cpu_detect.c 2019-02-22 19:23:26.620000000 +0000
@@ -41,6 +41,9 @@
#if defined(PIPE_ARCH_PPC)
#if defined(PIPE_OS_APPLE)
#include <sys/sysctl.h>
+#elif defined(PIPE_OS_LINUX)
+#include <asm/cputable.h>
+#include <linux/auxvec.h>
#else
#include <signal.h>
#include <setjmp.h>
@@ -92,7 +95,7 @@
#endif
-#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_APPLE)
+#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_APPLE) && !defined(PIPE_OS_LINUX)
static jmp_buf __lv_powerpc_jmpbuf;
static volatile sig_atomic_t __lv_powerpc_canjump = 0;
@@ -126,7 +129,43 @@
util_cpu_caps.has_altivec = 1;
}
}
-#else /* !PIPE_OS_APPLE */
+#elif defined(PIPE_OS_LINUX)
+ /* Taken from FFmpeg 4.1.1 (LGPL-2.1+) */
+ // The linux kernel could have the altivec support disabled
+ // even if the cpu has it.
+ int i, ret = 0;
+ int fd = open("/proc/self/auxv", O_RDONLY);
+ unsigned long buf[64] = { 0 };
+ ssize_t count;
+ boolean enable_vsx = TRUE;
+ /* VSX instructions can be explicitly enabled/disabled via GALLIVM_VSX=1 or 0 */
+ char *env_vsx = getenv("GALLIVM_VSX");
+ if (env_vsx && env_vsx[0] == '0') {
+ enable_vsx = FALSE;
+ }
+
+ if (fd < 0)
+ return 0;
+
+ while ((count = read(fd, buf, sizeof(buf))) > 0) {
+ for (i = 0; i < count / sizeof(*buf); i += 2) {
+ if (buf[i] == AT_NULL)
+ goto out;
+ if (buf[i] == AT_HWCAP) {
+ if (buf[i + 1] & PPC_FEATURE_HAS_ALTIVEC)
+ util_cpu_caps.has_altivec = 1;
+#ifdef PPC_FEATURE_HAS_VSX
+ if (enable_vsx && buf[i + 1] & PPC_FEATURE_HAS_VSX)
+ util_cpu_caps.has_vsx = 1;
+#endif
+ goto out;
+ }
+ }
+ }
+
+out:
+ close(fd);
+#else /* !PIPE_OS_APPLE, !PIPE_OS_LINUX */
/* not on Apple/Darwin, do it the brute-force way */
/* this is borrowed from the libmpeg2 library */
signal(SIGILL, sigill_handler);
|