FFmpeg
cpu.c
Go to the documentation of this file.
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 #if defined __linux__ || defined __ANDROID__
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <sys/auxv.h>
27 #include "asmdefs.h"
28 #include "libavutil/avstring.h"
29 #endif
30 
31 #if defined __linux__ || defined __ANDROID__
32 
33 #define HWCAP_LOONGSON_CPUCFG (1 << 14)
34 
35 static int cpucfg_available(void)
36 {
37  return getauxval(AT_HWCAP) & HWCAP_LOONGSON_CPUCFG;
38 }
39 
40 /* Most toolchains have no CPUCFG support yet */
41 static uint32_t read_cpucfg(uint32_t reg)
42 {
43  uint32_t __res;
44 
45  __asm__ __volatile__(
46  "parse_r __res,%0\n\t"
47  "parse_r reg,%1\n\t"
48  ".insn \n\t"
49  ".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t"
50  :"=r"(__res)
51  :"r"(reg)
52  :
53  );
54  return __res;
55 }
56 
57 #define LOONGSON_CFG1 0x1
58 
59 #define LOONGSON_CFG1_MMI (1 << 4)
60 #define LOONGSON_CFG1_MSA1 (1 << 5)
61 
62 static int cpu_flags_cpucfg(void)
63 {
64  int flags = 0;
65  uint32_t cfg1 = read_cpucfg(LOONGSON_CFG1);
66 
67  if (cfg1 & LOONGSON_CFG1_MMI)
68  flags |= AV_CPU_FLAG_MMI;
69 
70  if (cfg1 & LOONGSON_CFG1_MSA1)
71  flags |= AV_CPU_FLAG_MSA;
72 
73  return flags;
74 }
75 
76 static int cpu_flags_cpuinfo(void)
77 {
78  FILE *f = fopen("/proc/cpuinfo", "r");
79  char buf[200];
80  int flags = 0;
81 
82  if (!f)
83  return -1;
84 
85  while (fgets(buf, sizeof(buf), f)) {
86  /* Legacy kernel may not export MMI in ASEs implemented */
87  if (av_strstart(buf, "cpu model", NULL)) {
88  if (strstr(buf, "Loongson-3 "))
89  flags |= AV_CPU_FLAG_MMI;
90  }
91 
92  if (av_strstart(buf, "ASEs implemented", NULL)) {
93  if (strstr(buf, " loongson-mmi"))
94  flags |= AV_CPU_FLAG_MMI;
95  if (strstr(buf, " msa"))
96  flags |= AV_CPU_FLAG_MSA;
97 
98  break;
99  }
100  }
101  fclose(f);
102  return flags;
103 }
104 #endif
105 
107 {
108 #if defined __linux__ || defined __ANDROID__
109  if (cpucfg_available())
110  return cpu_flags_cpucfg();
111  else
112  return cpu_flags_cpuinfo();
113 #else
114  /* Assume no SIMD ASE supported */
115  return 0;
116 #endif
117 }
118 
120 {
121  int flags = av_get_cpu_flags();
122 
123  if (flags & AV_CPU_FLAG_MSA)
124  return 16;
125 
126  /*
127  * MMI itself is 64-bit but quad word load & store
128  * needs 128-bit align.
129  */
130  if (flags & AV_CPU_FLAG_MMI)
131  return 16;
132 
133  return 8;
134 }
#define AV_CPU_FLAG_MSA
Definition: cpu.h:75
#define NULL
Definition: coverity.c:32
MIPS assembly defines from sys/asm.h but rewritten for use with C inline assembly (rather than from w...
size_t ff_get_cpu_max_align_mips(void)
Definition: cpu.c:119
#define f(width, name)
Definition: cbs_vp9.c:255
int ff_get_cpu_flags_mips(void)
Definition: cpu.c:106
#define AV_CPU_FLAG_MMI
Definition: cpu.h:74
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:95
#define flags(name, subs,...)
Definition: cbs_av1.c:560
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:34
__asm__(".macro parse_r var r\n\t""\\var = -1\n\t"_IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)".iflt \\var\n\t"".error \"Unable to parse register name \\r\"\n\t"".endif\n\t"".endm")