nu_bitutil.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-2-7 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #ifndef __NU_BITUTIL_H__
  13. #define __NU_BITUTIL_H__
  14. #if defined(__ICCARM__)
  15. #include <arm_math.h>
  16. #endif
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. /* ----------------------------------------------
  21. * Count Leading Zeros Count Trailing Zeros
  22. * (MSB)00000000000000001000000000001000(LSB)
  23. * ################| |!!!
  24. * Find Highest Set Find First Set
  25. * ----------------------------------------------
  26. *
  27. * ----------------------------------------------
  28. * Count Leading Ones Count Trailing Ones
  29. * (MSB)11111111111111110111111111110111(LSB)
  30. * ^^^^^^^^^^^^^^^^| |@@@
  31. * Find Highest Zero Find First Zero
  32. * ----------------------------------------------
  33. */
  34. /* Count Leading Zeros in word - Find Highest Set
  35. EX: x=(MSB)00000000000000001000000000001000(LSB)
  36. ################|
  37. Find Highest Set
  38. nu_clz will start zero-counting from MSB and return the number.
  39. */
  40. __STATIC_INLINE int nu_clz(uint32_t x)
  41. {
  42. return x ? __CLZ(x):32;
  43. }
  44. /* Count Leading Ones in word - Find Highest Zero
  45. EX: x=(MSB)11111111111111110111111111110111(LSB)
  46. ^^^^^^^^^^^^^^^^|
  47. Find Highest Zero
  48. nu_clo will start one-counting from MSB and return the number.
  49. */
  50. __STATIC_INLINE int nu_clo(uint32_t x)
  51. {
  52. return nu_clz(~x);
  53. }
  54. /* Count Trailing Zero in word - Find First Set
  55. EX: x=(MSB)00000000000000001000000000001000(LSB)
  56. |!!!
  57. Find First Set
  58. nu_ctz will start zero-counting from LSB and return the number.
  59. */
  60. __STATIC_INLINE int nu_ctz(uint32_t x)
  61. {
  62. int c = 32;
  63. if (x)
  64. c = __CLZ(x & -x);
  65. return x ? 31 - c : c;
  66. }
  67. /* Count Trailing Ones in word - Find First Zero
  68. EX: x=(MSB)11111111111111110111111111110111(LSB)
  69. |@@@
  70. Find First Zero
  71. nu_cto will start one-counting from LSB and return the number.
  72. */
  73. __STATIC_INLINE int nu_cto(uint32_t x)
  74. {
  75. return nu_ctz(~x);
  76. }
  77. /* Get 16-bit from a byte-array in little-endian */
  78. __STATIC_INLINE uint16_t nu_get16_le(const uint8_t *pos)
  79. {
  80. uint16_t val;
  81. val = *pos ++;
  82. val += (*pos << 8);
  83. return val;
  84. }
  85. /* Set 16-bit to a byte-array in little-endian */
  86. __STATIC_INLINE void nu_set16_le(uint8_t *pos, uint16_t val)
  87. {
  88. *pos ++ = val & 0xFF;
  89. *pos = val >> 8;
  90. }
  91. /* Get 32-bit from a byte-array in little-endian */
  92. __STATIC_INLINE uint32_t nu_get32_le(const uint8_t *pos)
  93. {
  94. uint32_t val;
  95. val = *pos ++;
  96. val += (*pos ++ << 8);
  97. val += (*pos ++ << 16);
  98. val += (*pos ++ << 24);
  99. return val;
  100. }
  101. /* Get 24-bit from a byte-array in little-endian */
  102. __STATIC_INLINE uint32_t nu_get24_le(const uint8_t *pos)
  103. {
  104. uint32_t val;
  105. val = *pos ++;
  106. val += (*pos ++ << 8);
  107. val += (*pos ++ << 16);
  108. return val;
  109. }
  110. /* Set 24-bit to a byte-array in little-endian */
  111. __STATIC_INLINE void nu_set24_le(uint8_t *pos, uint32_t val)
  112. {
  113. *pos ++ = val & 0xFF;
  114. *pos ++ = (val >> 8) & 0xFF;
  115. *pos ++ = (val >> 16) & 0xFF;
  116. }
  117. /* Set 32-bit to a byte-array in little-endian */
  118. __STATIC_INLINE void nu_set32_le(uint8_t *pos, uint32_t val)
  119. {
  120. *pos ++ = val & 0xFF;
  121. *pos ++ = (val >> 8) & 0xFF;
  122. *pos ++ = (val >> 16) & 0xFF;
  123. *pos = (val >> 24) & 0xFF;
  124. }
  125. /* Get 16-bit from a byte-array in big-endian */
  126. __STATIC_INLINE uint16_t nu_get16_be(const uint8_t *pos)
  127. {
  128. uint16_t val;
  129. val = *pos ++;
  130. val <<= 8;
  131. val += *pos;
  132. return val;
  133. }
  134. /* Set 16-bit to a byte-array in big-endian */
  135. __STATIC_INLINE void nu_set16_be(uint8_t *pos, uint16_t val)
  136. {
  137. *pos ++ = val >> 8;
  138. *pos = (val & 0xFF);
  139. }
  140. /* Get 24-bit from a byte-array in big-endian */
  141. __STATIC_INLINE uint32_t nu_get24_be(const uint8_t *pos)
  142. {
  143. uint32_t val;
  144. val = *pos ++;
  145. val <<= 8;
  146. val += *pos ++;
  147. val <<= 8;
  148. val += *pos ++;
  149. return val;
  150. }
  151. /* Set 24-bit to a byte-array in big-endian */
  152. __STATIC_INLINE void nu_set24_be(uint8_t *pos, uint32_t val)
  153. {
  154. *pos ++ = val >> 16;
  155. *pos ++ = val >> 8;
  156. *pos ++ = (val & 0xFF);
  157. }
  158. /* Get 32-bit from a byte-array in big-endian */
  159. __STATIC_INLINE uint32_t nu_get32_be(const uint8_t *pos)
  160. {
  161. uint32_t val;
  162. val = *pos ++;
  163. val <<= 8;
  164. val += *pos ++;
  165. val <<= 8;
  166. val += *pos ++;
  167. val <<= 8;
  168. val += *pos;
  169. return val;
  170. }
  171. /* Set 32-bit to a byte-array in big-endian */
  172. __STATIC_INLINE void nu_set32_be(uint8_t *pos, uint32_t val)
  173. {
  174. *pos ++ = val >> 24;
  175. *pos ++ = val >> 16;
  176. *pos ++ = val >> 8;
  177. *pos ++ = (val & 0xFF);
  178. }
  179. #ifdef __cplusplus
  180. }
  181. #endif
  182. #endif //__NU_BITUTIL_H__