2
3
4
5
6
7
8
9
10
11
12
13
14
23# include <type_traits>
27
28
29
42# define SHZ_BACKEND SHZ_SH4
49
50
51
52#define SHZ_TLS_DISABLED 0
53#define SHZ_TLS_IMPLICIT 1
54#define SHZ_TLS_PTHREAD 2
55#define SHZ_TLS_CTHREAD 3
61# define SHZ_TLS_MODEL SHZ_TLS_IMPLICIT
68
69
70
73#elif defined(__GNUC__
)
75# if defined(__clang__
)
77# elif defined(__MINGW64__)
79# elif defined(__MINGW32__)
90
91
92
94#define SHZ_STRINGIFY_LITERAL(a) #a
98#define SHZ_COUNT_OF(array) (sizeof(array) / sizeof((array)[0
]))
100#define SHZ_CONTAINER_OF(ptr, type, member) ((type*)((char*)(ptr) - offsetof(type, member)))
102#define SHZ_SWAP(a, b) do { typeof(a) tmp = a; a = b; b = tmp; } while(false)
104#define SHZ_DECLARE_STRUCT(n, t) struct n; typedef struct n t
106#define SHZ_DECLARE_STRUCT_ALIGNED(n, t, a) struct SHZ_ALIGNAS
(a) n; typedef struct n t
111
112
113
116# define SHZ_ALIGNAS(N) __attribute__((aligned((N))))
118# define SHZ_SIMD(N) __attribute__((vector_size((N))))
120# define SHZ_HOT __attribute__((hot))
122# define SHZ_COLD __attribute__((cold))
124# define SHZ_FAST_MATH __attribute__((optimize("fast-math")))
126# define SHZ_NO_FAST_MATH __attribute__((optimize("no-fast-math")))
128# define SHZ_NO_UNROLL_LOOPS __attribute__((optimize("no-unroll-loops")))
130# define SHZ_NO_OPTIMIZATION __attribute__((optimize("O0")))
132# define SHZ_FUNC_ALIGNAS(N) __attribute__((aligned(N)))
134# define SHZ_FORCE_INLINE __attribute__((always_inline)) SHZ_INLINE
136# define SHZ_NO_INLINE __attribute__((noinline))
138# define SHZ_FLATTEN __attribute__((flatten))
140# define SHZ_PACKED __attribute__((packed))
142# define SHZ_PURE __attribute__((pure))
144# define SHZ_CONST __attribute__((const))
146# define SHZ_ALIASING __attribute__((__may_alias__))
148# define SHZ_LIKELY(e) __builtin_expect(!!(e), 1
)
150# define SHZ_UNLIKELY(e) __builtin_expect(!!(e), 0
)
152# define SHZ_PREFETCH(a) __builtin_prefetch(a)
154# define SHZ_RESTRICT __restrict__
156# define SHZ_MEMORY_BARRIER_SOFT() asm volatile("" : : : "memory")
158# define SHZ_MEMORY_BARRIER_HARD() __sync_synchronize()
159#elif defined(SHZ_MSVC)
161# define SHZ_ALIGNAS(N) __declspec(align(N))
169# define SHZ_FAST_MATH
171# define SHZ_NO_FAST_MATH
173# define SHZ_NO_UNROLL_LOOPS
175# define SHZ_NO_OPTIMIZATION
177# define SHZ_FUNC_ALIGNAS(N)
179# define SHZ_FORCE_INLINE __forceinline
181# define SHZ_NO_INLINE __declspec(noinline)
187# define SHZ_PURE SHZ_CONST
189# define SHZ_CONST constexpr
193# define SHZ_LIKELY(e) (e)
195# define SHZ_UNLIKELY(e) (e)
197# define SHZ_PREFETCH(a)
199# define SHZ_RESTRICT __restrict
201# define SHZ_MEMORY_BARRIER_SOFT()
203# define SHZ_MEMORY_BARRIER_HARD()
208# define SHZ_DECLS_BEGIN
210# define SHZ_DECLS_END
212# define SHZ_INLINE inline static
216# define SHZ_INIT(type, ...) ((type){ __VA_ARGS__ })
218# define SHZ_CONVERT(type, value)
224 static_assert(sizeof(type) == sizeof(value), "SHZ_CONVERT: Cannot convert between types of differing sizes.");
228# define SHZ_DECLS_BEGIN extern "C" {
230# define SHZ_DECLS_END }
232# define SHZ_INLINE inline
234# define SHZ_NOEXCEPT noexcept
236# define SHZ_INIT(type, ...) (type{ __VA_ARGS__ })
238# define SHZ_CONVERT(type, from)
239 [&]<typename To, typename V>(V&& value) -> To {
240 using TNR = std::remove_reference_t<To>;
241 using VNR = std::remove_reference_t<V>;
242 if constexpr (std::is_pointer_v<To>) {
243 if constexpr (std::is_pointer_v<VNR>) {
244 return reinterpret_cast<To>(value);
246 return reinterpret_cast<To>(&value);
248 } else if constexpr (std::is_reference_v<To>) {
249 static_assert(sizeof(VNR) == sizeof(TNR), "SHZ_CONVERT: Cannot convert between types of differing sizes when converting to a reference type.");
250 return reinterpret_cast<To>(value);
252 static_assert(sizeof(VNR) == sizeof(TNR), "SHZ_CONVERT: Cannot convert between types of differing sizes.");
253 return reinterpret_cast<To&>(value);
255 }.template operator
()<type>(from)
261
262
263
266# define SHZ_TLS_DECL(type, name, ...) static type name = __VA_ARGS__;
268# define SHZ_TLS_REF(name) (&name)
274# define SHZ_TLS_DECL(type, name, ...) static thread_local type name = __VA_ARGS__;
276# define SHZ_TLS_REF(name) (&name)
281# define SHZ_TLS_DECL(type, name, ...)
282 static pthread_key_t name;
283 static void tls_##name##_init_(void) {
284 int res = pthread_key_create(&name, free);
285 (void)res; assert
(!res);
287 static type* tls_##name##_ref_(void) {
288 static pthread_once_t once_ctrl = PTHREAD_ONCE_INIT
;
289 int ret = pthread_once(&once_ctrl, tls_##name##_init_);
290 (void)ret; assert
(!ret);
291 type* ptr = pthread_getspecific(name);
293 ptr = (type *)malloc(sizeof(type));
295 type temp = __VA_ARGS__;
296 memcpy(ptr, &temp, sizeof(type));
297 ret = pthread_setspecific(name, ptr);
303# define SHZ_TLS_REF(name) tls_##name##_ref_()
304#elif SHZ_TLS_MODEL == SHZ_TLS_CTHREAD
308# define SHZ_TLS_DECL(type, name, ...)
310 static void tls_##name##_init_(void) {
311 int res = tss_create(&name, free);
312 (void)res; assert(res == thrd_success);
314 static type* tls_##name##_ref_(void) {
315 static once_flag once_ctrl = ONCE_FLAG_INIT;
316 call_once(&once_ctrl, tls_##name##_init_);
317 type* ptr = (type *)tss_get(name);
319 ptr = (type *)malloc(sizeof(type));
321 type temp = __VA_ARGS__;
322 memcpy(ptr, &temp, sizeof(type));
323 int res = tss_set(name, ptr);
324 (void)res; assert(res == thrd_success);
329# define SHZ_TLS_REF(name) tls_##name##_ref_()
334
335
336
#define SHZ_SH4
Back-end for the Dreamcast's SH4.
SHZ_ALIASING int16_t shz_alias_int16_t
int16_t type whose value may be aliased as another type.
SHZ_ALIASING double shz_alias_double_t
double type whose value may be aliased as another type.
#define SHZ_TLS_IMPLICIT
Use thread_local keyword for TLS.
SHZ_ALIASING uint32_t shz_alias_uint32_t
uint32_t type whose value may be aliased as another type.
#define SHZ_SW
Generic C-based software back-end.
#define SHZ_STRINGIFY_LITERAL(a)
Stringifies a literal expression.
SHZ_ALIASING int64_t shz_alias_int64_t
int64_t type whose value may be aliased as another type.
SHZ_ALIASING uint16_t shz_alias_uint16_t
uint16_t type whose value may be aliased as another type.
SHZ_ALIASING int32_t shz_alias_int32_t
int32_t type whose value may be aliased as another type.
SHZ_ALIASING uint64_t shz_alias_uint64_t
uint64_t type whose value may be aliased as another type.
SHZ_ALIASING float shz_alias_float_t
float type whose value may be aliased as another type.
#define SHZ_TLS_PTHREAD
Use pthread unique keys for TLS.
#define SHZ_TLS_DISABLED
No thread-local variables.