From 43e1a59c047bd28917251d13e47e00594624b277 Mon Sep 17 00:00:00 2001 From: Denis Brockus Date: Fri, 24 Sep 2021 09:37:27 -0600 Subject: math_util: add creation of 64 bit bitmasks 32 bit processors don't all allow left shift of 64 bit values. So add this to make it work with 32 and 64 bit processors. uint64_t bitmask_uint64(int offset); BUG=none BRANCH=none TEST=make buildall Signed-off-by: Denis Brockus Change-Id: I114111c4774bb935a35c7711821b1f2f2f9c037d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3182630 Tested-by: Denis Brockus Auto-Submit: Denis Brockus Commit-Queue: Yuval Peress Reviewed-by: Yuval Peress --- common/math_util.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/math_util.h | 10 ++++++++++ 2 files changed, 50 insertions(+) diff --git a/common/math_util.c b/common/math_util.c index 8e07b678a5..52b0879626 100644 --- a/common/math_util.c +++ b/common/math_util.c @@ -293,3 +293,43 @@ int round_divide(int64_t dividend, int divisor) (dividend - divisor / 2) / divisor : (dividend + divisor / 2) / divisor; } + +#if ULONG_MAX == 0xFFFFFFFFUL +/* + * 32 bit processor + * + * Some 32 bit processors do not include a 64 bit shift + * operation. So fall back to 32 bit operations on a + * union. + */ +uint64_t bitmask_uint64(int offset) +{ + union mask64_t { + struct { +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + uint32_t lo; + uint32_t hi; +#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + uint32_t hi; + uint32_t lo; +#endif + }; + uint64_t val; + } mask; + + /* Clear out the mask */ + mask.val = 0; + + /* + * If the shift is out of range the result should + * remain 0, otherwise perform the shift + */ + if (offset >= 0 && offset < 64) { + if (offset < 32) + mask.lo = BIT(offset); + else + mask.hi = BIT(offset - 32); + } + return mask.val; +} +#endif diff --git a/include/math_util.h b/include/math_util.h index b78523de54..9ee075839e 100644 --- a/include/math_util.h +++ b/include/math_util.h @@ -9,6 +9,7 @@ #define __CROS_EC_MATH_UTIL_H #include +#include "limits.h" #ifdef CONFIG_FPU typedef float fp_t; @@ -230,4 +231,13 @@ void rotate_inv(const intv3_t v, const mat33_fp_t R, intv3_t res); */ int round_divide(int64_t dividend, int divisor); +/** + * Create a 64 bit bitmask of 2^offset + */ +#if ULONG_MAX == 0xFFFFFFFFUL +uint64_t bitmask_uint64(int offset); +#else +#define bitmask_uint64(o) ((uint64_t)1 << (o)) +#endif + #endif /* __CROS_EC_MATH_UTIL_H */ -- cgit v1.2.1