Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
4.3KB

  1. #ifndef INCLUDED_tlsfbits
  2. #define INCLUDED_tlsfbits
  3. #if defined(__cplusplus)
  4. #define tlsf_decl inline
  5. #else
  6. #define tlsf_decl static
  7. #endif
  8. /*
  9. ** Architecture-specific bit manipulation routines.
  10. **
  11. ** TLSF achieves O(1) cost for malloc and free operations by limiting
  12. ** the search for a free block to a free list of guaranteed size
  13. ** adequate to fulfill the request, combined with efficient free list
  14. ** queries using bitmasks and architecture-specific bit-manipulation
  15. ** routines.
  16. **
  17. ** Most modern processors provide instructions to count leading zeroes
  18. ** in a word, find the lowest and highest set bit, etc. These
  19. ** specific implementations will be used when available, falling back
  20. ** to a reasonably efficient generic implementation.
  21. **
  22. ** NOTE: TLSF spec relies on ffs/fls returning value 0..31.
  23. ** ffs/fls return 1-32 by default, returning 0 for error.
  24. */
  25. /*
  26. ** Detect whether or not we are building for a 32- or 64-bit (LP/LLP)
  27. ** architecture. There is no reliable portable method at compile-time.
  28. */
  29. #if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) \
  30. || defined (_WIN64) || defined (__LP64__) || defined (__LLP64__)
  31. #define TLSF_64BIT
  32. #endif
  33. /*
  34. ** gcc 3.4 and above have builtin support, specialized for architecture.
  35. ** Some compilers masquerade as gcc; patchlevel test filters them out.
  36. */
  37. #if defined (__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
  38. && defined (__GNUC_PATCHLEVEL__)
  39. tlsf_decl int tlsf_ffs(unsigned int word)
  40. {
  41. return __builtin_ffs(word) - 1;
  42. }
  43. tlsf_decl int tlsf_fls(unsigned int word)
  44. {
  45. const int bit = word ? 32 - __builtin_clz(word) : 0;
  46. return bit - 1;
  47. }
  48. #elif defined (_MSC_VER) && (_MSC_VER >= 1400) && (defined (_M_IX86) || defined (_M_X64))
  49. /* Microsoft Visual C++ support on x86/X64 architectures. */
  50. #include <intrin.h>
  51. #pragma intrinsic(_BitScanReverse)
  52. #pragma intrinsic(_BitScanForward)
  53. tlsf_decl int tlsf_fls(unsigned int word)
  54. {
  55. unsigned long index;
  56. return _BitScanReverse(&index, word) ? index : -1;
  57. }
  58. tlsf_decl int tlsf_ffs(unsigned int word)
  59. {
  60. unsigned long index;
  61. return _BitScanForward(&index, word) ? index : -1;
  62. }
  63. #elif defined (_MSC_VER) && defined (_M_PPC)
  64. /* Microsoft Visual C++ support on PowerPC architectures. */
  65. #include <ppcintrinsics.h>
  66. tlsf_decl int tlsf_fls(unsigned int word)
  67. {
  68. const int bit = 32 - _CountLeadingZeros(word);
  69. return bit - 1;
  70. }
  71. tlsf_decl int tlsf_ffs(unsigned int word)
  72. {
  73. const unsigned int reverse = word & (~word + 1);
  74. const int bit = 32 - _CountLeadingZeros(reverse);
  75. return bit - 1;
  76. }
  77. #elif defined (__ARMCC_VERSION)
  78. /* RealView Compilation Tools for ARM */
  79. tlsf_decl int tlsf_ffs(unsigned int word)
  80. {
  81. const unsigned int reverse = word & (~word + 1);
  82. const int bit = 32 - __clz(reverse);
  83. return bit - 1;
  84. }
  85. tlsf_decl int tlsf_fls(unsigned int word)
  86. {
  87. const int bit = word ? 32 - __clz(word) : 0;
  88. return bit - 1;
  89. }
  90. #elif defined (__ghs__)
  91. /* Green Hills support for PowerPC */
  92. #include <ppc_ghs.h>
  93. tlsf_decl int tlsf_ffs(unsigned int word)
  94. {
  95. const unsigned int reverse = word & (~word + 1);
  96. const int bit = 32 - __CLZ32(reverse);
  97. return bit - 1;
  98. }
  99. tlsf_decl int tlsf_fls(unsigned int word)
  100. {
  101. const int bit = word ? 32 - __CLZ32(word) : 0;
  102. return bit - 1;
  103. }
  104. #else
  105. /* Fall back to generic implementation. */
  106. tlsf_decl int tlsf_fls_generic(unsigned int word)
  107. {
  108. int bit = 32;
  109. if (!word) bit -= 1;
  110. if (!(word & 0xffff0000)) { word <<= 16; bit -= 16; }
  111. if (!(word & 0xff000000)) { word <<= 8; bit -= 8; }
  112. if (!(word & 0xf0000000)) { word <<= 4; bit -= 4; }
  113. if (!(word & 0xc0000000)) { word <<= 2; bit -= 2; }
  114. if (!(word & 0x80000000)) { word <<= 1; bit -= 1; }
  115. return bit;
  116. }
  117. /* Implement ffs in terms of fls. */
  118. tlsf_decl int tlsf_ffs(unsigned int word)
  119. {
  120. return tlsf_fls_generic(word & (~word + 1)) - 1;
  121. }
  122. tlsf_decl int tlsf_fls(unsigned int word)
  123. {
  124. return tlsf_fls_generic(word) - 1;
  125. }
  126. #endif
  127. /* Possibly 64-bit version of tlsf_fls. */
  128. #if defined (TLSF_64BIT)
  129. tlsf_decl int tlsf_fls_sizet(size_t size)
  130. {
  131. int high = (int)(size >> 32);
  132. int bits = 0;
  133. if (high)
  134. {
  135. bits = 32 + tlsf_fls(high);
  136. }
  137. else
  138. {
  139. bits = tlsf_fls((int)size & 0xffffffff);
  140. }
  141. return bits;
  142. }
  143. #else
  144. #define tlsf_fls_sizet tlsf_fls
  145. #endif
  146. #undef tlsf_decl
  147. #endif