#ifndef lib_utils_h #define lib_utils_h /* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file lib/utils.h * \brief Common utilities header. * \ingroup lib * * Define useful utilities used almost everywhere. * * Do not add or modify any macro unless you own the special skills needed to * prevent the creation of a mass destruction weapon from a nice looking * macro. */ #include "lib/preproc.h" /** Count the number of element of a table. */ #define COUNT(table) (sizeof (table) / sizeof ((table)[0])) /** Count the number of element of a table which is a member of a structure. */ #define COUNT_MEMBER(parent, table) (COUNT (((parent *) NULL)->table)) /** Return true iff \p a is before \p b modulo 2^32. This is useful to compare two * values of a overflowing counter. This only works iff \p a and \p b are * distant no more than 2^31. */ extern inline bool less_mod2p32 (u32 a, u32 b) { return (s32) (a - b) < 0; } /** Return true iff \p a is before or equal to \p b modulo 2^32. This is * useful to compare two values of a overflowing counter. This only works iff * \p a and \p b are distant no more than 2^31. */ extern inline bool lesseq_mod2p32 (u32 a, u32 b) { return (s32) (a - b) <= 0; } /** Return true iff \p a is before \p b modulo 2^16. This is useful to compare two * values of a overflowing counter. This only works iff \p a and \p b are * distant no more than 2^15. */ extern inline bool less_mod2p16 (u16 a, u16 b) { return (s16) (a - b) < 0; } /** Return true iff \p a is before or equal to \p b modulo 2^16. This is * useful to compare two values of a overflowing counter. This only works iff * \p a and \p b are distant no more than 2^15. */ extern inline bool lesseq_mod2p16 (u16 a, u16 b) { return (s16) (a - b) <= 0; } /** Return the absolute value. */ #define ABS(v) ({ typeof (v) _v = (v); _v > 0 ? _v : -_v; }) /** Return the maximum value. */ #define MAX(a, b) ({ typeof (a) _a = (a); typeof (b) _b = (b); \ _a > _b ? _a : _b; }) /** Return the minimum value. */ #define MIN(a, b) ({ typeof (a) _a = (a); typeof (b) _b = (b); \ _a < _b ? _a : _b; }) /** * Return the upper rounded integer value of a divided by b (a/b). * \param a the numerator * \param b the divisor * * \warning b is evaluated twice. You need to be careful if you do: * \code * uint b = 1; * uint a = CEIL_DIV (1, b++); * // a = (1 + b++ - 1) / b++; * \endcode */ #define CEIL_DIV(a, b) ( ((a) + (b) - 1) / (b) ) /** * Return the nearest integer (away from 0) of a divided by b (a/b). * \param a the numerator (must be >= 0) * \param b the divisor (must be > 0) * * \warning b is evaluated twice. */ #define ROUND_DIV(a, b) ( ((a) + (b) / 2) / (b) ) /** Exchange two value. */ #define XCH(a, b) do { \ typeof (b) _tmp = (a); \ (a) = (b); \ (b) = _tmp; \ } while (0) /** Rotate the word to the right. * NB = 0 or size max of val will not work. */ #define ROR(val, nb) ({ \ typeof (val) _val = (val); \ typeof (nb) _nb = (nb); \ typeof(_val) _tmp1 = (_val) >> (_nb); \ typeof(_val) _tmp2 = (_val) << ((8*sizeof(_val)) - (_nb)); \ _tmp2 | _tmp1; \ }) /** Rotate the word to the left. * NB = 0 or size max of val will not work. */ #define ROL(val, nb) ({ \ typeof (val) _val = (val); \ typeof (nb) _nb = (nb); \ typeof(_val) _tmp1 = (_val) << (_nb); \ typeof(_val) _tmp2 = (_val) >> ((8*sizeof(_val)) - (_nb)); \ _tmp2 | _tmp1; \ }) /** Return a bit mask composed of a number of LSB ones. * \param b number of one bits, 1 to 32 * * - BITS_ONES (0) => error * - BITS_ONES (1) => 0x00000001 * - BITS_ONES (15) => 0x00007fff * - BITS_ONES (32) => 0xffffffff */ #define BITS_ONES(b) ((1u << ((b) - 1) << 1) - 1) /** Return a bit mask composed of a number of LSB ones. * \param b number of one bits, 0 to 32 * * - BITS_ONES_OR_ZERO (0) => 0x00000000 * - BITS_ONES_OR_ZERO (1) => 0x00000001 * - BITS_ONES_OR_ZERO (15) => 0x00007fff * - BITS_ONES_OR_ZERO (32) => 0xffffffff */ #define BITS_ONES_OR_ZERO(b) ({ typeof (b) _b = (b);\ _b ? ((1u << (_b - 1) << 1) - 1) : 0; }) /** Return a bit mask composed of a number of LSB ones, corresponding to the * given bit field. * \param f bit field define * * The bit field is a preprocessor symbol composed of MSB and LSB separated by * a comma. */ #define BF_ONES(f) BF_ONES_ (f) #define BF_ONES_(m, l) BITS_ONES ((m) - (l) + 1) /** Return a bit mask composed of a number of shifted ones. * \param b number of one bits, 1 to 32 * \param s shift, 0 to 31 * * - BITS_MASK (0, 0) => error * - BITS_MASK (1, 14) => 0x00004000 * - BITS_MASK (15, 7) => 0x003fff80 * - BITS_MASK (32, 0) => 0xffffffff */ #define BITS_MASK(b, s) (BITS_ONES (b) << (s)) /** Return a bit mask composed of a number of shifted ones, corresponding to * the given bit field. * \param f bit field define * * \see BF_ONES. */ #define BF_MASK(f) BF_MASK_ (f) #define BF_MASK_(m, l) BITS_MASK ((m) - (l) + 1, (l)) /** Return true if the given value is small enough to fit in the given bit * field. * \param f bit field define * \param v value to check * * \see BF_ONES. */ #define BF_CHECK(f, v) BF_CHECK_ (f, (v)) #define BF_CHECK_(m, l, v) !((v) & ~BF_ONES_ ((m), (l))) /** Shift the given value to OR it at the right position in the given bit * field. * \param f bit field define * \param v value to shift * * The value is not masked, it should be masked or checked before. * \see BF_ONES. */ #define BF_SHIFT(f, v) BF_SHIFT_ (f, (v)) #define BF_SHIFT_(m, l, v) ((v) << (l)) /** Extract the given bit field. * \param f bit field define * \param v value to extract from * * \warning v MUST be unsigned * * \see BF_ONES. */ #define BF_GET(f, v) BF_GET_ (f, (v)) #define BF_GET_(m, l, v) ((v) << (31 - (m)) >> (31 - (m) + (l))) /** Set the given bit field, without changing other bits. * \param regv register value * \param f bit field define * \param v value to set * * The value is not masked, it should be masked or checked before. * \see BF_ONES. */ #define BF_SET(regv, f, v) \ (((regv) & ~BF_MASK_ (f)) | BF_SHIFT_ (f, (v))) /** Pack different bit fields together. * \param reg register name (prefix) * \param fv pair of (field, value) * * Example: * \code * #define MYREG__A 7, 0 * #define MYREG__B 23, 12 * BF_FILL (MYREG, (A, 0x42), (B, 0x123)) => 0x00123042 * \endcode */ #define BF_FILL(reg, fv...) \ (0 PREPROC_FOR_EACH_PARAM (BF_FILL_FIELD_, reg ## __, fv)) #define BF_FILL_FIELD_(reg, fv) \ BF_FILL_FIELD__ (reg, PREPROC_UNPACK (fv)) #define BF_FILL_FIELD__(reg, fv) \ BF_FILL_FIELD___ (reg, fv) #define BF_FILL_FIELD___(reg, f, v) \ | BF_SHIFT (reg ## f, v) /** Pack different bit masks together. * \param reg register name (prefix) * \param f list of fields * * Example: * \code * #define MYREG__A 7, 0 * #define MYREG__B 23, 12 * BF_MASKS (MYREG, A, B) => 0x00fff0ff * \endcode */ #define BF_MASKS(reg, f...) \ (0 PREPROC_FOR_EACH_PARAM (BF_MASKS_FIELD_, reg ## __, f)) #define BF_MASKS_FIELD_(reg, f) \ | BF_MASK (PASTE_EXPAND (reg, f)) /** Update several bit fields, without changing other bits. * \param regv register value * \param reg register name (prefix) * \param fv pair of (field, value) */ #define BF_UPDATE(regv, reg, fv...) \ (((regv) & ~(0 PREPROC_FOR_EACH_PARAM (BF_UPDATE_MASK_, reg ## __, fv))) \ | (0 PREPROC_FOR_EACH_PARAM (BF_FILL_FIELD_, reg ## __, fv))) #define BF_UPDATE_MASK_(reg, fv) \ BF_UPDATE_MASK__ (reg, PREPROC_UNPACK (fv)) #define BF_UPDATE_MASK__(reg, fv) \ BF_UPDATE_MASK___ (reg, fv) #define BF_UPDATE_MASK___(reg, f, v) \ | BF_MASK (reg ## f) /** Return the number of one bits. */ #define BITS_ONES_COUNT(x) ({ \ typeof (x) _x = (x); \ uint c = 0; \ while (_x) \ { \ _x = _x & (_x - 1); \ c++; \ } \ c; \ }) /** Return the offset of the given \p member in the given \p parent struct. */ #define OFFSET_OF(parent, member) ((uint) &((parent *) NULL)->member) /** When \p member is a member of \p parent struct and \p p a pointer to this * member, return a pointer to the containing struct. */ #define PARENT_OF(parent, member, p) \ ((parent *) ((u8 *) (p) - OFFSET_OF (parent, member))) /** Return the parent or NULL if p pointer is null. */ #define PARENT_OF_OR_NULL(parent, member, p) \ ({ typeof (p) _p = (p); _p ? PARENT_OF (parent, member, _p) : NULL; }) /** Cast to the corresponding volatile type. */ #define VOLATILE(v) ((volatile typeof (*(v)) *) (v)) /** Stop the compiler to reorder instructions across this barrier. You may * consider using volatile instead. */ #define REORDER_BARRIER() __asm__ __volatile__ ("" : : : "memory") /** Reverse bitfields if needed to have the first field using the least * significant bit. */ #define BITFIELDS_WORD(args...) BITFIELDS_WORD_ (args) #define BITFIELDS_WORD_ECHO(x) x #if DEFS_REVERSE_BITFIELDS # define BITFIELDS_WORD_(args...) \ PREPROC_FOR_EACH (BITFIELDS_WORD_ECHO, PREPROC_REVERSE (args)) #else # define BITFIELDS_WORD_(args...) \ PREPROC_FOR_EACH (BITFIELDS_WORD_ECHO, args) #endif /** Define a fixed point number from a double, with 32 bits precision. */ #define CONST_UF32(d) ((u32) ((1ull << 32) * (d) + 0.5)) /** Convert a size in bytes to the size in bits. */ #define BYTES_SIZE_TO_BITS(val) ((val) * 8) /** * Generic dichotomy search. * \param min minimum index * \param max maximum index (past the end) * \param index index unsigned integer variable * \param less comparison expression * * This will expand to a code block which make a dichotomy search in any * indexable object. * * In the following example, the variable \c i gets the found index. It may * index a value greater than the looked up value or be equal to max if all * elements are smaller than the looked up element. * * \code * extern int table[256]; * uint i; * int looked_up; * DICHOTOMY_SEARCH (0, COUNT (table), i, looked_up < table[i]); * \endcode */ #define DICHOTOMY_SEARCH(min, max, index, less) \ do { \ uint a_, b_; \ a_ = (min); \ b_ = (max); \ while (a_ != b_) \ { \ index = (a_ + b_) / 2; \ if (less) \ { \ b_ = index; \ } \ else \ { \ a_ = index + 1; \ } \ } \ index = a_; \ } while (0) BEGIN_DECLS /** Compare floating point numbers, return true if they are almost equal. * \param a first number to compare * \param b second number to compare * \param max_ulps maximum error as unit in the last place */ bool almost_eqf (float a, float b, int max_ulps); END_DECLS #endif /* lib_utils_h */