blob: fa0673483792319e93a89a527ebb217a0b2ea859 (
plain)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
/**************************************************************************//**
*
* @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-2-7 Wayne First version
*
******************************************************************************/
#ifndef __NU_BITUTIL_H__
#define __NU_BITUTIL_H__
#if defined(__ICCARM__)
#include <arm_math.h>
#elif defined (__ARMCC_VERSION)
#ifdef __has_include
#if __has_include("cmsis_compiler.h")
#include "cmsis_compiler.h"
#endif
#endif
#if !defined(__CLZ)
#define __CLZ __clz
#endif
#endif
#include <stdint.h>
#if !defined(__STATIC_INLINE)
#define __STATIC_INLINE static inline
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ----------------------------------------------
* Count Leading Zeros Count Trailing Zeros
* (MSB)00000000000000001000000000001000(LSB)
* ################| |!!!
* Find Highest Set Find First Set
* ----------------------------------------------
*
* ----------------------------------------------
* Count Leading Ones Count Trailing Ones
* (MSB)11111111111111110111111111110111(LSB)
* ^^^^^^^^^^^^^^^^| |@@@
* Find Highest Zero Find First Zero
* ----------------------------------------------
*/
/* Count Leading Zeros in word - Find Highest Set
EX: x=(MSB)00000000000000001000000000001000(LSB)
################|
Find Highest Set
nu_clz will start zero-counting from MSB and return the number.
*/
__STATIC_INLINE int nu_clz(uint32_t x)
{
return x ? __CLZ(x) : 32;
}
/* Count Leading Ones in word - Find Highest Zero
EX: x=(MSB)11111111111111110111111111110111(LSB)
^^^^^^^^^^^^^^^^|
Find Highest Zero
nu_clo will start one-counting from MSB and return the number.
*/
__STATIC_INLINE int nu_clo(uint32_t x)
{
return nu_clz(~x);
}
/* Count Trailing Zero in word - Find First Set
EX: x=(MSB)00000000000000001000000000001000(LSB)
|!!!
Find First Set
nu_ctz will start zero-counting from LSB and return the number.
*/
__STATIC_INLINE int nu_ctz(uint32_t x)
{
int c = 32;
if (x)
c = __CLZ(x & -x);
return x ? 31 - c : c;
}
/* Count Trailing Ones in word - Find First Zero
EX: x=(MSB)11111111111111110111111111110111(LSB)
|@@@
Find First Zero
nu_cto will start one-counting from LSB and return the number.
*/
__STATIC_INLINE int nu_cto(uint32_t x)
{
return nu_ctz(~x);
}
/* Get 16-bit from a byte-array in little-endian */
__STATIC_INLINE uint16_t nu_get16_le(const uint8_t *pos)
{
uint16_t val;
val = *pos ++;
val += (*pos << 8);
return val;
}
/* Set 16-bit to a byte-array in little-endian */
__STATIC_INLINE void nu_set16_le(uint8_t *pos, uint16_t val)
{
*pos ++ = val & 0xFF;
*pos = val >> 8;
}
/* Get 32-bit from a byte-array in little-endian */
__STATIC_INLINE uint32_t nu_get32_le(const uint8_t *pos)
{
uint32_t val;
val = *pos ++;
val += (*pos ++ << 8);
val += (*pos ++ << 16);
val += (*pos ++ << 24);
return val;
}
/* Get 24-bit from a byte-array in little-endian */
__STATIC_INLINE uint32_t nu_get24_le(const uint8_t *pos)
{
uint32_t val;
val = *pos ++;
val += (*pos ++ << 8);
val += (*pos ++ << 16);
return val;
}
/* Set 24-bit to a byte-array in little-endian */
__STATIC_INLINE void nu_set24_le(uint8_t *pos, uint32_t val)
{
*pos ++ = val & 0xFF;
*pos ++ = (val >> 8) & 0xFF;
*pos ++ = (val >> 16) & 0xFF;
}
/* Set 32-bit to a byte-array in little-endian */
__STATIC_INLINE void nu_set32_le(uint8_t *pos, uint32_t val)
{
*pos ++ = val & 0xFF;
*pos ++ = (val >> 8) & 0xFF;
*pos ++ = (val >> 16) & 0xFF;
*pos = (val >> 24) & 0xFF;
}
/* Get 16-bit from a byte-array in big-endian */
__STATIC_INLINE uint16_t nu_get16_be(const uint8_t *pos)
{
uint16_t val;
val = *pos ++;
val <<= 8;
val += *pos;
return val;
}
/* Set 16-bit to a byte-array in big-endian */
__STATIC_INLINE void nu_set16_be(uint8_t *pos, uint16_t val)
{
*pos ++ = val >> 8;
*pos = (val & 0xFF);
}
/* Get 24-bit from a byte-array in big-endian */
__STATIC_INLINE uint32_t nu_get24_be(const uint8_t *pos)
{
uint32_t val;
val = *pos ++;
val <<= 8;
val += *pos ++;
val <<= 8;
val += *pos ++;
return val;
}
/* Set 24-bit to a byte-array in big-endian */
__STATIC_INLINE void nu_set24_be(uint8_t *pos, uint32_t val)
{
*pos ++ = val >> 16;
*pos ++ = val >> 8;
*pos ++ = (val & 0xFF);
}
/* Get 32-bit from a byte-array in big-endian */
__STATIC_INLINE uint32_t nu_get32_be(const uint8_t *pos)
{
uint32_t val;
val = *pos ++;
val <<= 8;
val += *pos ++;
val <<= 8;
val += *pos ++;
val <<= 8;
val += *pos;
return val;
}
/* Set 32-bit to a byte-array in big-endian */
__STATIC_INLINE void nu_set32_be(uint8_t *pos, uint32_t val)
{
*pos ++ = val >> 24;
*pos ++ = val >> 16;
*pos ++ = val >> 8;
*pos ++ = (val & 0xFF);
}
#ifdef __cplusplus
}
#endif
#endif //__NU_BITUTIL_H__
|