cpu.c: Merge ia32 and x86_64 CPU info functions
authorErik de Castro Lopo <erikd@mega-nerd.com>
Mon, 27 Feb 2017 09:35:21 +0000 (20:35 +1100)
committerErik de Castro Lopo <erikd@mega-nerd.com>
Mon, 27 Feb 2017 09:41:25 +0000 (20:41 +1100)
After the removal of the OS SSE detection stuff ia32_cpu_info()
and x86_64_cpu_info() became very similar. Merging them makes
sense.

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

src/libFLAC/cpu.c
src/libFLAC/ia32/cpu_asm.nasm
src/libFLAC/include/private/cpu.h
src/libFLAC/stream_decoder.c
src/libFLAC/stream_encoder.c

index 4bad89c..67a076d 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#if defined(_MSC_VER)
-#  include <intrin.h> /* for __cpuid() and _xgetbv() */
-#endif
-
-#if defined __GNUC__ && defined HAVE_CPUID_H
-#  include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
+#if defined _MSC_VER
+#include <intrin.h> /* for __cpuid() and _xgetbv() */
+#elif defined __GNUC__ && defined HAVE_CPUID_H
+#include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
 #endif
 
 #ifndef NDEBUG
 #include <stdio.h>
-
 #define dfprintf fprintf
 #else
 /* This is bad practice, it should be a static void empty function */
 #endif
 
 
-#if defined FLAC__CPU_IA32
+#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM
+
 /* these are flags in EDX of CPUID AX=00000001 */
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
-#endif
+static const uint32_t FLAC__CPUINFO_X86_CPUID_CMOV    = 0x00008000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_MMX     = 0x00800000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE     = 0x02000000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE2    = 0x04000000;
 
-#if FLAC__HAS_X86INTRIN || FLAC__AVX_SUPPORTED || defined FLAC__HAS_NASM
 /* these are flags in ECX of CPUID AX=00000001 */
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE3    = 0x00000001;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_SSSE3   = 0x00000200;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE41   = 0x00080000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_SSE42   = 0x00100000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_OSXSAVE = 0x08000000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_AVX     = 0x10000000;
+static const uint32_t FLAC__CPUINFO_X86_CPUID_FMA     = 0x00001000;
 
-/* these are flags in ECX of CPUID AX=00000001 */
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000;
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000;
 /* these are flags in EBX of CPUID AX=00000007 */
-static const uint32_t FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020;
-#endif
+static const uint32_t FLAC__CPUINFO_X86_CPUID_AVX2    = 0x00000020;
 
-#if defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64
 static uint32_t
 cpu_xgetbv_x86(void)
 {
-#if (defined _MSC_VER || defined __INTEL_COMPILER) && FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED
+#if (defined _MSC_VER || defined __INTEL_COMPILER) && FLAC__AVX_SUPPORTED
        return (uint32_t)_xgetbv(0);
 #elif defined __GNUC__
        uint32_t lo, hi;
@@ -94,144 +87,146 @@ cpu_xgetbv_x86(void)
        return 0;
 #endif
 }
+
+static uint32_t
+cpu_have_cpuid(void)
+{
+#if defined FLAC__CPU_X86_64 || defined __i686__ || defined __SSE__ || (defined _M_IX86_FP && _M_IX86_FP > 0)
+       /* target CPU does have CPUID instruction */
+       return 1;
+#elif defined FLAC__HAS_NASM
+       return FLAC__cpu_have_cpuid_asm_ia32();
+#elif defined __GNUC__ && defined HAVE_CPUID_H
+       if (__get_cpuid_max(0, 0) != 0)
+               return 1;
+       else
+               return 0;
+#elif defined _MSC_VER
+       FLAC__uint32 flags1, flags2;
+       __asm {
+               pushfd
+               pushfd
+               pop             eax
+               mov             flags1, eax
+               xor             eax, 0x200000
+               push    eax
+               popfd
+               pushfd
+               pop             eax
+               mov             flags2, eax
+               popfd
+       }
+       if (((flags1^flags2) & 0x200000) != 0)
+               return 1;
+       else
+               return 0;
+#else
+       return 0;
 #endif
+}
 
 static void
-ia32_cpu_info (FLAC__CPUInfo *info)
+cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
 {
-#if !defined FLAC__CPU_IA32
-       (void) info;
+#if defined _MSC_VER
+       int cpuinfo[4];
+       int ext = level & 0x80000000;
+       __cpuid(cpuinfo, ext);
+       if ((uint32_t)cpuinfo[0] >= level) {
+#if FLAC__AVX_SUPPORTED
+               __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */
 #else
-       FLAC__bool ia32_osxsave = false;
-       FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
-
-#if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN)
-       info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */
-#if defined FLAC__HAS_NASM
-       if(!FLAC__cpu_have_cpuid_asm_ia32())
-               return;
-#endif
-       /* http://www.sandpile.org/x86/cpuid.htm */
-       if (FLAC__HAS_X86INTRIN) {
-               FLAC__cpu_info_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
-               info->ia32.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */
-               FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
-       }
-       else {
-#if FLAC__HAS_NASM
-               FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
+               __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */
 #endif
+               *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3];
+               return;
        }
-
-       info->ia32.cmov  = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV ) ? true : false;
-       info->ia32.mmx   = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX  ) ? true : false;
-       info->ia32.sse   = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE  ) ? true : false;
-       info->ia32.sse2  = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 ) ? true : false;
-       info->ia32.sse3  = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 ) ? true : false;
-       info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3) ? true : false;
-       info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41) ? true : false;
-       info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42) ? true : false;
-
-       if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
-               ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false;
-               info->ia32.avx   = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX    ) ? true : false;
-               info->ia32.fma   = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA    ) ? true : false;
-               FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
-               info->ia32.avx2  = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2   ) ? true : false;
-       }
-
-       dfprintf(stderr, "CPU info (IA-32):\n");
-       dfprintf(stderr, "  CMOV ....... %c\n", info->ia32.cmov    ? 'Y' : 'n');
-       dfprintf(stderr, "  MMX ........ %c\n", info->ia32.mmx     ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE ........ %c\n", info->ia32.sse     ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE2 ....... %c\n", info->ia32.sse2    ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE3 ....... %c\n", info->ia32.sse3    ? 'Y' : 'n');
-       dfprintf(stderr, "  SSSE3 ...... %c\n", info->ia32.ssse3   ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE41 ...... %c\n", info->ia32.sse41   ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE42 ...... %c\n", info->ia32.sse42   ? 'Y' : 'n');
-
-       if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
-               dfprintf(stderr, "  AVX ........ %c\n", info->ia32.avx     ? 'Y' : 'n');
-               dfprintf(stderr, "  FMA ........ %c\n", info->ia32.fma     ? 'Y' : 'n');
-               dfprintf(stderr, "  AVX2 ....... %c\n", info->ia32.avx2    ? 'Y' : 'n');
-       }
-
-       /*
-        * now have to check for OS support of AVX instructions
-        */
-       if (!FLAC__HAS_X86INTRIN || !info->ia32.avx || !ia32_osxsave || (cpu_xgetbv_x86() & 0x6) != 0x6) {
-               /* no OS AVX support */
-               info->ia32.avx     = false;
-               info->ia32.avx2    = false;
-               info->ia32.fma     = false;
-       }
-
-       if (FLAC__HAS_X86INTRIN && FLAC__AVX_SUPPORTED) {
-               dfprintf(stderr, "  AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n');
+#elif defined __GNUC__ && defined HAVE_CPUID_H
+       FLAC__uint32 ext = level & 0x80000000;
+       __cpuid(ext, *eax, *ebx, *ecx, *edx);
+       if (*eax >= level) {
+               __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
+               return;
        }
-#else
-       info->use_asm = false;
-#endif
+#elif defined FLAC__HAS_NASM && defined FLAC__CPU_IA32
+       FLAC__cpu_info_asm_ia32(level, eax, ebx, ecx, edx);
+       return;
 #endif
+       *eax = *ebx = *ecx = *edx = 0;
 }
 
+#endif
+
 static void
-x86_64_cpu_info (FLAC__CPUInfo *info)
+x86_cpu_info (FLAC__CPUInfo *info)
 {
-#if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN
+#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM
        FLAC__bool x86_osxsave = false;
+       FLAC__bool os_avx = false;
        FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
 
-       info->use_asm = true;
+       info->use_asm = true; /* we assume a minimum of 80386 */
+       if (!cpu_have_cpuid())
+               return;
 
-       /* http://www.sandpile.org/x86/cpuid.htm */
-       FLAC__cpu_info_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
+       cpuinfo_x86(0, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
        info->x86.intel = (flags_ebx == 0x756E6547 && flags_edx == 0x49656E69 && flags_ecx == 0x6C65746E) ? true : false; /* GenuineIntel */
-       FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
-       info->x86.sse3  = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 ) ? true : false;
-       info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3) ? true : false;
-       info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41) ? true : false;
-       info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42) ? true : false;
+       cpuinfo_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
+
+       info->x86.cmov  = (flags_edx & FLAC__CPUINFO_X86_CPUID_CMOV ) ? true : false;
+       info->x86.mmx   = (flags_edx & FLAC__CPUINFO_X86_CPUID_MMX  ) ? true : false;
+       info->x86.sse   = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE  ) ? true : false;
+       info->x86.sse2  = (flags_edx & FLAC__CPUINFO_X86_CPUID_SSE2 ) ? true : false;
+       info->x86.sse3  = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE3 ) ? true : false;
+       info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSSE3) ? true : false;
+       info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE41) ? true : false;
+       info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE42) ? true : false;
 
        if (FLAC__AVX_SUPPORTED) {
-               x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false;
-               info->x86.avx   = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX    ) ? true : false;
-               info->x86.fma   = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA    ) ? true : false;
-               FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
-               info->x86.avx2  = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2   ) ? true : false;
+               x86_osxsave     = (flags_ecx & FLAC__CPUINFO_X86_CPUID_OSXSAVE) ? true : false;
+               info->x86.avx   = (flags_ecx & FLAC__CPUINFO_X86_CPUID_AVX    ) ? true : false;
+               info->x86.fma   = (flags_ecx & FLAC__CPUINFO_X86_CPUID_FMA    ) ? true : false;
+               cpuinfo_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx);
+               info->x86.avx2  = (flags_ebx & FLAC__CPUINFO_X86_CPUID_AVX2   ) ? true : false;
        }
 
+#if defined FLAC__CPU_IA32
+       dfprintf(stderr, "CPU info (IA-32):\n");
+#else
        dfprintf(stderr, "CPU info (x86-64):\n");
-       dfprintf(stderr, "  SSE3 ....... %c\n", info->x86.sse3  ? 'Y' : 'n');
-       dfprintf(stderr, "  SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
-       dfprintf(stderr, "  SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
+#endif
+       dfprintf(stderr, "  CMOV ....... %c\n", info->x86.cmov    ? 'Y' : 'n');
+       dfprintf(stderr, "  MMX ........ %c\n", info->x86.mmx     ? 'Y' : 'n');
+       dfprintf(stderr, "  SSE ........ %c\n", info->x86.sse     ? 'Y' : 'n');
+       dfprintf(stderr, "  SSE2 ....... %c\n", info->x86.sse2    ? 'Y' : 'n');
+       dfprintf(stderr, "  SSE3 ....... %c\n", info->x86.sse3    ? 'Y' : 'n');
+       dfprintf(stderr, "  SSSE3 ...... %c\n", info->x86.ssse3   ? 'Y' : 'n');
+       dfprintf(stderr, "  SSE41 ...... %c\n", info->x86.sse41   ? 'Y' : 'n');
+       dfprintf(stderr, "  SSE42 ...... %c\n", info->x86.sse42   ? 'Y' : 'n');
 
        if (FLAC__AVX_SUPPORTED) {
-               dfprintf(stderr, "  AVX ........ %c\n", info->x86.avx   ? 'Y' : 'n');
-               dfprintf(stderr, "  FMA ........ %c\n", info->x86.fma   ? 'Y' : 'n');
-               dfprintf(stderr, "  AVX2 ....... %c\n", info->x86.avx2  ? 'Y' : 'n');
+               dfprintf(stderr, "  AVX ........ %c\n", info->x86.avx     ? 'Y' : 'n');
+               dfprintf(stderr, "  FMA ........ %c\n", info->x86.fma     ? 'Y' : 'n');
+               dfprintf(stderr, "  AVX2 ....... %c\n", info->x86.avx2    ? 'Y' : 'n');
        }
 
        /*
         * now have to check for OS support of AVX instructions
         */
-       if (!info->x86.avx || !x86_osxsave || (cpu_xgetbv_x86() & 0x6) != 0x6) {
+       if (FLAC__AVX_SUPPORTED && info->x86.avx && x86_osxsave && (cpu_xgetbv_x86() & 0x6) == 0x6) {
+               os_avx = true;
+       }
+       if (os_avx) {
+               dfprintf(stderr, "  AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
+       }
+       if (!os_avx) {
                /* no OS AVX support */
                info->x86.avx     = false;
                info->x86.avx2    = false;
                info->x86.fma     = false;
        }
-
-       if (FLAC__AVX_SUPPORTED) {
-               dfprintf(stderr, "  AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n');
-       }
 #else
-       /* Silence compiler warnings. */
-       (void) info;
-#if defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64
-       if (0) cpu_xgetbv_x86 ();
-#endif
+       info->use_asm = false;
 #endif
 }
 
@@ -245,51 +240,15 @@ void FLAC__cpu_info (FLAC__CPUInfo *info)
        info->type = FLAC__CPUINFO_TYPE_X86_64;
 #else
        info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
-       info->use_asm = false;
 #endif
 
        switch (info->type) {
-       case FLAC__CPUINFO_TYPE_IA32:
-               ia32_cpu_info (info);
-               break;
+       case FLAC__CPUINFO_TYPE_IA32: /* fallthrough */
        case FLAC__CPUINFO_TYPE_X86_64:
-               x86_64_cpu_info (info);
+               x86_cpu_info (info);
                break;
        default:
                info->use_asm = false;
                break;
        }
 }
-
-#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN
-
-void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
-{
-#if defined _MSC_VER || defined __INTEL_COMPILER
-       int cpuinfo[4];
-       int ext = level & 0x80000000;
-       __cpuid(cpuinfo, ext);
-       if((uint32_t)cpuinfo[0] >= level) {
-#if FLAC__AVX_SUPPORTED
-               __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */
-#else
-               __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */
-#endif
-
-               *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3];
-
-               return;
-       }
-#elif defined __GNUC__ && defined HAVE_CPUID_H
-       FLAC__uint32 ext = level & 0x80000000;
-       __cpuid(ext, *eax, *ebx, *ecx, *edx);
-       if (*eax >= level) {
-               __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
-
-               return;
-       }
-#endif
-       *eax = *ebx = *ecx = *edx = 0;
-}
-
-#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
index 31baa0a..dc031d5 100644 (file)
@@ -61,37 +61,57 @@ cident FLAC__cpu_have_cpuid_asm_ia32
        popfd
        ret
 
+
 ; **********************************************************************
 ;
-; void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx)
+; void FLAC__cpu_info_asm_ia32(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx)
 ;
 
 cident FLAC__cpu_info_asm_ia32
-       ;[esp + 8] == flags_edx
-       ;[esp + 12] == flags_ecx
+       ;[esp + 8] == level
+       ;[esp + 12] == flags_eax
+       ;[esp + 16] == flags_ebx
+       ;[esp + 20] == flags_ecx
+       ;[esp + 24] == flags_edx
 
        push    ebx
        call    FLAC__cpu_have_cpuid_asm_ia32
        test    eax, eax
        jz      .no_cpuid
-       mov     eax, 0
+
+       mov     eax, [esp + 8]
+       and     eax, 0x80000000
        cpuid
-       cmp     eax, 1
+       cmp     eax, [esp + 8]
        jb      .no_cpuid
        xor     ecx, ecx
-       mov     eax, 1
+       mov     eax, [esp + 8]
        cpuid
-       mov     ebx, [esp + 8]
-       mov     [ebx], edx
-       mov     ebx, [esp + 12]
+
+       push    ebx
+       ;[esp + 16] == flags_eax
+       mov     ebx, [esp + 16]
+       mov     [ebx], eax
+       pop     eax
+       ;[esp + 16] == flags_ebx
+       mov     ebx, [esp + 16]
+       mov     [ebx], eax
+       mov     ebx, [esp + 20]
        mov     [ebx], ecx
+       mov     ebx, [esp + 24]
+       mov     [ebx], edx
        jmp     .end
+
 .no_cpuid:
        xor     eax, eax
-       mov     ebx, [esp + 8]
-       mov     [ebx], eax
        mov     ebx, [esp + 12]
        mov     [ebx], eax
+       mov     ebx, [esp + 16]
+       mov     [ebx], eax
+       mov     ebx, [esp + 20]
+       mov     [ebx], eax
+       mov     ebx, [esp + 24]
+       mov     [ebx], eax
 .end:
        pop     ebx
        ret
index d09f090..3fe279b 100644 (file)
@@ -171,25 +171,12 @@ typedef struct {
        FLAC__bool avx;
        FLAC__bool avx2;
        FLAC__bool fma;
-} FLAC__CPUInfo_IA32;
-
-typedef struct {
-       FLAC__bool intel;
-
-       FLAC__bool sse3;
-       FLAC__bool ssse3;
-       FLAC__bool sse41;
-       FLAC__bool sse42;
-       FLAC__bool avx;
-       FLAC__bool avx2;
-       FLAC__bool fma;
 } FLAC__CPUInfo_x86;
 
 
 typedef struct {
        FLAC__bool use_asm;
        FLAC__CPUInfo_Type type;
-       FLAC__CPUInfo_IA32 ia32;
        FLAC__CPUInfo_x86 x86;
 } FLAC__CPUInfo;
 
@@ -197,8 +184,6 @@ void FLAC__cpu_info(FLAC__CPUInfo *info);
 
 FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
 
-void         FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
-
-void         FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
+void         FLAC__cpu_info_asm_ia32(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
 
 #endif
index f49fd1e..14d5fe7 100644 (file)
@@ -384,7 +384,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
                FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
 #ifdef FLAC__HAS_NASM
                decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
-               if(decoder->private_->cpuinfo.ia32.mmx) {
+               if (decoder->private_->cpuinfo.x86.mmx) {
                        decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32;
                        decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx;
                }
@@ -395,7 +395,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
 #endif
 #if FLAC__HAS_X86INTRIN && ! defined FLAC__INTEGER_ONLY_LIBRARY
 # if defined FLAC__SSE4_1_SUPPORTED
-               if(decoder->private_->cpuinfo.ia32.sse41) {
+               if (decoder->private_->cpuinfo.x86.sse41) {
                        decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_intrin_sse41;
                        decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse41;
                        decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41;
index 665fe55..32df4d3 100644 (file)
@@ -889,7 +889,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
 #  ifdef FLAC__CPU_IA32
                FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
 #   ifdef FLAC__HAS_NASM
-               if(encoder->private_->cpuinfo.ia32.sse) {
+               if (encoder->private_->cpuinfo.x86.sse) {
                        if(encoder->protected_->max_lpc_order < 4)
                                encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old;
                        else if(encoder->protected_->max_lpc_order < 8)
@@ -905,7 +905,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
                        encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32;
 
                encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */
-               if(encoder->private_->cpuinfo.ia32.mmx) {
+               if (encoder->private_->cpuinfo.x86.mmx) {
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx;
                }
@@ -914,13 +914,13 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32;
                }
 
-               if(encoder->private_->cpuinfo.ia32.mmx && encoder->private_->cpuinfo.ia32.cmov)
+               if (encoder->private_->cpuinfo.x86.mmx && encoder->private_->cpuinfo.x86.cmov)
                        encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
 #   endif /* FLAC__HAS_NASM */
 #   if FLAC__HAS_X86INTRIN
 #    if defined FLAC__SSE_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.sse) {
-                       if(encoder->private_->cpuinfo.ia32.sse42 || !encoder->private_->cpuinfo.ia32.intel) { /* use new autocorrelation functions */
+               if (encoder->private_->cpuinfo.x86.sse) {
+                       if (encoder->private_->cpuinfo.x86.sse42 || !encoder->private_->cpuinfo.x86.intel) { /* use new autocorrelation functions */
                                if(encoder->protected_->max_lpc_order < 4)
                                        encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new;
                                else if(encoder->protected_->max_lpc_order < 8)
@@ -948,19 +948,19 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
 #    endif
 
 #    ifdef FLAC__SSE2_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.sse2) {
+               if (encoder->private_->cpuinfo.x86.sse2) {
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients       = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2;
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2;
                }
 #    endif
 #    ifdef FLAC__SSE4_1_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.sse41) {
+               if (encoder->private_->cpuinfo.x86.sse41) {
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients       = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41;
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41;
                }
 #    endif
 #    ifdef FLAC__AVX2_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.avx2) {
+               if (encoder->private_->cpuinfo.x86.avx2) {
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2;
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients       = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2;
                        encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2;
@@ -968,13 +968,13 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
 #    endif
 
 #    ifdef FLAC__SSE2_SUPPORTED
-               if (encoder->private_->cpuinfo.ia32.sse2) {
+               if (encoder->private_->cpuinfo.x86.sse2) {
                        encoder->private_->local_fixed_compute_best_predictor      = FLAC__fixed_compute_best_predictor_intrin_sse2;
                        encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2;
                }
 #    endif
 #    ifdef FLAC__SSSE3_SUPPORTED
-               if (encoder->private_->cpuinfo.ia32.ssse3) {
+               if (encoder->private_->cpuinfo.x86.ssse3) {
                        encoder->private_->local_fixed_compute_best_predictor      = FLAC__fixed_compute_best_predictor_intrin_ssse3;
                        encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3;
                }
@@ -1041,15 +1041,15 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
        if(encoder->private_->cpuinfo.use_asm) {
 # if defined FLAC__CPU_IA32
 #  ifdef FLAC__SSE2_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.sse2)
+               if (encoder->private_->cpuinfo.x86.sse2)
                        encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2;
 #  endif
 #  ifdef FLAC__SSSE3_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.ssse3)
+               if (encoder->private_->cpuinfo.x86.ssse3)
                        encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3;
 #  endif
 #  ifdef FLAC__AVX2_SUPPORTED
-               if(encoder->private_->cpuinfo.ia32.avx2)
+               if (encoder->private_->cpuinfo.x86.avx2)
                        encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2;
 #  endif
 # elif defined FLAC__CPU_X86_64