Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1536279 > unrolled thread

[PATCH v2] add equivalent of BIT(x) for bitfields

Started bySebastian Frias <sf84@laposte.net>
First post2016-12-05 18:50 +0100
Last post2016-12-06 11:40 +0100
Articles 3 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2] add equivalent of BIT(x) for bitfields Sebastian Frias <sf84@laposte.net> - 2016-12-05 18:50 +0100
    Re: [PATCH v2] add equivalent of BIT(x) for bitfields Linus Torvalds <torvalds@linux-foundation.org> - 2016-12-05 19:30 +0100
      Re: [PATCH v2] add equivalent of BIT(x) for bitfields Sebastian Frias <sf84@laposte.net> - 2016-12-06 11:40 +0100

#1536279 — [PATCH v2] add equivalent of BIT(x) for bitfields

FromSebastian Frias <sf84@laposte.net>
Date2016-12-05 18:50 +0100
Subject[PATCH v2] add equivalent of BIT(x) for bitfields
Message-ID<sL5yO-7xB-29@gated-at.bofh.it>
Introduce GENVALUE(msb, lsb, value) macro to ease dealing with
continuous bitfields, just as BIT(x) does for single bits.

GENVALUE_ULL(msb, lsb, value) macro is also added.

This is useful mostly for creating values to be packed together
via OR operations, ex:

   u32 val = 0x11110000;
   val |= GENVALUE(19, 12, 0x5a);

now 'val = 0x1115a000'


Signed-off-by: Sebastian Frias <sf84@laposte.net>
---

Change in v2:
- rename the macro to GENVALUE as proposed by Linus
- longer comment attempts to show use case for the macro as
proposed by Borislav

---
 include/linux/bitops.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index a83c822..641675d 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -24,6 +24,20 @@
 #define GENMASK_ULL(h, l) \
 	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 
+#ifdef	__KERNEL__
+/*
+ * Equivalent of BIT(x) but for contiguous bitfields
+ * GENVALUE(1, 0,0xff) = 0x00000003
+ * GENVALUE(3, 0,0xff) = 0x0000000f
+ * GENVALUE(15,8,0xff) = 0x0000ff00
+ * GENVALUE(6, 6,   1) = 0x00000040 == BIT(6)
+ */
+#define GENVALUE(msb, lsb, val)     \
+	(((val) << (lsb)) & (GENMASK((msb), (lsb))))
+#define GENVALUE_ULL(msb, lsb, val) \
+	(((val) << (lsb)) & (GENMASK_ULL((msb), (lsb))))
+#endif
+
 extern unsigned int __sw_hweight8(unsigned int w);
 extern unsigned int __sw_hweight16(unsigned int w);
 extern unsigned int __sw_hweight32(unsigned int w);
-- 
1.8.3.1

[toc] | [next] | [standalone]


#1536303

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2016-12-05 19:30 +0100
Message-ID<sL6bv-84q-13@gated-at.bofh.it>
In reply to#1536279
On Mon, Dec 5, 2016 at 9:49 AM, Sebastian Frias <sf84@laposte.net> wrote:
> Introduce GENVALUE(msb, lsb, value) macro to ease dealing with
> continuous bitfields, just as BIT(x) does for single bits.

Oh, and looking at the implementation, this is wrong. You use "lsb"
twice, so it mustn't have side effects.

That's fine for all expected users (since you'd expect that the only
real use of this is with constant values for msb/lsb), but please add
actual checking.

You can use BUILD_BUG_ON_ZERO(!__builtin_constant_p(x)) or something.
That returns zero, so it's easy to use in expressions.

             Linus

[toc] | [prev] | [next] | [standalone]


#1536841

FromSebastian Frias <sf84@laposte.net>
Date2016-12-06 11:40 +0100
Message-ID<sLlke-Rj-25@gated-at.bofh.it>
In reply to#1536303
On 05/12/16 19:23, Linus Torvalds wrote:
> On Mon, Dec 5, 2016 at 9:49 AM, Sebastian Frias <sf84@laposte.net> wrote:
>> Introduce GENVALUE(msb, lsb, value) macro to ease dealing with
>> continuous bitfields, just as BIT(x) does for single bits.
> 
> Oh, and looking at the implementation, this is wrong. You use "lsb"
> twice, so it mustn't have side effects.
> 
> That's fine for all expected users (since you'd expect that the only
> real use of this is with constant values for msb/lsb), 

Yes, that's what I thought.

>but please add
> actual checking.

Sure! Thanks for the advice.

> 
> You can use BUILD_BUG_ON_ZERO(!__builtin_constant_p(x)) or something.
> That returns zero, so it's easy to use in expressions.

Done. v3 of the patch is submitted.

> 
>              Linus
> 

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web