1 /// @ref simd
2 /// @file glm/simd/platform.h
3 
4 #pragma once
5 
6 ///////////////////////////////////////////////////////////////////////////////////
7 // Platform
8 
9 #define GLM_PLATFORM_UNKNOWN		0x00000000
10 #define GLM_PLATFORM_WINDOWS		0x00010000
11 #define GLM_PLATFORM_LINUX			0x00020000
12 #define GLM_PLATFORM_APPLE			0x00040000
13 //#define GLM_PLATFORM_IOS			0x00080000
14 #define GLM_PLATFORM_ANDROID		0x00100000
15 #define GLM_PLATFORM_CHROME_NACL	0x00200000
16 #define GLM_PLATFORM_UNIX			0x00400000
17 #define GLM_PLATFORM_QNXNTO			0x00800000
18 #define GLM_PLATFORM_WINCE			0x01000000
19 #define GLM_PLATFORM_CYGWIN			0x02000000
20 
21 #ifdef GLM_FORCE_PLATFORM_UNKNOWN
22 #	define GLM_PLATFORM GLM_PLATFORM_UNKNOWN
23 #elif defined(__CYGWIN__)
24 #	define GLM_PLATFORM GLM_PLATFORM_CYGWIN
25 #elif defined(__QNXNTO__)
26 #	define GLM_PLATFORM GLM_PLATFORM_QNXNTO
27 #elif defined(__APPLE__)
28 #	define GLM_PLATFORM GLM_PLATFORM_APPLE
29 #elif defined(WINCE)
30 #	define GLM_PLATFORM GLM_PLATFORM_WINCE
31 #elif defined(_WIN32)
32 #	define GLM_PLATFORM GLM_PLATFORM_WINDOWS
33 #elif defined(__native_client__)
34 #	define GLM_PLATFORM GLM_PLATFORM_CHROME_NACL
35 #elif defined(__ANDROID__)
36 #	define GLM_PLATFORM GLM_PLATFORM_ANDROID
37 #elif defined(__linux)
38 #	define GLM_PLATFORM GLM_PLATFORM_LINUX
39 #elif defined(__unix)
40 #	define GLM_PLATFORM GLM_PLATFORM_UNIX
41 #else
42 #	define GLM_PLATFORM GLM_PLATFORM_UNKNOWN
43 #endif//
44 
45 // Report platform detection
46 #if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_MESSAGE_PLATFORM_DISPLAYED)
47 #	define GLM_MESSAGE_PLATFORM_DISPLAYED
48 #	if(GLM_PLATFORM & GLM_PLATFORM_QNXNTO)
49 #		pragma message("GLM: QNX platform detected")
50 //#	elif(GLM_PLATFORM & GLM_PLATFORM_IOS)
51 //#		pragma message("GLM: iOS platform detected")
52 #	elif(GLM_PLATFORM & GLM_PLATFORM_APPLE)
53 #		pragma message("GLM: Apple platform detected")
54 #	elif(GLM_PLATFORM & GLM_PLATFORM_WINCE)
55 #		pragma message("GLM: WinCE platform detected")
56 #	elif(GLM_PLATFORM & GLM_PLATFORM_WINDOWS)
57 #		pragma message("GLM: Windows platform detected")
58 #	elif(GLM_PLATFORM & GLM_PLATFORM_CHROME_NACL)
59 #		pragma message("GLM: Native Client detected")
60 #	elif(GLM_PLATFORM & GLM_PLATFORM_ANDROID)
61 #		pragma message("GLM: Android platform detected")
62 #	elif(GLM_PLATFORM & GLM_PLATFORM_LINUX)
63 #		pragma message("GLM: Linux platform detected")
64 #	elif(GLM_PLATFORM & GLM_PLATFORM_UNIX)
65 #		pragma message("GLM: UNIX platform detected")
66 #	elif(GLM_PLATFORM & GLM_PLATFORM_UNKNOWN)
67 #		pragma message("GLM: platform unknown")
68 #	else
69 #		pragma message("GLM: platform not detected")
70 #	endif
71 #endif//GLM_MESSAGES
72 
73 ///////////////////////////////////////////////////////////////////////////////////
74 // Compiler
75 
76 #define GLM_COMPILER_UNKNOWN		0x00000000
77 
78 // Intel
79 #define GLM_COMPILER_INTEL			0x00100000
80 #define GLM_COMPILER_INTEL14		0x00100040
81 #define GLM_COMPILER_INTEL15		0x00100050
82 #define GLM_COMPILER_INTEL16		0x00100060
83 #define GLM_COMPILER_INTEL17		0x00100070
84 
85 // Visual C++ defines
86 #define GLM_COMPILER_VC				0x01000000
87 #define GLM_COMPILER_VC12			0x010000B0
88 #define GLM_COMPILER_VC14			0x010000C0
89 #define GLM_COMPILER_VC15			0x010000D0
90 #define GLM_COMPILER_VC16			0x010000E0
91 
92 // GCC defines
93 #define GLM_COMPILER_GCC			0x02000000
94 #define GLM_COMPILER_GCC46			0x020000D0
95 #define GLM_COMPILER_GCC47			0x020000E0
96 #define GLM_COMPILER_GCC48			0x020000F0
97 #define GLM_COMPILER_GCC49			0x02000100
98 #define GLM_COMPILER_GCC5			0x02000200
99 #define GLM_COMPILER_GCC6			0x02000300
100 #define GLM_COMPILER_GCC7			0x02000400
101 #define GLM_COMPILER_GCC8			0x02000500
102 
103 // CUDA
104 #define GLM_COMPILER_CUDA			0x10000000
105 #define GLM_COMPILER_CUDA70			0x100000A0
106 #define GLM_COMPILER_CUDA75			0x100000B0
107 #define GLM_COMPILER_CUDA80			0x100000C0
108 
109 // Clang
110 #define GLM_COMPILER_CLANG			0x20000000
111 #define GLM_COMPILER_CLANG34		0x20000050
112 #define GLM_COMPILER_CLANG35		0x20000060
113 #define GLM_COMPILER_CLANG36		0x20000070
114 #define GLM_COMPILER_CLANG37		0x20000080
115 #define GLM_COMPILER_CLANG38		0x20000090
116 #define GLM_COMPILER_CLANG39		0x200000A0
117 #define GLM_COMPILER_CLANG40		0x200000B0
118 #define GLM_COMPILER_CLANG41		0x200000C0
119 #define GLM_COMPILER_CLANG42		0x200000D0
120 
121 // Build model
122 #define GLM_MODEL_32				0x00000010
123 #define GLM_MODEL_64				0x00000020
124 
125 // Force generic C++ compiler
126 #ifdef GLM_FORCE_COMPILER_UNKNOWN
127 #	define GLM_COMPILER GLM_COMPILER_UNKNOWN
128 
129 #elif defined(__INTEL_COMPILER)
130 #	if (__INTEL_COMPILER < 1400)
131 #		error "GLM requires ICC 2013 SP1 or newer"
132 #	elif __INTEL_COMPILER == 1400
133 #		define GLM_COMPILER GLM_COMPILER_INTEL14
134 #	elif __INTEL_COMPILER == 1500
135 #		define GLM_COMPILER GLM_COMPILER_INTEL15
136 #	elif __INTEL_COMPILER == 1600
137 #		define GLM_COMPILER GLM_COMPILER_INTEL16
138 #	elif __INTEL_COMPILER >= 1700
139 #		define GLM_COMPILER GLM_COMPILER_INTEL17
140 #	endif
141 
142 // CUDA
143 #elif defined(__CUDACC__)
144 #	if !defined(CUDA_VERSION) && !defined(GLM_FORCE_CUDA)
145 #		include <cuda.h>  // make sure version is defined since nvcc does not define it itself!
146 #	endif
147 #	if CUDA_VERSION < 7000
148 #		error "GLM requires CUDA 7.0 or higher"
149 #	elif (CUDA_VERSION >= 7000 && CUDA_VERSION < 7500)
150 #		define GLM_COMPILER GLM_COMPILER_CUDA70
151 #	elif (CUDA_VERSION >= 7500 && CUDA_VERSION < 8000)
152 #		define GLM_COMPILER GLM_COMPILER_CUDA75
153 #	elif (CUDA_VERSION >= 8000)
154 #		define GLM_COMPILER GLM_COMPILER_CUDA80
155 #	endif
156 
157 // Clang
158 #elif defined(__clang__)
159 #	if defined(__apple_build_version__)
160 #		if (__clang_major__ < 6)
161 #			error "GLM requires Clang 3.4 / Apple Clang 6.0 or higher"
162 #		elif __clang_major__ == 6 && __clang_minor__ == 0
163 #			define GLM_COMPILER GLM_COMPILER_CLANG35
164 #		elif __clang_major__ == 6 && __clang_minor__ >= 1
165 #			define GLM_COMPILER GLM_COMPILER_CLANG36
166 #		elif __clang_major__ >= 7
167 #			define GLM_COMPILER GLM_COMPILER_CLANG37
168 #		endif
169 #	else
170 #		if ((__clang_major__ == 3) && (__clang_minor__ < 4)) || (__clang_major__ < 3)
171 #			error "GLM requires Clang 3.4 or higher"
172 #		elif __clang_major__ == 3 && __clang_minor__ == 4
173 #			define GLM_COMPILER GLM_COMPILER_CLANG34
174 #		elif __clang_major__ == 3 && __clang_minor__ == 5
175 #			define GLM_COMPILER GLM_COMPILER_CLANG35
176 #		elif __clang_major__ == 3 && __clang_minor__ == 6
177 #			define GLM_COMPILER GLM_COMPILER_CLANG36
178 #		elif __clang_major__ == 3 && __clang_minor__ == 7
179 #			define GLM_COMPILER GLM_COMPILER_CLANG37
180 #		elif __clang_major__ == 3 && __clang_minor__ == 8
181 #			define GLM_COMPILER GLM_COMPILER_CLANG38
182 #		elif __clang_major__ == 3 && __clang_minor__ >= 9
183 #			define GLM_COMPILER GLM_COMPILER_CLANG39
184 #		elif __clang_major__ == 4 && __clang_minor__ == 0
185 #			define GLM_COMPILER GLM_COMPILER_CLANG40
186 #		elif __clang_major__ == 4 && __clang_minor__ == 1
187 #			define GLM_COMPILER GLM_COMPILER_CLANG41
188 #		elif __clang_major__ == 4 && __clang_minor__ >= 2
189 #			define GLM_COMPILER GLM_COMPILER_CLANG42
190 #		elif __clang_major__ >= 4
191 #			define GLM_COMPILER GLM_COMPILER_CLANG42
192 #		endif
193 #	endif
194 
195 // Visual C++
196 #elif defined(_MSC_VER)
197 #	if _MSC_VER < 1800
198 #		error "GLM requires Visual C++ 12 - 2013 or higher"
199 #	elif _MSC_VER == 1800
200 #		define GLM_COMPILER GLM_COMPILER_VC12
201 #	elif _MSC_VER == 1900
202 #		define GLM_COMPILER GLM_COMPILER_VC14
203 #	elif _MSC_VER >= 1910
204 #		define GLM_COMPILER GLM_COMPILER_VC15
205 #	endif//_MSC_VER
206 
207 // G++
208 #elif defined(__GNUC__) || defined(__MINGW32__)
209 #	if ((__GNUC__ == 4) && (__GNUC_MINOR__ < 6)) || (__GNUC__ < 4)
210 #		error "GLM requires GCC 4.7 or higher"
211 #	elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 6)
212 #		define GLM_COMPILER (GLM_COMPILER_GCC46)
213 #	elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 7)
214 #		define GLM_COMPILER (GLM_COMPILER_GCC47)
215 #	elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
216 #		define GLM_COMPILER (GLM_COMPILER_GCC48)
217 #	elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
218 #		define GLM_COMPILER (GLM_COMPILER_GCC49)
219 #	elif (__GNUC__ == 5)
220 #		define GLM_COMPILER (GLM_COMPILER_GCC5)
221 #	elif (__GNUC__ == 6)
222 #		define GLM_COMPILER (GLM_COMPILER_GCC6)
223 #	elif (__GNUC__ == 7)
224 #		define GLM_COMPILER (GLM_COMPILER_GCC7)
225 #	elif (__GNUC__ >= 8)
226 #		define GLM_COMPILER (GLM_COMPILER_GCC8)
227 #	endif
228 
229 #else
230 #	define GLM_COMPILER GLM_COMPILER_UNKNOWN
231 #endif
232 
233 #ifndef GLM_COMPILER
234 #	error "GLM_COMPILER undefined, your compiler may not be supported by GLM. Add #define GLM_COMPILER 0 to ignore this message."
235 #endif//GLM_COMPILER
236 
237 ///////////////////////////////////////////////////////////////////////////////////
238 // Instruction sets
239 
240 // User defines: GLM_FORCE_PURE GLM_FORCE_SSE2 GLM_FORCE_SSE3 GLM_FORCE_AVX GLM_FORCE_AVX2 GLM_FORCE_AVX2
241 
242 #define GLM_ARCH_X86_BIT		0x00000001
243 #define GLM_ARCH_SSE2_BIT		0x00000002
244 #define GLM_ARCH_SSE3_BIT		0x00000004
245 #define GLM_ARCH_SSSE3_BIT		0x00000008
246 #define GLM_ARCH_SSE41_BIT		0x00000010
247 #define GLM_ARCH_SSE42_BIT		0x00000020
248 #define GLM_ARCH_AVX_BIT		0x00000040
249 #define GLM_ARCH_AVX2_BIT		0x00000080
250 #define GLM_ARCH_AVX512_BIT		0x00000100 // Skylake subset
251 #define GLM_ARCH_ARM_BIT		0x00000100
252 #define GLM_ARCH_NEON_BIT		0x00000200
253 #define GLM_ARCH_MIPS_BIT		0x00010000
254 #define GLM_ARCH_PPC_BIT		0x01000000
255 
256 #define GLM_ARCH_PURE		(0x00000000)
257 #define GLM_ARCH_X86		(GLM_ARCH_X86_BIT)
258 #define GLM_ARCH_SSE2		(GLM_ARCH_SSE2_BIT | GLM_ARCH_X86)
259 #define GLM_ARCH_SSE3		(GLM_ARCH_SSE3_BIT | GLM_ARCH_SSE2)
260 #define GLM_ARCH_SSSE3		(GLM_ARCH_SSSE3_BIT | GLM_ARCH_SSE3)
261 #define GLM_ARCH_SSE41		(GLM_ARCH_SSE41_BIT | GLM_ARCH_SSSE3)
262 #define GLM_ARCH_SSE42		(GLM_ARCH_SSE42_BIT | GLM_ARCH_SSE41)
263 #define GLM_ARCH_AVX		(GLM_ARCH_AVX_BIT | GLM_ARCH_SSE42)
264 #define GLM_ARCH_AVX2		(GLM_ARCH_AVX2_BIT | GLM_ARCH_AVX)
265 #define GLM_ARCH_AVX512		(GLM_ARCH_AVX512_BIT | GLM_ARCH_AVX2) // Skylake subset
266 #define GLM_ARCH_ARM		(GLM_ARCH_ARM_BIT)
267 #define GLM_ARCH_NEON		(GLM_ARCH_NEON_BIT | GLM_ARCH_ARM)
268 #define GLM_ARCH_MIPS		(GLM_ARCH_MIPS_BIT)
269 #define GLM_ARCH_PPC		(GLM_ARCH_PPC_BIT)
270 
271 #if defined(GLM_FORCE_PURE)
272 #	define GLM_ARCH GLM_ARCH_PURE
273 #elif defined(GLM_FORCE_MIPS)
274 #	define GLM_ARCH (GLM_ARCH_MIPS)
275 #elif defined(GLM_FORCE_PPC)
276 #	define GLM_ARCH (GLM_ARCH_PPC)
277 #elif defined(GLM_FORCE_NEON)
278 #	define GLM_ARCH (GLM_ARCH_NEON)
279 #elif defined(GLM_FORCE_AVX512)
280 #	define GLM_ARCH (GLM_ARCH_AVX512)
281 #elif defined(GLM_FORCE_AVX2)
282 #	define GLM_ARCH (GLM_ARCH_AVX2)
283 #elif defined(GLM_FORCE_AVX)
284 #	define GLM_ARCH (GLM_ARCH_AVX)
285 #elif defined(GLM_FORCE_SSE42)
286 #	define GLM_ARCH (GLM_ARCH_SSE42)
287 #elif defined(GLM_FORCE_SSE41)
288 #	define GLM_ARCH (GLM_ARCH_SSE41)
289 #elif defined(GLM_FORCE_SSSE3)
290 #	define GLM_ARCH (GLM_ARCH_SSSE3)
291 #elif defined(GLM_FORCE_SSE3)
292 #	define GLM_ARCH (GLM_ARCH_SSE3)
293 #elif defined(GLM_FORCE_SSE2)
294 #	define GLM_ARCH (GLM_ARCH_SSE2)
295 #elif (GLM_COMPILER & (GLM_COMPILER_CLANG | GLM_COMPILER_GCC)) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_LINUX))
296 //	This is Skylake set of instruction set
297 #	if defined(__AVX512BW__) && defined(__AVX512F__) && defined(__AVX512CD__) && defined(__AVX512VL__) && defined(__AVX512DQ__)
298 #		define GLM_ARCH (GLM_ARCH_AVX512)
299 #	elif defined(__AVX2__)
300 #		define GLM_ARCH (GLM_ARCH_AVX2)
301 #	elif defined(__AVX__)
302 #		define GLM_ARCH (GLM_ARCH_AVX)
303 #	elif defined(__SSE4_2__)
304 #		define GLM_ARCH (GLM_ARCH_SSE42)
305 #	elif defined(__SSE4_1__)
306 #		define GLM_ARCH (GLM_ARCH_SSE41)
307 #	elif defined(__SSSE3__)
308 #		define GLM_ARCH (GLM_ARCH_SSSE3)
309 #	elif defined(__SSE3__)
310 #		define GLM_ARCH (GLM_ARCH_SSE3)
311 #	elif defined(__SSE2__)
312 #		define GLM_ARCH (GLM_ARCH_SSE2)
313 #	elif defined(__i386__) || defined(__x86_64__)
314 #		define GLM_ARCH (GLM_ARCH_X86)
315 #	elif defined(__ARM_NEON)
316 #		define GLM_ARCH (GLM_ARCH_ARM | GLM_ARCH_NEON)
317 #	elif defined(__arm__ )
318 #		define GLM_ARCH (GLM_ARCH_ARM)
319 #	elif defined(__mips__ )
320 #		define GLM_ARCH (GLM_ARCH_MIPS)
321 #	elif defined(__powerpc__ )
322 #		define GLM_ARCH (GLM_ARCH_PPC)
323 #	else
324 #		define GLM_ARCH (GLM_ARCH_PURE)
325 #	endif
326 #elif (GLM_COMPILER & GLM_COMPILER_VC) || ((GLM_COMPILER & GLM_COMPILER_INTEL) && (GLM_PLATFORM & GLM_PLATFORM_WINDOWS))
327 #	if defined(_M_ARM)
328 #		define GLM_ARCH (GLM_ARCH_ARM)
329 #	elif defined(__AVX2__)
330 #		define GLM_ARCH (GLM_ARCH_AVX2)
331 #	elif defined(__AVX__)
332 #		define GLM_ARCH (GLM_ARCH_AVX)
333 #	elif defined(_M_X64)
334 #		define GLM_ARCH (GLM_ARCH_SSE2)
335 #	elif defined(_M_IX86_FP)
336 #		if _M_IX86_FP >= 2
337 #			define GLM_ARCH (GLM_ARCH_SSE2)
338 #		else
339 #			define GLM_ARCH (GLM_ARCH_PURE)
340 #		endif
341 #	elif defined(_M_PPC)
342 #		define GLM_ARCH (GLM_ARCH_PPC)
343 #	else
344 #		define GLM_ARCH (GLM_ARCH_PURE)
345 #	endif
346 #else
347 #	define GLM_ARCH GLM_ARCH_PURE
348 #endif
349 
350 // With MinGW-W64, including intrinsic headers before intrin.h will produce some errors. The problem is
351 // that windows.h (and maybe other headers) will silently include intrin.h, which of course causes problems.
352 // To fix, we just explicitly include intrin.h here.
353 #if defined(__MINGW64__) && (GLM_ARCH != GLM_ARCH_PURE)
354 #	include <intrin.h>
355 #endif
356 
357 #if GLM_ARCH & GLM_ARCH_AVX2_BIT
358 #	include <immintrin.h>
359 #elif GLM_ARCH & GLM_ARCH_AVX_BIT
360 #	include <immintrin.h>
361 #elif GLM_ARCH & GLM_ARCH_SSE42_BIT
362 #	if GLM_COMPILER & GLM_COMPILER_CLANG
363 #		include <popcntintrin.h>
364 #	endif
365 #	include <nmmintrin.h>
366 #elif GLM_ARCH & GLM_ARCH_SSE41_BIT
367 #	include <smmintrin.h>
368 #elif GLM_ARCH & GLM_ARCH_SSSE3_BIT
369 #	include <tmmintrin.h>
370 #elif GLM_ARCH & GLM_ARCH_SSE3_BIT
371 #	include <pmmintrin.h>
372 #elif GLM_ARCH & GLM_ARCH_SSE2_BIT
373 #	include <emmintrin.h>
374 #endif//GLM_ARCH
375 
376 #if GLM_ARCH & GLM_ARCH_SSE2_BIT
377 	typedef __m128		glm_vec4;
378 	typedef __m128i		glm_ivec4;
379 	typedef __m128i		glm_uvec4;
380 #endif
381 
382 #if GLM_ARCH & GLM_ARCH_AVX_BIT
383 	typedef __m256d		glm_dvec4;
384 #endif
385 
386 #if GLM_ARCH & GLM_ARCH_AVX2_BIT
387 	typedef __m256i		glm_i64vec4;
388 	typedef __m256i		glm_u64vec4;
389 #endif
390