diff options
-rw-r--r-- | common/math_util.c | 40 | ||||
-rw-r--r-- | include/math_util.h | 10 |
2 files changed, 50 insertions, 0 deletions
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 <stdint.h> +#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 */ |