From patchwork Fri Jul 6 14:48:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 9890 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id D393A23F2A for ; Fri, 6 Jul 2012 14:48:06 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id 70D71A1886F for ; Fri, 6 Jul 2012 14:48:06 +0000 (UTC) Received: by yenq6 with SMTP id q6so9288867yen.11 for ; Fri, 06 Jul 2012 07:48:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :content-transfer-encoding:x-gm-message-state; bh=1Q0zVc278BUFYHoUoa3/wWXpSkcuVS/ZS2lJpWC99RA=; b=BJLWjYJB/DufWPSaR2/y/GOpnZwQSEzVvOFGHyPbtypx6MHOzKHH9z7oops6Fup91k mZaduGRuTElE5QwceEXH/ry2Msy7oIiv9hwQhpI1ZjDI/qeB01nKr7q+J0S3MSo0aZXu f5tCNz0P4O7bvHyXNZSsMxPRtXqhKEVhoLdCFPVHAjXcoGuhf+vQTkli2g5j3VG+gJnx X2/rAW1N9k2gtfSUWnMt+duzLTXJo82bkK05QWi1II24a+0D5N4gVYtHWwMyJLKKyjEp RdUT51cxLfSjp/nVCXZ7sQV+fi+9zBWwPfvTsC9dKutrJmYdkVLEtESRtBAcH4grPJMC j+rw== Received: by 10.50.160.198 with SMTP id xm6mr2809957igb.0.1341586085749; Fri, 06 Jul 2012 07:48:05 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.24.148 with SMTP id v20csp12078ibb; Fri, 6 Jul 2012 07:48:04 -0700 (PDT) Received: by 10.216.181.67 with SMTP id k45mr7247170wem.17.1341586083879; Fri, 06 Jul 2012 07:48:03 -0700 (PDT) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [81.2.115.146]) by mx.google.com with ESMTPS id q2si7604187wiv.11.2012.07.06.07.48.03 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 06 Jul 2012 07:48:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) client-ip=81.2.115.146; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 81.2.115.146 as permitted sender) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1Sn9pA-0006HQ-O9; Fri, 06 Jul 2012 15:48:00 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Jia Liu , Blue Swirl , Avi Kivity , Eric Blake , =?UTF-8?q?Andreas=20F=C3=A4rber?= Subject: [PATCH v4] bitops.h: Add functions to extract and deposit bitfields Date: Fri, 6 Jul 2012 15:48:00 +0100 Message-Id: <1341586080-24117-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkB4uB/i5jRs60DMPL68pI14rOAc0/jreuTAnq0rfRoBSjTWOZWLPgHekSx+cGFOoZsv8x9 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 Suggested-by: Avi Kivity Signed-off-by: Peter Maydell Reviewed-by: Eric Blake Reviewed-by: Andreas Färber --- Changes: v1->v2: added missing brackets v2->v3: renamed field32,field64 to extract32,extract64 added deposit32,deposit64 at Avi's suggestion fixed assertion as per Jay Foad's suggestion v3->v4: fixed gtk-doc comment formats, expanded doc comments slightly I took the liberty of leaving Eric and Andreas' Reviewed-by: tags on since there are no code changes in v4, only doc comments. bitops.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 90 insertions(+), 0 deletions(-) diff --git a/bitops.h b/bitops.h index 07d1a06..b967ef3 100644 --- a/bitops.h +++ b/bitops.h @@ -269,4 +269,94 @@ static inline unsigned long hweight_long(unsigned long w) return count; } +/** + * extract32: + * @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. 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 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: + * @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. 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 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: + * @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 + * + * Deposit @fieldval into the 32 bit @value at the bit field specified + * by the @start and @length parameters, and return the modified + * @value. Bits of @value outside the bit field are not modified. + * Bits of @fieldval above the least significant @length bits are + * ignored. The bit field must lie entirely within the 32 bit word. + * It is valid to request that all 64 bits are modified (ie @length + * 64 and @start 0). + * + * Returns: the modified @value. + */ +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); +} + +/** + * deposit32: + * @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 + * + * Deposit @fieldval into the 64 bit @value at the bit field specified + * by the @start and @length parameters, and return the modified + * @value. Bits of @value outside the bit field are not modified. + * Bits of @fieldval above the least significant @length bits are + * ignored. The bit field must lie entirely within the 32 bit word. + * It is valid to request that all 64 bits are modified (ie @length + * 64 and @start 0). + * + * Returns: the modified @value. + */ +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