libFLAC: CPUID detecion improvements.
authorErik de Castro Lopo <erikd@mega-nerd.com>
Sat, 28 Jun 2014 11:50:09 +0000 (21:50 +1000)
committerErik de Castro Lopo <erikd@mega-nerd.com>
Sat, 28 Jun 2014 12:25:18 +0000 (22:25 +1000)
According to docs, it's incorrect to just call CPUID with EAX=1.
One must to ensure that this value is supported.

CPUs that don't support CPUID level 1 are very old, but...
if FLAC tests CPUID presence it should also test CPUID level support.

Also the function FLAC__cpu_have_cpuid_asm_ia32 was simplified
according to the docs at Intel website and in Wikipedia.

Patch-from: lvqcl <lvqcl.mail@gmail.com>

src/libFLAC/cpu.c
src/libFLAC/ia32/cpu_asm.nasm

index 383f823..136b5a7 100644 (file)
@@ -565,6 +565,11 @@ void FLAC__cpu_info_x86(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx)
 {
 #if defined _MSC_VER || defined __INTEL_COMPILER
        int cpuinfo[4];
+       __cpuid(cpuinfo, 0);
+       if(cpuinfo[0] < 1) {
+               *flags_ecx = *flags_edx = 0;
+               return;
+       }
        __cpuid(cpuinfo, 1);
        *flags_ecx = cpuinfo[2];
        *flags_edx = cpuinfo[3];
index c73ae02..289d86c 100644 (file)
@@ -47,7 +47,6 @@ cglobal FLAC__cpu_info_extended_amd_asm_ia32
 ;
 
 cident FLAC__cpu_have_cpuid_asm_ia32
-       push    ebx
        pushfd
        pop     eax
        mov     edx, eax
@@ -56,14 +55,11 @@ cident FLAC__cpu_have_cpuid_asm_ia32
        popfd
        pushfd
        pop     eax
-       cmp     eax, edx
-       jz      .no_cpuid
-       mov     eax, 1
-       jmp     .end
-.no_cpuid:
-       xor     eax, eax
-.end:
-       pop     ebx
+       xor     eax, edx
+       and     eax, 0x00200000
+       shr     eax, 0x15
+       push    edx
+       popfd
        ret
 
 ; **********************************************************************
@@ -79,6 +75,10 @@ cident FLAC__cpu_info_asm_ia32
        call    FLAC__cpu_have_cpuid_asm_ia32
        test    eax, eax
        jz      .no_cpuid
+       mov     eax, 0
+       cpuid
+       cmp     eax, 1
+       jb      .no_cpuid
        mov     eax, 1
        cpuid
        mov     ebx, [esp + 8]