.../staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Simplified masking logic in pci/hive_isp_css_common/host/vmem.c.
---
I have tested this change on whole range of *valid* inputs, and it gives
the same results as before, but this function seems to be little
counter-intuitive as far as start is a (bit index) but end is
(bit index + 1).
It is follow up to: https://lore.kernel.org/linux-staging/20250901091050.1935505-1-abarnas@google.com/
---
.../staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
index 722b684fbc37..9703e39b7497 100644
--- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
+++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c
@@ -22,14 +22,14 @@ typedef hive_uedge *hive_wide;
static inline hive_uedge
subword(hive_uedge w, unsigned int start, unsigned int end)
{
- return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start;
+ return (w & __GENMASK_ULL(end-1, 0)) >> start;
}
/* inverse subword bits move like this: MSB[xxxx____xxxx]LSB -> MSB[xxxx0000xxxx]LSB */
static inline hive_uedge
inv_subword(hive_uedge w, unsigned int start, unsigned int end)
{
- return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1));
+ return w & (~__GENMASK_ULL(end-1, start));
}
#define uedge_bits (8 * sizeof(hive_uedge))
--
2.51.0.318.gd7df087d1a-goog
On Tue, Sep 02, 2025 at 07:38:40AM +0000, Adrian Barnaś wrote: > Simplified masking logic in pci/hive_isp_css_common/host/vmem.c. ... > --- > > I have tested this change on whole range of *valid* inputs, and it gives > the same results as before, but this function seems to be little > counter-intuitive as far as start is a (bit index) but end is > (bit index + 1). We can't change it without changing the callers at the same time. So, better to change just helpers and later on, if working, change the semantics of the parameter. > --- ... > subword(hive_uedge w, unsigned int start, unsigned int end) > { > - return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start; > + return (w & __GENMASK_ULL(end-1, 0)) >> start; Why __ variant? > } ... > inv_subword(hive_uedge w, unsigned int start, unsigned int end) > { > - return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1)); > + return w & (~__GENMASK_ULL(end-1, start)); > } Ditto. -- With Best Regards, Andy Shevchenko
On Tue, Sep 02, 2025 at 07:38:40AM +0000, Adrian Barnaś wrote: > Simplified masking logic in pci/hive_isp_css_common/host/vmem.c. > > --- > > I have tested this change on whole range of *valid* inputs, and it gives > the same results as before, but this function seems to be little > counter-intuitive as far as start is a (bit index) but end is > (bit index + 1). Yeah. The "end - 1" is unfortunate. I guess we accidentally started counting from 1... I looked at how to remove it but got lost. > > It is follow up to: https://lore.kernel.org/linux-staging/20250901091050.1935505-1-abarnas@google.com/ > --- > .../staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c > index 722b684fbc37..9703e39b7497 100644 > --- a/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c > +++ b/drivers/staging/media/atomisp/pci/hive_isp_css_common/host/vmem.c > @@ -22,14 +22,14 @@ typedef hive_uedge *hive_wide; > static inline hive_uedge > subword(hive_uedge w, unsigned int start, unsigned int end) > { > - return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start; > + return (w & __GENMASK_ULL(end-1, 0)) >> start; > } > > /* inverse subword bits move like this: MSB[xxxx____xxxx]LSB -> MSB[xxxx0000xxxx]LSB */ > static inline hive_uedge > inv_subword(hive_uedge w, unsigned int start, unsigned int end) > { > - return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1)); > + return w & (~__GENMASK_ULL(end-1, start)); > } nit: white space. Add spaces. Remove parentheses. These are supposed to be opposites, right? Subword and inverse Subword. You could dress them up to make them look more opposite. return (w & __GENMASK_ULL(end - 1, start)) >> start; return w & ~__GENMASK_ULL(end - 1, start); regards, dan carpenter
> These are supposed to be opposites, right? Subword and inverse Subword. > You could dress them up to make them look more opposite. In fact this name is misleading as well. For me it should be named `clear_subword()`. It is zero-ing the "subword" provided with low and high bit boundary (start, end), to be then easily replaced with binary or operation. And this operation is not an inverse of extracting a subword using the subword function. > The problem is (and actually with the (end-1, start) above that it might > generate a really bad code on some CPUs, so I really, really prefer the way > when _at least_ one of the parameters is constant. It would be easier to create a bitmask sing GENMASK_ULL and just reverse it but if it is not safe, this is what looks fine for me and works the same as previous function: // Added a helper to create a mask static inline unsigned long long subword_bitmask(unsigned int start, unsigned int end) { return GENMASK_ULL(end - 1 , 0) & ~(GENMASK_ULL(start, 0) >> 1); } /* inverse subword bits move like this: MSB[xxxx____xxxx]LSB -> MSB[xxxx0000xxxx]LSB */ static inline unsigned long long clear_subword(unsigned long long w, unsigned int start, unsigned int end) { return w & ~subword_bitmask(start, end); } Best regards Adrian Barnaś
On Tue, Sep 02, 2025 at 12:02:29PM +0300, Dan Carpenter wrote: > On Tue, Sep 02, 2025 at 07:38:40AM +0000, Adrian Barnaś wrote: ... > > static inline hive_uedge > > inv_subword(hive_uedge w, unsigned int start, unsigned int end) > > { > > - return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1)); > > + return w & (~__GENMASK_ULL(end-1, start)); > > } > > nit: white space. Add spaces. Remove parentheses. > > These are supposed to be opposites, right? Subword and inverse Subword. > You could dress them up to make them look more opposite. > > return (w & __GENMASK_ULL(end - 1, start)) >> start; > return w & ~__GENMASK_ULL(end - 1, start); The problem is (and actually with the (end-1, start) above that it might generate a really bad code on some CPUs, so I really, really prefer the way when _at least_ one of the parameters is constant. That said, using GENMASK_ULL(end - 1, 0) in both cases makes also them look more similar (and opposition comes on how start is being used). -- With Best Regards, Andy Shevchenko
On Tue, Sep 02, 2025 at 12:54:28PM +0300, Andy Shevchenko wrote: > On Tue, Sep 02, 2025 at 12:02:29PM +0300, Dan Carpenter wrote: > > On Tue, Sep 02, 2025 at 07:38:40AM +0000, Adrian Barnaś wrote: > > ... > > > > static inline hive_uedge > > > inv_subword(hive_uedge w, unsigned int start, unsigned int end) > > > { > > > - return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1)); > > > + return w & (~__GENMASK_ULL(end-1, start)); > > > } > > > > nit: white space. Add spaces. Remove parentheses. > > > > These are supposed to be opposites, right? Subword and inverse Subword. > > You could dress them up to make them look more opposite. > > > > return (w & __GENMASK_ULL(end - 1, start)) >> start; > > return w & ~__GENMASK_ULL(end - 1, start); > > The problem is (and actually with the (end-1, start) above that it might > generate a really bad code on some CPUs, so I really, really prefer the way > when _at least_ one of the parameters is constant. Ah. Okay. That makes sense. Thanks. regards, dan carpenter
© 2016 - 2025 Red Hat, Inc.