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
|
#ifndef _ASMLANGUAGE
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/* Helper to pass a int as a pointer or vice-versa.
|
/* Helper to pass a int as a pointer or vice-versa.
|
||||||
* Those are available for 32 bits architectures:
|
* 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));
|
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 */
|
#endif /* !_ASMLANGUAGE */
|
||||||
|
|
||||||
/* KB, MB, GB */
|
/* KB, MB, GB */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue