mathops.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #if !defined(_mathops_H)
  2. # define _mathops_H (1)
  3. # include <ogg/ogg.h>
  4. # ifdef __GNUC_PREREQ
  5. # if __GNUC_PREREQ(3,4)
  6. # include <limits.h>
  7. /*Note the casts to (int) below: this prevents OC_CLZ{32|64}_OFFS from
  8. "upgrading" the type of an entire expression to an (unsigned) size_t.*/
  9. # if INT_MAX>=2147483647
  10. # define OC_CLZ32_OFFS ((int)sizeof(unsigned)*CHAR_BIT)
  11. # define OC_CLZ32(_x) (__builtin_clz(_x))
  12. # elif LONG_MAX>=2147483647L
  13. # define OC_CLZ32_OFFS ((int)sizeof(unsigned long)*CHAR_BIT)
  14. # define OC_CLZ32(_x) (__builtin_clzl(_x))
  15. # endif
  16. # if INT_MAX>=9223372036854775807LL
  17. # define OC_CLZ64_OFFS ((int)sizeof(unsigned)*CHAR_BIT)
  18. # define OC_CLZ64(_x) (__builtin_clz(_x))
  19. # elif LONG_MAX>=9223372036854775807LL
  20. # define OC_CLZ64_OFFS ((int)sizeof(unsigned long)*CHAR_BIT)
  21. # define OC_CLZ64(_x) (__builtin_clzl(_x))
  22. # elif LLONG_MAX>=9223372036854775807LL|| \
  23. __LONG_LONG_MAX__>=9223372036854775807LL
  24. # define OC_CLZ64_OFFS ((int)sizeof(unsigned long long)*CHAR_BIT)
  25. # define OC_CLZ64(_x) (__builtin_clzll(_x))
  26. # endif
  27. # endif
  28. # endif
  29. /**
  30. * oc_ilog32 - Integer binary logarithm of a 32-bit value.
  31. * @_v: A 32-bit value.
  32. * Returns floor(log2(_v))+1, or 0 if _v==0.
  33. * This is the number of bits that would be required to represent _v in two's
  34. * complement notation with all of the leading zeros stripped.
  35. * The OC_ILOG_32() or OC_ILOGNZ_32() macros may be able to use a builtin
  36. * function instead, which should be faster.
  37. */
  38. int oc_ilog32(ogg_uint32_t _v);
  39. /**
  40. * oc_ilog64 - Integer binary logarithm of a 64-bit value.
  41. * @_v: A 64-bit value.
  42. * Returns floor(log2(_v))+1, or 0 if _v==0.
  43. * This is the number of bits that would be required to represent _v in two's
  44. * complement notation with all of the leading zeros stripped.
  45. * The OC_ILOG_64() or OC_ILOGNZ_64() macros may be able to use a builtin
  46. * function instead, which should be faster.
  47. */
  48. int oc_ilog64(ogg_int64_t _v);
  49. # if defined(OC_CLZ32)
  50. /**
  51. * OC_ILOGNZ_32 - Integer binary logarithm of a non-zero 32-bit value.
  52. * @_v: A non-zero 32-bit value.
  53. * Returns floor(log2(_v))+1.
  54. * This is the number of bits that would be required to represent _v in two's
  55. * complement notation with all of the leading zeros stripped.
  56. * If _v is zero, the return value is undefined; use OC_ILOG_32() instead.
  57. */
  58. # define OC_ILOGNZ_32(_v) (OC_CLZ32_OFFS-OC_CLZ32(_v))
  59. /**
  60. * OC_ILOG_32 - Integer binary logarithm of a 32-bit value.
  61. * @_v: A 32-bit value.
  62. * Returns floor(log2(_v))+1, or 0 if _v==0.
  63. * This is the number of bits that would be required to represent _v in two's
  64. * complement notation with all of the leading zeros stripped.
  65. */
  66. # define OC_ILOG_32(_v) (OC_ILOGNZ_32(_v)&-!!(_v))
  67. # else
  68. # define OC_ILOGNZ_32(_v) (oc_ilog32(_v))
  69. # define OC_ILOG_32(_v) (oc_ilog32(_v))
  70. # endif
  71. # if defined(CLZ64)
  72. /**
  73. * OC_ILOGNZ_64 - Integer binary logarithm of a non-zero 64-bit value.
  74. * @_v: A non-zero 64-bit value.
  75. * Returns floor(log2(_v))+1.
  76. * This is the number of bits that would be required to represent _v in two's
  77. * complement notation with all of the leading zeros stripped.
  78. * If _v is zero, the return value is undefined; use OC_ILOG_64() instead.
  79. */
  80. # define OC_ILOGNZ_64(_v) (CLZ64_OFFS-CLZ64(_v))
  81. /**
  82. * OC_ILOG_64 - Integer binary logarithm of a 64-bit value.
  83. * @_v: A 64-bit value.
  84. * Returns floor(log2(_v))+1, or 0 if _v==0.
  85. * This is the number of bits that would be required to represent _v in two's
  86. * complement notation with all of the leading zeros stripped.
  87. */
  88. # define OC_ILOG_64(_v) (OC_ILOGNZ_64(_v)&-!!(_v))
  89. # else
  90. # define OC_ILOGNZ_64(_v) (oc_ilog64(_v))
  91. # define OC_ILOG_64(_v) (oc_ilog64(_v))
  92. # endif
  93. # define OC_STATIC_ILOG0(_v) (!!(_v))
  94. # define OC_STATIC_ILOG1(_v) (((_v)&0x2)?2:OC_STATIC_ILOG0(_v))
  95. # define OC_STATIC_ILOG2(_v) \
  96. (((_v)&0xC)?2+OC_STATIC_ILOG1((_v)>>2):OC_STATIC_ILOG1(_v))
  97. # define OC_STATIC_ILOG3(_v) \
  98. (((_v)&0xF0)?4+OC_STATIC_ILOG2((_v)>>4):OC_STATIC_ILOG2(_v))
  99. # define OC_STATIC_ILOG4(_v) \
  100. (((_v)&0xFF00)?8+OC_STATIC_ILOG3((_v)>>8):OC_STATIC_ILOG3(_v))
  101. # define OC_STATIC_ILOG5(_v) \
  102. (((_v)&0xFFFF0000)?16+OC_STATIC_ILOG4((_v)>>16):OC_STATIC_ILOG4(_v))
  103. # define OC_STATIC_ILOG6(_v) \
  104. (((_v)&0xFFFFFFFF00000000ULL)?32+OC_STATIC_ILOG5((_v)>>32):OC_STATIC_ILOG5(_v))
  105. /**
  106. * OC_STATIC_ILOG_32 - The integer logarithm of an (unsigned, 32-bit) constant.
  107. * @_v: A non-negative 32-bit constant.
  108. * Returns floor(log2(_v))+1, or 0 if _v==0.
  109. * This is the number of bits that would be required to represent _v in two's
  110. * complement notation with all of the leading zeros stripped.
  111. * This macro is suitable for evaluation at compile time, but it should not be
  112. * used on values that can change at runtime, as it operates via exhaustive
  113. * search.
  114. */
  115. # define OC_STATIC_ILOG_32(_v) (OC_STATIC_ILOG5((ogg_uint32_t)(_v)))
  116. /**
  117. * OC_STATIC_ILOG_64 - The integer logarithm of an (unsigned, 64-bit) constant.
  118. * @_v: A non-negative 64-bit constant.
  119. * Returns floor(log2(_v))+1, or 0 if _v==0.
  120. * This is the number of bits that would be required to represent _v in two's
  121. * complement notation with all of the leading zeros stripped.
  122. * This macro is suitable for evaluation at compile time, but it should not be
  123. * used on values that can change at runtime, as it operates via exhaustive
  124. * search.
  125. */
  126. # define OC_STATIC_ILOG_64(_v) (OC_STATIC_ILOG6((ogg_int64_t)(_v)))
  127. #define OC_Q57(_v) ((ogg_int64_t)(_v)<<57)
  128. ogg_int64_t oc_bexp64(ogg_int64_t _z);
  129. ogg_int64_t oc_blog64(ogg_int64_t _w);
  130. #endif