On 7/14/2026 8:51 AM, Brian Cain wrote: > set_bit32()/test_bit32()/etc already let devices operate on > guest-visible uint32_t register arrays without depending on the > host's 'unsigned long' size. find_first_bit() has no such > equivalent, which pushes callers towards casting a uint32_t array > to 'unsigned long *'. > > Add find_first_bit32(), implemented the same way as find_first_bit(). > > Signed-off-by: Brian Cain <[email protected]> > --- > include/qemu/bitops.h | 30 ++++++++++++++++++++++++++---- > 1 file changed, 26 insertions(+), 4 deletions(-) > > diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h > index c7b838a6283..f7363a5479f 100644 > --- a/include/qemu/bitops.h > +++ b/include/qemu/bitops.h > @@ -43,10 +43,9 @@ > * be some guest-visible register view of the bit array. > * > * We do not currently implement uint32_t versions of find_last_bit(), > - * find_next_bit(), find_next_zero_bit(), find_first_bit() or > - * find_first_zero_bit(), because we haven't yet needed them. If you > - * need them you should implement them similarly to the 'unsigned long' > - * versions. > + * find_next_bit(), find_next_zero_bit() or find_first_zero_bit(), > + * because we haven't yet needed them. If you need them you should > + * implement them similarly to the 'unsigned long' versions. > * > * You can declare a bitmap to be used with these functions via the > * DECLARE_BITMAP and DECLARE_BITMAP32 macros in bitmap.h. > @@ -382,6 +381,29 @@ static inline int test_bit32(long nr, const uint32_t > *addr) > return 1U & (addr[BIT32_WORD(nr)] >> (nr & 31)); > } > > +/** > + * find_first_bit32 - find the first set bit in a memory region > + * @addr: The address to start the search at > + * @size: The maximum size to search > + * > + * Returns the bit number of the first set bit, > + * or @size if there is no set bit in the bitmap. > + */ > +static inline uint32_t find_first_bit32(const uint32_t *addr, uint32_t size) > +{ > + uint32_t result; > + > + for (result = 0; result < size; result += 32) { > + uint32_t tmp = *addr++; > + if (tmp) { > + result += ctz32(tmp); > + return result < size ? result : size; > + } > + } > + /* Not found */ > + return size; > +}
Either we should express size in terms of number of elements, or add an explicit check if size is not a multiple of 32. > + > /** > * DOC: Miscellaneous bit operations on single values > *
