summaryrefslogtreecommitdiff
path: root/libavutil/x86/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavutil/x86/cpu.c')
-rw-r--r--libavutil/x86/cpu.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index 8be6d94742..7a5d4e6a3a 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -3,20 +3,20 @@
* (c)1997-99 by H. Dietz and R. Fisher
* Converted to C and improved by Fabrice Bellard.
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -45,7 +45,7 @@
"cpuid \n\t" \
"xchg %%"REG_b", %%"REG_S \
: "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \
- : "0" (index))
+ : "0" (index), "2"(0))
#define xgetbv(index, eax, edx) \
__asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index))
@@ -143,7 +143,7 @@ int ff_get_cpu_flags_x86(void)
if (max_std_level >= 7) {
cpuid(7, eax, ebx, ecx, edx);
#if HAVE_AVX2
- if (ebx & 0x00000020)
+ if ((rval & AV_CPU_FLAG_AVX) && (ebx & 0x00000020))
rval |= AV_CPU_FLAG_AVX2;
#endif /* HAVE_AVX2 */
/* BMI1/2 don't need OS support */
@@ -167,6 +167,7 @@ int ff_get_cpu_flags_x86(void)
if (ext_caps & (1 << 22))
rval |= AV_CPU_FLAG_MMXEXT;
+ if (!strncmp(vendor.c, "AuthenticAMD", 12)) {
/* Allow for selectively disabling SSE2 functions on AMD processors
with SSE2 support but not SSE4a. This includes Athlon64, some
Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster
@@ -174,9 +175,19 @@ int ff_get_cpu_flags_x86(void)
AV_CPU_FLAG_SSE2 and AV_CPU_FLAG_SSE2SLOW are both set in this case
so that SSE2 is used unless explicitly disabled by checking
AV_CPU_FLAG_SSE2SLOW. */
- if (!strncmp(vendor.c, "AuthenticAMD", 12) &&
- rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040)) {
- rval |= AV_CPU_FLAG_SSE2SLOW;
+ if (rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040))
+ rval |= AV_CPU_FLAG_SSE2SLOW;
+
+ /* Similar to the above but for AVX functions on AMD processors.
+ This is necessary only for functions using YMM registers on Bulldozer
+ based CPUs as they lack 256-bits execution units. SSE/AVX functions
+ using XMM registers are always faster on them.
+ AV_CPU_FLAG_AVX and AV_CPU_FLAG_AVXSLOW are both set so that AVX is
+ used unless explicitly disabled by checking AV_CPU_FLAG_AVXSLOW.
+ TODO: Confirm if Excavator is affected or not by this once it's
+ released, and update the check if necessary. Same for btver2. */
+ if (family == 0x15 && (rval & AV_CPU_FLAG_AVX))
+ rval |= AV_CPU_FLAG_AVXSLOW;
}
/* XOP and FMA4 use the AVX instruction coding scheme, so they can't be