libpromeki
1.0.0-alpha
PROfessional MEdia toolKIt
Loading...
Searching...
No Matches
platform.h
Go to the documentation of this file.
1
9
#pragma once
10
11
12
#include <promeki/config.h>
13
#if PROMEKI_ENABLE_CORE
14
// ============================================================================
15
// Operating system detection
16
// ============================================================================
17
18
#if defined(__EMSCRIPTEN__)
19
#define PROMEKI_PLATFORM_EMSCRIPTEN 1
20
#define PROMEKI_PLATFORM "Emscripten"
21
#elif defined(_WIN64)
22
#define PROMEKI_PLATFORM_WINDOWS 64
23
#define PROMEKI_PLATFORM "Win64"
24
#elif defined(_WIN32)
25
#define PROMEKI_PLATFORM_WINDOWS 32
26
#define PROMEKI_PLATFORM "Win32"
27
#elif defined(__APPLE__)
28
#define PROMEKI_PLATFORM_APPLE 1
29
#define PROMEKI_PLATFORM "MacOS"
30
#elif defined(__linux__)
31
#define PROMEKI_PLATFORM_LINUX 1
32
#define PROMEKI_PLATFORM "Linux"
33
#elif defined(__FreeBSD__)
34
#define PROMEKI_PLATFORM_FREEBSD 1
35
#define PROMEKI_PLATFORM "FreeBSD"
36
#elif defined(__OpenBSD__)
37
#define PROMEKI_PLATFORM_OPENBSD 1
38
#define PROMEKI_PLATFORM "OpenBSD"
39
#else
40
#define PROMEKI_PLATFORM_UNKNOWN 1
41
#define PROMEKI_PLATFORM "Unknown"
42
#endif
43
44
// Convenience macro for any POSIX-like system (not Windows)
45
#if defined(PROMEKI_PLATFORM_LINUX) || defined(PROMEKI_PLATFORM_APPLE) || defined(PROMEKI_PLATFORM_FREEBSD) || \
46
defined(PROMEKI_PLATFORM_OPENBSD)
47
#define PROMEKI_PLATFORM_POSIX 1
48
#endif
49
50
// Convenience macro for any BSD-derived system
51
#if defined(PROMEKI_PLATFORM_FREEBSD) || defined(PROMEKI_PLATFORM_OPENBSD) || defined(PROMEKI_PLATFORM_APPLE)
52
#define PROMEKI_PLATFORM_BSD 1
53
#endif
54
55
// ============================================================================
56
// CPU architecture detection
57
// ============================================================================
58
//
59
// Exactly one of PROMEKI_ARCH_* is set for each build, plus PROMEKI_ARCH_64
60
// when the target ABI is 64-bit. PROMEKI_ARCH_NAME is a short string suitable
61
// for logging / build banners. See the ISA-capability macros below for
62
// SIMD-feature gating — never key SIMD code paths off the arch macros
63
// directly, since e.g. an x86_64 build may still be compiled without SSE
64
// enabled, and an arm32 build may or may not have NEON.
65
66
#if defined(__x86_64__) || defined(_M_X64)
67
#define PROMEKI_ARCH_X86_64 1
68
#define PROMEKI_ARCH_64 1
69
#define PROMEKI_ARCH_NAME "x86_64"
70
#elif defined(__i386__) || defined(_M_IX86)
71
#define PROMEKI_ARCH_X86 1
72
#define PROMEKI_ARCH_NAME "x86"
73
#elif defined(__aarch64__) || defined(_M_ARM64)
74
#define PROMEKI_ARCH_AARCH64 1
75
#define PROMEKI_ARCH_64 1
76
#define PROMEKI_ARCH_NAME "aarch64"
77
#elif defined(__arm__) || defined(_M_ARM)
78
#define PROMEKI_ARCH_ARM 1
79
#define PROMEKI_ARCH_NAME "arm"
80
#elif defined(__riscv) && (__riscv_xlen == 64)
81
#define PROMEKI_ARCH_RISCV64 1
82
#define PROMEKI_ARCH_64 1
83
#define PROMEKI_ARCH_NAME "riscv64"
84
#elif defined(__riscv)
85
#define PROMEKI_ARCH_RISCV 1
86
#define PROMEKI_ARCH_NAME "riscv"
87
#elif defined(__powerpc64__) || defined(__ppc64__)
88
#define PROMEKI_ARCH_PPC64 1
89
#define PROMEKI_ARCH_64 1
90
#define PROMEKI_ARCH_NAME "ppc64"
91
#elif defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__)
92
#define PROMEKI_ARCH_WASM 1
93
#if defined(__wasm64__)
94
#define PROMEKI_ARCH_64 1
95
#endif
96
#define PROMEKI_ARCH_NAME "wasm"
97
#else
98
#define PROMEKI_ARCH_UNKNOWN 1
99
#define PROMEKI_ARCH_NAME "Unknown"
100
#endif
101
102
// ============================================================================
103
// ISA capability detection
104
// ============================================================================
105
//
106
// Each PROMEKI_HAS_<FEATURE> is set to 1 when the corresponding instruction
107
// set is available at compile time and the matching intrinsics header has
108
// been pre-included by this header (or is safe to include). Code that wants
109
// to gate a SIMD path keys off these rather than off the arch macros — the
110
// arch is necessary but not sufficient (e.g. -march=armv8-a always has NEON,
111
// but armv7a builds may be compiled with or without -mfpu=neon).
112
//
113
// On x86, GCC / Clang define __SSE2__ / __SSE4_2__ / __AVX__ / __AVX2__ when
114
// the compiler has been told to target those. SSE2 is part of the x86_64
115
// ABI so it is always available on x86_64. On aarch64, NEON is part of the
116
// base ABI so it is always available; on arm32, __ARM_NEON gates it.
117
118
#if defined(__SSE2__) || defined(PROMEKI_ARCH_X86_64)
119
#define PROMEKI_HAS_SSE2 1
120
#endif
121
#if defined(__SSE3__)
122
#define PROMEKI_HAS_SSE3 1
123
#endif
124
#if defined(__SSSE3__)
125
#define PROMEKI_HAS_SSSE3 1
126
#endif
127
#if defined(__SSE4_1__)
128
#define PROMEKI_HAS_SSE4_1 1
129
#endif
130
#if defined(__SSE4_2__)
131
#define PROMEKI_HAS_SSE4_2 1
132
#endif
133
#if defined(__AVX__)
134
#define PROMEKI_HAS_AVX 1
135
#endif
136
#if defined(__AVX2__)
137
#define PROMEKI_HAS_AVX2 1
138
#endif
139
#if defined(__AVX512F__)
140
#define PROMEKI_HAS_AVX512F 1
141
#endif
142
143
// aarch64 always has NEON (mandatory in the base ABI); on arm32 it's gated
144
// by the compiler's -mfpu=neon flag, which sets __ARM_NEON.
145
#if defined(PROMEKI_ARCH_AARCH64) || defined(__ARM_NEON)
146
#define PROMEKI_HAS_NEON 1
147
#endif
148
149
// Convenience: any 128-bit float vector ISA we know how to write intrinsics
150
// for from a single PROMEKI_HAS_SIMD128 gate. Code that just wants "do I
151
// have a 128-bit float vector unit" can key off this.
152
#if defined(PROMEKI_HAS_SSE2) || defined(PROMEKI_HAS_NEON)
153
#define PROMEKI_HAS_SIMD128 1
154
#endif
155
156
// ============================================================================
157
// Compiler detection
158
// ============================================================================
159
160
// Note: Clang check must come before GCC check since Clang also defines __GNUC__
161
#if defined(__clang__)
162
#define PROMEKI_COMPILER_CLANG 1
163
#elif defined(__GNUC__)
164
#define PROMEKI_COMPILER_GCC 1
165
#elif defined(_MSC_VER)
166
#define PROMEKI_COMPILER_MSVC 1
167
#endif
168
169
// Convenience macro for GCC-compatible compilers (GCC or Clang)
170
#if defined(PROMEKI_COMPILER_GCC) || defined(PROMEKI_COMPILER_CLANG)
171
#define PROMEKI_COMPILER_GCC_COMPAT 1
172
#endif
173
174
// NVIDIA's nvcc is a driver around a host compiler (typically GCC or Clang),
175
// so this is set in addition to one of the host-compiler macros above when
176
// the current TU is being processed by nvcc. Use it to gate CUDA-only
177
// constructs (`#pragma unroll`, `__device__`, etc.).
178
#if defined(__CUDACC__)
179
#define PROMEKI_COMPILER_NVCC 1
180
#endif
181
182
// ============================================================================
183
// Compiler feature macros
184
// ============================================================================
185
186
// PROMEKI_UNROLL — request loop unrolling on the immediately-following loop.
187
// Clang and nvcc honour `#pragma unroll`; GCC ignores it (and warns under
188
// -Wunknown-pragmas, which we treat as an error in precommit). Falls back
189
// to a no-op everywhere else — at -O3, GCC will already unroll loops with
190
// constant trip counts on its own, so dropping the hint costs nothing in
191
// practice.
192
#if defined(PROMEKI_COMPILER_CLANG) || defined(PROMEKI_COMPILER_NVCC)
193
#define PROMEKI_UNROLL _Pragma("unroll")
194
#else
195
#define PROMEKI_UNROLL
196
#endif
197
198
// ============================================================================
199
// C library detection
200
// ============================================================================
201
202
#if defined(__GLIBC__)
203
#define PROMEKI_LIBC_GLIBC 1
204
#define PROMEKI_LIBC_GLIBC_VERSION_MAJOR __GLIBC__
205
#define PROMEKI_LIBC_GLIBC_VERSION_MINOR __GLIBC_MINOR__
206
#endif
207
208
#endif
// PROMEKI_ENABLE_CORE
include
promeki
platform.h
Generated on 2026-05-21 02:27:58 from commit ffbc5cc (1.0.0-alpha).