tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cpu.c (4512B)


      1 /*
      2 * This file is part of FFmpeg.
      3 *
      4 * FFmpeg is free software; you can redistribute it and/or
      5 * modify it under the terms of the GNU Lesser General Public
      6 * License as published by the Free Software Foundation; either
      7 * version 2.1 of the License, or (at your option) any later version.
      8 *
      9 * FFmpeg is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 * Lesser General Public License for more details.
     13 *
     14 * You should have received a copy of the GNU Lesser General Public
     15 * License along with FFmpeg; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17 */
     18 
     19 #include "libavutil/cpu.h"
     20 #include "libavutil/cpu_internal.h"
     21 #include "config.h"
     22 
     23 #if HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
     24 #include <stdint.h>
     25 #include <sys/auxv.h>
     26 
     27 #define HWCAP_AARCH64_ASIMDDP (1 << 20)
     28 #define HWCAP_AARCH64_SVE     (1 << 22)
     29 #define HWCAP2_AARCH64_SVE2   (1 << 1)
     30 #define HWCAP2_AARCH64_I8MM   (1 << 13)
     31 
     32 static int detect_flags(void)
     33 {
     34    int flags = 0;
     35 
     36    unsigned long hwcap = ff_getauxval(AT_HWCAP);
     37    unsigned long hwcap2 = ff_getauxval(AT_HWCAP2);
     38 
     39    if (hwcap & HWCAP_AARCH64_ASIMDDP)
     40        flags |= AV_CPU_FLAG_DOTPROD;
     41    if (hwcap & HWCAP_AARCH64_SVE)
     42        flags |= AV_CPU_FLAG_SVE;
     43    if (hwcap2 & HWCAP2_AARCH64_SVE2)
     44        flags |= AV_CPU_FLAG_SVE2;
     45    if (hwcap2 & HWCAP2_AARCH64_I8MM)
     46        flags |= AV_CPU_FLAG_I8MM;
     47 
     48    return flags;
     49 }
     50 
     51 #elif defined(__APPLE__) && HAVE_SYSCTLBYNAME
     52 #include <sys/sysctl.h>
     53 
     54 static int have_feature(const char *feature) {
     55    uint32_t value = 0;
     56    size_t size = sizeof(value);
     57    if (!sysctlbyname(feature, &value, &size, NULL, 0))
     58        return value;
     59    return 0;
     60 }
     61 
     62 static int detect_flags(void)
     63 {
     64    int flags = 0;
     65 
     66    if (have_feature("hw.optional.arm.FEAT_DotProd"))
     67        flags |= AV_CPU_FLAG_DOTPROD;
     68    if (have_feature("hw.optional.arm.FEAT_I8MM"))
     69        flags |= AV_CPU_FLAG_I8MM;
     70 
     71    return flags;
     72 }
     73 
     74 #elif defined(__OpenBSD__)
     75 #include <machine/armreg.h>
     76 #include <machine/cpu.h>
     77 #include <sys/types.h>
     78 #include <sys/sysctl.h>
     79 
     80 static int detect_flags(void)
     81 {
     82    int flags = 0;
     83 
     84 #ifdef CPU_ID_AA64ISAR0
     85    int mib[2];
     86    uint64_t isar0;
     87    uint64_t isar1;
     88    size_t len;
     89 
     90    mib[0] = CTL_MACHDEP;
     91    mib[1] = CPU_ID_AA64ISAR0;
     92    len = sizeof(isar0);
     93    if (sysctl(mib, 2, &isar0, &len, NULL, 0) != -1) {
     94        if (ID_AA64ISAR0_DP(isar0) >= ID_AA64ISAR0_DP_IMPL)
     95            flags |= AV_CPU_FLAG_DOTPROD;
     96    }
     97 
     98    mib[0] = CTL_MACHDEP;
     99    mib[1] = CPU_ID_AA64ISAR1;
    100    len = sizeof(isar1);
    101    if (sysctl(mib, 2, &isar1, &len, NULL, 0) != -1) {
    102 #ifdef ID_AA64ISAR1_I8MM_IMPL
    103        if (ID_AA64ISAR1_I8MM(isar1) >= ID_AA64ISAR1_I8MM_IMPL)
    104            flags |= AV_CPU_FLAG_I8MM;
    105 #endif
    106    }
    107 #endif
    108 
    109    return flags;
    110 }
    111 
    112 #elif defined(_WIN32)
    113 #include <windows.h>
    114 
    115 static int detect_flags(void)
    116 {
    117    int flags = 0;
    118 #ifdef PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE
    119    if (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE))
    120        flags |= AV_CPU_FLAG_DOTPROD;
    121 #endif
    122 #ifdef PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE
    123    /* There's no PF_* flag that indicates whether plain I8MM is available
    124     * or not. But if SVE_I8MM is available, that also implies that
    125     * regular I8MM is available. */
    126    if (IsProcessorFeaturePresent(PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE))
    127        flags |= AV_CPU_FLAG_I8MM;
    128 #endif
    129 #ifdef PF_ARM_SVE_INSTRUCTIONS_AVAILABLE
    130    if (IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE))
    131        flags |= AV_CPU_FLAG_SVE;
    132 #endif
    133 #ifdef PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE
    134    if (IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE))
    135        flags |= AV_CPU_FLAG_SVE2;
    136 #endif
    137    return flags;
    138 }
    139 #else
    140 
    141 static int detect_flags(void)
    142 {
    143    return 0;
    144 }
    145 
    146 #endif
    147 
    148 int ff_get_cpu_flags_aarch64(void)
    149 {
    150    int flags = AV_CPU_FLAG_ARMV8 * HAVE_ARMV8 |
    151                AV_CPU_FLAG_NEON  * HAVE_NEON;
    152 
    153 #ifdef __ARM_FEATURE_DOTPROD
    154    flags |= AV_CPU_FLAG_DOTPROD;
    155 #endif
    156 #ifdef __ARM_FEATURE_MATMUL_INT8
    157    flags |= AV_CPU_FLAG_I8MM;
    158 #endif
    159 #ifdef __ARM_FEATURE_SVE
    160    flags |= AV_CPU_FLAG_SVE;
    161 #endif
    162 #ifdef __ARM_FEATURE_SVE2
    163    flags |= AV_CPU_FLAG_SVE2;
    164 #endif
    165 
    166    flags |= detect_flags();
    167 
    168    return flags;
    169 }
    170 
    171 size_t ff_get_cpu_max_align_aarch64(void)
    172 {
    173    int flags = av_get_cpu_flags();
    174 
    175    if (flags & AV_CPU_FLAG_NEON)
    176        return 16;
    177 
    178    return 8;
    179 }