helper: add bitfield helper macros

This patch ports FIELD_{GET,PREP,FIT} macros and related macro
from FreeBSD, referenced file:
- `src/tree/sys/compat/linuxkpi/common/include/linux/bitfield.h`

Checkpatch-ignore: MACRO_ARG_REUSE

Change-Id: I6fdf4514d3f95d62fadf7654409a4878d470a600
Signed-off-by: Walter Ji <walter.ji@oss.cipunited.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8171
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Walter Ji
2024-03-04 17:29:15 +08:00
committed by Antonio Borneo
parent 744955e5b4
commit e30828a276
2 changed files with 61 additions and 0 deletions

View File

@@ -19,6 +19,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la
%D%/nvp.c \
%D%/align.h \
%D%/binarybuffer.h \
%D%/bitfield.h \
%D%/bits.h \
%D%/configuration.h \
%D%/list.h \

60
src/helper/bitfield.h Normal file
View File

@@ -0,0 +1,60 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2020-2024 The FreeBSD Foundation
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
*/
#ifndef OPENOCD_HELPER_BITFIELD_H
#define OPENOCD_HELPER_BITFIELD_H
/**
* These macros come from FreeBSD, check source on
* https://cgit.freebsd.org/src/tree/sys/compat/linuxkpi/common/include/linux/bitfield.h
* Which does not include example usages of them.
*/
#define __bf_shf(x) (__builtin_ffsll(x) - 1)
/**
* FIELD_FIT(_mask, _value) - Check if a value fits in the specified bitfield mask
* @_mask: Bitfield mask
* @_value: Value to check
*
* This macro checks whether a given value fits within the range defined by the
* specified bitfield mask. It ensures that no bits outside the mask are set.
*
* Return: true if the value fits, false otherwise.
*/
#define FIELD_FIT(_mask, _value) \
(!(((typeof(_mask))(_value) << __bf_shf(_mask)) & ~(_mask)))
/**
* FIELD_PREP(_mask, _value) - Prepare a value for insertion into a bitfield
* @_mask: Bitfield mask
* @_value: Value to insert
*
* This macro prepares a value for insertion into a bitfield by shifting the
* value into the position defined by the mask and applying the mask.
*
* Return: The prepared bitfield value.
*/
#define FIELD_PREP(_mask, _value) \
(((typeof(_mask))(_value) << __bf_shf(_mask)) & (_mask))
/**
* FIELD_GET(_mask, _value) - Extract a value from a bitfield
* @_mask: Bitfield mask
* @_value: Bitfield value to extract from
*
* This macro extracts a value from a bitfield by masking and shifting the
* relevant bits down to the least significant position.
*
* Return: The extracted value.
*/
#define FIELD_GET(_mask, _value) \
((typeof(_mask))(((_value) & (_mask)) >> __bf_shf(_mask)))
#endif /* OPENOCD_HELPER_BITFIELD_H */