]> granicus.if.org Git - libvpx/blob - vpx_ports/ppc_cpudetect.c
Merge "block error avx2: sum in 32 bits when possible"
[libvpx] / vpx_ports / ppc_cpudetect.c
1 /*
2  *  Copyright (c) 2017 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include <fcntl.h>
12 #include <unistd.h>
13 #include <stdint.h>
14 #include <asm/cputable.h>
15 #include <linux/auxvec.h>
16
17 #include "./vpx_config.h"
18 #include "vpx_ports/ppc.h"
19
20 #if CONFIG_RUNTIME_CPU_DETECT
21 static int cpu_env_flags(int *flags) {
22   char *env;
23   env = getenv("VPX_SIMD_CAPS");
24   if (env && *env) {
25     *flags = (int)strtol(env, NULL, 0);
26     return 0;
27   }
28   *flags = 0;
29   return -1;
30 }
31
32 static int cpu_env_mask(void) {
33   char *env;
34   env = getenv("VPX_SIMD_CAPS_MASK");
35   return env && *env ? (int)strtol(env, NULL, 0) : ~0;
36 }
37
38 int ppc_simd_caps(void) {
39   int flags;
40   int mask;
41   int fd;
42   ssize_t count;
43   unsigned int i;
44   uint64_t buf[64];
45
46   // If VPX_SIMD_CAPS is set then allow only those capabilities.
47   if (!cpu_env_flags(&flags)) {
48     return flags;
49   }
50
51   mask = cpu_env_mask();
52
53   fd = open("/proc/self/auxv", O_RDONLY);
54   if (fd < 0) {
55     return 0;
56   }
57
58   while ((count = read(fd, buf, sizeof(buf))) > 0) {
59     for (i = 0; i < (count / sizeof(*buf)); i += 2) {
60       if (buf[i] == AT_HWCAP) {
61 #if HAVE_VSX
62         if (buf[i + 1] & PPC_FEATURE_HAS_VSX) {
63           flags |= HAS_VSX;
64         }
65 #endif  // HAVE_VSX
66         goto out_close;
67       } else if (buf[i] == AT_NULL) {
68         goto out_close;
69       }
70     }
71   }
72 out_close:
73   close(fd);
74   return flags & mask;
75 }
76 #else
77 // If there is no RTCD the function pointers are not used and can not be
78 // changed.
79 int ppc_simd_caps(void) { return 0; }
80 #endif  // CONFIG_RUNTIME_CPU_DETECT