lavu/intmath.h: Add msvc/icl ctzll optimisations.
[ffmpeg.git] / libavutil / intmath.h
1 /*
2  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #ifndef AVUTIL_INTMATH_H
22 #define AVUTIL_INTMATH_H
23
24 #include <stdint.h>
25
26 #include "config.h"
27 #include "attributes.h"
28
29 #if ARCH_ARM
30 #   include "arm/intmath.h"
31 #endif
32 #if ARCH_X86
33 #   include "x86/intmath.h"
34 #endif
35
36 #if HAVE_FAST_CLZ
37 #if defined( __INTEL_COMPILER )
38 #ifndef ff_log2
39 #   define ff_log2(x) (_bit_scan_reverse((x)|1))
40 #   ifndef ff_log2_16bit
41 #      define ff_log2_16bit av_log2
42 #   endif
43 #endif /* ff_log2 */
44 #elif AV_GCC_VERSION_AT_LEAST(3,4)
45 #ifndef ff_log2
46 #   define ff_log2(x) (31 - __builtin_clz((x)|1))
47 #   ifndef ff_log2_16bit
48 #      define ff_log2_16bit av_log2
49 #   endif
50 #endif /* ff_log2 */
51 #endif /* AV_GCC_VERSION_AT_LEAST(3,4) */
52 #endif
53
54 extern const uint8_t ff_log2_tab[256];
55
56 #ifndef ff_log2
57 #define ff_log2 ff_log2_c
58 #if !defined( _MSC_VER )
59 static av_always_inline av_const int ff_log2_c(unsigned int v)
60 {
61     int n = 0;
62     if (v & 0xffff0000) {
63         v >>= 16;
64         n += 16;
65     }
66     if (v & 0xff00) {
67         v >>= 8;
68         n += 8;
69     }
70     n += ff_log2_tab[v];
71
72     return n;
73 }
74 #else
75 static av_always_inline av_const int ff_log2_c(unsigned int v)
76 {
77     unsigned long n;
78     _BitScanReverse(&n, v|1);
79     return n;
80 }
81 #define ff_log2_16bit av_log2
82 #endif
83 #endif
84
85 #ifndef ff_log2_16bit
86 #define ff_log2_16bit ff_log2_16bit_c
87 static av_always_inline av_const int ff_log2_16bit_c(unsigned int v)
88 {
89     int n = 0;
90     if (v & 0xff00) {
91         v >>= 8;
92         n += 8;
93     }
94     n += ff_log2_tab[v];
95
96     return n;
97 }
98 #endif
99
100 #define av_log2       ff_log2
101 #define av_log2_16bit ff_log2_16bit
102
103 /**
104  * @addtogroup lavu_math
105  * @{
106  */
107
108 #if HAVE_FAST_CLZ
109 #if defined( __INTEL_COMPILER )
110 #ifndef ff_ctz
111 #define ff_ctz(v) _bit_scan_forward(v)
112 #endif
113 #elif AV_GCC_VERSION_AT_LEAST(3,4)
114 #ifndef ff_ctz
115 #define ff_ctz(v) __builtin_ctz(v)
116 #endif
117 #ifndef ff_ctzll
118 #define ff_ctzll(v) __builtin_ctzll(v)
119 #endif
120 #endif
121 #endif
122
123 #ifndef ff_ctz
124 #define ff_ctz ff_ctz_c
125 /**
126  * Trailing zero bit count.
127  *
128  * @param v  input value. If v is 0, the result is undefined.
129  * @return   the number of trailing 0-bits
130  */
131 #if !defined( _MSC_VER )
132 /* We use the De-Bruijn method outlined in:
133  * http://supertech.csail.mit.edu/papers/debruijn.pdf. */
134 static av_always_inline av_const int ff_ctz_c(int v)
135 {
136     static const uint8_t debruijn_ctz32[32] = {
137         0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
138         31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
139     };
140     return debruijn_ctz32[(uint32_t)((v & -v) * 0x077CB531U) >> 27];
141 }
142 #else
143 static av_always_inline av_const int ff_ctz_c( int v )
144 {
145     unsigned long c;
146     _BitScanForward(&c, v);
147     return c;
148 }
149 #endif
150 #endif
151
152 #ifndef ff_ctzll
153 #define ff_ctzll ff_ctzll_c
154 /* We use the De-Bruijn method outlined in:
155  * http://supertech.csail.mit.edu/papers/debruijn.pdf. */
156 static av_always_inline av_const int ff_ctzll_c(long long v)
157 {
158     static const uint8_t debruijn_ctz64[64] = {
159         0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
160         62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
161         63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
162         51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
163     };
164     return debruijn_ctz64[(uint64_t)((v & -v) * 0x022FDD63CC95386D) >> 58];
165 }
166 #endif
167
168 /**
169  * @}
170  */
171 #endif /* AVUTIL_INTMATH_H */