util: add portable arithmetic shift right
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 <bogdan.m.davidoaia@intel.com>
This commit is contained in:
parent
c632271879
commit
bcca0dcbbd
1 changed files with 21 additions and 0 deletions
|
@ -30,6 +30,8 @@ extern "C" {
|
|||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* 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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue