55#define OJPH_COMPILER_MSVC
56#elif (defined __GNUC__)
57#define OJPH_COMPILER_GNUC
61#define OJPH_EMSCRIPTEN
64#ifdef OJPH_COMPILER_MSVC
71#ifdef OJPH_COMPILER_MSVC
72 #define OJPH_FORCE_INLINE static __forceinline
73 #define OJPH_NO_INLINE static __declspec(noinline)
75 #define OJPH_FORCE_INLINE static inline __attribute__((always_inline))
76 #define OJPH_NO_INLINE static __attribute__((noinline))
82#if defined(__arm__) || defined(__TARGET_ARCH_ARM) \
83 || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
85#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
86 #define OJPH_ARCH_I386
87#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) \
89 #define OJPH_ARCH_X86_64
90#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
91 #define OJPH_ARCH_IA64
92#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
93 || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
94 || defined(_M_MPPC) || defined(_M_PPC)
95 #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
96 #define OJPH_ARCH_PPC64
101 #define OJPH_ARCH_UNKNOWN
105#if defined(OJPH_ARCH_PPC64) && \
106 (defined(__LITTLE_ENDIAN__) || \
107 (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
108 #define OJPH_ARCH_PPC64LE
115#if !defined(OJPH_ARCH_X86_64) && !defined(OJPH_ARCH_I386) && \
116 !defined(OJPH_ARCH_ARM) && !defined(OJPH_ARCH_PPC64LE) && \
117 !defined(OJPH_DISABLE_SIMD)
118#define OJPH_DISABLE_SIMD
124#if (defined WIN32) || (defined _WIN32) || (defined _WIN64)
125#define OJPH_OS_WINDOWS
126#elif (defined __APPLE__)
128#elif (defined __ANDROID__)
129#define OJPH_OS_ANDROID
130#elif (defined __linux)
132#elif (defined __FreeBSD__)
133#define OJPH_OS_FREEBSD
134#elif (defined __OpenBSD__)
135#define OJPH_OS_OPENBSD
141#if defined(OJPH_OS_WINDOWS) && defined(OJPH_BUILD_SHARED_LIBRARY)
142#define OJPH_EXPORT __declspec(dllexport)
187 #if defined(OJPH_COMPILER_MSVC) \
188 && (defined(OJPH_ARCH_X86_64) || defined(OJPH_ARCH_I386))
189 return (
ui32)__popcnt(val);
190 #elif (defined OJPH_COMPILER_GNUC)
191 return (
ui32)__builtin_popcount(val);
193 val -= ((val >> 1) & 0x55555555);
194 val = (((val >> 2) & 0x33333333) + (val & 0x33333333));
195 val = (((val >> 4) + val) & 0x0f0f0f0f);
198 return (
int)(val & 0x0000003f);
203#ifdef OJPH_COMPILER_MSVC
204 #pragma intrinsic(_BitScanReverse)
208 #ifdef OJPH_COMPILER_MSVC
209 unsigned long result = 0;
210 _BitScanReverse(&result, val);
211 return 31 ^ (
ui32)result;
212 #elif (defined OJPH_COMPILER_GNUC)
213 return (
ui32)__builtin_clz(val);
225#ifdef OJPH_COMPILER_MSVC
226 #if (defined OJPH_ARCH_X86_64 || defined OJPH_ARCH_ARM)
227 #pragma intrinsic(_BitScanReverse64)
228 #elif (defined OJPH_ARCH_I386)
229 #pragma intrinsic(_BitScanReverse)
231 #error Error unsupport MSVC version
236 #ifdef OJPH_COMPILER_MSVC
237 unsigned long result = 0;
238 #if (defined OJPH_ARCH_X86_64) || (defined OJPH_ARCH_ARM)
239 _BitScanReverse64(&result, val);
240 #elif (defined OJPH_ARCH_I386)
243 _BitScanReverse(&result, lsb);
245 _BitScanReverse(&result, msb);
249 #error Error unsupport MSVC version
251 return 63 ^ (
ui32)result;
252 #elif (defined OJPH_COMPILER_GNUC)
253 return (
ui32)__builtin_clzll(val);
261 return 64 - population_count64(val);
266#ifdef OJPH_COMPILER_MSVC
267 #pragma intrinsic(_BitScanForward)
271 #ifdef OJPH_COMPILER_MSVC
272 unsigned long result = 0;
273 _BitScanForward(&result, val);
275 #elif (defined OJPH_COMPILER_GNUC)
276 return (
ui32)__builtin_ctz(val);
288#ifdef OJPH_COMPILER_MSVC
289 #pragma intrinsic(_BitScanForward64)
293 #ifdef OJPH_COMPILER_MSVC
294 unsigned long result = 0;
295 #if (defined OJPH_ARCH_X86_64) || (defined OJPH_ARCH_ARM)
296 _BitScanForward64(&result, val);
297 #elif (defined OJPH_ARCH_I386)
300 _BitScanForward(&result, lsb);
302 _BitScanForward(&result, msb);
307 #elif (defined OJPH_COMPILER_GNUC)
308 return (
ui32)__builtin_ctzll(val);
319 #ifdef OJPH_COMPILER_MSVC
320 return (
si32)(val + (val >= 0.0f ? 0.5f : -0.5f));
321 #elif (defined OJPH_COMPILER_GNUC)
322 return (
si32)(val + (val >= 0.0f ? 0.5f : -0.5f));
324 return (
si32)round(val);
331 #ifdef OJPH_COMPILER_MSVC
333 #elif (defined OJPH_COMPILER_GNUC)
336 return (
si32)trunc(val);
343 #ifndef OJPH_EMSCRIPTEN
359 template <
typename T, ui32 N>
369 template <
typename T, ui32 N>
371 intptr_t p =
reinterpret_cast<intptr_t
>(ptr);
374 return reinterpret_cast<T *
>(p);
384#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
386#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
388#elif defined(OJPH_COMPILER_MSVC)
396 const uint16_t n = 0x0001;
410 return (
ui16)((t << 8) | (t >> 8));
417 return (
ui16)((t << 8) | (t >> 8));
473 std::memcpy(&val, p,
sizeof(val));
477 return (
ui32)p[0] | ((
ui32)p[1] << 8)
478 | ((
ui32)p[2] << 16) | ((
ui32)p[3] << 24);
489 std::memcpy(&val, p,
sizeof(val));
493 return (
ui32)p[0] | ((
ui32)p[1] << 16);
const ui32 object_alignment
static ui16 swap_bytes_if_le(ui16 t)
@ ARM_CPU_EXT_LEVEL_GENERIC
@ ARM_CPU_EXT_LEVEL_ASIMD
const ui32 byte_alignment
const bool is_machine_little_endian
static si32 ojph_round(float val)
static bool check_if_machine_is_little_endian()
static ui32 load_le_ui16x2(const ui16 *p)
static ui32 load_le_ui32(const ui8 *p)
size_t calc_aligned_size(size_t size)
@ PPC_CPU_EXT_LEVEL_ARCH_3_1
@ PPC_CPU_EXT_LEVEL_GENERIC
@ PPC_CPU_EXT_LEVEL_ARCH_3_00
static ui32 population_count(ui32 val)
static ui16 swap_bytes_if_be(ui16 t)
OJPH_EXPORT int get_cpu_ext_level()
static si32 ojph_trunc(float val)
static ui32 count_trailing_zeros(ui32 val)
static ui32 count_leading_zeros(ui32 val)
const ui32 log_byte_alignment
@ X86_CPU_EXT_LEVEL_AVX512
@ X86_CPU_EXT_LEVEL_GENERIC
@ X86_CPU_EXT_LEVEL_SSE41
@ X86_CPU_EXT_LEVEL_SSE42
@ X86_CPU_EXT_LEVEL_SSSE3
@ X86_CPU_EXT_LEVEL_AVX2FMA