bitops: Provide sextract32() and sextract64()

A common operation in instruction decoding is to take a field
from an instruction that represents a signed integer in some
arbitrary number of bits, and sign extend it into a C signed
integer type for manipulation. Provide new functions sextract32()
and sextract64() which perform this operation; they are like
the existing extract32() and extract64() except that the field
is sign-extended into the returned result.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Message-id: 1372419632-5521-2-git-send-email-peter.maydell@linaro.org
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Peter Maydell 2013-06-28 12:40:31 +01:00 committed by Anthony Liguori
parent fd1d9926e9
commit 2dc6bebde9
1 changed files with 50 additions and 0 deletions

View File

@ -221,6 +221,56 @@ static inline uint64_t extract64(uint64_t value, int start, int length)
return (value >> start) & (~0ULL >> (64 - length));
}
/**
* sextract32:
* @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
*
* Extract from the 32 bit input @value the bit field specified by the
* @start and @length parameters, and return it, sign extended to
* an int32_t (ie with the most significant bit of the field propagated
* to all the upper bits of the return value). The bit field must lie
* entirely within the 32 bit word. It is valid to request that
* all 32 bits are returned (ie @length 32 and @start 0).
*
* Returns: the sign extended value of the bit field extracted from the
* input value.
*/
static inline int32_t sextract32(uint32_t value, int start, int length)
{
assert(start >= 0 && length > 0 && length <= 32 - start);
/* Note that this implementation relies on right shift of signed
* integers being an arithmetic shift.
*/
return ((int32_t)(value << (32 - length - start))) >> (32 - length);
}
/**
* sextract64:
* @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
*
* Extract from the 64 bit input @value the bit field specified by the
* @start and @length parameters, and return it, sign extended to
* an int64_t (ie with the most significant bit of the field propagated
* to all the upper bits of the return value). The bit field must lie
* entirely within the 64 bit word. It is valid to request that
* all 64 bits are returned (ie @length 64 and @start 0).
*
* Returns: the sign extended value of the bit field extracted from the
* input value.
*/
static inline uint64_t sextract64(uint64_t value, int start, int length)
{
assert(start >= 0 && length > 0 && length <= 64 - start);
/* Note that this implementation relies on right shift of signed
* integers being an arithmetic shift.
*/
return ((int64_t)(value << (64 - length - start))) >> (64 - length);
}
/**
* deposit32:
* @value: initial value to insert bit field into