]> git.sesse.net Git - x264/commitdiff
Check for OS AVX support in addition to CPUID
authorFiona Glaser <fiona@x264.com>
Thu, 27 Jan 2011 13:33:25 +0000 (05:33 -0800)
committerFiona Glaser <fiona@x264.com>
Thu, 27 Jan 2011 13:40:15 +0000 (05:40 -0800)
Even if not using ymm registers, AVX operations will cause SIGILLs on unsupported OSs.
On Windows, AVX is only available on Windows 7 SP1 or later.

common/cpu.c
common/x86/cpu-a.asm
x264.h

index 742254cb927567951b79e260306f1210880699db..8d4f63522d345f65d19f3b4a36e09cac0296d68b 100644 (file)
@@ -94,7 +94,8 @@ static void sigill_handler( int sig )
 
 #if HAVE_MMX
 int x264_cpu_cpuid_test( void );
-uint32_t x264_cpu_cpuid( uint32_t op, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx );
+void x264_cpu_cpuid( uint32_t op, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx );
+void x264_cpu_xgetbv( uint32_t op, int *eax, int *edx );
 
 uint32_t x264_cpu_detect( void )
 {
@@ -130,8 +131,14 @@ uint32_t x264_cpu_detect( void )
         cpu |= X264_CPU_SSE4;
     if( ecx&0x00100000 )
         cpu |= X264_CPU_SSE42;
-    if( ecx&0x10000000 )
-        cpu |= X264_CPU_AVX;
+    /* Check OXSAVE and AVX bits */
+    if( (ecx&0x18000000) == 0x18000000 )
+    {
+        /* Check for OS support */
+        x264_cpu_xgetbv( 0, &eax, &edx );
+        if( (eax&0x6) == 0x6 )
+            cpu |= X264_CPU_AVX;
+    }
 
     if( cpu & X264_CPU_SSSE3 )
         cpu |= X264_CPU_SSE2_IS_FAST;
index d4033af86faaa5199bf1d05c7215a5e95d9e4194..75a2bc493959bff8c23c492e4ba1d7e3365e982d 100644 (file)
 
 SECTION .text
 
-%ifdef ARCH_X86_64
-
 ;-----------------------------------------------------------------------------
-; int cpu_cpuid( int op, int *eax, int *ebx, int *ecx, int *edx )
+; void cpu_cpuid( int op, int *eax, int *ebx, int *ecx, int *edx )
 ;-----------------------------------------------------------------------------
 cglobal cpu_cpuid, 5,7
-    push    rbx
-    mov     r11,   r1
-    mov     r10,   r2
-    movifnidn r9,  r3
-    movifnidn r8,  r4
-    mov     eax,   r0d
+    push rbx
+    push  r4
+    push  r3
+    push  r2
+    push  r1
+    mov  eax, r0d
     cpuid
-    mov     [r11], eax
-    mov     [r10], ebx
-    mov     [r9],  ecx
-    mov     [r8],  edx
-    pop     rbx
+    pop  rsi
+    mov [rsi], eax
+    pop  rsi
+    mov [rsi], ebx
+    pop  rsi
+    mov [rsi], ecx
+    pop  rsi
+    mov [rsi], edx
+    pop  rbx
+    RET
+
+;-----------------------------------------------------------------------------
+; void cpu_xgetbv( int op, int *eax, int *edx )
+;-----------------------------------------------------------------------------
+cglobal cpu_xgetbv, 3,7
+    push  r2
+    push  r1
+    mov  ecx, r0d
+    xgetbv
+    pop  rsi
+    mov [rsi], eax
+    pop  rsi
+    mov [rsi], edx
     RET
 
-%else
+%ifndef ARCH_X86_64
 
 ;-----------------------------------------------------------------------------
 ; int cpu_cpuid_test( void )
@@ -77,22 +93,6 @@ cglobal cpu_cpuid_test
     popfd
     ret
 
-;-----------------------------------------------------------------------------
-; int cpu_cpuid( int op, int *eax, int *ebx, int *ecx, int *edx )
-;-----------------------------------------------------------------------------
-cglobal cpu_cpuid, 0,6
-    mov     eax,    r0m
-    cpuid
-    mov     esi,    r1m
-    mov     [esi],  eax
-    mov     esi,    r2m
-    mov     [esi],  ebx
-    mov     esi,    r3m
-    mov     [esi],  ecx
-    mov     esi,    r4m
-    mov     [esi],  edx
-    RET
-
 ;-----------------------------------------------------------------------------
 ; void stack_align( void (*func)(void*), void *arg );
 ;-----------------------------------------------------------------------------
diff --git a/x264.h b/x264.h
index 3c91c90410c92ead69f3ba4c6d2ab29e9f41f26c..8f505b12cae22f94658cea00a7acaa3436663384 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -122,9 +122,8 @@ typedef struct
 #define X264_CPU_FAST_NEON_MRC  0x080000  /* Transfer from NEON to ARM register is fast (Cortex-A9) */
 #define X264_CPU_SLOW_CTZ       0x100000  /* BSR/BSF x86 instructions are really slow on some CPUs */
 #define X264_CPU_SLOW_ATOM      0x200000  /* The Atom just sucks */
-#define X264_CPU_AVX            0x400000  /* AVX support -- we don't currently use YMM registers, just
-                                           * the 3-operand capability, so we don't require OS support
-                                           * for AVX. */
+#define X264_CPU_AVX            0x400000  /* AVX support: requires OS support even if YMM registers
+                                           * aren't used. */
 
 /* Analyse flags
  */