18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _TOOLS_LINUX_BITOPS_H_
38c2ecf20Sopenharmony_ci#define _TOOLS_LINUX_BITOPS_H_
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/types.h>
68c2ecf20Sopenharmony_ci#include <limits.h>
78c2ecf20Sopenharmony_ci#ifndef __WORDSIZE
88c2ecf20Sopenharmony_ci#define __WORDSIZE (__SIZEOF_LONG__ * 8)
98c2ecf20Sopenharmony_ci#endif
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef BITS_PER_LONG
128c2ecf20Sopenharmony_ci# define BITS_PER_LONG __WORDSIZE
138c2ecf20Sopenharmony_ci#endif
148c2ecf20Sopenharmony_ci#include <linux/bits.h>
158c2ecf20Sopenharmony_ci#include <linux/compiler.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define BITS_PER_TYPE(type)	(sizeof(type) * BITS_PER_BYTE)
188c2ecf20Sopenharmony_ci#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
198c2ecf20Sopenharmony_ci#define BITS_TO_U64(nr)		DIV_ROUND_UP(nr, BITS_PER_TYPE(u64))
208c2ecf20Sopenharmony_ci#define BITS_TO_U32(nr)		DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
218c2ecf20Sopenharmony_ci#define BITS_TO_BYTES(nr)	DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciextern unsigned int __sw_hweight8(unsigned int w);
248c2ecf20Sopenharmony_ciextern unsigned int __sw_hweight16(unsigned int w);
258c2ecf20Sopenharmony_ciextern unsigned int __sw_hweight32(unsigned int w);
268c2ecf20Sopenharmony_ciextern unsigned long __sw_hweight64(__u64 w);
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/*
298c2ecf20Sopenharmony_ci * Include this here because some architectures need generic_ffs/fls in
308c2ecf20Sopenharmony_ci * scope
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * XXX: this needs to be asm/bitops.h, when we get to per arch optimizations
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci#include <asm-generic/bitops.h>
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#define for_each_set_bit(bit, addr, size) \
378c2ecf20Sopenharmony_ci	for ((bit) = find_first_bit((addr), (size));		\
388c2ecf20Sopenharmony_ci	     (bit) < (size);					\
398c2ecf20Sopenharmony_ci	     (bit) = find_next_bit((addr), (size), (bit) + 1))
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define for_each_clear_bit(bit, addr, size) \
428c2ecf20Sopenharmony_ci	for ((bit) = find_first_zero_bit((addr), (size));       \
438c2ecf20Sopenharmony_ci	     (bit) < (size);                                    \
448c2ecf20Sopenharmony_ci	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* same as for_each_set_bit() but use bit as value to start with */
478c2ecf20Sopenharmony_ci#define for_each_set_bit_from(bit, addr, size) \
488c2ecf20Sopenharmony_ci	for ((bit) = find_next_bit((addr), (size), (bit));	\
498c2ecf20Sopenharmony_ci	     (bit) < (size);					\
508c2ecf20Sopenharmony_ci	     (bit) = find_next_bit((addr), (size), (bit) + 1))
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic inline unsigned long hweight_long(unsigned long w)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic inline unsigned fls_long(unsigned long l)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	if (sizeof(l) == 4)
608c2ecf20Sopenharmony_ci		return fls(l);
618c2ecf20Sopenharmony_ci	return fls64(l);
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/**
658c2ecf20Sopenharmony_ci * rol32 - rotate a 32-bit value left
668c2ecf20Sopenharmony_ci * @word: value to rotate
678c2ecf20Sopenharmony_ci * @shift: bits to roll
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_cistatic inline __u32 rol32(__u32 word, unsigned int shift)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	return (word << shift) | (word >> ((-shift) & 31));
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#endif
75