diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2012-07-03 09:58:09 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2012-07-03 09:58:09 +0000 |
commit | 4262313b5381b47ee958f7046c7eea117929c62e (patch) | |
tree | d81cf07d598dc6f38e786c8a736a486581b47e99 | |
parent | 42a1976ec06574ab7a02d3751d8a9a34c3ceba3f (diff) | |
download | qemu-arm-4262313b5381b47ee958f7046c7eea117929c62e.tar.gz |
bitops.h: Add functions to extract and deposit bitfields
Add functions deposit32(), deposit64(), extract32() and extract64()
to extract and deposit bitfields in 32 and 64 bit words. Based on
ideas by Jia Liu and Avi Kivity.
Suggested-by: Jia Liu <proljc@gmail.com>
Suggested-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Eric Blake <eblake@redhat.com>
-rw-r--r-- | bitops.h | 66 |
1 files changed, 66 insertions, 0 deletions
@@ -269,4 +269,70 @@ static inline unsigned long hweight_long(unsigned long w) return count; } +/** + * extract32 - return a specified bit field from a uint32_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint32_t extract32(uint32_t value, int start, int length) +{ + assert(start >= 0 && length > 0 && length <= 32 - start); + return (value >> start) & (~0U >> (32 - length)); +} + +/** + * extract64 - return a specified bit field from a uint64_t value + * @value: The value to extract the bit field from + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * + * Returns the value of the bit field extracted from the input value. + */ +static inline uint64_t extract64(uint64_t value, int start, int length) +{ + assert(start >= 0 && length > 0 && length <= 64 - start); + return (value >> start) & (~0ULL >> (64 - length)); +} + +/** + * deposit32 - Insert into a specified bit field in a uint32_t + * @value: Initial value to insert bit field into + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * @fieldval: The value to insert into the bit field + * + * Returns the input value with the fieldval inserted + * into it at the specified location. + */ +static inline uint32_t deposit32(uint32_t value, int start, int length, + uint32_t fieldval) +{ + uint32_t mask; + assert(start >= 0 && length > 0 && length <= 32 - start); + mask = (~0U >> (32 - length)) << start; + return (value & ~mask) | ((fieldval << start) & mask); +} + +/** + * deposit64 - Insert into a specified bit field in a uint64_t + * @value: Initial value to insert bit field into + * @start: The lowest bit in the bit field (numbered from 0) + * @length: The length of the bit field + * @fieldval: The value to insert into the bit field + * + * Returns the input value with the fieldval inserted + * into it at the specified location. + */ +static inline uint64_t deposit64(uint64_t value, int start, int length, + uint64_t fieldval) +{ + uint64_t mask; + assert(start >= 0 && length > 0 && length <= 64 - start); + mask = (~0ULL >> (64 - length)) << start; + return (value & ~mask) | ((fieldval << start) & mask); +} + #endif |