Path: blob/main/sys/compat/linuxkpi/common/include/linux/bitfield.h
39604 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2020-2024 The FreeBSD Foundation4*5* This software was developed by Björn Zeeb under sponsorship from6* the FreeBSD Foundation.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*/2930#ifndef _LINUXKPI_LINUX_BITFIELD_H31#define _LINUXKPI_LINUX_BITFIELD_H3233#include <linux/types.h>34#include <asm/byteorder.h>3536/* Use largest possible type. */37static inline uint64_t ___lsb(uint64_t f) { return (f & -f); }38static inline uint64_t ___bitmask(uint64_t f) { return (f / ___lsb(f)); }3940#define _uX_get_bits(_n) \41static __inline uint ## _n ## _t \42u ## _n ## _get_bits(uint ## _n ## _t v, uint ## _n ## _t f) \43{ \44return ((v & f) / ___lsb(f)); \45}4647_uX_get_bits(64)48_uX_get_bits(32)49_uX_get_bits(16)50_uX_get_bits(8)5152#define _leX_get_bits(_n) \53static __inline uint ## _n ## _t \54le ## _n ## _get_bits(__le ## _n v, uint ## _n ## _t f) \55{ \56return ((le ## _n ## _to_cpu(v) & f) / ___lsb(f)); \57}5859_leX_get_bits(64)60_leX_get_bits(32)61_leX_get_bits(16)6263#define _uX_encode_bits(_n) \64static __inline uint ## _n ## _t \65u ## _n ## _encode_bits(uint ## _n ## _t v, uint ## _n ## _t f) \66{ \67return ((v & ___bitmask(f)) * ___lsb(f)); \68}6970_uX_encode_bits(64)71_uX_encode_bits(32)72_uX_encode_bits(16)73_uX_encode_bits(8)7475#define _leX_encode_bits(_n) \76static __inline uint ## _n ## _t \77le ## _n ## _encode_bits(__le ## _n v, uint ## _n ## _t f) \78{ \79return (cpu_to_le ## _n((v & ___bitmask(f)) * ___lsb(f))); \80}8182_leX_encode_bits(64)83_leX_encode_bits(32)84_leX_encode_bits(16)8586#define _leXp_replace_bits(_n) \87static __inline void \88le ## _n ## p_replace_bits(uint ## _n ## _t *p, \89uint ## _n ## _t v, uint ## _n ## _t f) \90{ \91*p = (*p & ~(cpu_to_le ## _n(f))) | \92le ## _n ## _encode_bits(v, f); \93}9495_leXp_replace_bits(64)96_leXp_replace_bits(32)97_leXp_replace_bits(16)9899#define _uXp_replace_bits(_n) \100static __inline void \101u ## _n ## p_replace_bits(uint ## _n ## _t *p, \102uint ## _n ## _t v, uint ## _n ## _t f) \103{ \104*p = (*p & ~f) | u ## _n ## _encode_bits(v, f); \105}106107_uXp_replace_bits(64)108_uXp_replace_bits(32)109_uXp_replace_bits(16)110_uXp_replace_bits(8)111112#define _uX_replace_bits(_n) \113static __inline uint ## _n ## _t \114u ## _n ## _replace_bits(uint ## _n ## _t p, \115uint ## _n ## _t v, uint ## _n ## _t f) \116{ \117return ((p & ~f) | u ## _n ## _encode_bits(v, f)); \118}119120_uX_replace_bits(64)121_uX_replace_bits(32)122_uX_replace_bits(16)123_uX_replace_bits(8)124125#define __bf_shf(x) (__builtin_ffsll(x) - 1)126127#define FIELD_FIT(_mask, _value) \128(!(((typeof(_mask))(_value) << __bf_shf(_mask)) & ~(_mask)))129130#define FIELD_PREP(_mask, _value) \131(((typeof(_mask))(_value) << __bf_shf(_mask)) & (_mask))132133/* Likely would need extra sanity checks compared to FIELD_PREP()? */134#define FIELD_PREP_CONST(_mask, _value) \135(((typeof(_mask))(_value) << __bf_shf(_mask)) & (_mask))136137#define FIELD_GET(_mask, _value) \138((typeof(_mask))(((_value) & (_mask)) >> __bf_shf(_mask)))139140#endif /* _LINUXKPI_LINUX_BITFIELD_H */141142143