X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=include%2Flinux%2Fcompiler.h;h=e3390d2682395eaeb11be84ecd40bb7e46aafe64;hb=HEAD;hp=fe04cc6f9bfb7181ffc365d99bd634845da62c6a;hpb=e72388a0aa23da8bc8e24a0cbe9d523c5a9ce294;p=carl9170fw.git diff --git a/include/linux/compiler.h b/include/linux/compiler.h index fe04cc6..e3390d2 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -17,14 +17,16 @@ #ifndef __SHARED_COMPILER_H #define __SHARED_COMPILER_H -#define __noinline __attribute__((noinline)) +#define __noreturn __attribute__((noreturn)) #define __inline __attribute__((always_inline)) #define __hot __attribute__((hot)) #define __cold __attribute__((cold)) -#define __unused __attribute__((unused)) #define __force __attribute__((force)) -#define __section(s) __attribute__((section("." # s))) -#define __packed __attribute__((packed)) +#define __in_section(s) __attribute__((section("." # s))) +#define __visible __attribute__((externally_visible)) + +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) #define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) @@ -41,6 +43,42 @@ #define BIT(b) (1 << (b)) #define MASK(w) (BIT(w) - 1) +/** + * __struct_group() - Create a mirrored named and anonyomous struct + * + * @TAG: The tag name for the named sub-struct (usually empty) + * @NAME: The identifier name of the mirrored sub-struct + * @ATTRS: Any struct attributes (usually empty) + * @MEMBERS: The member declarations for the mirrored structs + * + * Used to create an anonymous union of two structs with identical layout + * and size: one anonymous and one named. The former's members can be used + * normally without sub-struct naming, and the latter can be used to + * reason about the start, end, and size of the group of struct members. + * The named struct can also be explicitly tagged for layer reuse, as well + * as both having struct attributes appended. + */ +#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ + union { \ + struct { MEMBERS } ATTRS; \ + struct TAG { MEMBERS } ATTRS NAME; \ + } + +/** + * struct_group() - Wrap a set of declarations in a mirrored struct + * + * @NAME: The identifier name of the mirrored sub-struct + * @MEMBERS: The member declarations for the mirrored structs + * + * Used to create an anonymous union of two structs with identical + * layout and size: one anonymous and one named. The former can be + * used normally without sub-struct naming, and the latter can be + * used to reason about the start, end, and size of the group of + * struct members. + */ +#define struct_group(NAME, MEMBERS...) \ + __struct_group(/* no tag */, NAME, /* no attrs */, MEMBERS) + #undef offsetof #ifdef __compiler_offsetof # define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER) @@ -48,6 +86,23 @@ # define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif +/** + * sizeof_field() - Report the size of a struct field in bytes + * + * @TYPE: The structure containing the field of interest + * @MEMBER: The field to return the size of + */ +#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) + +/** + * offsetofend() - Report the offset of a struct field within the struct + * + * @TYPE: The type of the structure + * @MEMBER: The member within the structure to get the end offset of + */ +#define offsetofend(TYPE, MEMBER) \ + (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER)) + #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) @@ -76,7 +131,7 @@ #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type, member)); }) + (type *)(((unsigned long)__mptr - offsetof(type, member))); }) #define MAX_ERRNO 4095 @@ -102,4 +157,93 @@ static inline long IS_ERR_OR_NULL(const void *ptr) return !ptr || IS_ERR_VALUE((unsigned long)ptr); } +static inline unsigned int hweight8(unsigned int w) +{ + unsigned int res = w - ((w >> 1) & 0x55); + res = (res & 0x33) + ((res >> 2) & 0x33); + return (res + (res >> 4)) & 0x0F; +} + +static inline unsigned int hweight16(unsigned int w) +{ + unsigned int res = w - ((w >> 1) & 0x5555); + res = (res & 0x3333) + ((res >> 2) & 0x3333); + res = (res + (res >> 4)) & 0x0F0F; + return (res + (res >> 8)) & 0x00FF; +} + +/** + * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union + * + * @TYPE: The type of each flexible array element + * @NAME: The name of the flexible array member + * + * In order to have a flexible array member in a union or alone in a + * struct, it needs to be wrapped in an anonymous struct with at least 1 + * named member, but that member can be empty. + */ +#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ + struct { \ + struct { } __empty_ ## NAME; \ + TYPE NAME[]; \ + } + +#define __bf_shf(x) (__builtin_ffsll(x) - 1) + +#define FIELD_MAX(_mask) \ + ({ \ + (typeof(_mask))((_mask) >> __bf_shf(_mask)); \ + }) + +#if __has_attribute(__error__) +# define __compiletime_error(msg) __attribute__((__error__(msg))) +#else +# define __compiletime_error(msg) +#endif + +extern void __compiletime_error("value doesn't fit into mask") +__field_overflow(void); +extern void __compiletime_error("bad bitfield mask") +__bad_mask(void); +static inline u64 field_multiplier(u32 field) +{ + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) + __bad_mask(); + return field & -field; +} +static inline u64 field_mask(const u32 field) +{ + return field / field_multiplier(field); +} +#define field_max(field) ((typeof(field))field_mask(field)) +#define ____MAKE_OP(type,base,to,from) \ +static 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 inline __##type type##_replace_bits(__##type old, \ + base val, base field) \ +{ \ + return (old & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static inline void type##p_replace_bits(__##type *p, \ + base val, base field) \ +{ \ + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ +} \ +static 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(u##size,u##size,,) +____MAKE_OP(u8,u8,,) +__MAKE_OP(16) +__MAKE_OP(32) +#undef __MAKE_OP +#undef ____MAKE_OP + #endif /* __SHARED_COMPILER_H */