-
Notifications
You must be signed in to change notification settings - Fork 0
/
arm_inlines_binary.h
123 lines (102 loc) · 2.68 KB
/
arm_inlines_binary.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*!\file arm_inlines_binary.h
** \author SMFSW
** \copyright MIT (c) 2017-2024, SMFSW
** \brief Binary manipulation inlines
*/
/****************************************************************/
#ifndef ARM_INLINES_BINARY_H_
#define ARM_INLINES_BINARY_H_
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************/
/*!\brief Create specified number of bits mask
** \note function limited to arm native 32b
** \param[in] bits - Number of bits to create mask
** \return Mask value for specified number of bits
**/
__INLINE DWORD maskBits(const BYTE bits)
{
const uintCPU_t nb_bits = 32;
const uintCPU_t nb = MIN(bits, nb_bits);
DWORD mask = 0;
for (uintCPU_t i = 0 ; i < nb ; i++)
{
mask |= LSHIFT(1UL, i);
}
return mask;
}
/*!\brief Check the number of clear/set bits in a variable
** \note function limited to arm native 32b
** \param[in] val - Variable to check for bits
** \param[in] bits - Number of bits to check
** \param[in] state - Logic state to check
** \return Number of state specified bits in val
**/
__INLINE BYTE nbBitsState(const DWORD val, const BYTE bits, const BOOL state)
{
const uintCPU_t nb_bits = 32;
const uintCPU_t nb = MIN(bits, nb_bits);
BYTE ret = 0;
for (uintCPU_t i = 0 ; i < nb ; i++)
{
if ((val & LSHIFT(1UL, i)) != 0U)
{
ret++;
}
}
if (!state)
{
ret = (BYTE) nb - ret;
}
return ret;
}
/*!\brief Get power of 2 of the most significant set bit
** \note function limited to arm native 32b
** \param[in] val - Variable to check for bits
** \return Power of 2 of most significant bit set
** \retval >=0: Index (power of 2) of most significant bit set
** \retval -1: no bit set
**/
__INLINE SDWORD getMSBitSet(const DWORD val)
{
const uintCPU_t nb_bits = 32;
SDWORD ret = -1;
for (uintCPU_t i = nb_bits ; i > 0U ; i--)
{
const uintCPU_t bit = i - 1U;
if ((val & LSHIFT(1UL, bit)) != 0U)
{
ret = (SDWORD) bit;
break;
}
}
return ret;
}
/*!\brief Swap specified number of bits in value (mirroring bits)
** \note function limited to arm native 32b
** \param[in] val - Value to swap
** \param[in] bits - Number of bits to swap
** \return Swapped binary value
**/
__INLINE DWORD swapBits(const DWORD val, const BYTE bits)
{
const uintCPU_t nb_bits = 32;
const uintCPU_t nb = MIN(bits, nb_bits) - 1U;
DWORD swap = 0;
for (uintCPU_t i = nb + 1U ; i > 0U ; i--)
{
const uintCPU_t bit = i - 1U;
if ((val & LSHIFT(1UL, bit)) != 0U)
{
swap |= LSHIFT(1UL, (nb - bit));
}
}
return swap;
}
/****************************************************************/
#ifdef __cplusplus
}
#endif
#endif /* ARM_INLINES_BINARY_H_ */
/****************************************************************/