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));
|
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:
|
* deposit32:
|
||||||
* @value: initial value to insert bit field into
|
* @value: initial value to insert bit field into
|
||||||
|
|
Loading…
Reference in New Issue