From a60231f4363e1c0fc9eac2e4443d1f2a9915170e Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Mon, 13 Aug 2001 22:32:40 +0000 Subject: [PATCH] Miroslav's patch to add run-time detection of operating system support for SSE/SSE2 instructions --- src/libFLAC/cpu.c | 37 ++++++++++++++++++++++++++----- src/libFLAC/ia32/cpu_asm.nasm | 18 +++------------ src/libFLAC/include/private/cpu.h | 2 +- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/libFLAC/cpu.c b/src/libFLAC/cpu.c index 4cc9ac5d..8b71ffba 100644 --- a/src/libFLAC/cpu.c +++ b/src/libFLAC/cpu.c @@ -21,6 +21,12 @@ #include #include +#if !defined(FLAC__NO_ASM) && defined(FLAC__CPU_IA32) && defined(FLAC__HAS_NASM) && !defined(FLAC__SSE_OS) && !defined(NO_VFORK) +#include +#include +#include +#endif + const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; @@ -44,17 +50,36 @@ void FLAC__cpu_info(FLAC__CPUInfo *info) info->data.ia32.mmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_MMX)? true : false; info->data.ia32.fxsr = (cpuid & FLAC__CPUINFO_IA32_CPUID_FXSR)? true : false; info->data.ia32.sse = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE)? true : false; - info->data.ia32.sse2 = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE2)? true : false; /* @@@ also need to check for operating system support? */ + info->data.ia32.sse2 = (cpuid & FLAC__CPUINFO_IA32_CPUID_SSE2)? true : false; + +#ifndef FLAC__SSE_OS +#ifndef NO_VFORK + if(info->data.ia32.sse == true || info->data.ia32.sse2 == true) { + int pid, status, sse; + pid = vfork(); + if(!pid) { + FLAC__cpu_info_sse_test_asm_ia32(); + exit(0); + } + sse = 0; + if(pid > 0) { + waitpid(pid, &status, 0); + if(WIFEXITED(status) && WEXITSTATUS(status) == 0) + sse = 1; /* there was normal exit, no SIGILL */ + } + if(!sse) + info->data.ia32.sse = info->data.ia32.sse2 = false; + } +#else + /* we are assuming OS isn't supporting SSE */ + info->data.ia32.sse = info->data.ia32.sse2 = false; +#endif +#endif cpuid = FLAC__cpu_info_extended_amd_asm_ia32(); info->data.ia32._3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW)? true : false; info->data.ia32.ext3dnow = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false; info->data.ia32.extmmx = (cpuid & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX)? true : false; - -#ifndef FLAC__SSE_OS - if(!FLAC__cpu_info_sse_os_asm_ia32()) /* this function currently always returns false */ - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = false; -#endif } #else info->use_asm = false; diff --git a/src/libFLAC/ia32/cpu_asm.nasm b/src/libFLAC/ia32/cpu_asm.nasm index c3323cb8..2da60196 100644 --- a/src/libFLAC/ia32/cpu_asm.nasm +++ b/src/libFLAC/ia32/cpu_asm.nasm @@ -22,7 +22,7 @@ cglobal FLAC__cpu_info_asm_ia32 cglobal FLAC__cpu_info_extended_amd_asm_ia32 -cglobal FLAC__cpu_info_sse_os_asm_ia32 +cglobal FLAC__cpu_info_sse_test_asm_ia32 code_section @@ -81,20 +81,8 @@ cident FLAC__cpu_info_extended_amd_asm_ia32 pop ebx ret -;WATCHOUT - DO NOT call this function until you have verified CPU support of -; SSE by inspecting the return value from FLAC__cpu_info_asm_ia32 -;NOTE - Since we're not in priv level 0 we can't just check CR4 bits 9 & 10, -; so right now we just assume there is no OS support. If you know -; how to write code to trap a #UD exception in nasm so we can implement -; this function correctly, let us know! -cident FLAC__cpu_info_sse_os_asm_ia32 - push ebx - mov eax, 1 - cpuid - mov eax, 0 ;we would like to 'move eax, cr4' - shr eax, 9 - and eax, 3 +cident FLAC__cpu_info_sse_test_asm_ia32 + xorps xmm0, xmm0 pop ebx - ret end diff --git a/src/libFLAC/include/private/cpu.h b/src/libFLAC/include/private/cpu.h index 3d0b83c4..3a02d510 100644 --- a/src/libFLAC/include/private/cpu.h +++ b/src/libFLAC/include/private/cpu.h @@ -63,7 +63,7 @@ void FLAC__cpu_info(FLAC__CPUInfo *info); #ifdef FLAC__HAS_NASM unsigned FLAC__cpu_info_asm_ia32(); unsigned FLAC__cpu_info_extended_amd_asm_ia32(); -unsigned FLAC__cpu_info_sse_os_asm_ia32(); +unsigned FLAC__cpu_info_sse_test_asm_ia32(); #endif #endif #endif