Add AVX/AVX2/FMA support to CPU detection code.
[flac.git] / src / libFLAC / include / private / cpu.h
1 /* libFLAC - Free Lossless Audio Codec library
2  * Copyright (C) 2001-2009  Josh Coalson
3  * Copyright (C) 2011-2013  Xiph.Org Foundation
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * - Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * - Neither the name of the Xiph.org Foundation nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifndef FLAC__PRIVATE__CPU_H
34 #define FLAC__PRIVATE__CPU_H
35
36 #include "FLAC/ordinals.h"
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #if defined FLAC__HAS_X86INTRIN
43 /* SSE intrinsics support by ICC/MSVC/GCC */
44 #if defined __INTEL_COMPILER
45   #define FLAC__SSE_TARGET(x)
46   #define FLAC__SSE_SUPPORTED 1
47   #define FLAC__SSE2_SUPPORTED 1
48   #if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */
49     #define FLAC__SSSE3_SUPPORTED 1
50     #define FLAC__SSE4_1_SUPPORTED 1
51   #endif
52   #if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */
53     #define FLAC__AVX_SUPPORTED 1
54   #endif
55   #if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */
56     #define FLAC__AVX2_SUPPORTED 1
57     #define FLAC__FMA_SUPPORTED 1
58   #endif
59 #elif defined _MSC_VER
60   #define FLAC__SSE_TARGET(x)
61   #define FLAC__SSE_SUPPORTED 1
62   #define FLAC__SSE2_SUPPORTED 1
63   #if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */
64     #define FLAC__SSSE3_SUPPORTED 1
65     #define FLAC__SSE4_1_SUPPORTED 1
66   #endif
67   #if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */
68     #define FLAC__AVX_SUPPORTED 1
69   #endif
70   #if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */
71     #define FLAC__AVX2_SUPPORTED 1
72     #define FLAC__FMA_SUPPORTED 1
73   #endif
74 #elif defined __GNUC__
75   #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* since GCC 4.9 -msse.. compiler options aren't necessary */
76     #define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x)))
77     #define FLAC__SSE_SUPPORTED 1
78     #define FLAC__SSE2_SUPPORTED 1
79     #define FLAC__SSSE3_SUPPORTED 1
80     #define FLAC__SSE4_1_SUPPORTED 1
81     #define FLAC__AVX_SUPPORTED 1
82     #define FLAC__AVX2_SUPPORTED 1
83     #define FLAC__FMA_SUPPORTED 1
84   #else /* for GCC older than 4.9 */
85     #define FLAC__SSE_TARGET(x)
86     #ifdef __SSE__
87       #define FLAC__SSE_SUPPORTED 1
88     #endif
89     #ifdef __SSE2__
90       #define FLAC__SSE2_SUPPORTED 1
91     #endif
92     #ifdef __SSSE3__
93       #define FLAC__SSSE3_SUPPORTED 1
94     #endif
95     #ifdef __SSE4_1__
96       #define FLAC__SSE4_1_SUPPORTED 1
97     #endif
98     #ifdef __AVX__
99       #define FLAC__AVX_SUPPORTED 1
100     #endif
101     #ifdef __AVX2__
102       #define FLAC__AVX2_SUPPORTED 1
103     #endif
104     #ifdef __FMA__
105       #define FLAC__FMA_SUPPORTED 1
106     #endif
107   #endif /* GCC version */
108 #endif /* compiler version */
109 #endif /* intrinsics support */
110
111 typedef enum {
112         FLAC__CPUINFO_TYPE_IA32,
113         FLAC__CPUINFO_TYPE_X86_64,
114         FLAC__CPUINFO_TYPE_UNKNOWN
115 } FLAC__CPUInfo_Type;
116
117 #if defined FLAC__CPU_IA32
118 typedef struct {
119         FLAC__bool cmov;
120         FLAC__bool mmx;
121         FLAC__bool sse;
122         FLAC__bool sse2;
123
124         FLAC__bool sse3;
125         FLAC__bool ssse3;
126         FLAC__bool sse41;
127         FLAC__bool sse42;
128         FLAC__bool avx;
129         FLAC__bool avx2;
130         FLAC__bool fma;
131 } FLAC__CPUInfo_IA32;
132 #elif defined FLAC__CPU_X86_64
133 typedef struct {
134         FLAC__bool sse3;
135         FLAC__bool ssse3;
136         FLAC__bool sse41;
137         FLAC__bool sse42;
138         FLAC__bool avx;
139         FLAC__bool avx2;
140         FLAC__bool fma;
141 } FLAC__CPUInfo_x86;
142 #endif
143
144 typedef struct {
145         FLAC__bool use_asm;
146         FLAC__CPUInfo_Type type;
147 #if defined FLAC__CPU_IA32
148         FLAC__CPUInfo_IA32 ia32;
149 #elif defined FLAC__CPU_X86_64
150         FLAC__CPUInfo_x86 x86;
151 #endif
152 } FLAC__CPUInfo;
153
154 void FLAC__cpu_info(FLAC__CPUInfo *info);
155
156 #ifndef FLAC__NO_ASM
157 # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
158 FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
159 void         FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx);
160 # endif
161 # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
162 FLAC__uint32 FLAC__cpu_have_cpuid_x86(void);
163 void         FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx);
164 FLAC__uint32 FLAC__cpu_xgetbv_x86(void);
165 # endif
166 #endif
167
168 #endif