[libav-commits] x86: Add YASM implementations of cpuid and xgetbv from x264

Diego Biurrun git at libav.org
Thu Oct 4 19:41:43 CEST 2012


Module: libav
Branch: master
Commit: 1f6d86991f191568d45484f2b3740c2dcd0a7b45

Author:    Diego Biurrun <diego at biurrun.de>
Committer: Diego Biurrun <diego at biurrun.de>
Date:      Wed Oct  3 16:46:17 2012 +0200

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.

---

 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 libav-commits mailing list