mirror of https://gitee.com/openkylin/qemu.git
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:
parent
fd1d9926e9
commit
2dc6bebde9
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue