T-EMU  2
The Terma Emulator
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
Bitmanip.h
Go to the documentation of this file.
1 //===-- temu-c/Bitmanip.h - Low level bit/byte manipulation -----*- C++ -*-===//
2 //
3 // T-EMU: The Terma Emulator
4 // (c) Terma 2015
5 // Authors: Mattias Holm <maho (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEMU_BITMANIP_H
10 #define TEMU_BITMANIP_H
11 
12 #include <stdint.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 // Swap half words inside 32 bit word
19 static inline uint32_t
20 temu_swap32Half(uint32_t Word)
21 {
22  uint32_t Res = Word << 16 | Word >> 16;
23  return Res;
24 }
25 
26 // Swap words inside 64 bit word
27 static inline uint64_t
28 temu_swap64Word(uint64_t DWord)
29 {
30  uint64_t Res = DWord << 32 | DWord >> 32;
31  return Res;
32 }
33 
34 
35 // Swap bytes in 16 bit word
36 static inline uint16_t
37 temu_swap16(uint16_t HWord)
38 {
39 #if 1
40  uint16_t Res = __builtin_bswap16(HWord);
41 #else
42  uint16_t Res = HWord << 8 | HWord >> 8;
43 #endif
44  return Res;
45 }
46 
47 // Swap bytes in 32 bit word
48 static inline uint32_t
49 temu_swap32(uint32_t Word)
50 {
51 #if 1
52  uint32_t Res = __builtin_bswap32(Word);
53 #else
54  uint32_t Res = (((uint32_t)temu_swap16(Word)) << 16)
55  | (uint32_t)temu_swap16(Word >> 16);
56 #endif
57  return Res;
58 }
59 
60 // Swap bytes in 64 bit word
61 static inline uint64_t
62 temu_swap64(uint64_t DWord)
63 {
64 #if 1
65  uint64_t Res = __builtin_bswap64(DWord);
66 #else
67  uint64_t Res = (((uint64_t)temu_swap32(DWord)) << 32)
68  | (uint64_t)temu_swap32(DWord >> 32);
69 #endif
70  return Res;
71 }
72 
73 // Swap between big endian and host endian. Note that at present we
74 // only have little endian hosts, so these functions simply
75 // wrap. However, they declare intent and it is recommended that you
76 // use these for swapping when you want to go between little<->host
77 // and big<->host.
78 
79 static inline uint32_t
80 temu_swapBigHost32Half(uint32_t Word)
81 {
82  return temu_swap32Half(Word);
83 }
84 
85 
86 static inline uint64_t
87 temu_swapBigHost64Word(uint64_t DWord)
88 {
89  return temu_swap64Word(DWord);
90 }
91 
92 
93 static inline uint32_t
94 temu_swapLittleHost32Half(uint32_t Word)
95 {
96  return Word;
97 }
98 
99 
100 static inline uint64_t
101 temu_swapLittleHost64Word(uint64_t DWord)
102 {
103  return DWord;
104 }
105 
106 
107 static inline uint16_t
108 temu_swapBigHost16(uint16_t HWord)
109 {
110  return temu_swap16(HWord);
111 }
112 
113 static inline uint32_t
114 temu_swapBigHost32(uint32_t Word)
115 {
116  return temu_swap32(Word);
117 }
118 
119 static inline uint64_t
120 temu_swapBigHost64(uint64_t DWord)
121 {
122  return temu_swap64(DWord);
123 }
124 
125 static inline uint16_t
126 temu_swapLittleHost16(uint16_t HWord)
127 {
128  return HWord;
129 }
130 
131 static inline uint32_t
132 temu_swapLittleHost32(uint32_t Word)
133 {
134  return Word;
135 }
136 
137 static inline uint64_t
138 temu_swapLittleHost64(uint64_t DWord)
139 {
140  return DWord;
141 }
142 
143 
144 // Count trailing zeroes, this can be used as a square root on a power
145 // of 2 word.
146 static inline int
147 temu_ctz32(uint32_t Word)
148 {
149  if (Word == 0) return 32; // Due to semantics of compiler ctz
150  int Res = __builtin_ctz(Word);
151  return Res;
152 }
153 
154 // Count leading zeroes
155 static inline int
156 temu_clz32(uint32_t Word)
157 {
158  if (Word == 0) return 32;
159  int Res = __builtin_clz(Word);
160  return Res;
161 }
162 
163 // Count number of bits set in word
164 static inline int
165 temu_popcount32(uint32_t Word)
166 {
167  int Res = __builtin_popcount(Word);
168  return Res;
169 }
170 
171 // Compute parity of word
172 static inline int
173 temu_parity32(uint32_t Word)
174 {
175  int Res = __builtin_parity(Word);
176  return Res;
177 }
178 
179 
180 // Count trailing zeroes
181 static inline int
182 temu_ctz64(uint64_t Word)
183 {
184  if (Word == 0) return 64;
185  int Res = __builtin_ctzl(Word);
186  return Res;
187 }
188 
189 // Count leading zeroes
190 static inline int
191 temu_clz64(uint64_t Word)
192 {
193  if (Word == 0) return 64;
194  int Res = __builtin_clzl(Word);
195  return Res;
196 }
197 
198 // Count count number of bit set
199 static inline int
200 temu_popcount64(uint64_t Word)
201 {
202  int Res = __builtin_popcountl(Word);
203  return Res;
204 }
205 
206 // Compute parity
207 static inline int
208 temu_parity64(uint64_t Word)
209 {
210  int Res = __builtin_parityl(Word);
211  return Res;
212 }
213 
214 // Predicate for checking if word is a power of 2
215 // See Hacker's Delight, 1st edition, p11
216 static inline int
217 temu_isPow2_32(uint32_t Word)
218 {
219  if (Word) {
220  return (Word & (Word - 1)) == 0;
221  }
222  return 0;
223 }
224 
225 // Predicate for checking if word is a power of 2
226 //
227 static inline int
228 temu_isPow2_64(uint64_t Word)
229 {
230  if (Word) {
231  return (Word & (Word - 1)) == 0;
232  }
233  return 0;
234 }
235 
236 // Clear lower set bit in word
237 static inline uint32_t
238 temu_clearLeftmostBit32(uint32_t Word)
239 {
240  return Word & (Word - 1);
241 }
242 
243 static inline uint64_t
244 temu_clearLeftmostBit64(uint64_t Word)
245 {
246  return Word & (Word - 1);
247 }
248 
249 // Set right most bit that is zero
250 static inline uint32_t
251 temu_setRightmostZeroBit32(uint32_t Word)
252 {
253  return Word | (Word + 1);
254 }
255 
256 static inline uint64_t
257 temu_setRightmostZeoroBit64(uint64_t Word)
258 {
259  return Word | (Word + 1);
260 }
261 
262 // Isolate left most bit
263 static inline uint32_t
264 temu_isolateLeftmostBit32(uint32_t Word)
265 {
266  return Word & -Word;
267 }
268 
269 static inline uint64_t
270 temu_isolateLeftmostBit64(uint64_t Word)
271 {
272  return Word & -Word;
273 
274 }
275 
276 // Isolate right most bit with value zero (it will be 1 in the result)
277 static inline uint32_t
278 temu_isolateRightMostZeroBit32(uint32_t Word)
279 {
280  return (~Word) & (Word+1);
281 }
282 static inline uint64_t
283 temu_isolateRightMostZeroBit64(uint64_t Word)
284 {
285  return (~Word) & (Word+1);
286 }
287 
288 // Get word with all trailing zeroes set
289 static inline uint32_t
290 temu_identifyTrailingZeroes32(uint32_t Word)
291 {
292  return (~Word) & (Word-1);
293 }
294 
295 
296 static inline uint64_t
297 temu_identifyTrailingZeroes64(uint64_t Word)
298 {
299  return (~Word) & (Word-1);
300 }
301 
302 // Get word with all trailing zeroes set, and the fist bit set
303 static inline uint32_t
304 temu_identifyTrailingZeroesAndFirst32(uint32_t Word)
305 {
306  return Word ^ (Word-1);
307 }
308 
309 
310 static inline uint64_t
311 temu_identifyTrailingZeroesAndFirst64(uint64_t Word)
312 {
313  return Word ^ (Word-1);
314 }
315 
316 
317 static inline uint32_t
318 temu_propagateRightMostBit32(uint32_t Word)
319 {
320  return Word | (Word-1);
321 }
322 
323 static inline uint64_t
324 temu_propagateRightMostBit64(uint64_t Word)
325 {
326  return Word | (Word-1);
327 }
328 
329 static inline uint32_t
330 temu_clearRightMostBits32(uint32_t Word)
331 {
332  return ((Word | (Word-1)) + 1) & Word;
333 }
334 
335 static inline uint64_t
336 temu_clearRightMostBits64(uint64_t Word)
337 {
338  return ((Word | (Word-1)) + 1) & Word;
339 }
340 
341 
342 
343 #ifdef __cplusplus
344 }
345 #endif
346 
347 #endif /* !TEMU_BITMANIP_H */