]> git.sesse.net Git - ffmpeg/commitdiff
x86: Add YASM implementations of cpuid and xgetbv from x264
authorDiego Biurrun <diego@biurrun.de>
Wed, 3 Oct 2012 14:46:17 +0000 (16:46 +0200)
committerDiego Biurrun <diego@biurrun.de>
Thu, 4 Oct 2012 17:29:14 +0000 (19:29 +0200)
This allows detecting CPU features with builds that have neither
gcc inline assembly nor the right compiler intrinsics enabled.

libavutil/x86/Makefile
libavutil/x86/cpu.c
libavutil/x86/cpu.h
libavutil/x86/cpuid.asm [new file with mode: 0644]

index 454635366915a7fa00acd2af2e54a5623d1f1dd8..3dd696c26a20ad42b3d018870f5fae12b84e3a60 100644 (file)
@@ -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                                            \
index 5de60147c65f57597923b11bf9d77aa1cf3995ca..fb1dd299bc540ecd1921a48b26c512e20213d441 100644 (file)
 
 #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 (                                          \
 
 #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)
index e14cb57416c5126887dfa0246ac2364e72b7b233..e4f6f0bd5a2094425020fbc2851258b824277e9d 100644 (file)
@@ -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 (file)
index 0000000..d2ac1f0
--- /dev/null
@@ -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