Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751622AbdLLGUI (ORCPT ); Tue, 12 Dec 2017 01:20:08 -0500 Received: from zeniv.linux.org.uk ([195.92.253.2]:38068 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750731AbdLLGUG (ORCPT ); Tue, 12 Dec 2017 01:20:06 -0500 Date: Tue, 12 Dec 2017 06:20:02 +0000 From: Al Viro To: Jakub Kicinski Cc: Linus Torvalds , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC][PATCH] new byteorder primitives - ..._{replace,get}_bits() Message-ID: <20171212062002.GY21978@ZenIV.linux.org.uk> References: <20171210045326.GO21978@ZenIV.linux.org.uk> <420a198d-61f8-81cf-646d-10446cb41def@synopsys.com> <20171211050520.GV21978@ZenIV.linux.org.uk> <20171211053803.GW21978@ZenIV.linux.org.uk> <20171211155422.GA12326@ZenIV.linux.org.uk> <20171211200224.23bc5df4@cakuba.netronome.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171211200224.23bc5df4@cakuba.netronome.com> User-Agent: Mutt/1.9.0 (2017-09-02) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1671 Lines: 36 On Mon, Dec 11, 2017 at 08:02:24PM -0800, Jakub Kicinski wrote: > On Mon, 11 Dec 2017 15:54:22 +0000, Al Viro wrote: > > Essentially, it gives helpers for work with bitfields in fixed-endian. > > Suppose we have e.g. a little-endian 32bit value with fixed layout; > > expressing that as a bitfield would go like > > struct foo { > > unsigned foo:4; /* bits 0..3 */ > > unsigned :2; > > unsigned bar:12; /* bits 6..17 */ > > unsigned baz:14; /* bits 18..31 */ > > } > > Even for host-endian it doesn't work all that well - you end up with > > ifdefs in structure definition and generated code stinks. For fixed-endian > > it gets really painful, and people tend to use explicit shift-and-mask > > kind of macros for accessing the fields (and often enough get the > > endianness conversions wrong, at that). With these primitives > > > > struct foo v <=> __le32 v > > v.foo = i ? 1 : 2 <=> v = le32_replace_bits(v, i ? 1 : 2, 0, 4) > > f(4 + v.baz) <=> f(4 + le32_get_bits(v, 18, 14)) > > Looks very useful. The [start bit, size] pair may not land itself > too nicely to creating defines, though. Which is why in > include/linux/bitfield.h we tried to use a shifted mask and work > backwards from that single value what the start and size are. commit > 3e9b3112ec74 ("add basic register-field manipulation macros") has the > description. Could a similar trick perhaps be applicable here? Umm... What's wrong with #define FIELD_FOO 0,4 #define FIELD_BAR 6,12 #define FIELD_BAZ 18,14 A macro can bloody well expand to any sequence of tokens - le32_get_bits(v, FIELD_BAZ) will become le32_get_bits(v, 18, 14) just fine. What's the problem with that?