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