summaryrefslogtreecommitdiff
path: root/libavutil
diff options
context:
space:
mode:
Diffstat (limited to 'libavutil')
-rw-r--r--libavutil/x86/Makefile3
-rw-r--r--libavutil/x86/cpu.c17
-rw-r--r--libavutil/x86/cpu.h4
-rw-r--r--libavutil/x86/cpuid.asm91
4 files changed, 113 insertions, 2 deletions
diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile
index 4546353669..3dd696c26a 100644
--- a/libavutil/x86/Makefile
+++ b/libavutil/x86/Makefile
@@ -1,4 +1,5 @@
OBJS += x86/cpu.o \
x86/float_dsp_init.o \
-YASM-OBJS += x86/float_dsp.o \
+YASM-OBJS += x86/cpuid.o \
+ x86/float_dsp.o \
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index 5de60147c6..fb1dd299bc 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -22,10 +22,21 @@
#include <stdlib.h>
#include <string.h>
+
#include "libavutil/x86/asm.h"
+#include "libavutil/x86/cpu.h"
#include "libavutil/cpu.h"
-#if HAVE_INLINE_ASM
+#if HAVE_YASM
+
+#define cpuid(index, eax, ebx, ecx, edx) \
+ ff_cpu_cpuid(index, &eax, &ebx, &ecx, &edx)
+
+#define xgetbv(index, eax, edx) \
+ ff_cpu_xgetbv(index, &eax, &edx)
+
+#elif HAVE_INLINE_ASM
+
/* ebx saving is necessary for PIC. gcc seems unable to see it alone */
#define cpuid(index, eax, ebx, ecx, edx) \
__asm__ volatile ( \
@@ -90,6 +101,10 @@
#define cpuid_test() 1
+#elif HAVE_YASM
+
+#define cpuid_test ff_cpu_cpuid_test
+
#elif HAVE_INLINE_ASM || HAVE_RWEFLAGS
static int cpuid_test(void)
diff --git a/libavutil/x86/cpu.h b/libavutil/x86/cpu.h
index e14cb57416..e4f6f0bd5a 100644
--- a/libavutil/x86/cpu.h
+++ b/libavutil/x86/cpu.h
@@ -54,4 +54,8 @@
#define INLINE_AVX(flags) CPUEXT(flags, _INLINE, AVX)
#define INLINE_FMA4(flags) CPUEXT(flags, _INLINE, FMA4)
+void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx);
+void ff_cpu_xgetbv(int op, int *eax, int *edx);
+int ff_cpu_cpuid_test(void);
+
#endif /* AVUTIL_X86_CPU_H */
diff --git a/libavutil/x86/cpuid.asm b/libavutil/x86/cpuid.asm
new file mode 100644
index 0000000000..d2ac1f01dc
--- /dev/null
+++ b/libavutil/x86/cpuid.asm
@@ -0,0 +1,91 @@
+;*****************************************************************************
+;* Copyright (C) 2005-2010 x264 project
+;*
+;* Authors: Loren Merritt <lorenm@u.washington.edu>
+;* Jason Garrett-Glaser <darkshikari@gmail.com>
+;*
+;* This file is part of Libav.
+;*
+;* Libav 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,
+;* 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
+;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+
+SECTION .text
+
+;-----------------------------------------------------------------------------
+; void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx)
+;-----------------------------------------------------------------------------
+cglobal cpu_cpuid, 5,7
+ push rbx
+ push r4
+ push r3
+ push r2
+ push r1
+ mov eax, r0d
+ xor ecx, ecx
+ cpuid
+ pop r4
+ mov [r4], eax
+ pop r4
+ mov [r4], ebx
+ pop r4
+ mov [r4], ecx
+ pop r4
+ mov [r4], edx
+ pop rbx
+ RET
+
+;-----------------------------------------------------------------------------
+; void ff_cpu_xgetbv(int op, int *eax, int *edx)
+;-----------------------------------------------------------------------------
+cglobal cpu_xgetbv, 3,7
+ push r2
+ push r1
+ mov ecx, r0d
+ xgetbv
+ pop r4
+ mov [r4], eax
+ pop r4
+ mov [r4], edx
+ RET
+
+%if ARCH_X86_64 == 0
+;-----------------------------------------------------------------------------
+; int ff_cpu_cpuid_test(void)
+; return 0 if unsupported
+;-----------------------------------------------------------------------------
+cglobal cpu_cpuid_test
+ pushfd
+ push ebx
+ push ebp
+ push esi
+ push edi
+ pushfd
+ pop eax
+ mov ebx, eax
+ xor eax, 0x200000
+ push eax
+ popfd
+ pushfd
+ pop eax
+ xor eax, ebx
+ pop edi
+ pop esi
+ pop ebp
+ pop ebx
+ popfd
+ ret
+%endif