[FFmpeg-cvslog] x86: Add YASM implementations of cpuid and xgetbv from x264
Diego Biurrun
git at videolan.org
Fri Oct 5 17:08:42 CEST 2012
ffmpeg | branch: master | Diego Biurrun <diego at biurrun.de> | Wed Oct 3 16:46:17 2012 +0200| [1f6d86991f191568d45484f2b3740c2dcd0a7b45] | committer: Diego Biurrun
x86: Add YASM implementations of cpuid and xgetbv from x264
This allows detecting CPU features with builds that have neither
gcc inline assembly nor the right compiler intrinsics enabled.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1f6d86991f191568d45484f2b3740c2dcd0a7b45
---
libavutil/x86/Makefile | 3 +-
libavutil/x86/cpu.c | 17 ++++++++-
libavutil/x86/cpu.h | 4 +++
libavutil/x86/cpuid.asm | 91 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/libavutil/x86/Makefile b/libavutil/x86/Makefile
index 4546353..3dd696c 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 5de6014..fb1dd29 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 e14cb57..e4f6f0b 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 0000000..d2ac1f0
--- /dev/null
+++ b/libavutil/x86/cpuid.asm
@@ -0,0 +1,91 @@
+;*****************************************************************************
+;* Copyright (C) 2005-2010 x264 project
+;*
+;* Authors: Loren Merritt <lorenm at u.washington.edu>
+;* Jason Garrett-Glaser <darkshikari at 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
More information about the ffmpeg-cvslog
mailing list