The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.
Dependencies: GR-PEACH_video R_BSP TLV320_RBSP USBHost_custom
Fork of GR-PEACH_Audio_Playback_Sample by
cpu.c
00001 /* libFLAC - Free Lossless Audio Codec library 00002 * Copyright (C) 2001-2009 Josh Coalson 00003 * Copyright (C) 2011-2014 Xiph.Org Foundation 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 00009 * - Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 00012 * - Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 00016 * - Neither the name of the Xiph.org Foundation nor the names of its 00017 * contributors may be used to endorse or promote products derived from 00018 * this software without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00021 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 00024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifdef HAVE_CONFIG_H 00034 # include <config.h> 00035 #endif 00036 00037 #include "private/cpu.h" 00038 #include <stdlib.h> 00039 #include <memory.h> 00040 #ifdef DEBUG 00041 # include <stdio.h> 00042 #endif 00043 00044 #if defined FLAC__CPU_IA32 00045 # include <signal.h> 00046 00047 static void disable_sse(FLAC__CPUInfo *info) 00048 { 00049 info->ia32.sse = false; 00050 info->ia32.sse2 = false; 00051 info->ia32.sse3 = false; 00052 info->ia32.ssse3 = false; 00053 info->ia32.sse41 = false; 00054 info->ia32.sse42 = false; 00055 } 00056 00057 static void disable_avx(FLAC__CPUInfo *info) 00058 { 00059 info->ia32.avx = false; 00060 info->ia32.avx2 = false; 00061 info->ia32.fma = false; 00062 } 00063 00064 #elif defined FLAC__CPU_X86_64 00065 00066 static void disable_avx(FLAC__CPUInfo *info) 00067 { 00068 info->x86.avx = false; 00069 info->x86.avx2 = false; 00070 info->x86.fma = false; 00071 } 00072 #endif 00073 00074 #if defined (__NetBSD__) || defined(__OpenBSD__) 00075 #include <sys/param.h> 00076 #include <sys/sysctl.h> 00077 #include <machine/cpu.h> 00078 #endif 00079 00080 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 00081 #include <sys/types.h> 00082 #include <sys/sysctl.h> 00083 #endif 00084 00085 #if defined(__APPLE__) 00086 /* how to get sysctlbyname()? */ 00087 #endif 00088 00089 #ifdef FLAC__CPU_IA32 00090 /* these are flags in EDX of CPUID AX=00000001 */ 00091 static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; 00092 static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; 00093 static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; 00094 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; 00095 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; 00096 #endif 00097 00098 /* these are flags in ECX of CPUID AX=00000001 */ 00099 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001; 00100 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; 00101 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000; 00102 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000; 00103 00104 #if defined FLAC__AVX_SUPPORTED 00105 /* these are flags in ECX of CPUID AX=00000001 */ 00106 static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000; 00107 static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000; 00108 static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000; 00109 /* these are flags in EBX of CPUID AX=00000007 */ 00110 static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020; 00111 #endif 00112 00113 /* 00114 * Extra stuff needed for detection of OS support for SSE on IA-32 00115 */ 00116 #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS 00117 # if defined(__linux__) 00118 /* 00119 * If the OS doesn't support SSE, we will get here with a SIGILL. We 00120 * modify the return address to jump over the offending SSE instruction 00121 * and also the operation following it that indicates the instruction 00122 * executed successfully. In this way we use no global variables and 00123 * stay thread-safe. 00124 * 00125 * 3 + 3 + 6: 00126 * 3 bytes for "xorps xmm0,xmm0" 00127 * 3 bytes for estimate of how long the follwing "inc var" instruction is 00128 * 6 bytes extra in case our estimate is wrong 00129 * 12 bytes puts us in the NOP "landing zone" 00130 */ 00131 # include <sys/ucontext.h> 00132 static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc) 00133 { 00134 (void)signal, (void)si; 00135 ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6; 00136 } 00137 # elif defined(_MSC_VER) 00138 # include <windows.h> 00139 # endif 00140 #endif 00141 00142 00143 void FLAC__cpu_info(FLAC__CPUInfo *info) 00144 { 00145 /* 00146 * IA32-specific 00147 */ 00148 #ifdef FLAC__CPU_IA32 00149 FLAC__bool ia32_fxsr = false; 00150 FLAC__bool ia32_osxsave = false; 00151 (void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */ 00152 memset(info, 0, sizeof(*info)); 00153 info->type = FLAC__CPUINFO_TYPE_IA32; 00154 #if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) 00155 info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */ 00156 #ifdef FLAC__HAS_X86INTRIN 00157 if(!FLAC__cpu_have_cpuid_x86()) 00158 return; 00159 #else 00160 if(!FLAC__cpu_have_cpuid_asm_ia32()) 00161 return; 00162 #endif 00163 { 00164 /* http://www.sandpile.org/x86/cpuid.htm */ 00165 #ifdef FLAC__HAS_X86INTRIN 00166 FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; 00167 FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); 00168 #else 00169 FLAC__uint32 flags_ecx, flags_edx; 00170 FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx); 00171 #endif 00172 info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false; 00173 info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false; 00174 ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false; 00175 info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false; 00176 info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false; 00177 info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; 00178 info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; 00179 info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false; 00180 info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false; 00181 #if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED 00182 ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false; 00183 info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false; 00184 info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false; 00185 FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); 00186 info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false; 00187 #endif 00188 } 00189 00190 #ifdef DEBUG 00191 fprintf(stderr, "CPU info (IA-32):\n"); 00192 fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n'); 00193 fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n'); 00194 fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n'); 00195 fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n'); 00196 fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n'); 00197 fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n'); 00198 fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n'); 00199 fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n'); 00200 # if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED 00201 fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n'); 00202 fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n'); 00203 fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n'); 00204 # endif 00205 #endif 00206 00207 /* 00208 * now have to check for OS support of SSE instructions 00209 */ 00210 if(info->ia32.sse) { 00211 #if defined FLAC__NO_SSE_OS 00212 /* assume user knows better than us; turn it off */ 00213 disable_sse(info); 00214 #elif defined FLAC__SSE_OS 00215 /* assume user knows better than us; leave as detected above */ 00216 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__) 00217 int sse = 0; 00218 size_t len; 00219 /* at least one of these must work: */ 00220 len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse); 00221 len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ 00222 if(!sse) 00223 disable_sse(info); 00224 #elif defined(__NetBSD__) || defined (__OpenBSD__) 00225 # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__) 00226 int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; 00227 size_t len = sizeof(val); 00228 if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) 00229 disable_sse(info); 00230 else { /* double-check SSE2 */ 00231 mib[1] = CPU_SSE2; 00232 len = sizeof(val); 00233 if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) { 00234 disable_sse(info); 00235 info->ia32.sse = true; 00236 } 00237 } 00238 # else 00239 disable_sse(info); 00240 # endif 00241 #elif defined(__linux__) 00242 int sse = 0; 00243 struct sigaction sigill_save; 00244 struct sigaction sigill_sse; 00245 sigill_sse.sa_sigaction = sigill_handler_sse_os; 00246 __sigemptyset(&sigill_sse.sa_mask); 00247 sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */ 00248 if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) 00249 { 00250 /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */ 00251 /* see sigill_handler_sse_os() for an explanation of the following: */ 00252 asm volatile ( 00253 "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */ 00254 "incl %0\n\t" /* SIGILL handler will jump over this */ 00255 /* landing zone */ 00256 "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */ 00257 "nop\n\t" 00258 "nop\n\t" 00259 "nop\n\t" 00260 "nop\n\t" 00261 "nop\n\t" 00262 "nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */ 00263 "nop\n\t" 00264 "nop" /* SIGILL jump lands here if "inc" is 1 byte */ 00265 : "=r"(sse) 00266 : "0"(sse) 00267 ); 00268 00269 sigaction(SIGILL, &sigill_save, NULL); 00270 } 00271 00272 if(!sse) 00273 disable_sse(info); 00274 #elif defined(_MSC_VER) 00275 __try { 00276 __asm { 00277 xorps xmm0,xmm0 00278 } 00279 } 00280 __except(EXCEPTION_EXECUTE_HANDLER) { 00281 if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) 00282 disable_sse(info); 00283 } 00284 #elif defined(__GNUC__) /* MinGW goes here */ 00285 int sse = 0; 00286 /* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */ 00287 /* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */ 00288 if (ia32_fxsr) { 00289 struct { 00290 FLAC__uint32 buff[128]; 00291 } __attribute__((aligned(16))) fxsr; 00292 FLAC__uint32 old_val, new_val; 00293 00294 asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr)); 00295 old_val = fxsr.buff[50]; 00296 fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */ 00297 asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */ 00298 fxsr.buff[50] = old_val; /* restore old value in the buffer */ 00299 asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */ 00300 new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */ 00301 fxsr.buff[50] = old_val; /* again restore old value in the buffer */ 00302 asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */ 00303 00304 if ((old_val^new_val) == 0x0013c0de) 00305 sse = 1; 00306 } 00307 if(!sse) 00308 disable_sse(info); 00309 #else 00310 /* no way to test, disable to be safe */ 00311 disable_sse(info); 00312 #endif 00313 #ifdef DEBUG 00314 fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n'); 00315 #endif 00316 } 00317 else /* info->ia32.sse == false */ 00318 disable_sse(info); 00319 00320 /* 00321 * now have to check for OS support of AVX instructions 00322 */ 00323 if(info->ia32.avx && ia32_osxsave) { 00324 FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86(); 00325 if ((ecr & 0x6) != 0x6) 00326 disable_avx(info); 00327 #ifdef DEBUG 00328 fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n'); 00329 #endif 00330 } 00331 else /* no OS AVX support*/ 00332 disable_avx(info); 00333 #else 00334 info->use_asm = false; 00335 #endif 00336 00337 /* 00338 * x86-64-specific 00339 */ 00340 #elif defined FLAC__CPU_X86_64 00341 FLAC__bool x86_osxsave = false; 00342 (void) x86_osxsave; /* to avoid warnings about unused variables */ 00343 memset(info, 0, sizeof(*info)); 00344 info->type = FLAC__CPUINFO_TYPE_X86_64; 00345 #if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN 00346 info->use_asm = true; 00347 { 00348 /* http://www.sandpile.org/x86/cpuid.htm */ 00349 FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; 00350 FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); 00351 info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; 00352 info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; 00353 info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false; 00354 info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false; 00355 #if defined FLAC__AVX_SUPPORTED 00356 x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false; 00357 info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false; 00358 info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false; 00359 FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); 00360 info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false; 00361 #endif 00362 } 00363 #ifdef DEBUG 00364 fprintf(stderr, "CPU info (x86-64):\n"); 00365 fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); 00366 fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); 00367 fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); 00368 fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); 00369 # if defined FLAC__AVX_SUPPORTED 00370 fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); 00371 fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); 00372 fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); 00373 # endif 00374 #endif 00375 00376 /* 00377 * now have to check for OS support of AVX instructions 00378 */ 00379 if(info->x86.avx && x86_osxsave) { 00380 FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86(); 00381 if ((ecr & 0x6) != 0x6) 00382 disable_avx(info); 00383 #ifdef DEBUG 00384 fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); 00385 #endif 00386 } 00387 else /* no OS AVX support*/ 00388 disable_avx(info); 00389 #else 00390 info->use_asm = false; 00391 #endif 00392 00393 /* 00394 * unknown CPU 00395 */ 00396 #else 00397 info->type = FLAC__CPUINFO_TYPE_UNKNOWN; 00398 info->use_asm = false; 00399 #endif 00400 } 00401 00402 #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN 00403 00404 #if defined _MSC_VER 00405 #include <intrin.h> /* for __cpuid() and _xgetbv() */ 00406 #elif defined __GNUC__ && defined HAVE_CPUID_H 00407 #include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */ 00408 #endif 00409 00410 FLAC__uint32 FLAC__cpu_have_cpuid_x86(void) 00411 { 00412 #ifdef FLAC__CPU_X86_64 00413 return 1; 00414 #else 00415 # if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CPUID support (or OSes that work on those CPUs)? */ 00416 FLAC__uint32 flags1, flags2; 00417 __asm { 00418 pushfd 00419 pushfd 00420 pop eax 00421 mov flags1, eax 00422 xor eax, 0x200000 00423 push eax 00424 popfd 00425 pushfd 00426 pop eax 00427 mov flags2, eax 00428 popfd 00429 } 00430 if (((flags1^flags2) & 0x200000) != 0) 00431 return 1; 00432 else 00433 return 0; 00434 # elif defined __GNUC__ && defined HAVE_CPUID_H 00435 if (__get_cpuid_max(0, 0) != 0) 00436 return 1; 00437 else 00438 return 0; 00439 # else 00440 return 0; 00441 # endif 00442 #endif 00443 } 00444 00445 void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) 00446 { 00447 #if defined _MSC_VER || defined __INTEL_COMPILER 00448 int cpuinfo[4]; 00449 int ext = level & 0x80000000; 00450 __cpuid(cpuinfo, ext); 00451 if((unsigned)cpuinfo[0] < level) { 00452 *eax = *ebx = *ecx = *edx = 0; 00453 return; 00454 } 00455 #if defined FLAC__AVX_SUPPORTED 00456 __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */ 00457 #else 00458 __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */ 00459 #endif 00460 *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; 00461 #elif defined __GNUC__ && defined HAVE_CPUID_H 00462 FLAC__uint32 ext = level & 0x80000000; 00463 __cpuid(ext, *eax, *ebx, *ecx, *edx); 00464 if (*eax < level) { 00465 *eax = *ebx = *ecx = *edx = 0; 00466 return; 00467 } 00468 __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); 00469 #else 00470 *eax = *ebx = *ecx = *edx = 0; 00471 #endif 00472 } 00473 00474 FLAC__uint32 FLAC__cpu_xgetbv_x86(void) 00475 { 00476 #if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTED 00477 return (FLAC__uint32)_xgetbv(0); 00478 #elif defined __GNUC__ 00479 FLAC__uint32 lo, hi; 00480 asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); 00481 return lo; 00482 #else 00483 return 0; 00484 #endif 00485 } 00486 00487 #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
Generated on Tue Jul 12 2022 19:32:28 by 1.7.2