1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-02-25     GuEe-GUI     the first version
9  */
10 
11 #ifndef __MISC_H__
12 #define __MISC_H__
13 
14 #include <rtdef.h>
15 #include <cpuport.h>
16 
17 #ifdef ARCH_CPU_64BIT
18 #define RT_BITS_PER_LONG 64
19 #else
20 #define RT_BITS_PER_LONG 32
21 #endif
22 #define RT_BITS_PER_LONG_LONG 64
23 
24 #define RT_DIV_ROUND_UP(n, d)   (((n) + (d) - 1) / (d))
25 
26 #define RT_DIV_ROUND_CLOSEST(x, divisor)        \
27 ({                                              \
28     typeof(x) __x = x;                          \
29     typeof(divisor) __d = divisor;              \
30     (((typeof(x))-1) > 0 ||                     \
31      ((typeof(divisor))-1) > 0 ||               \
32      (((__x) > 0) == ((__d) > 0))) ?            \
33             (((__x) + ((__d) / 2)) / (__d)) :   \
34             (((__x) - ((__d) / 2)) / (__d));    \
35 })
36 
37 #define __KEY_PLACEHOLDER_1                     0,
38 #define ____KEY_ENABLED(__ignored, val, ...)    val
39 #define ___KEY_ENABLED(arg1_or_junk)            ____KEY_ENABLED(arg1_or_junk 1, 0)
40 #define __KEY_ENABLED(value)                    ___KEY_ENABLED(__KEY_PLACEHOLDER_##value)
41 #define RT_KEY_ENABLED(key)                     __KEY_ENABLED(key)
42 
43 #define RT_FIELD_PREP(mask, val)    (((rt_uint64_t)(val) << (__rt_ffsl((mask)) - 1)) & (mask))
44 #define RT_FIELD_GET(mask, val)     (((val) & (mask)) >> (__rt_ffsl((mask)) - 1))
45 
46 #define RT_BIT(n)               (1UL << (n))
47 #define RT_BIT_ULL(n)           (1ULL << (n))
48 #define RT_BIT_MASK(nr)         (1UL << ((nr) % RT_BITS_PER_LONG))
49 #define RT_BIT_WORD(nr)         ((nr) / RT_BITS_PER_LONG)
50 
51 #define RT_BITS_PER_BYTE        8
52 #define RT_BITS_PER_TYPE(type)  (sizeof(type) * RT_BITS_PER_BYTE)
53 #define RT_BITS_TO_BYTES(nr)    RT_DIV_ROUND_UP(nr, RT_BITS_PER_TYPE(char))
54 #define RT_BITS_TO_LONGS(nr)    RT_DIV_ROUND_UP(nr, RT_BITS_PER_TYPE(long))
55 
56 #define RT_GENMASK(h, l)        (((~0UL) << (l)) & (~0UL >> (RT_BITS_PER_LONG - 1 - (h))))
57 #define RT_GENMASK_ULL(h, l)    (((~0ULL) << (l)) & (~0ULL >> (RT_BITS_PER_LONG_LONG - 1 - (h))))
58 
59 #define RT_ARRAY_SIZE(arr)      (sizeof(arr) / sizeof(arr[0]))
60 
61 #define rt_offsetof(s, field)   ((rt_size_t)&((s *)0)->field)
62 
63 #define rt_err_ptr(err)         ((void *)(rt_base_t)(err))
64 #define rt_ptr_err(ptr)         ((rt_err_t)(rt_base_t)(ptr))
65 #define rt_is_err_value(ptr)    ((rt_ubase_t)(void *)(ptr) >= (rt_ubase_t)-4095)
66 #define rt_is_err(ptr)          rt_is_err_value(ptr)
67 #define rt_is_err_or_null(ptr)  (!(ptr) || rt_is_err_value((rt_ubase_t)(ptr)))
68 
69 #define rt_upper_32_bits(n)     ((rt_uint32_t)(((n) >> 16) >> 16))
70 #define rt_lower_32_bits(n)     ((rt_uint32_t)((n) & 0xffffffff))
71 #define rt_upper_16_bits(n)     ((rt_uint16_t)((n) >> 16))
72 #define rt_lower_16_bits(n)     ((rt_uint16_t)((n) & 0xffff))
73 
74 #define rt_min(x, y)            \
75 ({                              \
76     typeof(x) _x = (x);         \
77     typeof(y) _y = (y);         \
78     (void) (&_x == &_y);        \
79     _x < _y ? _x : _y;          \
80 })
81 
82 #define rt_max(x, y)            \
83 ({                              \
84     typeof(x) _x = (x);         \
85     typeof(y) _y = (y);         \
86     (void) (&_x == &_y);        \
87     _x > _y ? _x : _y;          \
88 })
89 
90 #define rt_min_t(type, x, y)    \
91 ({                              \
92     type _x = (x);              \
93     type _y = (y);              \
94     _x < _y ? _x: _y;           \
95 })
96 
97 #define rt_max_t(type, x, y)    \
98 ({                              \
99     type _x = (x);              \
100     type _y = (y);              \
101     _x > _y ? _x: _y;           \
102 })
103 
104 #define rt_clamp(val, lo, hi)   rt_min((typeof(val))rt_max(val, lo), hi)
105 
106 #define rt_do_div(n, base)              \
107 ({                                      \
108     rt_uint32_t _base = (base), _rem;   \
109     _rem = ((rt_uint64_t)(n)) % _base;  \
110     (n) = ((rt_uint64_t)(n)) / _base;   \
111     if (_rem > _base / 2)               \
112         ++(n);                          \
113     _rem;                               \
114 })
115 
116 #define rt_abs(x)                       \
117 ({                                      \
118     long ret;                           \
119     if (sizeof(x) == sizeof(long))      \
120     {                                   \
121         long __x = (x);                 \
122         ret = (__x < 0) ? -__x : __x;   \
123     }                                   \
124     else                                \
125     {                                   \
126         int __x = (x);                  \
127         ret = (__x < 0) ? -__x : __x;   \
128     }                                   \
129     ret;                                \
130 })
131 
132 #ifndef rt_ilog2
rt_ilog2(rt_ubase_t v)133 rt_inline int rt_ilog2(rt_ubase_t v)
134 {
135     int l = 0;
136 
137     while ((1UL << l) < v)
138     {
139         l++;
140     }
141 
142     return l;
143 }
144 #endif /* !rt_ilog2 */
145 
146 #endif /* __MISC_H__ */
147