Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
u-boot.16418
0027-linux-bitfield.h-Add-primitives-for.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0027-linux-bitfield.h-Add-primitives-for.patch of Package u-boot.16418
From 25073d1f4beeb4eb4d2917207e9c5862b7629e0d Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> Date: Mon, 4 May 2020 14:45:20 +0200 Subject: [PATCH] linux/bitfield.h: Add primitives for manipulating bitfields both in host- and fixed-endian Imports Al Viro's original Linux commit 00b0c9b82663a, which contains an in depth explanation and two fixes from Johannes Berg: e7d4a95da86e0 "bitfield: fix *_encode_bits()", 37a3862e12382 "bitfield: add u8 helpers". Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de> [s.nawrocki: added empty lines between functions and macros] Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> --- include/linux/bitfield.h | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 8b9d6fff00..7acba4c524 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -103,4 +103,54 @@ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ }) +extern void __compiletime_error("value doesn't fit into mask") +__field_overflow(void); +extern void __compiletime_error("bad bitfield mask") +__bad_mask(void); +static __always_inline u64 field_multiplier(u64 field) +{ + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) + __bad_mask(); + return field & -field; +} +static __always_inline u64 field_mask(u64 field) +{ + return field / field_multiplier(field); +} + +#define ____MAKE_OP(type,base,to,from) \ +static __always_inline __##type type##_encode_bits(base v, base field) \ +{ \ + if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ + __field_overflow(); \ + return to((v & field_mask(field)) * field_multiplier(field)); \ +} \ +static __always_inline __##type type##_replace_bits(__##type old, \ + base val, base field) \ +{ \ + return (old & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline void type##p_replace_bits(__##type *p, \ + base val, base field) \ +{ \ + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static __always_inline base type##_get_bits(__##type v, base field) \ +{ \ + return (from(v) & field)/field_multiplier(field); \ +} + +#define __MAKE_OP(size) \ + ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \ + ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \ + ____MAKE_OP(u##size,u##size,,) + +____MAKE_OP(u8,u8,,) +__MAKE_OP(16) +__MAKE_OP(32) +__MAKE_OP(64) + +#undef __MAKE_OP +#undef ____MAKE_OP + #endif
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor