TEMU  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, 2016, 2017
5 // Authors: Mattias Holm <maho (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEMU_BITMANIP_H
10 #define TEMU_BITMANIP_H
11 
12 #include <assert.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
25 static inline uint32_t
26 temu_swap32Half(uint32_t Word)
27 {
28  uint32_t Res = Word << 16 | Word >> 16;
29  return Res;
30 }
31 
37 static inline uint64_t
38 temu_swap64Word(uint64_t DWord)
39 {
40  uint64_t Res = DWord << 32 | DWord >> 32;
41  return Res;
42 }
43 
49 static inline uint16_t
50 temu_swap16(uint16_t HWord)
51 {
52 #if 1
53  uint16_t Res = __builtin_bswap16(HWord);
54 #else
55  uint16_t Res = HWord << 8 | HWord >> 8;
56 #endif
57  return Res;
58 }
59 
65 static inline uint32_t
66 temu_swap32(uint32_t Word)
67 {
68 #if 1
69  uint32_t Res = __builtin_bswap32(Word);
70 #else
71  uint32_t Res =
72  (((uint32_t)temu_swap16(Word)) << 16) | (uint32_t)temu_swap16(Word >> 16);
73 #endif
74  return Res;
75 }
76 
82 static inline uint64_t
83 temu_swap64(uint64_t DWord)
84 {
85 #if 1
86  uint64_t Res = __builtin_bswap64(DWord);
87 #else
88  uint64_t Res = (((uint64_t)temu_swap32(DWord)) << 32) |
89  (uint64_t)temu_swap32(DWord >> 32);
90 #endif
91  return Res;
92 }
93 
104 static inline uint32_t
105 temu_swapBigHost32Half(uint32_t Word)
106 {
107  return temu_swap32Half(Word);
108 }
109 
120 static inline uint64_t
121 temu_swapBigHost64Word(uint64_t DWord)
122 {
123  return temu_swap64Word(DWord);
124 }
125 
136 static inline uint32_t
137 temu_swapLittleHost32Half(uint32_t Word)
138 {
139  return Word;
140 }
141 
152 static inline uint64_t
153 temu_swapLittleHost64Word(uint64_t DWord)
154 {
155  return DWord;
156 }
157 
168 static inline uint16_t
169 temu_swapBigHost16(uint16_t HWord)
170 {
171  return temu_swap16(HWord);
172 }
173 
184 static inline uint32_t
185 temu_swapBigHost32(uint32_t Word)
186 {
187  return temu_swap32(Word);
188 }
189 
200 static inline uint64_t
201 temu_swapBigHost64(uint64_t DWord)
202 {
203  return temu_swap64(DWord);
204 }
205 
216 static inline uint16_t
217 temu_swapLittleHost16(uint16_t HWord)
218 {
219  return HWord;
220 }
221 
232 static inline uint32_t
233 temu_swapLittleHost32(uint32_t Word)
234 {
235  return Word;
236 }
237 
248 static inline uint64_t
249 temu_swapLittleHost64(uint64_t DWord)
250 {
251  return DWord;
252 }
253 
261 static inline int
262 temu_ctz32(uint32_t Word)
263 {
264  if (Word == 0)
265  return 32; // Due to semantics of compiler ctz
266  int Res = __builtin_ctz(Word);
267  return Res;
268 }
269 
276 static inline int
277 temu_clz32(uint32_t Word)
278 {
279  if (Word == 0)
280  return 32;
281  int Res = __builtin_clz(Word);
282  return Res;
283 }
284 
291 static inline int
292 temu_popcount32(uint32_t Word)
293 {
294  int Res = __builtin_popcount(Word);
295  return Res;
296 }
297 
304 static inline int
305 temu_parity32(uint32_t Word)
306 {
307  int Res = __builtin_parity(Word);
308  return Res;
309 }
310 
317 static inline int
318 temu_ctz64(uint64_t Word)
319 {
320  if (Word == 0)
321  return 64;
322  int Res = __builtin_ctzl(Word);
323  return Res;
324 }
325 
332 static inline int
333 temu_clz64(uint64_t Word)
334 {
335  if (Word == 0)
336  return 64;
337  int Res = __builtin_clzl(Word);
338  return Res;
339 }
340 
347 static inline int
348 temu_popcount64(uint64_t Word)
349 {
350  int Res = __builtin_popcountl(Word);
351  return Res;
352 }
353 
360 static inline int
361 temu_parity64(uint64_t Word)
362 {
363  int Res = __builtin_parityl(Word);
364  return Res;
365 }
366 
374 static inline int
375 temu_isPow2_32(uint32_t Word)
376 {
377  if (Word) {
378  return (Word & (Word - 1)) == 0;
379  }
380  return 0;
381 }
382 
389 static inline int
390 temu_isPow2_64(uint64_t Word)
391 {
392  if (Word) {
393  return (Word & (Word - 1)) == 0;
394  }
395  return 0;
396 }
397 
404 static inline uint32_t
405 temu_clearLeftmostBit32(uint32_t Word)
406 {
407  return Word & (Word - 1);
408 }
409 
416 static inline uint64_t
417 temu_clearLeftmostBit64(uint64_t Word)
418 {
419  return Word & (Word - 1);
420 }
421 
428 static inline uint32_t
429 temu_setRightmostZeroBit32(uint32_t Word)
430 {
431  return Word | (Word + 1);
432 }
433 
440 static inline uint64_t
441 temu_setRightmostZeoroBit64(uint64_t Word)
442 {
443  return Word | (Word + 1);
444 }
445 
452 static inline uint32_t
453 temu_isolateLeftmostBit32(uint32_t Word)
454 {
455  return Word & -Word;
456 }
457 
464 static inline uint64_t
465 temu_isolateLeftmostBit64(uint64_t Word)
466 {
467  return Word & -Word;
468 }
469 
477 static inline uint32_t
478 temu_isolateRightMostZeroBit32(uint32_t Word)
479 {
480  return (~Word) & (Word + 1);
481 }
482 
490 static inline uint64_t
491 temu_isolateRightMostZeroBit64(uint64_t Word)
492 {
493  return (~Word) & (Word + 1);
494 }
495 
502 static inline uint32_t
503 temu_identifyTrailingZeroes32(uint32_t Word)
504 {
505  return (~Word) & (Word - 1);
506 }
507 
514 static inline uint64_t
515 temu_identifyTrailingZeroes64(uint64_t Word)
516 {
517  return (~Word) & (Word - 1);
518 }
519 
526 static inline uint32_t
527 temu_identifyTrailingZeroesAndFirst32(uint32_t Word)
528 {
529  return Word ^ (Word - 1);
530 }
531 
538 static inline uint64_t
539 temu_identifyTrailingZeroesAndFirst64(uint64_t Word)
540 {
541  return Word ^ (Word - 1);
542 }
543 
550 static inline uint32_t
551 temu_propagateRightMostBit32(uint32_t Word)
552 {
553  return Word | (Word - 1);
554 }
555 
562 static inline uint64_t
563 temu_propagateRightMostBit64(uint64_t Word)
564 {
565  return Word | (Word - 1);
566 }
567 
574 static inline uint32_t
575 temu_clearRightMostBits32(uint32_t Word)
576 {
577  return ((Word | (Word - 1)) + 1) & Word;
578 }
579 
586 static inline uint64_t
587 temu_clearRightMostBits64(uint64_t Word)
588 {
589  return ((Word | (Word - 1)) + 1) & Word;
590 }
591 
599 static inline uint32_t
600 temu_roundDownToPow2_32(uint32_t Word, uint32_t Size)
601 {
602  uint32_t Res = Word & -Size;
603  return Res;
604 }
605 
613 static inline uint64_t
614 temu_roundDownToPow2_64(uint64_t Word, uint64_t Size)
615 {
616  uint64_t Res = Word & -Size;
617  return Res;
618 }
619 
627 static inline uint32_t
628 temu_roundUpToPow2_32(uint32_t Word, uint32_t Size)
629 {
630  uint32_t Res = (Word + (Size - 1)) & -Size;
631  return Res;
632 }
633 
641 static inline uint64_t
642 temu_roundUpToPow2_64(uint64_t Word, uint64_t Size)
643 {
644  uint64_t Res = (Word + (Size - 1)) & -Size;
645  return Res;
646 }
647 
656 static inline bool
657 temu_crossesBoundary32(uint32_t A, uint32_t L, uint32_t Size)
658 {
659  return -(A | -Size) < L;
660 }
661 
670 static inline bool
671 temu_crossesBoundary64(uint64_t A, uint64_t L, uint64_t Size)
672 {
673  return -(A | -Size) < L;
674 }
675 
682 static inline uint32_t
683 temu_roundUpNearestPow2_32(uint32_t Word)
684 {
685  uint32_t Res = 1 << (32 - temu_clz32(Word - 1));
686  return Res;
687 }
688 
695 static inline uint64_t
696 temu_roundUpNearestPow2_64(uint64_t Word)
697 {
698  uint64_t Res = 1 << (64 - temu_clz64(Word - 1));
699  return Res;
700 }
701 
708 static inline uint32_t
709 temu_roundDownNearestPow2_32(uint32_t Word)
710 {
711  uint32_t Res = 1 << (31 - temu_clz32(Word));
712  return Res;
713 }
714 
721 static inline uint64_t
722 temu_roundDownNearestPow2_64(uint64_t Word)
723 {
724  uint64_t Res = 1 << (63 - temu_clz64(Word));
725  return Res;
726 }
727 
738 static inline uint16_t
739 temu_bitreverse16(uint16_t Word)
740 {
741  uint32_t Res = (Word & 0x55555555) << 1 | (Word & 0xaaaaaaaa) >> 1;
742  Res = (Res & 0x33333333) << 2 | (Res & 0xcccccccc) >> 2;
743  Res = (Res & 0x0f0f0f0f) << 4 | (Res & 0xf0f0f0f0) >> 4;
744  Res = (Res & 0x00ff00ff) << 8 | (Res & 0xff00ff00) >> 8;
745  return Res;
746 }
747 
757 static inline uint32_t
758 temu_bitreverse32(uint32_t Word)
759 {
760  uint32_t Res = (Word & 0x55555555) << 1 | (Word & 0xaaaaaaaa) >> 1;
761  Res = (Res & 0x33333333) << 2 | (Res & 0xcccccccc) >> 2;
762  Res = (Res & 0x0f0f0f0f) << 4 | (Res & 0xf0f0f0f0) >> 4;
763  Res = (Res & 0x00ff00ff) << 8 | (Res & 0xff00ff00) >> 8;
764  Res = (Res & 0x0000ffff) << 16 | (Res & 0xffff0000) >> 16;
765  return Res;
766 }
767 
768 static inline uint64_t
769 temu_signExtend_8_64(uint8_t Val)
770 {
771  return (int64_t)(int8_t)Val;
772 }
773 
774 static inline uint32_t
775 temu_signExtend_8_32(uint8_t Val)
776 {
777  return (int32_t)(int8_t)Val;
778 }
779 
780 static inline uint16_t
781 temu_signExtend_8_16(uint8_t Val)
782 {
783  return (int16_t)(int8_t)Val;
784 }
785 
796 static inline uint32_t
797 temu_signed32AddOverflows(uint32_t a, uint32_t b, uint32_t carry)
798 {
799  assert(carry <= 1);
800  return ((((a + b + carry) ^ a) & ((a + b + carry) ^ b)) >> 31) & 1;
801 }
802 
803 static inline uint32_t
804 temu_rotate32Left(uint32_t a, uint32_t steps)
805 {
806  return ((a << steps) | (a >> (32 - steps)));
807 }
808 
809 static inline uint32_t
810 temu_rotate32Right(uint32_t a, uint32_t steps)
811 {
812  return ((a >> steps) | (a << (32 - steps)));
813 }
814 
815 #ifdef __cplusplus
816 }
817 #endif
818 
819 #endif /* !TEMU_BITMANIP_H */