From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UsXFo-0007gV-LQ for qemu-devel@nongnu.org; Fri, 28 Jun 2013 07:54:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UsXFm-0005t6-0i for qemu-devel@nongnu.org; Fri, 28 Jun 2013 07:54:16 -0400 Received: from 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa ([2001:8b0:1d0::1]:58314 helo=mnementh.archaic.org.uk) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UsXFl-0005sx-Pf for qemu-devel@nongnu.org; Fri, 28 Jun 2013 07:54:13 -0400 From: Peter Maydell Date: Fri, 28 Jun 2013 12:40:31 +0100 Message-Id: <1372419632-5521-2-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1372419632-5521-1-git-send-email-peter.maydell@linaro.org> References: <1372419632-5521-1-git-send-email-peter.maydell@linaro.org> Subject: [Qemu-devel] [PATCH 1/2] bitops: Provide sextract32() and sextract64() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Richard Henderson , Markus Armbruster , patches@linaro.org 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 --- include/qemu/bitops.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h index affcc96..06e2e6f 100644 --- a/include/qemu/bitops.h +++ b/include/qemu/bitops.h @@ -222,6 +222,56 @@ static inline uint64_t extract64(uint64_t value, int start, int 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 * @start: the lowest bit in the bit field (numbered from 0) -- 1.7.9.5