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