From bcca0dcbbd7a7ff1c634ef44678fc0ee52d5125d Mon Sep 17 00:00:00 2001 From: Bogdan Davidoaia Date: Tue, 28 Jun 2016 14:20:46 +0300 Subject: [PATCH] util: add portable arithmetic shift right MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add arithmetic_shift_right function, as the behaviour for shifting right a negative signed value is implementation-defined (see ISO/IEC 9899 ยง6.5.7). Change-Id: I05d930a96e8591dc248295bff853ed9e9cb263a2 Signed-off-by: Bogdan Davidoaia --- include/misc/util.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/misc/util.h b/include/misc/util.h index 5d68386d554..80ce2c83cec 100644 --- a/include/misc/util.h +++ b/include/misc/util.h @@ -30,6 +30,8 @@ extern "C" { #ifndef _ASMLANGUAGE +#include + /* Helper to pass a int as a pointer or vice-versa. * Those are available for 32 bits architectures: */ @@ -66,6 +68,25 @@ static inline int is_power_of_two(unsigned int x) { return (x != 0) && !(x & (x - 1)); } + +static inline int64_t arithmetic_shift_right(int64_t value, uint8_t shift) +{ + int64_t sign_ext; + + if (shift == 0) { + return value; + } + + /* extract sign bit */ + sign_ext = (value >> 63) & 1; + + /* make all bits of sign_ext be the same as the value's sign bit */ + sign_ext = -sign_ext; + + /* shift value and fill opened bit positions with sign bit */ + return (value >> shift) | (sign_ext << (64 - shift)); +} + #endif /* !_ASMLANGUAGE */ /* KB, MB, GB */