Advertisement
Guest User

bitmap with bit instructions

a guest
Oct 20th, 2014
769
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.21 KB | None | 0 0
  1. /*
  2.  * Copyright (c) 2014 The Native Client Authors. All rights reserved.
  3.  * Use of this source code is governed by a BSD-style license that can be
  4.  * found in the LICENSE file.
  5.  */
  6.  
  7. #ifndef BITMAP_H_
  8. #define BITMAP_H_
  9.  
  10. #include <stdbool.h>
  11. #include <stddef.h>
  12. #include <stdint.h>
  13. #include <stdlib.h>
  14.  
  15. #if defined(_MSC_VER)
  16. # define BITMAP_INLINE __forceinline
  17. #elif defined(__GNUC__)
  18. # define BITMAP_INLINE __inline __attribute__ ((always_inline))
  19. #else
  20. # define BITMAP_INLINE inline
  21. #endif
  22.  
  23. #if defined(__LP64__) || defined(_WIN64)
  24. typedef uint64_t bitmap_word;
  25. #else
  26. typedef uint64_t bitmap_word;
  27. #endif
  28.  
  29. static BITMAP_INLINE bitmap_word *bitmap_allocate(size_t indexes) {
  30.   size_t word_count = ((indexes + sizeof(bitmap_word) - 1) / sizeof(bitmap_word));
  31.   return (bitmap_word*)calloc(word_count, sizeof(bitmap_word));
  32. }
  33.  
  34. #if (defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && \
  35.     !defined(__native_client__))
  36.  
  37. /*
  38.  * Unfortunately limitations of GNU inline assembler make it impossible for us
  39.  * to create a single "perfect" function.  Thus we have two functions here.
  40.  * Use bitmap_bit_is_set in "if (bitmap_bit_is_set(...))" constructs.
  41.  * Use bitmap_is_bit_set in "a |= bitmap_is_bit_set(...)" constructs.
  42.  */
  43. static BITMAP_INLINE bool bitmap_bit_is_set(bitmap_word bitmap[],
  44.                                             size_t index) {
  45.   bool flag;
  46.   asm goto ("bt {%[index],%[bitmap]|%[bitmap],%[index]}\n"
  47.             "jc %l2"
  48.             :
  49.             : [bitmap]"m" (*bitmap),
  50.               [index]"r"(index)
  51.             : "cc"
  52.             : bit_is_set);
  53.   return 0;
  54. bit_is_set:
  55.   return 1;
  56. }
  57.  
  58. static BITMAP_INLINE bool bitmap_is_bit_set(bitmap_word bitmap[],
  59.                                             size_t index) {
  60.   bool flag;
  61.   asm("bt {%[index],%[bitmap]|%[bitmap],%[index]}\n"
  62.       "setb %[flag]"
  63.       : [flag]"=q"(flag)
  64.       : [bitmap]"m" (*bitmap),
  65.         [index]"r"(index)
  66.       : "cc");
  67.   return flag;
  68. }
  69.  
  70. static BITMAP_INLINE void bitmap_set_bit(bitmap_word bitmap[], size_t index) {
  71.   asm("bts {%[index],%[bitmap]|%[bitmap],%[index]}"
  72.       : [bitmap]"+m" (*bitmap)
  73.       : [index]"r"(index));
  74. }
  75.  
  76. static BITMAP_INLINE void bitmap_clear_bit(bitmap_word bitmap[], size_t index) {
  77.   asm("btc {%[index],%[bitmap]|%[bitmap],%[index]}"
  78.       : [bitmap]"+m" (*bitmap)
  79.       : [index]"r"(index));
  80. }
  81.  
  82. #else
  83.  
  84. static BITMAP_INLINE bool bitmap_bit_is_set(bitmap_word bitmap[],
  85.                                             size_t index) {
  86.   return (bitmap[index / sizeof *bitmap] &
  87.       (((bitmap_word)1) << (index % sizeof *bitmap))) != 0;
  88. }
  89.  
  90. static BITMAP_INLINE bool bitmap_is_bit_set(bitmap_word bitmap[],
  91.                                             size_t index) {
  92.   return (bitmap[index / sizeof *bitmap] &
  93.       (((bitmap_word)1) << (index % sizeof *bitmap))) != 0;
  94. }
  95.  
  96. static BITMAP_INLINE void bitmap_set_bit(bitmap_word bitmap[], size_t index) {
  97.   bitmap[index / sizeof *bitmap] |=
  98.       ((bitmap_word)1) << (index % sizeof *bitmap);
  99. }
  100.  
  101. static BITMAP_INLINE void bitmap_clear_bit(bitmap_word *bitmap, size_t index) {
  102.   bitmap[index / sizeof *bitmap] &=
  103.       ~(((bitmap_word)1) << (index % sizeof *bitmap));
  104. }
  105.  
  106. #endif
  107.  
  108. #endif  /* BITMAP_H */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement