HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
macros.hpp
1// Copyright Take Vos 2024.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#if defined(_MSC_BUILD)
8#include <intrin.h>
9#endif
10#include <version>
11#include <exception>
12
13// All the HI_HAS_* macros tell us if the compiler will generate code with these instructions.
14// Therefor we can use intrinsics for these instructions without checking the cpu-id.
15// Which instrinsics are available is handled by a different macro.
16
17#if defined(HI_GENERIC)
18// Nothing defined when generic.
19
20// MSVC platform detection.
21// - _M_AMD64 determines if the processor is 64 bit, both x86-64 and arm64.
22// - _M_IX86 is not defined on x86-64, but _M_IX86_FP is.
23#elif defined(_M_IX86_FP)
24#define HI_HAS_X86 1
25#if defined(_M_AMD64)
26#define HI_HAS_X86_64 1
27#endif
28#elif defined(_M_ARM_FP)
29#define HI_HAS_ARM 1
30#if defined(_M_AMD64)
31#define HI_HAS_ARM64 1
32#endif
33
34// clang/gcc platform detection
35#elif defined(__amd64__) or defined(__amd64) or defined(__x86_64__) or defined(__x86_64) or defined(_M_AMD64) or defined(_M_X64)
36#define HI_HAS_X86 1
37#define HI_HAS_X86_64 1
38#elif defined(__aarch64__) or defined(_M_ARM64)
39#define HI_HAS_ARM 1
40#define HI_HAS_ARM64 1
41#elif defined(__i386__) or defined(_M_IX86)
42#define HI_HAS_X86 1
43#elif defined(__arm__) or defined(__arm) or defined(_ARM) or defined(_M_ARM)
44#define HI_HAS_ARM 1
45#endif
46
47#if defined(HI_GENERIC)
48// Don't add any cpu features.
49
50// Detect MSVC /arch option for x86 features.
51#elif defined(_M_IX86_FP)
52// MSVC /arch:SSE (x86)
53#if _M_IX86_FP >= 1 or defined(HI_HAS_X86_64)
54#define HI_HAS_SSE 1
55#define HI_HAS_MMX 1
56#define HI_HAS_SCE 1
57#define HI_HAS_OSFXSR 1
58#define HI_HAS_FXSR 1
59#define HI_HAS_FPU 1
60#define HI_HAS_CX8 1
61#define HI_HAS_CMOV 1
62#endif
63
64// MSVC /arch:SSE2 (x86)
65#if _M_IX86_FP >= 2 or defined(HI_HAS_X86_64)
66#define HI_HAS_SSE2 1
67#endif
68
69// MSVC /arch:AVX (x86-64-v2)
70#if defined(__AVX__)
71#define HI_HAS_SSSE3 1
72#define HI_HAS_SSE4_1 1
73#define HI_HAS_SSE4_2 1
74#define HI_HAS_SSE3 1
75#define HI_HAS_POPCNT 1
76#define HI_HAS_LAHF 1
77#define HI_HAS_CX16 1
78#define HI_HAS_AVX 1
79#endif
80
81// MSVC /arch:AVX2 (x86-64-v3)
82#if defined(__AVX2__)
83#define HI_HAS_AVX2 1
84#define HI_HAS_BMI1 1
85#define HI_HAS_BMI2 1
86#define HI_HAS_F16C 1
87#define HI_HAS_FMA 1
88#define HI_HAS_LZCNT 1
89#define HI_HAS_MOVBE 1
90#define HI_HAS_OSXSAVE 1
91#endif
92
93// MSVC /arch:AVX512 (x86-64-v4)
94#if defined(__AVX512F__) and defined(__AVX512BW__) and defined(__AVX512CD__) and defined(__AVX512DQ__) and defined(__AVX512VL__)
95#define HI_HAS_AVX512F 1
96#define HI_HAS_AVX512BW 1
97#define HI_HAS_AVX512CD 1
98#define HI_HAS_AVX512DQ 1
99#define HI_HAS_AVX512VL 1
100#endif
101
102// Detect MSVC /arch option for arm features.
103#elif defined(_M_ARM_FP)
104#if _M_ARM_FP >= 30 and _M_ARM_FP < 40
105#define HI_HAS_VFP3
106#endif
107#if _M_ARM_FP >= 40 and _M_ARM_FP < 50
108#define HI_HAS_VFP4
109#endif
110
111// Check for other CPU features from individual macro definition on compilers
112// other than MSVC.
113#else
114#if defined(__MMX__)
115#define HI_HAS_MMX 1
116#endif
117#if defined(__SSE__)
118#define HI_HAS_SSE 1
119#endif
120#if defined(__SSE2__)
121#define HI_HAS_SSE2 1
122#endif
123#if defined(__SSE3__)
124#define HI_HAS_SSE3 1
125#endif
126#if defined(__SSSE3__)
127#define HI_HAS_SSSE3 1
128#endif
129#if defined(__SSE4_1__)
130#define HI_HAS_SSE4_1 1
131#endif
132#if defined(__SSE4_2__)
133#define HI_HAS_SSE4_2 1
134#endif
135#if defined(__POPCNT__)
136#define HI_HAS_POPCNT 1
137#endif
138#if defined(__LAHF_SAHF__)
139#define HI_HAS_LAHF 1
140#endif
141#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
142#define HI_HAS_CX16 1
143#endif
144#if defined(__AVX__)
145#define HI_HAS_AVX 1
146#endif
147#if defined(__AVX2__)
148#define HI_HAS_AVX2 1
149#endif
150#if defined(__BMI__)
151#define HI_HAS_BMI1 1
152#endif
153#if defined(__BMI2__)
154#define HI_HAS_BMI2 1
155#endif
156#if defined(__F16C__)
157#define HI_HAS_F16C 1
158#endif
159#if defined(__FMA__)
160#define HI_HAS_FMA 1
161#endif
162#if defined(__LZCNT__)
163#define HI_HAS_LZCNT 1
164#endif
165#if defined(__MOVBE__)
166#define HI_HAS_MOVBE 1
167#endif
168#if defined(__XSAVE__)
169#define HI_HAS_XSAVE 1
170#endif
171#if defined(__AVX512BW__)
172#define HI_HAS_AVX512BW 1
173#endif
174#if defined(__AVX512CD__)
175#define HI_HAS_AVX512CD 1
176#endif
177#if defined(__AVX512DQ__)
178#define HI_HAS_AVX512DQ 1
179#endif
180#if defined(__AVX512F__)
181#define HI_HAS_AVX512F 1
182#endif
183#if defined(__AVX512VL__)
184#define HI_HAS_AVX512VL 1
185#endif
186#if defined(__SHA__)
187#define HI_HAS_SHA 1
188#endif
189#if defined(__AES__)
190#define HI_HAS_AES 1
191#endif
192#if defined(__PCLMUL__)
193#define HI_HAS_PCLMUL 1
194#endif
195#if defined(__RDRND__)
196#define HI_HAS_RDRND 1
197#endif
198#if defined(__RDSEED__)
199#define HI_HAS_RDSEED 1
200#endif
201#endif
202
203// clang-format off
204#if defined(HI_HAS_SSE2) and defined(HI_HAS_SSE) and defined(HI_HAS_SCE) and \
205 defined(HI_HAS_OSFXSR) and defined(HI_HAS_MMX) and defined(HI_HAS_FXSR) and \
206 defined(HI_HAS_FPU) and defined(HI_HAS_CX8) and defined(HI_HAS_CMOV)
207#define HI_HAS_X86_64_V1 1
208#endif
209
210#if defined(HI_HAS_X86_64_V1) and defined(HI_HAS_SSSE3) and defined(HI_HAS_SSE4_1) and \
211 defined(HI_HAS_SSE4_2) and defined(HI_HAS_SSE3) and defined(HI_HAS_POPCNT) and \
212 defined(HI_HAS_LAHF) and defined(HI_HAS_CX16)
213#define HI_HAS_X86_64_V2 1
214#endif
215
216#if defined(HI_HAS_X86_64_V2) and defined(HI_HAS_AVX) and defined(HI_HAS_AVX2) and \
217 defined(HI_HAS_BMI1) and defined(HI_HAS_BMI2) and defined(HI_HAS_F16C) and \
218 defined(HI_HAS_FMA) and defined(HI_HAS_LZCNT) and defined(HI_HAS_MOVBE) and \
219 defined(HI_HAS_OSXSAVE)
220#define HI_HAS_X86_64_V3 1
221#endif
222
223#if defined(HI_HAS_X86_64_V3) and defined(HI_HAS_AVX512F) and defined(HI_HAS_AVX512BW) and \
224 defined(HI_HAS_AVX512CD) and defined(HI_HAS_AVX512DQ) and defined(HI_HAS_AVX512VL)
225#define HI_HAS_X86_64_V4 1
226#endif
227// clang-format on
228
229#ifndef hi_stringify
230#define hi_stringify_(x) #x
231#define hi_stringify(x) hi_stringify_(x)
232#endif
233
234#ifndef hi_keywords
235#define hi_keywords
236#define hi_export
237#define hi_export_module(...)
238#if defined(__clang__) or defined(__GNUC__)
239#define hi_target(...) [[gnu::target(__VA_ARGS__)]]
240#define hi_no_inline [[gnu::noinline]]
241#define hi_force_inline [[gnu::always_inline]]
242#define hi_restrict __restrict__
243#define hi_warning_push() _Pragma("warning(push)")
244#define hi_warning_pop() _Pragma("warning(push)")
245#define hi_warning_ignore_msvc(...)
246#define hi_warning_ignore_clang(...) _Pragma(hi_stringify(clang diagnostic ignored __VA_ARGS__))
247#define hi_warning_ignore_gcc(...)
248#define hi_no_sanitize_address
249#define hi_assume(...) __builtin_assume(not not(__VA_ARGS__))
250#define hi_assert_break() __builtin_trap()
251#define hi_debug_break() __builtin_debugtrap()
252#elif defined(_MSC_BUILD)
253#define hi_target(...)
254#define hi_no_inline [[msvc::noinline]]
255#define hi_force_inline [[msvc::forceinline]]
256#define hi_restrict __restrict
257#define hi_warning_push() _Pragma("warning( push )")
258#define hi_warning_pop() _Pragma("warning( pop )")
259#define hi_warning_ignore_msvc(...) _Pragma(hi_stringify(warning(disable : __VA_ARGS__)))
260#define hi_warning_ignore_clang(...)
261#define hi_warning_ignore_gcc(...)
262#define hi_no_sanitize_address __declspec(no_sanitize_address)
263#define hi_assume(...) __assume(not not(__VA_ARGS__))
264#define hi_assert_break() __int2c()
265#define hi_debug_break() __debugbreak()
266#else
267#define hi_target(...)
268#define hi_no_inline
269#define hi_force_inline
270#define hi_restrict
271#define hi_warning_push()
272#define hi_warning_pop()
273#define hi_warning_ignore_msvc(...)
274#define hi_warning_ignore_clang(...)
275#define hi_warning_ignore_gcc(...)
276#define hi_no_sanitize_address
277#define hi_assume(...) static_assert(std::convertible_to<decltype(not not(__VA_ARGS__)), bool>)
278#define hi_assert_break() std::terminate()
279#define hi_debug_break() std::terminate()
280#endif
281#endif