Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: src/libFLAC/cpu.c

Issue 1961133002: Update FLAC to 1.3.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/flac.git@master
Patch Set: build config tweaks for Windows Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/libFLAC/bitwriter.c ('k') | src/libFLAC/crc.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* libFLAC - Free Lossless Audio Codec library 1 /* libFLAC - Free Lossless Audio Codec library
2 * Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Josh Coalson 2 * Copyright (C) 2001-2009 Josh Coalson
3 * Copyright (C) 2011-2014 Xiph.Org Foundation
3 * 4 *
4 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
6 * are met: 7 * are met:
7 * 8 *
8 * - Redistributions of source code must retain the above copyright 9 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
10 * 11 *
11 * - Redistributions in binary form must reproduce the above copyright 12 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
14 * 15 *
15 * - Neither the name of the Xiph.org Foundation nor the names of its 16 * - Neither the name of the Xiph.org Foundation nor the names of its
16 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission. 18 * this software without specific prior written permission.
18 * 19 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 31 */
31 32
32 #if HAVE_CONFIG_H 33 #ifdef HAVE_CONFIG_H
33 # include <config.h> 34 # include <config.h>
34 #endif 35 #endif
35 36
36 #include "private/cpu.h" 37 #include "private/cpu.h"
37 #include <stdlib.h> 38 #include <stdlib.h>
38 #include <stdio.h> 39 #include <memory.h>
40 #ifdef DEBUG
41 # include <stdio.h>
42 #endif
39 43
40 #if defined FLAC__CPU_IA32 44 #if defined FLAC__CPU_IA32
41 # include <signal.h> 45 # include <signal.h>
42 #elif defined FLAC__CPU_PPC
43 # if !defined FLAC__NO_ASM
44 # if defined FLAC__SYS_DARWIN
45 # include <sys/sysctl.h>
46 # include <mach/mach.h>
47 # include <mach/mach_host.h>
48 # include <mach/host_info.h>
49 # include <mach/machine.h>
50 # ifndef CPU_SUBTYPE_POWERPC_970
51 # define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
52 # endif
53 # else /* FLAC__SYS_DARWIN */
54 46
55 # include <signal.h> 47 static void disable_sse(FLAC__CPUInfo *info)
56 # include <setjmp.h> 48 {
49 » info->ia32.sse = false;
50 » info->ia32.sse2 = false;
51 » info->ia32.sse3 = false;
52 » info->ia32.ssse3 = false;
53 » info->ia32.sse41 = false;
54 » info->ia32.sse42 = false;
55 }
57 56
58 static sigjmp_buf jmpbuf; 57 static void disable_avx(FLAC__CPUInfo *info)
59 static volatile sig_atomic_t canjump = 0; 58 {
59 » info->ia32.avx = false;
60 » info->ia32.avx2 = false;
61 » info->ia32.fma = false;
62 }
60 63
61 static void sigill_handler (int sig) 64 #elif defined FLAC__CPU_X86_64
65
66 static void disable_avx(FLAC__CPUInfo *info)
62 { 67 {
63 » if (!canjump) { 68 » info->x86.avx = false;
64 » » signal (sig, SIG_DFL); 69 » info->x86.avx2 = false;
65 » » raise (sig); 70 » info->x86.fma = false;
66 » }
67 » canjump = 0;
68 » siglongjmp (jmpbuf, 1);
69 } 71 }
70 # endif /* FLAC__SYS_DARWIN */ 72 #endif
71 # endif /* FLAC__NO_ASM */
72 #endif /* FLAC__CPU_PPC */
73 73
74 #if defined (__NetBSD__) || defined(__OpenBSD__) 74 #if defined (__NetBSD__) || defined(__OpenBSD__)
75 #include <sys/param.h> 75 #include <sys/param.h>
76 #include <sys/sysctl.h> 76 #include <sys/sysctl.h>
77 #include <machine/cpu.h> 77 #include <machine/cpu.h>
78 #endif 78 #endif
79 79
80 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__ ) 80 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__ )
81 #include <sys/types.h> 81 #include <sys/types.h>
82 #include <sys/sysctl.h> 82 #include <sys/sysctl.h>
83 #endif 83 #endif
84 84
85 #if defined(__APPLE__) 85 #if defined(__APPLE__)
86 /* how to get sysctlbyname()? */ 86 /* how to get sysctlbyname()? */
87 #endif 87 #endif
88 88
89 #ifdef FLAC__CPU_IA32
89 /* these are flags in EDX of CPUID AX=00000001 */ 90 /* these are flags in EDX of CPUID AX=00000001 */
90 static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; 91 static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000;
91 static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; 92 static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000;
92 static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; 93 static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000;
93 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; 94 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
94 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; 95 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
96 #endif
97
95 /* these are flags in ECX of CPUID AX=00000001 */ 98 /* these are flags in ECX of CPUID AX=00000001 */
96 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001; 99 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001;
97 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; 100 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200;
98 /* these are flags in EDX of CPUID AX=80000001 */ 101 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000;
99 static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000; 102 static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
100 static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x4000000 0;
101 static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
102 103
104 #if defined FLAC__AVX_SUPPORTED
105 /* these are flags in ECX of CPUID AX=00000001 */
106 static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000;
107 static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000;
108 static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000;
109 /* these are flags in EBX of CPUID AX=00000007 */
110 static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020;
111 #endif
103 112
104 /* 113 /*
105 * Extra stuff needed for detection of OS support for SSE on IA-32 114 * Extra stuff needed for detection of OS support for SSE on IA-32
106 */ 115 */
107 #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM & & !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS 116 #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SS E_OS
108 # if defined(__linux__) 117 # if defined(__linux__)
109 /* 118 /*
110 * If the OS doesn't support SSE, we will get here with a SIGILL. We 119 * If the OS doesn't support SSE, we will get here with a SIGILL. We
111 * modify the return address to jump over the offending SSE instruction 120 * modify the return address to jump over the offending SSE instruction
112 * and also the operation following it that indicates the instruction 121 * and also the operation following it that indicates the instruction
113 * executed successfully. In this way we use no global variables and 122 * executed successfully. In this way we use no global variables and
114 * stay thread-safe. 123 * stay thread-safe.
115 * 124 *
116 * 3 + 3 + 6: 125 * 3 + 3 + 6:
117 * 3 bytes for "xorps xmm0,xmm0" 126 * 3 bytes for "xorps xmm0,xmm0"
118 * 3 bytes for estimate of how long the follwing "inc var" instruction is 127 * 3 bytes for estimate of how long the follwing "inc var" instruction is
119 * 6 bytes extra in case our estimate is wrong 128 * 6 bytes extra in case our estimate is wrong
120 * 12 bytes puts us in the NOP "landing zone" 129 * 12 bytes puts us in the NOP "landing zone"
121 */ 130 */
122 # undef USE_OBSOLETE_SIGCONTEXT_FLAVOR /* #define this to use the older signal handler method */
123 # ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR
124 static void sigill_handler_sse_os(int signal, struct sigcontext sc)
125 {
126 (void)signal;
127 sc.eip += 3 + 3 + 6;
128 }
129 # else
130 # include <sys/ucontext.h> 131 # include <sys/ucontext.h>
131 static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc) 132 static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc)
132 { 133 {
133 (void)signal, (void)si; 134 (void)signal, (void)si;
134 ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6 ; 135 ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6 ;
135 } 136 }
136 # endif
137 # elif defined(_MSC_VER) 137 # elif defined(_MSC_VER)
138 # include <windows.h> 138 # include <windows.h>
139 # undef USE_TRY_CATCH_FLAVOR /* #define this to use the try/catch method for ca tching illegal opcode exception */
140 # ifdef USE_TRY_CATCH_FLAVOR
141 # else
142 LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep)
143 {
144 if(ep->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTR UCTION) {
145 ep->ContextRecord->Eip += 3 + 3 + 6;
146 return EXCEPTION_CONTINUE_EXECUTION;
147 }
148 return EXCEPTION_CONTINUE_SEARCH;
149 }
150 # endif
151 # endif 139 # endif
152 #endif 140 #endif
153 141
154 142
155 void FLAC__cpu_info(FLAC__CPUInfo *info) 143 void FLAC__cpu_info(FLAC__CPUInfo *info)
156 { 144 {
157 /* 145 /*
158 * IA32-specific 146 * IA32-specific
159 */ 147 */
160 #ifdef FLAC__CPU_IA32 148 #ifdef FLAC__CPU_IA32
149 FLAC__bool ia32_fxsr = false;
150 FLAC__bool ia32_osxsave = false;
151 (void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */
152 memset(info, 0, sizeof(*info));
161 info->type = FLAC__CPUINFO_TYPE_IA32; 153 info->type = FLAC__CPUINFO_TYPE_IA32;
162 #if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM 154 #if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INT RIN)
163 info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA3 2 */ 155 info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA3 2 */
164 » info->data.ia32.cpuid = FLAC__cpu_have_cpuid_asm_ia32()? true : false; 156 #ifdef FLAC__HAS_X86INTRIN
165 » info->data.ia32.bswap = info->data.ia32.cpuid; /* CPUID => BSWAP since i t came after */ 157 » if(!FLAC__cpu_have_cpuid_x86())
166 » info->data.ia32.cmov = false; 158 » » return;
167 » info->data.ia32.mmx = false; 159 #else
168 » info->data.ia32.fxsr = false; 160 » if(!FLAC__cpu_have_cpuid_asm_ia32())
169 » info->data.ia32.sse = false; 161 » » return;
170 » info->data.ia32.sse2 = false; 162 #endif
171 » info->data.ia32.sse3 = false; 163 » {
172 » info->data.ia32.ssse3 = false; 164 » » /* http://www.sandpile.org/x86/cpuid.htm */
173 » info->data.ia32._3dnow = false; 165 #ifdef FLAC__HAS_X86INTRIN
174 » info->data.ia32.ext3dnow = false; 166 » » FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
175 » info->data.ia32.extmmx = false; 167 » » FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags _edx);
176 » if(info->data.ia32.cpuid) { 168 #else
177 » » /* http://www.sandpile.org/ia32/cpuid.htm */ 169 » » FLAC__uint32 flags_ecx, flags_edx;
178 » » FLAC__uint32 flags_edx, flags_ecx;
179 FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx); 170 FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx);
180 » » info->data.ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CM OV )? true : false; 171 #endif
181 » » info->data.ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MM X )? true : false; 172 » » info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false;
182 » » info->data.ia32.fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FX SR )? true : false; 173 » » info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false;
183 » » info->data.ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SS E )? true : false; 174 » » ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false;
184 » » info->data.ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SS E2 )? true : false; 175 » » info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false;
185 » » info->data.ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SS E3 )? true : false; 176 » » info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false;
186 » » info->data.ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SS SE3)? true : false; 177 » » info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
187 178 » » info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
188 #ifdef FLAC__USE_3DNOW 179 » » info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
189 » » flags_edx = FLAC__cpu_info_extended_amd_asm_ia32(); 180 » » info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
190 » » info->data.ia32._3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID _EXTENDED_AMD_3DNOW )? true : false; 181 #if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
191 » » info->data.ia32.ext3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID _EXTENDED_AMD_EXT3DNOW)? true : false; 182 » » ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE )? true : false;
192 » » info->data.ia32.extmmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID _EXTENDED_AMD_EXTMMX )? true : false; 183 » » info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false;
193 #else 184 » » info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false;
194 » » info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.i a32.extmmx = false; 185 » » FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags _edx);
195 #endif 186 » » info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false;
196 187 #endif
197 #ifdef DEBUG 188 » }
198 » » fprintf(stderr, "CPU info (IA-32):\n"); 189
199 » » fprintf(stderr, " CPUID ...... %c\n", info->data.ia32.cpuid ? 'Y' : 'n'); 190 #ifdef DEBUG
200 » » fprintf(stderr, " BSWAP ...... %c\n", info->data.ia32.bswap ? 'Y' : 'n'); 191 » fprintf(stderr, "CPU info (IA-32):\n");
201 » » fprintf(stderr, " CMOV ....... %c\n", info->data.ia32.cmov ? 'Y' : 'n'); 192 » fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
202 » » fprintf(stderr, " MMX ........ %c\n", info->data.ia32.mmx ? 'Y' : 'n'); 193 » fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
203 » » fprintf(stderr, " FXSR ....... %c\n", info->data.ia32.fxsr ? 'Y' : 'n'); 194 » fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
204 » » fprintf(stderr, " SSE ........ %c\n", info->data.ia32.sse ? 'Y' : 'n'); 195 » fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
205 » » fprintf(stderr, " SSE2 ....... %c\n", info->data.ia32.sse2 ? 'Y' : 'n'); 196 » fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
206 » » fprintf(stderr, " SSE3 ....... %c\n", info->data.ia32.sse3 ? 'Y' : 'n'); 197 » fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
207 » » fprintf(stderr, " SSSE3 ...... %c\n", info->data.ia32.ssse3 ? 'Y' : 'n'); 198 » fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
208 » » fprintf(stderr, " 3DNow! ..... %c\n", info->data.ia32._3dnow ? 'Y' : 'n'); 199 » fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
209 » » fprintf(stderr, " 3DNow!-ext . %c\n", info->data.ia32.ext3dnow? 'Y' : 'n'); 200 # if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
210 » » fprintf(stderr, " 3DNow!-MMX . %c\n", info->data.ia32.extmmx ? 'Y' : 'n'); 201 » fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
211 #endif 202 » fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
212 203 » fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
213 » » /* 204 # endif
214 » » * now have to check for OS support of SSE/SSE2 205 #endif
215 » » */ 206
216 » » if(info->data.ia32.fxsr || info->data.ia32.sse || info->data.ia3 2.sse2) { 207 » /*
208 » * now have to check for OS support of SSE instructions
209 » */
210 » if(info->ia32.sse) {
217 #if defined FLAC__NO_SSE_OS 211 #if defined FLAC__NO_SSE_OS
218 » » » /* assume user knows better than us; turn it off */ 212 » » /* assume user knows better than us; turn it off */
219 » » » info->data.ia32.fxsr = info->data.ia32.sse = info->data. ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 213 » » disable_sse(info);
220 #elif defined FLAC__SSE_OS 214 #elif defined FLAC__SSE_OS
221 » » » /* assume user knows better than us; leave as detected a bove */ 215 » » /* assume user knows better than us; leave as detected above */
222 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly __) || defined(__APPLE__) 216 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly __) || defined(__APPLE__)
223 » » » int sse = 0; 217 » » int sse = 0;
224 » » » size_t len; 218 » » size_t len;
225 » » » /* at least one of these must work: */ 219 » » /* at least one of these must work: */
226 » » » len = sizeof(sse); sse = sse || (sysctlbyname("hw.instru ction_sse", &sse, &len, NULL, 0) == 0 && sse); 220 » » len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_ss e", &sse, &len, NULL, 0) == 0 && sse);
227 » » » len = sizeof(sse); sse = sse || (sysctlbyname("hw.option al.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ 221 » » len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
228 » » » if(!sse) 222 » » if(!sse)
229 » » » » info->data.ia32.fxsr = info->data.ia32.sse = inf o->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 223 » » » disable_sse(info);
230 #elif defined(__NetBSD__) || defined (__OpenBSD__) 224 #elif defined(__NetBSD__) || defined (__OpenBSD__)
231 # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__) 225 # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__)
232 » » » int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; 226 » » int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
233 » » » size_t len = sizeof(val); 227 » » size_t len = sizeof(val);
234 » » » if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) 228 » » if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val)
235 » » » » info->data.ia32.fxsr = info->data.ia32.sse = inf o->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 229 » » » disable_sse(info);
236 » » » else { /* double-check SSE2 */ 230 » » else { /* double-check SSE2 */
237 » » » » mib[1] = CPU_SSE2; 231 » » » mib[1] = CPU_SSE2;
238 » » » » len = sizeof(val); 232 » » » len = sizeof(val);
239 » » » » if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !v al) 233 » » » if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) {
240 » » » » » info->data.ia32.sse2 = info->data.ia32.s se3 = info->data.ia32.ssse3 = false; 234 » » » » disable_sse(info);
235 » » » » info->ia32.sse = true;
241 } 236 }
237 }
242 # else 238 # else
243 » » » info->data.ia32.fxsr = info->data.ia32.sse = info->data. ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 239 » » disable_sse(info);
244 # endif 240 # endif
245 #elif defined(__linux__) 241 #elif defined(__linux__)
246 » » » int sse = 0; 242 » » int sse = 0;
247 » » » struct sigaction sigill_save; 243 » » struct sigaction sigill_save;
248 #ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR 244 » » struct sigaction sigill_sse;
249 » » » if(0 == sigaction(SIGILL, NULL, &sigill_save) && signal( SIGILL, (void (*)(int))sigill_handler_sse_os) != SIG_ERR) 245 » » sigill_sse.sa_sigaction = sigill_handler_sse_os;
250 #else 246 » » __sigemptyset(&sigill_sse.sa_mask);
251 » » » struct sigaction sigill_sse; 247 » » 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 */
252 » » » sigill_sse.sa_sigaction = sigill_handler_sse_os; 248 » » if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
253 » » » __sigemptyset(&sigill_sse.sa_mask); 249 » » {
254 » » » sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_R ESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */ 250 » » » /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly- HOWTO.html */
255 » » » if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) 251 » » » /* see sigill_handler_sse_os() for an explanation of the following: */
256 #endif 252 » » » asm volatile (
257 » » » { 253 » » » » "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL i f unsupported by OS */
258 » » » » /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-A ssembly-HOWTO.html */ 254 » » » » "incl %0\n\t" /* SIGILL handler will jump over this */
259 » » » » /* see sigill_handler_sse_os() for an explanatio n of the following: */ 255 » » » » /* landing zone */
260 » » » » asm volatile ( 256 » » » » "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */
261 » » » » » "xorl %0,%0\n\t" /* for some re ason, still need to do this to clear 'sse' var */ 257 » » » » "nop\n\t"
262 » » » » » "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */ 258 » » » » "nop\n\t"
263 » » » » » "incl %0\n\t" /* SIGILL hand ler will jump over this */ 259 » » » » "nop\n\t"
264 » » » » » /* landing zone */ 260 » » » » "nop\n\t"
265 » » » » » "nop\n\t" /* SIGILL jump lands here if " inc" is 9 bytes */ 261 » » » » "nop\n\t"
266 » » » » » "nop\n\t" 262 » » » » "nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */
267 » » » » » "nop\n\t" 263 » » » » "nop\n\t"
268 » » » » » "nop\n\t" 264 » » » » "nop" /* SIGILL jump lands here if "inc" is 1 byte */
269 » » » » » "nop\n\t" 265 » » » » : "=r"(sse)
270 » » » » » "nop\n\t" 266 » » » » : "0"(sse)
271 » » » » » "nop\n\t" /* SIGILL jump lands here if " inc" is 3 bytes (expected) */ 267 » » » );
272 » » » » » "nop\n\t" 268
273 » » » » » "nop" /* SIGILL jump lands here if " inc" is 1 byte */ 269 » » » sigaction(SIGILL, &sigill_save, NULL);
274 » » » » » : "=r"(sse) 270 » » }
275 » » » » » : "r"(sse) 271
276 » » » » ); 272 » » if(!sse)
277 273 » » » disable_sse(info);
278 » » » » sigaction(SIGILL, &sigill_save, NULL); 274 #elif defined(_MSC_VER)
275 » » __try {
276 » » » __asm {
277 » » » » xorps xmm0,xmm0
279 } 278 }
280 279 » » }
281 » » » if(!sse) 280 » » __except(EXCEPTION_EXECUTE_HANDLER) {
282 » » » » info->data.ia32.fxsr = info->data.ia32.sse = inf o->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 281 » » » if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION)
283 #elif defined(_MSC_VER) 282 » » » » disable_sse(info);
284 # ifdef USE_TRY_CATCH_FLAVOR 283 » » }
285 » » » _try { 284 #elif defined(__GNUC__) /* MinGW goes here */
286 » » » » __asm { 285 » » int sse = 0;
287 # if _MSC_VER <= 1200 286 » » /* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */
288 » » » » » /* VC6 assembler doesn't know SSE, have to emit bytecode instead */ 287 » » /* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) * /
289 » » » » » _emit 0x0F 288 » » if (ia32_fxsr) {
290 » » » » » _emit 0x57 289 » » » struct {
291 » » » » » _emit 0xC0 290 » » » » FLAC__uint32 buff[128];
292 # else 291 » » » } __attribute__((aligned(16))) fxsr;
293 » » » » » xorps xmm0,xmm0 292 » » » FLAC__uint32 old_val, new_val;
294 # endif 293
295 » » » » } 294 » » » asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr));
296 » » » } 295 » » » old_val = fxsr.buff[50];
297 » » » _except(EXCEPTION_EXECUTE_HANDLER) { 296 » » » fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */
298 » » » » if (_exception_code() == STATUS_ILLEGAL_INSTRUCT ION) 297 » » » asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */
299 » » » » » info->data.ia32.fxsr = info->data.ia32.s se = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false ; 298 » » » fxsr.buff[50] = old_val; /* restore old value in the buffer */
300 » » » } 299 » » » asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */
301 # else 300 » » » new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */
302 » » » int sse = 0; 301 » » » fxsr.buff[50] = old_val; /* again restore old value in the buffer */
303 » » » LPTOP_LEVEL_EXCEPTION_FILTER save = SetUnhandledExceptio nFilter(sigill_handler_sse_os); 302 » » » asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */
304 » » » /* see GCC version above for explanation */ 303
305 » » » /* http://msdn2.microsoft.com/en-us/library/4ks26t93.as px */ 304 » » » if ((old_val^new_val) == 0x0013c0de)
306 » » » /* http://www.codeproject.com/cpp/gccasm.asp */ 305 » » » » sse = 1;
307 » » » /* http://www.hick.org/~mmiller/msvc_inline_asm.html */ 306 » » }
308 » » » __asm { 307 » » if(!sse)
309 # if _MSC_VER <= 1200 308 » » » disable_sse(info);
310 » » » » /* VC6 assembler doesn't know SSE, have to emit bytecode instead */ 309 #else
311 » » » » _emit 0x0F 310 » » /* no way to test, disable to be safe */
312 » » » » _emit 0x57 311 » » disable_sse(info);
313 » » » » _emit 0xC0 312 #endif
314 # else 313 #ifdef DEBUG
315 » » » » xorps xmm0,xmm0 314 » » fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n ');
316 # endif 315 #endif
317 » » » » inc sse 316 » }
318 » » » » nop 317 » else /* info->ia32.sse == false */
319 » » » » nop 318 » » disable_sse(info);
320 » » » » nop 319
321 » » » » nop 320 » /*
322 » » » » nop 321 » * now have to check for OS support of AVX instructions
323 » » » » nop 322 » */
324 » » » » nop 323 » if(info->ia32.avx && ia32_osxsave) {
325 » » » » nop 324 » » FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
326 » » » » nop 325 » » if ((ecr & 0x6) != 0x6)
327 » » » } 326 » » » disable_avx(info);
328 » » » SetUnhandledExceptionFilter(save); 327 #ifdef DEBUG
329 » » » if(!sse) 328 » » fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n ');
330 » » » » info->data.ia32.fxsr = info->data.ia32.sse = inf o->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 329 #endif
330 » }
331 » else /* no OS AVX support*/
332 » » disable_avx(info);
333 #else
334 » info->use_asm = false;
335 #endif
336
337 /*
338 * x86-64-specific
339 */
340 #elif defined FLAC__CPU_X86_64
341 » FLAC__bool x86_osxsave = false;
342 » (void) x86_osxsave; /* to avoid warnings about unused variables */
343 » memset(info, 0, sizeof(*info));
344 » info->type = FLAC__CPUINFO_TYPE_X86_64;
345 #if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN
346 » info->use_asm = true;
347 » {
348 » » /* http://www.sandpile.org/x86/cpuid.htm */
349 » » FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx;
350 » » FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags _edx);
351 » » info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false;
352 » » info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false;
353 » » info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false;
354 » » info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false;
355 #if defined FLAC__AVX_SUPPORTED
356 » » x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE) ? true : false;
357 » » info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX ) ? true : false;
358 » » info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA ) ? true : false;
359 » » FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags _edx);
360 » » info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 ) ? true : false;
361 #endif
362 » }
363 #ifdef DEBUG
364 » fprintf(stderr, "CPU info (x86-64):\n");
365 » fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n');
366 » fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n');
367 » fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n');
368 » fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n');
369 # if defined FLAC__AVX_SUPPORTED
370 » fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n');
371 » fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n');
372 » fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n');
331 # endif 373 # endif
332 #else 374 #endif
333 » » » /* no way to test, disable to be safe */ 375
334 » » » info->data.ia32.fxsr = info->data.ia32.sse = info->data. ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; 376 » /*
335 #endif 377 » * now have to check for OS support of AVX instructions
336 #ifdef DEBUG 378 » */
337 » » fprintf(stderr, " SSE OS sup . %c\n", info->data.ia32.sse ? 'Y' : 'n'); 379 » if(info->x86.avx && x86_osxsave) {
338 #endif 380 » » FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86();
339 381 » » if ((ecr & 0x6) != 0x6)
340 » » } 382 » » » disable_avx(info);
341 » } 383 #ifdef DEBUG
384 » » fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n' );
385 #endif
386 » }
387 » else /* no OS AVX support*/
388 » » disable_avx(info);
342 #else 389 #else
343 info->use_asm = false; 390 info->use_asm = false;
344 #endif 391 #endif
345 392
346 /* 393 /*
347 * PPC-specific 394 * unknown CPU
348 */
349 #elif defined FLAC__CPU_PPC
350 » info->type = FLAC__CPUINFO_TYPE_PPC;
351 # if !defined FLAC__NO_ASM
352 » info->use_asm = true;
353 # ifdef FLAC__USE_ALTIVEC
354 # if defined FLAC__SYS_DARWIN
355 » {
356 » » int val = 0, mib[2] = { CTL_HW, HW_VECTORUNIT };
357 » » size_t len = sizeof(val);
358 » » info->data.ppc.altivec = !(sysctl(mib, 2, &val, &len, NULL, 0) | | !val);
359 » }
360 » {
361 » » host_basic_info_data_t hostInfo;
362 » » mach_msg_type_number_t infoCount;
363
364 » » infoCount = HOST_BASIC_INFO_COUNT;
365 » » host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostI nfo, &infoCount);
366
367 » » info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) & & (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970);
368 » }
369 # else /* FLAC__USE_ALTIVEC && !FLAC__SYS_DARWIN */
370 » {
371 » » /* no Darwin, do it the brute-force way */
372 » » /* @@@@@@ this is not thread-safe; replace with SSE OS method ab ove or remove */
373 » » info->data.ppc.altivec = 0;
374 » » info->data.ppc.ppc64 = 0;
375
376 » » signal (SIGILL, sigill_handler);
377 » » canjump = 0;
378 » » if (!sigsetjmp (jmpbuf, 1)) {
379 » » » canjump = 1;
380
381 » » » asm volatile (
382 » » » » "mtspr 256, %0\n\t"
383 » » » » "vand %%v0, %%v0, %%v0"
384 » » » » :
385 » » » » : "r" (-1)
386 » » » );
387
388 » » » info->data.ppc.altivec = 1;
389 » » }
390 » » canjump = 0;
391 » » if (!sigsetjmp (jmpbuf, 1)) {
392 » » » int x = 0;
393 » » » canjump = 1;
394
395 » » » /* PPC64 hardware implements the cntlzd instruction */
396 » » » asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) );
397
398 » » » info->data.ppc.ppc64 = 1;
399 » » }
400 » » signal (SIGILL, SIG_DFL); /*@@@@@@ should save and restore old s ignal */
401 » }
402 # endif
403 # else /* !FLAC__USE_ALTIVEC */
404 » info->data.ppc.altivec = 0;
405 » info->data.ppc.ppc64 = 0;
406 # endif
407 # else
408 » info->use_asm = false;
409 # endif
410
411 /*
412 * unknown CPI
413 */ 395 */
414 #else 396 #else
415 info->type = FLAC__CPUINFO_TYPE_UNKNOWN; 397 info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
416 info->use_asm = false; 398 info->use_asm = false;
417 #endif 399 #endif
418 } 400 }
401
402 #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X8 6INTRIN
403
404 #if defined _MSC_VER
405 #include <intrin.h> /* for __cpuid() and _xgetbv() */
406 #elif defined __GNUC__ && defined HAVE_CPUID_H
407 #include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */
408 #endif
409
410 FLAC__uint32 FLAC__cpu_have_cpuid_x86(void)
411 {
412 #ifdef FLAC__CPU_X86_64
413 return 1;
414 #else
415 # if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CP UID support (or OSes that work on those CPUs)? */
416 FLAC__uint32 flags1, flags2;
417 __asm {
418 pushfd
419 pushfd
420 pop eax
421 mov flags1, eax
422 xor eax, 0x200000
423 push eax
424 popfd
425 pushfd
426 pop eax
427 mov flags2, eax
428 popfd
429 }
430 if (((flags1^flags2) & 0x200000) != 0)
431 return 1;
432 else
433 return 0;
434 # elif defined __GNUC__ && defined HAVE_CPUID_H
435 if (__get_cpuid_max(0, 0) != 0)
436 return 1;
437 else
438 return 0;
439 # else
440 return 0;
441 # endif
442 #endif
443 }
444
445 void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx , FLAC__uint32 *ecx, FLAC__uint32 *edx)
446 {
447 #if defined _MSC_VER || defined __INTEL_COMPILER
448 int cpuinfo[4];
449 int ext = level & 0x80000000;
450 __cpuid(cpuinfo, ext);
451 if((unsigned)cpuinfo[0] < level) {
452 *eax = *ebx = *ecx = *edx = 0;
453 return;
454 }
455 #if defined FLAC__AVX_SUPPORTED
456 __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */
457 #else
458 __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex * /
459 #endif
460 *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[ 3];
461 #elif defined __GNUC__ && defined HAVE_CPUID_H
462 FLAC__uint32 ext = level & 0x80000000;
463 __cpuid(ext, *eax, *ebx, *ecx, *edx);
464 if (*eax < level) {
465 *eax = *ebx = *ecx = *edx = 0;
466 return;
467 }
468 __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx);
469 #else
470 *eax = *ebx = *ecx = *edx = 0;
471 #endif
472 }
473
474 FLAC__uint32 FLAC__cpu_xgetbv_x86(void)
475 {
476 #if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTE D
477 return (FLAC__uint32)_xgetbv(0);
478 #elif defined __GNUC__
479 FLAC__uint32 lo, hi;
480 asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0));
481 return lo;
482 #else
483 return 0;
484 #endif
485 }
486
487 #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
OLDNEW
« no previous file with comments | « src/libFLAC/bitwriter.c ('k') | src/libFLAC/crc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698