From 3efc88abbb6237f13859cf5ceb535e1a54a3003c Mon Sep 17 00:00:00 2001 From: "Herman S." <429230+has207@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:25:22 +0900 Subject: [PATCH] [Base] Fix math.h portability: use __builtin_ffs and fix lzcnt narrowing ffs() can collide with POSIX macro definitions on some platforms; __builtin_ffs is the portable GCC/Clang intrinsic. log2_floor/log2_ceil passed template types directly to lzcnt which has only uint32_t and uint64_t overloads, causing implicit narrowing on smaller types. --- src/xenia/base/math.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/xenia/base/math.h b/src/xenia/base/math.h index becb8a6a7..116f85b09 100644 --- a/src/xenia/base/math.h +++ b/src/xenia/base/math.h @@ -296,7 +296,7 @@ inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { } #else inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { - int i = ffs(v); + int i = __builtin_ffs(v); *out_first_set_index = i - 1; return i != 0; } @@ -315,11 +315,19 @@ inline bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) { template inline T log2_floor(T v) { - return sizeof(T) * 8 - 1 - lzcnt(v); + if constexpr (sizeof(T) <= sizeof(uint32_t)) { + return sizeof(T) * 8 - 1 - lzcnt(static_cast(v)); + } else { + return sizeof(T) * 8 - 1 - lzcnt(static_cast(v)); + } } template inline T log2_ceil(T v) { - return sizeof(T) * 8 - lzcnt(v - 1); + if constexpr (sizeof(T) <= sizeof(uint32_t)) { + return sizeof(T) * 8 - lzcnt(static_cast(v - 1)); + } else { + return sizeof(T) * 8 - lzcnt(static_cast(v - 1)); + } } template